@umituz/react-native-settings 4.20.55 → 4.20.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -3
- package/package.json +1 -2
- package/src/application/README.md +322 -0
- package/src/domains/about/README.md +452 -0
- package/src/domains/about/presentation/hooks/README.md +350 -0
- package/src/domains/appearance/README.md +596 -0
- package/src/domains/appearance/hooks/README.md +366 -0
- package/src/domains/appearance/infrastructure/services/README.md +455 -0
- package/src/domains/cloud-sync/README.md +451 -0
- package/src/domains/cloud-sync/presentation/components/README.md +493 -0
- package/src/domains/dev/README.md +477 -0
- package/src/domains/disclaimer/README.md +421 -0
- package/src/domains/disclaimer/presentation/components/README.md +394 -0
- package/src/domains/faqs/README.md +586 -0
- package/src/domains/feedback/README.md +565 -0
- package/src/domains/feedback/presentation/hooks/README.md +428 -0
- package/src/domains/legal/README.md +549 -0
- package/src/domains/rating/README.md +452 -0
- package/src/domains/rating/presentation/components/README.md +475 -0
- package/src/domains/video-tutorials/README.md +482 -0
- package/src/domains/video-tutorials/presentation/components/README.md +433 -0
- package/src/infrastructure/README.md +509 -0
- package/src/infrastructure/repositories/README.md +475 -0
- package/src/infrastructure/services/README.md +510 -0
- package/src/presentation/components/README.md +482 -0
- package/src/presentation/components/SettingsErrorBoundary/README.md +461 -0
- package/src/presentation/components/SettingsFooter/README.md +446 -0
- package/src/presentation/components/SettingsItemCard/README.md +457 -0
- package/src/presentation/components/SettingsSection/README.md +421 -0
- package/src/presentation/hooks/README.md +413 -0
- package/src/presentation/hooks/mutations/README.md +430 -0
- package/src/presentation/hooks/queries/README.md +441 -0
- package/src/presentation/navigation/README.md +532 -0
- package/src/presentation/navigation/components/README.md +330 -0
- package/src/presentation/navigation/hooks/README.md +399 -0
- package/src/presentation/navigation/utils/README.md +442 -0
- package/src/presentation/screens/README.md +525 -0
- package/src/presentation/screens/components/SettingsContent/README.md +404 -0
- package/src/presentation/screens/components/SettingsHeader/README.md +322 -0
- package/src/presentation/screens/components/sections/CustomSettingsList/README.md +388 -0
- package/src/presentation/screens/components/sections/FeatureSettingsSection/README.md +232 -0
- package/src/presentation/screens/components/sections/IdentitySettingsSection/README.md +325 -0
- package/src/presentation/screens/components/sections/ProfileSectionLoader/README.md +480 -0
- package/src/presentation/screens/components/sections/SupportSettingsSection/README.md +391 -0
- package/src/presentation/screens/hooks/README.md +383 -0
- package/src/presentation/screens/types/README.md +439 -0
- package/src/presentation/screens/utils/README.md +288 -0
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
# Infrastructure Layer
|
|
2
|
+
|
|
3
|
+
The infrastructure layer provides concrete implementations of the interfaces defined in the application layer, handling data persistence and external service integrations.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
infrastructure/
|
|
9
|
+
├── repositories/
|
|
10
|
+
│ └── SettingsRepository.ts # Settings storage implementation
|
|
11
|
+
└── services/
|
|
12
|
+
└── SettingsService.ts # Settings business logic service
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Components
|
|
16
|
+
|
|
17
|
+
### SettingsRepository
|
|
18
|
+
|
|
19
|
+
Concrete implementation of `ISettingsRepository` using `@umituz/react-native-storage` for data persistence.
|
|
20
|
+
|
|
21
|
+
#### Features
|
|
22
|
+
|
|
23
|
+
- **Automatic Defaults**: Creates default settings for new users
|
|
24
|
+
- **Type Safety**: Full TypeScript support
|
|
25
|
+
- **Error Handling**: Comprehensive error catching and reporting
|
|
26
|
+
- **Storage Integration**: Uses storage repository for persistence
|
|
27
|
+
|
|
28
|
+
#### Usage
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { SettingsRepository } from '@umituz/react-native-settings';
|
|
32
|
+
|
|
33
|
+
const repository = new SettingsRepository();
|
|
34
|
+
|
|
35
|
+
// Get settings
|
|
36
|
+
const result = await repository.getSettings('user123');
|
|
37
|
+
if (result.success) {
|
|
38
|
+
console.log(result.data?.theme); // 'auto'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Save settings
|
|
42
|
+
await repository.saveSettings({
|
|
43
|
+
userId: 'user123',
|
|
44
|
+
theme: 'dark',
|
|
45
|
+
language: 'en-US',
|
|
46
|
+
// ... other settings
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Delete settings
|
|
50
|
+
await repository.deleteSettings('user123');
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### Implementation Details
|
|
54
|
+
|
|
55
|
+
**getSettings(userId):**
|
|
56
|
+
|
|
57
|
+
1. Creates storage key from user ID
|
|
58
|
+
2. Attempts to retrieve from storage
|
|
59
|
+
3. Returns defaults if not found
|
|
60
|
+
4. Saves defaults for next time
|
|
61
|
+
5. Returns error on failure
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
const storageKey = createUserKey(StorageKey.USER_PREFERENCES, userId);
|
|
65
|
+
const defaults = this.defaultSettings(userId);
|
|
66
|
+
const result = await storageRepository.getItem<UserSettings>(storageKey, defaults);
|
|
67
|
+
|
|
68
|
+
if (!result.success) {
|
|
69
|
+
await this.saveSettings(defaults);
|
|
70
|
+
return { success: true, data: defaults };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return { success: true, data: result.data || defaults };
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**saveSettings(settings):**
|
|
77
|
+
|
|
78
|
+
1. Creates storage key from user ID
|
|
79
|
+
2. Saves settings to storage
|
|
80
|
+
3. Returns success or error
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const storageKey = createUserKey(StorageKey.USER_PREFERENCES, settings.userId);
|
|
84
|
+
const result = await storageRepository.setItem(storageKey, settings);
|
|
85
|
+
|
|
86
|
+
if (!result.success) {
|
|
87
|
+
return {
|
|
88
|
+
success: false,
|
|
89
|
+
error: {
|
|
90
|
+
code: 'SAVE_SETTINGS_FAILED',
|
|
91
|
+
message: 'Failed to save settings to storage',
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return { success: true };
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**deleteSettings(userId):**
|
|
100
|
+
|
|
101
|
+
1. Creates storage key from user ID
|
|
102
|
+
2. Removes from storage
|
|
103
|
+
3. Returns success or error
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
const storageKey = createUserKey(StorageKey.USER_PREFERENCES, userId);
|
|
107
|
+
const result = await storageRepository.removeItem(storageKey);
|
|
108
|
+
|
|
109
|
+
return result.success
|
|
110
|
+
? { success: true }
|
|
111
|
+
: {
|
|
112
|
+
success: false,
|
|
113
|
+
error: {
|
|
114
|
+
code: 'DELETE_SETTINGS_FAILED',
|
|
115
|
+
message: 'Failed to delete settings',
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### SettingsService
|
|
121
|
+
|
|
122
|
+
Business logic service for high-level settings operations.
|
|
123
|
+
|
|
124
|
+
#### Usage
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import { SettingsService } from '@umituz/react-native-settings';
|
|
128
|
+
|
|
129
|
+
const service = new SettingsService(repository);
|
|
130
|
+
|
|
131
|
+
// Initialize settings for new user
|
|
132
|
+
await service.initializeUser('user123');
|
|
133
|
+
|
|
134
|
+
// Update specific settings
|
|
135
|
+
await service.updateTheme('user123', 'dark');
|
|
136
|
+
await service.updateLanguage('user123', 'tr-TR');
|
|
137
|
+
|
|
138
|
+
// Reset to defaults
|
|
139
|
+
await service.resetToDefaults('user123');
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Storage Integration
|
|
143
|
+
|
|
144
|
+
### Storage Keys
|
|
145
|
+
|
|
146
|
+
The repository uses the following storage keys:
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
enum StorageKey {
|
|
150
|
+
USER_PREFERENCES = 'user_preferences', // Main settings storage
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Storage Format
|
|
155
|
+
|
|
156
|
+
Settings are stored as JSON:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"userId": "user123",
|
|
161
|
+
"theme": "dark",
|
|
162
|
+
"language": "en-US",
|
|
163
|
+
"notificationsEnabled": true,
|
|
164
|
+
"emailNotifications": true,
|
|
165
|
+
"pushNotifications": false,
|
|
166
|
+
"soundEnabled": true,
|
|
167
|
+
"vibrationEnabled": false,
|
|
168
|
+
"privacyMode": false,
|
|
169
|
+
"disclaimerAccepted": true,
|
|
170
|
+
"updatedAt": "2025-01-08T10:30:00.000Z"
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Default Settings
|
|
175
|
+
|
|
176
|
+
When creating new settings, these defaults are used:
|
|
177
|
+
|
|
178
|
+
| Setting | Default Value | Description |
|
|
179
|
+
|---------|---------------|-------------|
|
|
180
|
+
| `theme` | `'auto'` | Follow system theme |
|
|
181
|
+
| `language` | `'en-US'` | English (United States) |
|
|
182
|
+
| `notificationsEnabled` | `true` | Notifications enabled |
|
|
183
|
+
| `emailNotifications` | `true` | Email notifications enabled |
|
|
184
|
+
| `pushNotifications` | `true` | Push notifications enabled |
|
|
185
|
+
| `soundEnabled` | `true` | Sound effects enabled |
|
|
186
|
+
| `vibrationEnabled` | `true` | Haptic feedback enabled |
|
|
187
|
+
| `privacyMode` | `false` | Privacy mode disabled |
|
|
188
|
+
| `disclaimerAccepted` | `false` | Disclaimer not accepted |
|
|
189
|
+
|
|
190
|
+
## Error Handling
|
|
191
|
+
|
|
192
|
+
All repository methods return `SettingsResult<T>`:
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// Success case
|
|
196
|
+
{ success: true, data: settings }
|
|
197
|
+
|
|
198
|
+
// Error case
|
|
199
|
+
{
|
|
200
|
+
success: false,
|
|
201
|
+
error: {
|
|
202
|
+
code: 'GET_SETTINGS_FAILED',
|
|
203
|
+
message: 'Detailed error message'
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Error Codes
|
|
209
|
+
|
|
210
|
+
| Code | Description |
|
|
211
|
+
|------|-------------|
|
|
212
|
+
| `GET_SETTINGS_FAILED` | Failed to retrieve settings |
|
|
213
|
+
| `SAVE_SETTINGS_FAILED` | Failed to save settings |
|
|
214
|
+
| `DELETE_SETTINGS_FAILED` | Failed to delete settings |
|
|
215
|
+
|
|
216
|
+
## Examples
|
|
217
|
+
|
|
218
|
+
### Custom Repository Implementation
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
import type { ISettingsRepository, UserSettings, SettingsResult } from '@umituz/react-native-settings';
|
|
222
|
+
|
|
223
|
+
class AsyncStorageRepository implements ISettingsRepository {
|
|
224
|
+
async getSettings(userId: string): Promise<SettingsResult<UserSettings>> {
|
|
225
|
+
try {
|
|
226
|
+
const key = `settings_${userId}`;
|
|
227
|
+
const json = await AsyncStorage.getItem(key);
|
|
228
|
+
|
|
229
|
+
if (!json) {
|
|
230
|
+
return {
|
|
231
|
+
success: false,
|
|
232
|
+
error: { code: 'NOT_FOUND', message: 'Settings not found' },
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const data = JSON.parse(json);
|
|
237
|
+
return { success: true, data };
|
|
238
|
+
} catch (error) {
|
|
239
|
+
return {
|
|
240
|
+
success: false,
|
|
241
|
+
error: {
|
|
242
|
+
code: 'GET_SETTINGS_FAILED',
|
|
243
|
+
message: error.message,
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async saveSettings(settings: UserSettings): Promise<SettingsResult<void>> {
|
|
250
|
+
try {
|
|
251
|
+
const key = `settings_${settings.userId}`;
|
|
252
|
+
const json = JSON.stringify(settings);
|
|
253
|
+
await AsyncStorage.setItem(key, json);
|
|
254
|
+
return { success: true };
|
|
255
|
+
} catch (error) {
|
|
256
|
+
return {
|
|
257
|
+
success: false,
|
|
258
|
+
error: {
|
|
259
|
+
code: 'SAVE_SETTINGS_FAILED',
|
|
260
|
+
message: error.message,
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async deleteSettings(userId: string): Promise<SettingsResult<void>> {
|
|
267
|
+
try {
|
|
268
|
+
const key = `settings_${userId}`;
|
|
269
|
+
await AsyncStorage.removeItem(key);
|
|
270
|
+
return { success: true };
|
|
271
|
+
} catch (error) {
|
|
272
|
+
return {
|
|
273
|
+
success: false,
|
|
274
|
+
error: {
|
|
275
|
+
code: 'DELETE_SETTINGS_FAILED',
|
|
276
|
+
message: error.message,
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Using Custom Repository
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
import { useSettings } from '@umituz/react-native-settings';
|
|
288
|
+
|
|
289
|
+
// Provide custom repository to your app
|
|
290
|
+
const customRepository = new AsyncStorageRepository();
|
|
291
|
+
|
|
292
|
+
function App() {
|
|
293
|
+
return (
|
|
294
|
+
<SettingsProvider repository={customRepository}>
|
|
295
|
+
<MyApp />
|
|
296
|
+
</SettingsProvider>
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Migration Handler
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
class MigrationSettingsRepository implements ISettingsRepository {
|
|
305
|
+
constructor(private baseRepository: ISettingsRepository) {}
|
|
306
|
+
|
|
307
|
+
async getSettings(userId: string): Promise<SettingsResult<UserSettings>> {
|
|
308
|
+
const result = await this.baseRepository.getSettings(userId);
|
|
309
|
+
|
|
310
|
+
if (result.success && result.data) {
|
|
311
|
+
// Migration: Add new fields
|
|
312
|
+
const migrated = this.migrateSettings(result.data);
|
|
313
|
+
if (migrated !== result.data) {
|
|
314
|
+
await this.saveSettings(migrated);
|
|
315
|
+
return { success: true, data: migrated };
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return result;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
private migrateSettings(settings: UserSettings): UserSettings {
|
|
323
|
+
// Add new field with default
|
|
324
|
+
if (!('newField' in settings)) {
|
|
325
|
+
return { ...settings, newField: defaultValue };
|
|
326
|
+
}
|
|
327
|
+
return settings;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Delegate other methods
|
|
331
|
+
async saveSettings(settings: UserSettings) {
|
|
332
|
+
return this.baseRepository.saveSettings(settings);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
async deleteSettings(userId: string) {
|
|
336
|
+
return this.baseRepository.deleteSettings(userId);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Encrypted Storage
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
import * as SecureStore from 'expo-secure-store';
|
|
345
|
+
|
|
346
|
+
class SecureSettingsRepository implements ISettingsRepository {
|
|
347
|
+
async getSettings(userId: string): Promise<SettingsResult<UserSettings>> {
|
|
348
|
+
try {
|
|
349
|
+
const key = `secure_settings_${userId}`;
|
|
350
|
+
const json = await SecureStore.getItemAsync(key);
|
|
351
|
+
|
|
352
|
+
if (!json) {
|
|
353
|
+
return { success: false, error: { code: 'NOT_FOUND', message: 'Not found' } };
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const data = JSON.parse(json);
|
|
357
|
+
return { success: true, data };
|
|
358
|
+
} catch (error) {
|
|
359
|
+
return {
|
|
360
|
+
success: false,
|
|
361
|
+
error: { code: 'GET_SETTINGS_FAILED', message: error.message },
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
async saveSettings(settings: UserSettings): Promise<SettingsResult<void>> {
|
|
367
|
+
try {
|
|
368
|
+
const key = `secure_settings_${settings.userId}`;
|
|
369
|
+
const json = JSON.stringify(settings);
|
|
370
|
+
await SecureStore.setItemAsync(key, json);
|
|
371
|
+
return { success: true };
|
|
372
|
+
} catch (error) {
|
|
373
|
+
return {
|
|
374
|
+
success: false,
|
|
375
|
+
error: { code: 'SAVE_SETTINGS_FAILED', message: error.message },
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
async deleteSettings(userId: string): Promise<SettingsResult<void>> {
|
|
381
|
+
try {
|
|
382
|
+
const key = `secure_settings_${userId}`;
|
|
383
|
+
await SecureStore.deleteItemAsync(key);
|
|
384
|
+
return { success: true };
|
|
385
|
+
} catch (error) {
|
|
386
|
+
return {
|
|
387
|
+
success: false,
|
|
388
|
+
error: { code: 'DELETE_SETTINGS_FAILED', message: error.message },
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
## Testing
|
|
396
|
+
|
|
397
|
+
### Mock Repository
|
|
398
|
+
|
|
399
|
+
```typescript
|
|
400
|
+
class MockSettingsRepository implements ISettingsRepository {
|
|
401
|
+
private storage: Map<string, UserSettings> = new Map();
|
|
402
|
+
|
|
403
|
+
async getSettings(userId: string): Promise<SettingsResult<UserSettings>> {
|
|
404
|
+
const settings = this.storage.get(userId);
|
|
405
|
+
return settings
|
|
406
|
+
? { success: true, data: settings }
|
|
407
|
+
: { success: false, error: { code: 'NOT_FOUND', message: 'Not found' } };
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
async saveSettings(settings: UserSettings): Promise<SettingsResult<void>> {
|
|
411
|
+
this.storage.set(settings.userId, settings);
|
|
412
|
+
return { success: true };
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
async deleteSettings(userId: string): Promise<SettingsResult<void>> {
|
|
416
|
+
this.storage.delete(userId);
|
|
417
|
+
return { success: true };
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Test helper methods
|
|
421
|
+
clear() {
|
|
422
|
+
this.storage.clear();
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
hasSettings(userId: string): boolean {
|
|
426
|
+
return this.storage.has(userId);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Test Example
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
import { SettingsRepository } from '@umituz/react-native-settings';
|
|
435
|
+
|
|
436
|
+
describe('SettingsRepository', () => {
|
|
437
|
+
let repository: SettingsRepository;
|
|
438
|
+
|
|
439
|
+
beforeEach(() => {
|
|
440
|
+
repository = new SettingsRepository();
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
it('should save and retrieve settings', async () => {
|
|
444
|
+
const settings: UserSettings = {
|
|
445
|
+
userId: 'test123',
|
|
446
|
+
theme: 'dark',
|
|
447
|
+
language: 'en-US',
|
|
448
|
+
notificationsEnabled: true,
|
|
449
|
+
emailNotifications: true,
|
|
450
|
+
pushNotifications: false,
|
|
451
|
+
soundEnabled: true,
|
|
452
|
+
vibrationEnabled: false,
|
|
453
|
+
privacyMode: false,
|
|
454
|
+
disclaimerAccepted: true,
|
|
455
|
+
updatedAt: new Date(),
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
const saveResult = await repository.saveSettings(settings);
|
|
459
|
+
expect(saveResult.success).toBe(true);
|
|
460
|
+
|
|
461
|
+
const getResult = await repository.getSettings('test123');
|
|
462
|
+
expect(getResult.success).toBe(true);
|
|
463
|
+
expect(getResult.data?.theme).toBe('dark');
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
it('should return defaults for new user', async () => {
|
|
467
|
+
const result = await repository.getSettings('newuser');
|
|
468
|
+
|
|
469
|
+
expect(result.success).toBe(true);
|
|
470
|
+
expect(result.data?.theme).toBe('auto');
|
|
471
|
+
expect(result.data?.language).toBe('en-US');
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
it('should delete settings', async () => {
|
|
475
|
+
await repository.saveSettings({
|
|
476
|
+
userId: 'deleteMe',
|
|
477
|
+
theme: 'light',
|
|
478
|
+
// ... other required fields
|
|
479
|
+
} as any);
|
|
480
|
+
|
|
481
|
+
const deleteResult = await repository.deleteSettings('deleteMe');
|
|
482
|
+
expect(deleteResult.success).toBe(true);
|
|
483
|
+
|
|
484
|
+
const getResult = await repository.getSettings('deleteMe');
|
|
485
|
+
expect(getResult.data?.theme).toBe('auto'); // Returns defaults
|
|
486
|
+
});
|
|
487
|
+
});
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
## Best Practices
|
|
491
|
+
|
|
492
|
+
1. **Use Repository Interface**: Program to `ISettingsRepository`, not concrete implementation
|
|
493
|
+
2. **Handle Errors**: Always check `success` flag
|
|
494
|
+
3. **Type Safety**: Use TypeScript types for all operations
|
|
495
|
+
4. **Validation**: Validate data before saving
|
|
496
|
+
5. **Default Values**: Always provide sensible defaults
|
|
497
|
+
6. **Error Messages**: Include detailed, helpful error messages
|
|
498
|
+
7. **Testing**: Use mock repositories in tests
|
|
499
|
+
8. **Migration**: Handle schema migrations gracefully
|
|
500
|
+
|
|
501
|
+
## Related
|
|
502
|
+
|
|
503
|
+
- **Application Layer**: Repository interfaces and types
|
|
504
|
+
- **Presentation Hooks**: React hooks for UI integration
|
|
505
|
+
- **Storage Package**: `@umituz/react-native-storage`
|
|
506
|
+
|
|
507
|
+
## License
|
|
508
|
+
|
|
509
|
+
MIT
|