@umituz/react-native-auth 3.4.32 → 3.4.34
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 +347 -348
- package/package.json +2 -3
- package/src/application/README.md +323 -442
- package/src/domain/ConfigAndErrors.md +296 -431
- package/src/domain/README.md +361 -210
- package/src/domain/entities/AuthUser.md +231 -372
- package/src/domain/entities/UserProfile.md +271 -441
- package/src/index.ts +35 -0
- package/src/infrastructure/README.md +388 -444
- package/src/infrastructure/services/README.md +386 -312
- package/src/infrastructure/utils/validation/BaseValidators.ts +35 -0
- package/src/infrastructure/utils/validation/CollectionValidators.ts +56 -0
- package/src/infrastructure/utils/validation/DateValidators.ts +63 -0
- package/src/infrastructure/utils/validation/FormValidators.ts +22 -0
- package/src/infrastructure/utils/validation/NumberValidators.ts +55 -0
- package/src/infrastructure/utils/validation/StringValidators.ts +55 -0
- package/src/infrastructure/utils/validation/sanitization.ts +98 -0
- package/src/infrastructure/utils/validation/types.ts +15 -0
- package/src/presentation/README.md +631 -563
- package/src/presentation/components/ProfileComponents.md +307 -504
- package/src/presentation/components/README.md +254 -92
- package/src/presentation/hooks/README.md +247 -83
- package/src/presentation/hooks/useAccountManagement.md +295 -344
- package/src/presentation/hooks/useAuth.md +271 -227
- package/src/presentation/hooks/useAuthBottomSheet.md +417 -367
- package/src/presentation/hooks/useAuthRequired.md +308 -194
- package/src/presentation/hooks/useProfileUpdate.md +251 -279
- package/src/presentation/hooks/useSocialLogin.md +312 -287
- package/src/presentation/hooks/useUserProfile.md +259 -192
- package/src/presentation/screens/README.md +151 -153
|
@@ -1,443 +1,273 @@
|
|
|
1
1
|
# UserProfile Entity
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
): Promise<string> {
|
|
275
|
-
// Dosyayı blob'a çevir
|
|
276
|
-
const response = await fetch(uri);
|
|
277
|
-
const blob = await response.blob();
|
|
278
|
-
|
|
279
|
-
// Storage referansı oluştur
|
|
280
|
-
const storageRef = ref(storage, `avatars/${uid}/${Date.now()}.jpg`);
|
|
281
|
-
|
|
282
|
-
// Yükle
|
|
283
|
-
await uploadBytes(storageRef, blob);
|
|
284
|
-
|
|
285
|
-
// URL al
|
|
286
|
-
const downloadURL = await getDownloadURL(storageRef);
|
|
287
|
-
|
|
288
|
-
return downloadURL;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
// Kullanım
|
|
292
|
-
async function handleProfilePhotoUpload(uid: string) {
|
|
293
|
-
// Resim seç
|
|
294
|
-
const result = await ImagePicker.launchImageLibraryAsync({
|
|
295
|
-
mediaTypes: ['images'],
|
|
296
|
-
allowsEditing: true,
|
|
297
|
-
aspect: [1, 1],
|
|
298
|
-
quality: 0.8,
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
if (result.canceled) {
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Yükle
|
|
306
|
-
const photoURL = await uploadProfilePhoto(uid, result.assets[0].uri);
|
|
307
|
-
|
|
308
|
-
// Profili güncelle
|
|
309
|
-
await updateUserProfile(uid, { photoURL });
|
|
310
|
-
}
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
## Profil Tamamlama Kontrolü
|
|
314
|
-
|
|
315
|
-
```typescript
|
|
316
|
-
function isProfileComplete(profile: UserProfile): boolean {
|
|
317
|
-
return !!(
|
|
318
|
-
profile.displayName &&
|
|
319
|
-
profile.email &&
|
|
320
|
-
profile.photoURL
|
|
321
|
-
);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
function getProfileCompleteness(profile: UserProfile): {
|
|
325
|
-
percentage: number;
|
|
326
|
-
missing: string[];
|
|
327
|
-
} {
|
|
328
|
-
const required: Array<keyof UserProfile> = [
|
|
329
|
-
'displayName',
|
|
330
|
-
'email',
|
|
331
|
-
'photoURL',
|
|
332
|
-
];
|
|
333
|
-
|
|
334
|
-
const completed = required.filter(field => !!profile[field]);
|
|
335
|
-
const percentage = (completed.length / required.length) * 100;
|
|
336
|
-
|
|
337
|
-
const missing = required.filter(field => !profile[field]);
|
|
338
|
-
|
|
339
|
-
return { percentage, missing };
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// Kullanım
|
|
343
|
-
const completeness = getProfileCompleteness(profile);
|
|
344
|
-
console.log(`Profil %${completeness.percentage} tamamlandı`);
|
|
345
|
-
console.log('Eksik:', completeness.missing); // ['displayName', 'photoURL']
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
## Profil İsim Görüntüleme
|
|
349
|
-
|
|
350
|
-
```typescript
|
|
351
|
-
function getProfileDisplayName(profile: UserProfile): string {
|
|
352
|
-
if (profile.displayName) {
|
|
353
|
-
return profile.displayName;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
if (profile.email) {
|
|
357
|
-
const emailName = profile.email.split('@')[0];
|
|
358
|
-
return emailName.charAt(0).toUpperCase() + emailName.slice(1);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
if (profile.isAnonymous) {
|
|
362
|
-
return 'Misafir';
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
return 'Kullanıcı';
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
function getProfileInitials(profile: UserProfile): string {
|
|
369
|
-
if (profile.displayName) {
|
|
370
|
-
const names = profile.displayName.trim().split(' ');
|
|
371
|
-
if (names.length >= 2) {
|
|
372
|
-
return (names[0][0] + names[names.length - 1][0]).toUpperCase();
|
|
373
|
-
}
|
|
374
|
-
return names[0][0].toUpperCase();
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
if (profile.email) {
|
|
378
|
-
return profile.email[0].toUpperCase();
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
return '?';
|
|
382
|
-
}
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
## Profil Meta Verileri
|
|
386
|
-
|
|
387
|
-
### Extra Fields Ekleme
|
|
388
|
-
|
|
389
|
-
```typescript
|
|
390
|
-
interface ExtendedUserProfile extends UserProfile {
|
|
391
|
-
bio?: string;
|
|
392
|
-
location?: string;
|
|
393
|
-
website?: string;
|
|
394
|
-
phoneNumber?: string;
|
|
395
|
-
dateOfBirth?: Date;
|
|
396
|
-
gender?: 'male' | 'female' | 'other' | 'prefer_not_to_say';
|
|
397
|
-
preferences?: {
|
|
398
|
-
newsletter: boolean;
|
|
399
|
-
notifications: boolean;
|
|
400
|
-
language: string;
|
|
401
|
-
};
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// Kullanım
|
|
405
|
-
const extendedProfile: ExtendedUserProfile = {
|
|
406
|
-
...baseProfile,
|
|
407
|
-
bio: 'Software developer',
|
|
408
|
-
location: 'Istanbul, Turkey',
|
|
409
|
-
website: 'https://johndoe.com',
|
|
410
|
-
preferences: {
|
|
411
|
-
newsletter: true,
|
|
412
|
-
notifications: true,
|
|
413
|
-
language: 'tr',
|
|
414
|
-
},
|
|
415
|
-
};
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
## Firestore Index'leri
|
|
419
|
-
|
|
420
|
-
```json
|
|
421
|
-
{
|
|
422
|
-
"indexes": [
|
|
423
|
-
{
|
|
424
|
-
"collectionGroup": "users",
|
|
425
|
-
"queryScope": "COLLECTION",
|
|
426
|
-
"fields": [
|
|
427
|
-
{ "fieldPath": "displayName", "order": "ASCENDING" },
|
|
428
|
-
{ "fieldPath": "createdAt", "order": "DESCENDING" }
|
|
429
|
-
]
|
|
430
|
-
}
|
|
431
|
-
]
|
|
432
|
-
}
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
## İlgili Entity'ler
|
|
436
|
-
|
|
437
|
-
- **[`AuthUser`](./AuthUser.md)** - Authentication kullanıcı entity'si
|
|
438
|
-
- **[`UpdateProfileParams`](#tip-tanımları)** - Profil güncelleme parametreleri
|
|
439
|
-
|
|
440
|
-
## İlgili Hook'lar
|
|
441
|
-
|
|
442
|
-
- **[`useUserProfile`](../../presentation/hooks/useUserProfile.md)** - Profil verileri hook'u
|
|
443
|
-
- **[`useProfileUpdate`](../../presentation/hooks/useProfileUpdate.md)** - Profil güncelleme hook'u
|
|
3
|
+
User profile entity for Firestore document storage.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Strategy
|
|
8
|
+
|
|
9
|
+
**Purpose**: Represents user profile data stored in Firestore. Contains display information, metadata, and profile settings.
|
|
10
|
+
|
|
11
|
+
**When to Use**:
|
|
12
|
+
- Storing user profile data
|
|
13
|
+
- Displaying user information
|
|
14
|
+
- Profile management operations
|
|
15
|
+
- User metadata tracking
|
|
16
|
+
|
|
17
|
+
**Location**: `src/domain/entities/UserProfile.ts`
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Type Definition
|
|
22
|
+
|
|
23
|
+
### UserProfile Interface
|
|
24
|
+
|
|
25
|
+
**PROPERTIES**:
|
|
26
|
+
- `uid: string` - User ID
|
|
27
|
+
- `email: string | null` - Email address
|
|
28
|
+
- `displayName: string | null` - Display name
|
|
29
|
+
- `photoURL: string | null` - Profile photo URL
|
|
30
|
+
- `isAnonymous: boolean` - Anonymous flag
|
|
31
|
+
- `createdAt: Date | null` - Account creation date
|
|
32
|
+
- `lastLoginAt: Date | null` - Last login timestamp
|
|
33
|
+
|
|
34
|
+
### UpdateProfileParams
|
|
35
|
+
|
|
36
|
+
**PROPERTIES**:
|
|
37
|
+
- `displayName?: string` - New display name
|
|
38
|
+
- `photoURL?: string` - New photo URL
|
|
39
|
+
|
|
40
|
+
**Rules**:
|
|
41
|
+
- MUST provide at least one field
|
|
42
|
+
- MUST validate updates before saving
|
|
43
|
+
- MUST handle partial updates
|
|
44
|
+
|
|
45
|
+
**Constraints**:
|
|
46
|
+
- Optional fields
|
|
47
|
+
- Only provided fields updated
|
|
48
|
+
- Validation applies
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Profile States
|
|
53
|
+
|
|
54
|
+
### Complete Profile
|
|
55
|
+
|
|
56
|
+
**CHARACTERISTICS**:
|
|
57
|
+
- Has displayName
|
|
58
|
+
- Has email
|
|
59
|
+
- Has photoURL
|
|
60
|
+
- Not anonymous
|
|
61
|
+
|
|
62
|
+
**Rules**:
|
|
63
|
+
- SHOULD encourage completion
|
|
64
|
+
- MAY require for features
|
|
65
|
+
- MUST validate updates
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
### Minimal Profile
|
|
70
|
+
|
|
71
|
+
**CHARACTERISTICS**:
|
|
72
|
+
- May have null displayName
|
|
73
|
+
- Has email
|
|
74
|
+
- May not have photoURL
|
|
75
|
+
- Not anonymous
|
|
76
|
+
|
|
77
|
+
**Rules**:
|
|
78
|
+
- MUST have email
|
|
79
|
+
- CAN be incomplete
|
|
80
|
+
- SHOULD encourage completion
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
### Anonymous Profile
|
|
85
|
+
|
|
86
|
+
**CHARACTERISTICS**:
|
|
87
|
+
- isAnonymous = true
|
|
88
|
+
- Null email
|
|
89
|
+
- Null displayName
|
|
90
|
+
- Null photoURL
|
|
91
|
+
|
|
92
|
+
**Rules**:
|
|
93
|
+
- MUST treat as temporary
|
|
94
|
+
- SHOULD encourage upgrade
|
|
95
|
+
- MUST offer registration
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Profile Operations
|
|
100
|
+
|
|
101
|
+
### Creation
|
|
102
|
+
|
|
103
|
+
**RULES**:
|
|
104
|
+
- MUST create on user registration
|
|
105
|
+
- MUST include uid
|
|
106
|
+
- MUST set initial timestamps
|
|
107
|
+
- MUST NOT delete existing profiles
|
|
108
|
+
|
|
109
|
+
**CONSTRAINTS**:
|
|
110
|
+
- One profile per uid
|
|
111
|
+
- Created in Firestore
|
|
112
|
+
- Auto-generated timestamps
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
### Updates
|
|
117
|
+
|
|
118
|
+
**RULES**:
|
|
119
|
+
- MUST validate input data
|
|
120
|
+
- MUST update updatedAt timestamp
|
|
121
|
+
- MUST preserve existing data
|
|
122
|
+
- MUST handle concurrent updates
|
|
123
|
+
|
|
124
|
+
**CONSTRAINTS**:
|
|
125
|
+
- Partial updates supported
|
|
126
|
+
- Fields not provided unchanged
|
|
127
|
+
- Validation required
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
### Deletion
|
|
132
|
+
|
|
133
|
+
**RULES**:
|
|
134
|
+
- MUST mark as deleted (not actual delete)
|
|
135
|
+
- MAY retain data for grace period
|
|
136
|
+
- MUST handle cleanup properly
|
|
137
|
+
- MUST be reversible (initially)
|
|
138
|
+
|
|
139
|
+
**CONSTRAINTS**:
|
|
140
|
+
- Soft delete recommended
|
|
141
|
+
- May have retention period
|
|
142
|
+
- Permanent delete after period
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Validation
|
|
147
|
+
|
|
148
|
+
### Display Name Validation
|
|
149
|
+
|
|
150
|
+
**RULES**:
|
|
151
|
+
- MUST be 2-50 characters if provided
|
|
152
|
+
- MUST not contain only spaces
|
|
153
|
+
- SHOULD trim whitespace
|
|
154
|
+
- MAY allow special characters
|
|
155
|
+
|
|
156
|
+
**CONSTRAINTS**:
|
|
157
|
+
- Minimum length: 2 characters
|
|
158
|
+
- Maximum length: 100 characters
|
|
159
|
+
- Cannot be only whitespace
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### Photo URL Validation
|
|
164
|
+
|
|
165
|
+
**RULES**:
|
|
166
|
+
- MUST be valid URL if provided
|
|
167
|
+
- MUST use HTTP or HTTPS
|
|
168
|
+
- SHOULD point to image file
|
|
169
|
+
- MUST be accessible
|
|
170
|
+
|
|
171
|
+
**CONSTRAINTS**:
|
|
172
|
+
- Valid URL format required
|
|
173
|
+
- HTTP or HTTPS protocol
|
|
174
|
+
- Image file extension preferred
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Profile Completeness
|
|
179
|
+
|
|
180
|
+
### Completeness Calculation
|
|
181
|
+
|
|
182
|
+
**FACTORS**:
|
|
183
|
+
- displayName presence
|
|
184
|
+
- email presence
|
|
185
|
+
- photoURL presence
|
|
186
|
+
|
|
187
|
+
**RULES**:
|
|
188
|
+
- SHOULD track completeness percentage
|
|
189
|
+
- MAY require for features
|
|
190
|
+
- MUST show user what's missing
|
|
191
|
+
|
|
192
|
+
**CONSTRAINTS**:
|
|
193
|
+
- 3 core fields checked
|
|
194
|
+
- Percentage calculation
|
|
195
|
+
- Missing fields list
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Firestore Integration
|
|
200
|
+
|
|
201
|
+
### Collection Structure
|
|
202
|
+
|
|
203
|
+
**COLLECTION**: `users`
|
|
204
|
+
|
|
205
|
+
**DOCUMENT ID**: User uid
|
|
206
|
+
|
|
207
|
+
**INDEXES**:
|
|
208
|
+
- displayName (ASCENDING)
|
|
209
|
+
- createdAt (DESCENDING)
|
|
210
|
+
- Composite indexes as needed
|
|
211
|
+
|
|
212
|
+
**Rules**:
|
|
213
|
+
- MUST use users collection by default
|
|
214
|
+
- MAY configure custom collection
|
|
215
|
+
- MUST create required indexes
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
### Timestamps
|
|
220
|
+
|
|
221
|
+
**SERVER TIMESTAMPS**:
|
|
222
|
+
- `createdAt` - Document creation
|
|
223
|
+
- `updatedAt` - Last update
|
|
224
|
+
- `lastLoginAt` - Last login
|
|
225
|
+
|
|
226
|
+
**Rules**:
|
|
227
|
+
- MUST use serverTimestamp() for creation
|
|
228
|
+
- MUST update on modification
|
|
229
|
+
- MUST track login time
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Privacy & Security
|
|
234
|
+
|
|
235
|
+
### Data Access
|
|
236
|
+
|
|
237
|
+
**RULES**:
|
|
238
|
+
- MUST NOT expose sensitive data
|
|
239
|
+
- MUST validate read permissions
|
|
240
|
+
- MUST log profile access
|
|
241
|
+
- MUST respect privacy settings
|
|
242
|
+
|
|
243
|
+
**MUST NOT**:
|
|
244
|
+
- Show internal IDs publicly
|
|
245
|
+
- Expose email without permission
|
|
246
|
+
- Log full profile data
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
### Anonymous Profiles
|
|
251
|
+
|
|
252
|
+
**RULES**:
|
|
253
|
+
- MUST indicate anonymous status
|
|
254
|
+
- MUST NOT show as authenticated
|
|
255
|
+
- SHOULD encourage upgrade
|
|
256
|
+
- MUST preserve during upgrade
|
|
257
|
+
|
|
258
|
+
**CONSTRAINTS**:
|
|
259
|
+
- Temporary state
|
|
260
|
+
- Limited data
|
|
261
|
+
- Upgrade path available
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Related Entities
|
|
266
|
+
|
|
267
|
+
- **AuthUser** (`./AuthUser.md`) - Authentication user entity
|
|
268
|
+
- **UpdateProfileParams** (see above) - Update parameters
|
|
269
|
+
|
|
270
|
+
## Related Infrastructure
|
|
271
|
+
|
|
272
|
+
- **UserDocumentService** (`../../infrastructure/services/UserDocumentService.ts`) - Document management
|
|
273
|
+
- **Firestore** - Database storage
|