Skip to content

Commit d560da5

Browse files
committed
feat: Add DemoDataMigrationService
- Migrates user data on demo login - Handles UserAppSettings migration - Handles UserContentPreferences migration - Idempotent and resilient
1 parent 7fff7dc commit d560da5

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import 'package:ht_data_repository/ht_data_repository.dart';
2+
import 'package:ht_shared/ht_shared.dart';
3+
4+
/// {@template demo_data_migration_service}
5+
/// A service responsible for migrating user data (settings and preferences)
6+
/// from an anonymous user ID to a new authenticated user ID in demo mode.
7+
///
8+
/// This service is specifically designed for the in-memory data clients
9+
/// used in the demo environment, as backend APIs typically handle this
10+
/// migration automatically.
11+
/// {@endtemplate}
12+
class DemoDataMigrationService {
13+
/// {@macro demo_data_migration_service}
14+
const DemoDataMigrationService({
15+
required HtDataRepository<UserAppSettings> userAppSettingsRepository,
16+
required HtDataRepository<UserContentPreferences>
17+
userContentPreferencesRepository,
18+
}) : _userAppSettingsRepository = userAppSettingsRepository,
19+
_userContentPreferencesRepository = userContentPreferencesRepository;
20+
21+
final HtDataRepository<UserAppSettings> _userAppSettingsRepository;
22+
final HtDataRepository<UserContentPreferences>
23+
_userContentPreferencesRepository;
24+
25+
/// Migrates user settings and content preferences from an old anonymous
26+
/// user ID to a new authenticated user ID.
27+
///
28+
/// This operation is designed to be idempotent and resilient to missing
29+
/// data for the old user ID.
30+
Future<void> migrateAnonymousData({
31+
required String oldUserId,
32+
required String newUserId,
33+
}) async {
34+
print(
35+
'[DemoDataMigrationService] Attempting to migrate data from '
36+
'anonymous user ID: $oldUserId to authenticated user ID: $newUserId',
37+
);
38+
39+
// Migrate UserAppSettings
40+
try {
41+
final oldSettings = await _userAppSettingsRepository.read(
42+
id: oldUserId,
43+
userId: oldUserId,
44+
);
45+
final newSettings = oldSettings.copyWith(id: newUserId);
46+
await _userAppSettingsRepository.update(
47+
id: newUserId,
48+
item: newSettings,
49+
userId: newUserId,
50+
);
51+
await _userAppSettingsRepository.delete(
52+
id: oldUserId,
53+
userId: oldUserId,
54+
);
55+
print(
56+
'[DemoDataMigrationService] UserAppSettings migrated successfully '
57+
'from $oldUserId to $newUserId.',
58+
);
59+
} on NotFoundException {
60+
print(
61+
'[DemoDataMigrationService] No UserAppSettings found for old user ID: '
62+
'$oldUserId. Skipping migration for settings.',
63+
);
64+
} catch (e, s) {
65+
print(
66+
'[DemoDataMigrationService] Error migrating UserAppSettings from '
67+
'$oldUserId to $newUserId: $e\n$s',
68+
);
69+
}
70+
71+
// Migrate UserContentPreferences
72+
try {
73+
final oldPreferences = await _userContentPreferencesRepository.read(
74+
id: oldUserId,
75+
userId: oldUserId,
76+
);
77+
final newPreferences = oldPreferences.copyWith(id: newUserId);
78+
await _userContentPreferencesRepository.update(
79+
id: newUserId,
80+
item: newPreferences,
81+
userId: newUserId,
82+
);
83+
await _userContentPreferencesRepository.delete(
84+
id: oldUserId,
85+
userId: oldUserId,
86+
);
87+
print(
88+
'[DemoDataMigrationService] UserContentPreferences migrated '
89+
'successfully from $oldUserId to $newUserId.',
90+
);
91+
} on NotFoundException {
92+
print(
93+
'[DemoDataMigrationService] No UserContentPreferences found for old '
94+
'user ID: $oldUserId. Skipping migration for preferences.',
95+
);
96+
} catch (e, s) {
97+
print(
98+
'[DemoDataMigrationService] Error migrating UserContentPreferences '
99+
'from $oldUserId to $newUserId: $e\n$s',
100+
);
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)