@umituz/react-native-settings 4.20.58 → 4.20.59
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/.github/ISSUE_TEMPLATE/bug_report.md +51 -0
- package/.github/ISSUE_TEMPLATE/documentation.md +52 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +63 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +84 -0
- package/AI_AGENT_GUIDELINES.md +367 -0
- package/ARCHITECTURE.md +246 -0
- package/CHANGELOG.md +67 -0
- package/CODE_OF_CONDUCT.md +75 -0
- package/CONTRIBUTING.md +107 -0
- package/DOCUMENTATION_MIGRATION.md +319 -0
- package/DOCUMENTATION_TEMPLATE.md +155 -0
- package/LICENSE +21 -0
- package/README.md +321 -498
- package/SECURITY.md +98 -0
- package/SETTINGS_SCREEN_GUIDE.md +185 -0
- package/TESTING.md +358 -0
- package/package.json +13 -2
- package/src/application/README.md +85 -271
- package/src/domains/about/README.md +85 -440
- package/src/domains/about/presentation/hooks/README.md +93 -348
- package/src/domains/appearance/README.md +95 -584
- package/src/domains/appearance/hooks/README.md +95 -303
- package/src/domains/appearance/infrastructure/services/README.md +83 -397
- package/src/domains/appearance/presentation/components/README.md +95 -489
- package/src/domains/cloud-sync/README.md +73 -439
- package/src/domains/cloud-sync/presentation/components/README.md +95 -493
- package/src/domains/dev/README.md +71 -457
- package/src/domains/disclaimer/README.md +77 -411
- package/src/domains/disclaimer/presentation/components/README.md +95 -392
- package/src/domains/faqs/README.md +86 -574
- package/src/domains/feedback/README.md +79 -553
- package/src/domains/feedback/presentation/hooks/README.md +93 -426
- package/src/domains/legal/README.md +88 -537
- package/src/domains/rating/README.md +73 -440
- package/src/domains/rating/presentation/components/README.md +95 -475
- package/src/domains/video-tutorials/README.md +77 -470
- package/src/domains/video-tutorials/presentation/components/README.md +95 -431
- package/src/infrastructure/README.md +78 -425
- package/src/infrastructure/repositories/README.md +88 -420
- package/src/infrastructure/services/README.md +74 -460
- package/src/presentation/components/README.md +97 -480
- package/src/presentation/components/SettingsErrorBoundary/README.md +48 -436
- package/src/presentation/components/SettingsFooter/README.md +48 -427
- package/src/presentation/components/SettingsItemCard/README.md +152 -391
- package/src/presentation/components/SettingsItemCard/STRATEGY.md +164 -0
- package/src/presentation/components/SettingsSection/README.md +47 -401
- package/src/presentation/hooks/README.md +95 -389
- package/src/presentation/hooks/mutations/README.md +99 -376
- package/src/presentation/hooks/queries/README.md +111 -353
- package/src/presentation/navigation/README.md +70 -502
- package/src/presentation/navigation/components/README.md +70 -295
- package/src/presentation/navigation/hooks/README.md +75 -367
- package/src/presentation/navigation/utils/README.md +100 -380
- package/src/presentation/screens/README.md +53 -504
- package/src/presentation/screens/components/SettingsContent/README.md +53 -382
- package/src/presentation/screens/components/SettingsHeader/README.md +48 -303
- package/src/presentation/screens/components/sections/CustomSettingsList/README.md +47 -359
- package/src/presentation/screens/components/sections/FeatureSettingsSection/README.md +81 -176
- package/src/presentation/screens/components/sections/IdentitySettingsSection/README.md +40 -297
- package/src/presentation/screens/components/sections/ProfileSectionLoader/README.md +47 -451
- package/src/presentation/screens/components/sections/SupportSettingsSection/README.md +45 -361
- package/src/presentation/screens/hooks/README.md +64 -354
- package/src/presentation/screens/types/README.md +79 -409
- package/src/presentation/screens/utils/README.md +65 -255
|
@@ -2,509 +2,123 @@
|
|
|
2
2
|
|
|
3
3
|
Service layer for settings management including business logic, validation, and orchestration of repository operations.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Purpose
|
|
6
6
|
|
|
7
|
-
-
|
|
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
|
|
7
|
+
Provides high-level business logic for settings management, encapsulating validation, defaults management, and data transformation. The service layer sits between the presentation layer and the repository layer.
|
|
13
8
|
|
|
14
|
-
##
|
|
9
|
+
## File Paths
|
|
15
10
|
|
|
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
11
|
```
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
}
|
|
12
|
+
src/infrastructure/services/
|
|
13
|
+
└── SettingsService.ts # Main settings service
|
|
141
14
|
```
|
|
142
15
|
|
|
143
|
-
|
|
16
|
+
## Strategy
|
|
144
17
|
|
|
145
|
-
|
|
18
|
+
1. **Business Logic Encapsulation**: Contain all settings-related business rules
|
|
19
|
+
2. **Validation**: Validate settings before persistence
|
|
20
|
+
3. **Defaults Management**: Handle default value logic consistently
|
|
21
|
+
4. **Data Transformation**: Transform data between layers
|
|
22
|
+
5. **Error Handling**: Provide consistent error handling across operations
|
|
146
23
|
|
|
147
|
-
|
|
148
|
-
const defaults = await settingsService.resetSettings('user123');
|
|
24
|
+
## Restrictions
|
|
149
25
|
|
|
150
|
-
|
|
151
|
-
console.log(defaults.language); // 'en-US' (default)
|
|
152
|
-
```
|
|
26
|
+
### DO NOT
|
|
153
27
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
```
|
|
28
|
+
- ❌ DO NOT include UI-specific logic in services
|
|
29
|
+
- ❌ DO NOT access storage directly; use repositories
|
|
30
|
+
- ❌ DO NOT bypass validation for any reason
|
|
31
|
+
- ❌ DO NOT swallow errors without proper handling
|
|
32
|
+
- ❌ DO NOT create circular dependencies with repositories
|
|
180
33
|
|
|
181
|
-
###
|
|
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
|
-
```
|
|
34
|
+
### NEVER
|
|
197
35
|
|
|
198
|
-
|
|
36
|
+
- ❌ NEVER save invalid data to storage
|
|
37
|
+
- ❌ EVER return partial results without proper error indication
|
|
38
|
+
- ❌ EVER assume data exists without checking
|
|
39
|
+
- ❌ EVER expose internal storage format
|
|
199
40
|
|
|
200
|
-
|
|
201
|
-
// Theme validation
|
|
202
|
-
validateSettings({ theme: 'dark' }); // ✅ Valid
|
|
203
|
-
validateSettings({ theme: 'light' }); // ✅ Valid
|
|
204
|
-
validateSettings({ theme: 'auto' }); // ✅ Valid
|
|
205
|
-
validateSettings({ theme: 'invalid' }); // ❌ Invalid
|
|
41
|
+
### AVOID
|
|
206
42
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
validateSettings({ language: 'xx' }); // ❌ Invalid
|
|
43
|
+
- ❌ AVOID creating services that are too broad
|
|
44
|
+
- ❌ AVOID mixing concerns (validation + persistence + presentation)
|
|
45
|
+
- ❌ AVOID synchronous operations that could block
|
|
46
|
+
- ❌ AVOID inconsistent error handling
|
|
212
47
|
|
|
213
|
-
|
|
214
|
-
validateSettings({ notificationsEnabled: true }); // ✅ Valid
|
|
215
|
-
validateSettings({ notificationsEnabled: 'yes' }); // ❌ Invalid
|
|
216
|
-
```
|
|
48
|
+
## Rules
|
|
217
49
|
|
|
218
|
-
###
|
|
50
|
+
### ALWAYS
|
|
219
51
|
|
|
220
|
-
|
|
52
|
+
- ✅ ALWAYS validate settings before saving
|
|
53
|
+
- ✅ ALWAYS apply defaults for missing values
|
|
54
|
+
- ✅ ALWAYS handle errors consistently
|
|
55
|
+
- ✅ ALWAYS return typed results
|
|
56
|
+
- ✅ ALWAYS use repositories for persistence
|
|
221
57
|
|
|
222
|
-
|
|
223
|
-
const base = {
|
|
224
|
-
theme: 'light',
|
|
225
|
-
language: 'en-US',
|
|
226
|
-
notificationsEnabled: true,
|
|
227
|
-
};
|
|
58
|
+
### MUST
|
|
228
59
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
60
|
+
- ✅ MUST validate all inputs
|
|
61
|
+
- ✅ MUST provide default values
|
|
62
|
+
- ✅ MUST handle storage errors
|
|
63
|
+
- ✅ MUST maintain data integrity
|
|
232
64
|
|
|
233
|
-
|
|
234
|
-
// {
|
|
235
|
-
// theme: 'dark',
|
|
236
|
-
// language: 'en-US', // Preserved
|
|
237
|
-
// notificationsEnabled: true, // Preserved
|
|
238
|
-
// }
|
|
239
|
-
```
|
|
65
|
+
### SHOULD
|
|
240
66
|
|
|
241
|
-
|
|
67
|
+
- ✅ SHOULD provide clear error messages
|
|
68
|
+
- ✅ SHOULD use immutable operations
|
|
69
|
+
- ✅ SHOULD cache frequently accessed settings
|
|
70
|
+
- ✅ SHOULD log important operations
|
|
242
71
|
|
|
243
|
-
|
|
72
|
+
## AI Agent Guidelines
|
|
244
73
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
```
|
|
74
|
+
1. **When adding validation**: Provide clear error messages for invalid data
|
|
75
|
+
2. **When handling defaults**: Apply defaults consistently across all operations
|
|
76
|
+
3. **When transforming data**: Keep transformations pure and predictable
|
|
77
|
+
4. **When handling errors**: Transform technical errors into domain errors
|
|
78
|
+
5. **When adding methods**: Follow existing patterns for consistency
|
|
251
79
|
|
|
252
|
-
|
|
80
|
+
## Service Reference
|
|
253
81
|
|
|
254
|
-
|
|
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
|
-
```
|
|
82
|
+
### SettingsService
|
|
261
83
|
|
|
262
|
-
|
|
84
|
+
Main service for settings management with validation, defaults, and transformation.
|
|
263
85
|
|
|
264
|
-
|
|
265
|
-
function validateBoolean(value: any): boolean {
|
|
266
|
-
return typeof value === 'boolean';
|
|
267
|
-
}
|
|
268
|
-
```
|
|
86
|
+
**Location**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/infrastructure/services/SettingsService.ts`
|
|
269
87
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
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
|
-
```
|
|
88
|
+
**Methods**:
|
|
89
|
+
- `getSettings(userId: string): Promise<UserSettings>` - Get user settings with defaults
|
|
90
|
+
- `updateSettings(userId: string, updates: Partial<UserSettings>): Promise<UserSettings>` - Update with validation
|
|
91
|
+
- `resetSettings(userId: string): Promise<UserSettings>` - Reset to defaults
|
|
92
|
+
- `validateSettings(settings: Partial<UserSettings>): void` - Validate and throw on error
|
|
93
|
+
- `mergeSettings(base: UserSettings, updates: Partial<UserSettings>): UserSettings>` - Merge settings
|
|
307
94
|
|
|
308
95
|
## Default Values
|
|
309
96
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
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
|
-
}
|
|
97
|
+
**theme**: `'auto'` - Follow system theme
|
|
98
|
+
**language**: `'en-US'` - English (United States)
|
|
99
|
+
**notificationsEnabled**: `true` - Notifications on
|
|
100
|
+
**emailNotifications**: `true` - Email notifications on
|
|
101
|
+
**pushNotifications**: `true` - Push notifications on
|
|
102
|
+
**soundEnabled**: `true` - Sound on
|
|
103
|
+
**vibrationEnabled**: `true` - Vibration on
|
|
464
104
|
|
|
465
|
-
|
|
466
|
-
const settings = await super.getSettings(userId);
|
|
105
|
+
## Validation Rules
|
|
467
106
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
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
|
-
```
|
|
107
|
+
**Theme**: Must be 'light', 'dark', or 'auto'
|
|
108
|
+
**Language**: Must match format 'xx-XX' (e.g., 'en-US')
|
|
109
|
+
**Booleans**: Must be boolean type, not string/number
|
|
110
|
+
**Required Fields**: Cannot be empty or undefined
|
|
491
111
|
|
|
492
112
|
## Best Practices
|
|
493
113
|
|
|
494
114
|
1. **Validation**: Always validate before persistence
|
|
495
115
|
2. **Defaults**: Apply defaults for missing values
|
|
496
116
|
3. **Error Handling**: Provide clear error messages
|
|
497
|
-
4. **Type Safety**: Use TypeScript
|
|
117
|
+
4. **Type Safety**: Use TypeScript throughout
|
|
498
118
|
5. **Immutability**: Return new objects, don't mutate
|
|
499
119
|
6. **Caching**: Cache frequently accessed settings
|
|
500
120
|
7. **Logging**: Log important operations
|
|
501
121
|
|
|
502
|
-
## Related
|
|
503
|
-
|
|
504
|
-
- **Settings Repository**: Data persistence layer
|
|
505
|
-
- **Application Layer**: Interface definitions
|
|
506
|
-
- **Settings Mutations**: Mutation hooks
|
|
507
|
-
|
|
508
122
|
## License
|
|
509
123
|
|
|
510
124
|
MIT
|