Skip to content

Commit 3a8c878

Browse files
authored
Merge pull request #20 from headlines-toolkit/fix_new_user_unprepared_settings_and_preferences
refactor(auth): introduce _ensureUserDataExists to handle default doc…
2 parents 1df3380 + 696b872 commit 3a8c878

File tree

1 file changed

+66
-79
lines changed

1 file changed

+66
-79
lines changed

lib/src/services/auth_service.dart

Lines changed: 66 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -229,45 +229,8 @@ class AuthService {
229229
user = await _userRepository.create(item: user);
230230
_log.info('Created new user: ${user.id} with appRole: ${user.appRole}');
231231

232-
// Create default UserAppSettings for the new user
233-
final defaultAppSettings = UserAppSettings(
234-
id: user.id,
235-
displaySettings: const DisplaySettings(
236-
baseTheme: AppBaseTheme.system,
237-
accentTheme: AppAccentTheme.defaultBlue,
238-
fontFamily: 'SystemDefault',
239-
textScaleFactor: AppTextScaleFactor.medium,
240-
fontWeight: AppFontWeight.regular,
241-
),
242-
language: 'en',
243-
feedPreferences: const FeedDisplayPreferences(
244-
headlineDensity: HeadlineDensity.standard,
245-
headlineImageStyle: HeadlineImageStyle.largeThumbnail,
246-
showSourceInHeadlineFeed: true,
247-
showPublishDateInHeadlineFeed: true,
248-
),
249-
);
250-
await _userAppSettingsRepository.create(
251-
item: defaultAppSettings,
252-
userId: user.id,
253-
);
254-
_log.info('Created default UserAppSettings for user: ${user.id}');
255-
256-
// Create default UserContentPreferences for the new user
257-
final defaultUserPreferences = UserContentPreferences(
258-
id: user.id,
259-
followedCountries: const [],
260-
followedSources: const [],
261-
followedTopics: const [],
262-
savedHeadlines: const [],
263-
);
264-
await _userContentPreferencesRepository.create(
265-
item: defaultUserPreferences,
266-
userId: user.id,
267-
);
268-
_log.info(
269-
'Created default UserContentPreferences for user: ${user.id}',
270-
);
232+
// Ensure default documents are created for the new user.
233+
await _ensureUserDataExists(user);
271234
}
272235
} on HtHttpException {
273236
// Propagate known exceptions from dependencies or from this method's logic.
@@ -322,6 +285,9 @@ class AuthService {
322285
);
323286
user = await _userRepository.create(item: user);
324287
_log.info('Created anonymous user: ${user.id}');
288+
289+
// Ensure default documents are created for the new anonymous user.
290+
await _ensureUserDataExists(user);
325291
} on HtHttpException catch (e) {
326292
_log.severe('Error creating anonymous user: $e');
327293
throw const OperationFailedException('Failed to create anonymous user.');
@@ -332,46 +298,6 @@ class AuthService {
332298
);
333299
}
334300

335-
// Create default UserAppSettings for the new anonymous user
336-
final defaultAppSettings = UserAppSettings(
337-
id: user.id,
338-
displaySettings: const DisplaySettings(
339-
baseTheme: AppBaseTheme.system,
340-
accentTheme: AppAccentTheme.defaultBlue,
341-
fontFamily: 'SystemDefault',
342-
textScaleFactor: AppTextScaleFactor.medium,
343-
fontWeight: AppFontWeight.regular,
344-
),
345-
language: 'en',
346-
feedPreferences: const FeedDisplayPreferences(
347-
headlineDensity: HeadlineDensity.standard,
348-
headlineImageStyle: HeadlineImageStyle.largeThumbnail,
349-
showSourceInHeadlineFeed: true,
350-
showPublishDateInHeadlineFeed: true,
351-
),
352-
);
353-
await _userAppSettingsRepository.create(
354-
item: defaultAppSettings,
355-
userId: user.id, // Pass user ID for scoping
356-
);
357-
_log.info('Created default UserAppSettings for anonymous user: ${user.id}');
358-
359-
// Create default UserContentPreferences for the new anonymous user
360-
final defaultUserPreferences = UserContentPreferences(
361-
id: user.id,
362-
followedCountries: const [],
363-
followedSources: const [],
364-
followedTopics: const [],
365-
savedHeadlines: const [],
366-
);
367-
await _userContentPreferencesRepository.create(
368-
item: defaultUserPreferences,
369-
userId: user.id, // Pass user ID for scoping
370-
);
371-
_log.info(
372-
'Created default UserContentPreferences for anonymous user: ${user.id}',
373-
);
374-
375301
// 2. Generate token
376302
try {
377303
final token = await _authTokenService.generateToken(user);
@@ -541,6 +467,9 @@ class AuthService {
541467
'User ${permanentUser.id} successfully linked with email $linkedEmail.',
542468
);
543469

470+
// Ensure user data exists after linking.
471+
await _ensureUserDataExists(permanentUser);
472+
544473
// 3. Generate a new authentication token for the now-permanent user.
545474
final newToken = await _authTokenService.generateToken(permanentUser);
546475
_log.info('Generated new token for linked user ${permanentUser.id}');
@@ -666,4 +595,62 @@ class AuthService {
666595
rethrow;
667596
}
668597
}
598+
599+
/// Ensures that the essential user-specific documents (settings, preferences)
600+
/// exist for a given user, creating them with default values if they are missing.
601+
///
602+
/// This method is crucial for maintaining data integrity, especially for users
603+
/// who might have been created before these documents were part of the standard
604+
/// user creation process.
605+
Future<void> _ensureUserDataExists(User user) async {
606+
// Check for UserAppSettings
607+
try {
608+
await _userAppSettingsRepository.read(id: user.id, userId: user.id);
609+
} on NotFoundException {
610+
_log.info(
611+
'UserAppSettings not found for user ${user.id}. Creating with defaults.',
612+
);
613+
final defaultAppSettings = UserAppSettings(
614+
id: user.id,
615+
displaySettings: const DisplaySettings(
616+
baseTheme: AppBaseTheme.system,
617+
accentTheme: AppAccentTheme.defaultBlue,
618+
fontFamily: 'SystemDefault',
619+
textScaleFactor: AppTextScaleFactor.medium,
620+
fontWeight: AppFontWeight.regular,
621+
),
622+
language: 'en',
623+
feedPreferences: const FeedDisplayPreferences(
624+
headlineDensity: HeadlineDensity.standard,
625+
headlineImageStyle: HeadlineImageStyle.largeThumbnail,
626+
showSourceInHeadlineFeed: true,
627+
showPublishDateInHeadlineFeed: true,
628+
),
629+
);
630+
await _userAppSettingsRepository.create(
631+
item: defaultAppSettings,
632+
userId: user.id,
633+
);
634+
}
635+
636+
// Check for UserContentPreferences
637+
try {
638+
await _userContentPreferencesRepository.read(id: user.id, userId: user.id);
639+
} on NotFoundException {
640+
_log.info(
641+
'UserContentPreferences not found for user ${user.id}. Creating with defaults.',
642+
);
643+
final defaultUserPreferences = UserContentPreferences(
644+
id: user.id,
645+
followedCountries: const [],
646+
followedSources: const [],
647+
followedTopics: const [],
648+
savedHeadlines: const [],
649+
);
650+
await _userContentPreferencesRepository.create(
651+
item: defaultUserPreferences,
652+
userId: user.id,
653+
);
654+
}
655+
}
669656
}

0 commit comments

Comments
 (0)