@umituz/react-native-settings 4.20.56 → 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,510 @@
|
|
|
1
|
+
# Settings Service
|
|
2
|
+
|
|
3
|
+
Service layer for settings management including business logic, validation, and orchestration of repository operations.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Business Logic**: Encapsulates settings-related business rules
|
|
8
|
+
- **Validation**: Validates settings before persistence
|
|
9
|
+
- **Defaults Management**: Handles default value logic
|
|
10
|
+
- **Transformation**: Transforms data between layers
|
|
11
|
+
- **Error Handling**: Consistent error handling across operations
|
|
12
|
+
- **Caching**: Optional caching layer for performance
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
This service is part of `@umituz/react-native-settings`.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### Basic Service Usage
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { SettingsService } from '@umituz/react-native-settings';
|
|
24
|
+
|
|
25
|
+
const settingsService = new SettingsService();
|
|
26
|
+
|
|
27
|
+
// Get user settings
|
|
28
|
+
const settings = await settingsService.getSettings('user123');
|
|
29
|
+
|
|
30
|
+
// Update settings
|
|
31
|
+
const updated = await settingsService.updateSettings('user123', {
|
|
32
|
+
theme: 'dark',
|
|
33
|
+
language: 'tr-TR',
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Reset settings
|
|
37
|
+
const defaults = await settingsService.resetSettings('user123');
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### With Repository Injection
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { SettingsService, ISettingsRepository } from '@umituz/react-native-settings';
|
|
44
|
+
|
|
45
|
+
const repository: ISettingsRepository = new SettingsRepository();
|
|
46
|
+
const settingsService = new SettingsService(repository);
|
|
47
|
+
|
|
48
|
+
const settings = await settingsService.getSettings('user123');
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Methods
|
|
52
|
+
|
|
53
|
+
### getSettings(userId: string): Promise<UserSettings>
|
|
54
|
+
|
|
55
|
+
Retrieves settings for a user with defaults applied.
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
const settings = await settingsService.getSettings('user123');
|
|
59
|
+
|
|
60
|
+
console.log(settings.theme); // 'light' | 'dark' | 'auto'
|
|
61
|
+
console.log(settings.language); // 'en-US'
|
|
62
|
+
console.log(settings.notificationsEnabled); // true
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Returns**: Complete UserSettings object with defaults for missing values.
|
|
66
|
+
|
|
67
|
+
**Example**:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
async function loadUserSettings(userId: string) {
|
|
71
|
+
try {
|
|
72
|
+
const settings = await settingsService.getSettings(userId);
|
|
73
|
+
applyTheme(settings.theme);
|
|
74
|
+
applyLanguage(settings.language);
|
|
75
|
+
return settings;
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error('Failed to load settings:', error);
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### updateSettings(userId: string, updates: Partial<UserSettings>): Promise<UserSettings>
|
|
84
|
+
|
|
85
|
+
Updates user settings with validation and transformation.
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
const updated = await settingsService.updateSettings('user123', {
|
|
89
|
+
theme: 'dark',
|
|
90
|
+
notificationsEnabled: false,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
console.log(updated.theme); // 'dark'
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Validation**:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
// Valid updates
|
|
100
|
+
await settingsService.updateSettings('user123', {
|
|
101
|
+
theme: 'dark', // ✅ Valid
|
|
102
|
+
language: 'tr-TR', // ✅ Valid
|
|
103
|
+
notificationsEnabled: true, // ✅ Valid
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Invalid updates
|
|
107
|
+
await settingsService.updateSettings('user123', {
|
|
108
|
+
theme: 'invalid', // ❌ Throws ValidationError
|
|
109
|
+
language: '', // ❌ Throws ValidationError
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Example**:
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
async function updateUserPreferences(
|
|
117
|
+
userId: string,
|
|
118
|
+
theme: 'light' | 'dark',
|
|
119
|
+
language: string
|
|
120
|
+
) {
|
|
121
|
+
try {
|
|
122
|
+
const updated = await settingsService.updateSettings(userId, {
|
|
123
|
+
theme,
|
|
124
|
+
language,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Apply changes
|
|
128
|
+
applyTheme(updated.theme);
|
|
129
|
+
applyLanguage(updated.language);
|
|
130
|
+
|
|
131
|
+
return updated;
|
|
132
|
+
} catch (error) {
|
|
133
|
+
if (error instanceof ValidationError) {
|
|
134
|
+
Alert.alert('Invalid Settings', error.message);
|
|
135
|
+
} else {
|
|
136
|
+
Alert.alert('Error', 'Failed to update settings');
|
|
137
|
+
}
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### resetSettings(userId: string): Promise<UserSettings>
|
|
144
|
+
|
|
145
|
+
Resets user settings to default values.
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const defaults = await settingsService.resetSettings('user123');
|
|
149
|
+
|
|
150
|
+
console.log(defaults.theme); // 'light' (default)
|
|
151
|
+
console.log(defaults.language); // 'en-US' (default)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Example**:
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
async function handleResetSettings(userId: string) {
|
|
158
|
+
Alert.alert(
|
|
159
|
+
'Reset Settings',
|
|
160
|
+
'Are you sure you want to reset all settings to default?',
|
|
161
|
+
[
|
|
162
|
+
{ text: 'Cancel', style: 'cancel' },
|
|
163
|
+
{
|
|
164
|
+
text: 'Reset',
|
|
165
|
+
style: 'destructive',
|
|
166
|
+
onPress: async () => {
|
|
167
|
+
try {
|
|
168
|
+
const defaults = await settingsService.resetSettings(userId);
|
|
169
|
+
applySettings(defaults);
|
|
170
|
+
Alert.alert('Success', 'Settings have been reset');
|
|
171
|
+
} catch (error) {
|
|
172
|
+
Alert.alert('Error', 'Failed to reset settings');
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
]
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### validateSettings(settings: Partial<UserSettings>): void
|
|
182
|
+
|
|
183
|
+
Validates settings and throws ValidationError if invalid.
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
try {
|
|
187
|
+
settingsService.validateSettings({
|
|
188
|
+
theme: 'dark',
|
|
189
|
+
language: 'en-US',
|
|
190
|
+
});
|
|
191
|
+
// Valid
|
|
192
|
+
} catch (error) {
|
|
193
|
+
// Invalid
|
|
194
|
+
console.error(error.message);
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Validation Rules**:
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
// Theme validation
|
|
202
|
+
validateSettings({ theme: 'dark' }); // ✅ Valid
|
|
203
|
+
validateSettings({ theme: 'light' }); // ✅ Valid
|
|
204
|
+
validateSettings({ theme: 'auto' }); // ✅ Valid
|
|
205
|
+
validateSettings({ theme: 'invalid' }); // ❌ Invalid
|
|
206
|
+
|
|
207
|
+
// Language validation
|
|
208
|
+
validateSettings({ language: 'en-US' }); // ✅ Valid
|
|
209
|
+
validateSettings({ language: 'tr-TR' }); // ✅ Valid
|
|
210
|
+
validateSettings({ language: '' }); // ❌ Invalid
|
|
211
|
+
validateSettings({ language: 'xx' }); // ❌ Invalid
|
|
212
|
+
|
|
213
|
+
// Boolean validation
|
|
214
|
+
validateSettings({ notificationsEnabled: true }); // ✅ Valid
|
|
215
|
+
validateSettings({ notificationsEnabled: 'yes' }); // ❌ Invalid
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### mergeSettings(base: UserSettings, updates: Partial<UserSettings>): UserSettings
|
|
219
|
+
|
|
220
|
+
Merges updates with base settings, preserving undefined values.
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
const base = {
|
|
224
|
+
theme: 'light',
|
|
225
|
+
language: 'en-US',
|
|
226
|
+
notificationsEnabled: true,
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const merged = settingsService.mergeSettings(base, {
|
|
230
|
+
theme: 'dark',
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
console.log(merged);
|
|
234
|
+
// {
|
|
235
|
+
// theme: 'dark',
|
|
236
|
+
// language: 'en-US', // Preserved
|
|
237
|
+
// notificationsEnabled: true, // Preserved
|
|
238
|
+
// }
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Validation
|
|
242
|
+
|
|
243
|
+
### Theme Validation
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
function validateTheme(theme: string): boolean {
|
|
247
|
+
const validThemes = ['light', 'dark', 'auto'];
|
|
248
|
+
return validThemes.includes(theme);
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Language Validation
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
function validateLanguage(language: string): boolean {
|
|
256
|
+
// Check format (e.g., 'en-US', 'tr-TR')
|
|
257
|
+
const languageRegex = /^[a-z]{2}-[A-Z]{2}$/;
|
|
258
|
+
return languageRegex.test(language);
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Boolean Validation
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
function validateBoolean(value: any): boolean {
|
|
266
|
+
return typeof value === 'boolean';
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Complete Validation
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
interface ValidationResult {
|
|
274
|
+
valid: boolean;
|
|
275
|
+
errors: Record<string, string>;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function validateSettingsComplete(
|
|
279
|
+
settings: Partial<UserSettings>
|
|
280
|
+
): ValidationResult {
|
|
281
|
+
const errors: Record<string, string> = {};
|
|
282
|
+
|
|
283
|
+
if (settings.theme !== undefined) {
|
|
284
|
+
if (!validateTheme(settings.theme)) {
|
|
285
|
+
errors.theme = 'Invalid theme mode';
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (settings.language !== undefined) {
|
|
290
|
+
if (!validateLanguage(settings.language)) {
|
|
291
|
+
errors.language = 'Invalid language format';
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (settings.notificationsEnabled !== undefined) {
|
|
296
|
+
if (!validateBoolean(settings.notificationsEnabled)) {
|
|
297
|
+
errors.notificationsEnabled = 'Must be a boolean';
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return {
|
|
302
|
+
valid: Object.keys(errors).length === 0,
|
|
303
|
+
errors,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Default Values
|
|
309
|
+
|
|
310
|
+
### Default Settings
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
const defaultSettings: UserSettings = {
|
|
314
|
+
userId: '',
|
|
315
|
+
theme: 'auto',
|
|
316
|
+
language: 'en-US',
|
|
317
|
+
notificationsEnabled: true,
|
|
318
|
+
emailNotifications: true,
|
|
319
|
+
pushNotifications: true,
|
|
320
|
+
soundEnabled: true,
|
|
321
|
+
vibrationEnabled: true,
|
|
322
|
+
quietHoursEnabled: false,
|
|
323
|
+
quietHoursStart: '22:00',
|
|
324
|
+
quietHoursEnd: '08:00',
|
|
325
|
+
};
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Applying Defaults
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
function applyDefaults(settings: Partial<UserSettings>): UserSettings {
|
|
332
|
+
return {
|
|
333
|
+
...defaultSettings,
|
|
334
|
+
...settings,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const userSettings = applyDefaults({
|
|
339
|
+
theme: 'dark',
|
|
340
|
+
language: 'tr-TR',
|
|
341
|
+
});
|
|
342
|
+
// Returns: { theme: 'dark', language: 'tr-TR', notificationsEnabled: true, ... }
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## Error Handling
|
|
346
|
+
|
|
347
|
+
### ValidationError
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
class ValidationError extends Error {
|
|
351
|
+
constructor(
|
|
352
|
+
message: string,
|
|
353
|
+
public field: string,
|
|
354
|
+
public value: any
|
|
355
|
+
) {
|
|
356
|
+
super(message);
|
|
357
|
+
this.name = 'ValidationError';
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**Example**:
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
try {
|
|
366
|
+
await settingsService.updateSettings('user123', {
|
|
367
|
+
theme: 'invalid',
|
|
368
|
+
});
|
|
369
|
+
} catch (error) {
|
|
370
|
+
if (error instanceof ValidationError) {
|
|
371
|
+
console.error(`Field: ${error.field}`);
|
|
372
|
+
console.error(`Value: ${error.value}`);
|
|
373
|
+
console.error(`Message: ${error.message}`);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### SettingsError
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
class SettingsError extends Error {
|
|
382
|
+
constructor(
|
|
383
|
+
message: string,
|
|
384
|
+
public code: string,
|
|
385
|
+
public originalError?: Error
|
|
386
|
+
) {
|
|
387
|
+
super(message);
|
|
388
|
+
this.name = 'SettingsError';
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
**Example**:
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
try {
|
|
397
|
+
await settingsService.getSettings('user123');
|
|
398
|
+
} catch (error) {
|
|
399
|
+
if (error instanceof SettingsError) {
|
|
400
|
+
switch (error.code) {
|
|
401
|
+
case 'NOT_FOUND':
|
|
402
|
+
console.log('User not found');
|
|
403
|
+
break;
|
|
404
|
+
case 'STORAGE_ERROR':
|
|
405
|
+
console.log('Storage error');
|
|
406
|
+
break;
|
|
407
|
+
case 'NETWORK_ERROR':
|
|
408
|
+
console.log('Network error');
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Transformations
|
|
416
|
+
|
|
417
|
+
### Data Normalization
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
function normalizeSettings(raw: any): UserSettings {
|
|
421
|
+
return {
|
|
422
|
+
userId: raw.userId || '',
|
|
423
|
+
theme: raw.theme || 'auto',
|
|
424
|
+
language: raw.language || 'en-US',
|
|
425
|
+
notificationsEnabled: raw.notificationsEnabled ?? true,
|
|
426
|
+
emailNotifications: raw.emailNotifications ?? true,
|
|
427
|
+
pushNotifications: raw.pushNotifications ?? true,
|
|
428
|
+
soundEnabled: raw.soundEnabled ?? true,
|
|
429
|
+
vibrationEnabled: raw.vibrationEnabled ?? true,
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Data Serialization
|
|
435
|
+
|
|
436
|
+
```typescript
|
|
437
|
+
function serializeSettings(settings: UserSettings): any {
|
|
438
|
+
return {
|
|
439
|
+
user_id: settings.userId,
|
|
440
|
+
theme: settings.theme,
|
|
441
|
+
language: settings.language,
|
|
442
|
+
notifications_enabled: settings.notificationsEnabled,
|
|
443
|
+
email_notifications: settings.emailNotifications,
|
|
444
|
+
push_notifications: settings.pushNotifications,
|
|
445
|
+
sound_enabled: settings.soundEnabled,
|
|
446
|
+
vibration_enabled: settings.vibrationEnabled,
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## Caching
|
|
452
|
+
|
|
453
|
+
### In-Memory Cache
|
|
454
|
+
|
|
455
|
+
```typescript
|
|
456
|
+
class CachedSettingsService extends SettingsService {
|
|
457
|
+
private cache = new Map<string, UserSettings>();
|
|
458
|
+
|
|
459
|
+
async getSettings(userId: string): Promise<UserSettings> {
|
|
460
|
+
// Check cache
|
|
461
|
+
if (this.cache.has(userId)) {
|
|
462
|
+
return this.cache.get(userId)!;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Fetch from repository
|
|
466
|
+
const settings = await super.getSettings(userId);
|
|
467
|
+
|
|
468
|
+
// Cache result
|
|
469
|
+
this.cache.set(userId, settings);
|
|
470
|
+
|
|
471
|
+
return settings;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
async updateSettings(
|
|
475
|
+
userId: string,
|
|
476
|
+
updates: Partial<UserSettings>
|
|
477
|
+
): Promise<UserSettings> {
|
|
478
|
+
const settings = await super.updateSettings(userId, updates);
|
|
479
|
+
|
|
480
|
+
// Update cache
|
|
481
|
+
this.cache.set(userId, settings);
|
|
482
|
+
|
|
483
|
+
return settings;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
invalidateCache(userId: string): void {
|
|
487
|
+
this.cache.delete(userId);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
## Best Practices
|
|
493
|
+
|
|
494
|
+
1. **Validation**: Always validate before persistence
|
|
495
|
+
2. **Defaults**: Apply defaults for missing values
|
|
496
|
+
3. **Error Handling**: Provide clear error messages
|
|
497
|
+
4. **Type Safety**: Use TypeScript types throughout
|
|
498
|
+
5. **Immutability**: Return new objects, don't mutate
|
|
499
|
+
6. **Caching**: Cache frequently accessed settings
|
|
500
|
+
7. **Logging**: Log important operations
|
|
501
|
+
|
|
502
|
+
## Related
|
|
503
|
+
|
|
504
|
+
- **Settings Repository**: Data persistence layer
|
|
505
|
+
- **Application Layer**: Interface definitions
|
|
506
|
+
- **Settings Mutations**: Mutation hooks
|
|
507
|
+
|
|
508
|
+
## License
|
|
509
|
+
|
|
510
|
+
MIT
|