11import 'package:core/core.dart' ;
2+ import 'package:flutter_news_app_api_server_full_source_code/src/config/environment_config.dart' ;
23import 'package:flutter_news_app_api_server_full_source_code/src/services/mongodb_token_blacklist_service.dart' ;
34import 'package:flutter_news_app_api_server_full_source_code/src/services/mongodb_verification_code_storage_service.dart' ;
45import 'package:logging/logging.dart' ;
@@ -25,6 +26,7 @@ class DatabaseSeedingService {
2526 _log.info ('Starting database seeding process...' );
2627
2728 await _ensureIndexes ();
29+ await _seedInitialAdminUser ();
2830
2931 await _seedCollection <Country >(
3032 collectionName: 'countries' ,
@@ -73,6 +75,82 @@ class DatabaseSeedingService {
7375 _log.info ('Database seeding process completed.' );
7476 }
7577
78+ /// Seeds the initial administrator user from the environment variable.
79+ Future <void > _seedInitialAdminUser () async {
80+ _log.info ('Checking for initial admin user...' );
81+ final adminEmail = EnvironmentConfig .initialAdminEmail;
82+
83+ if (adminEmail == null || adminEmail.isEmpty) {
84+ _log.info ('INITIAL_ADMIN_EMAIL not set. Skipping admin user seeding.' );
85+ return ;
86+ }
87+
88+ final usersCollection = _db.collection ('users' );
89+ final existingAdmin = await usersCollection.findOne ({'email' : adminEmail});
90+
91+ if (existingAdmin != null ) {
92+ _log.info ('Admin user with email $adminEmail already exists.' );
93+ return ;
94+ }
95+
96+ _log.info ('Creating initial admin user for email: $adminEmail ' );
97+ final adminId = ObjectId ();
98+ final adminUser = User (
99+ id: adminId.oid,
100+ email: adminEmail,
101+ appRole: AppUserRole .standardUser, // Admins are standard app users
102+ dashboardRole: DashboardUserRole .admin, // With admin dashboard role
103+ createdAt: DateTime .now (),
104+ feedActionStatus: Map .fromEntries (
105+ FeedActionType .values.map (
106+ (type) =>
107+ MapEntry (type, const UserFeedActionStatus (isCompleted: false )),
108+ ),
109+ ),
110+ );
111+
112+ await usersCollection.insertOne (
113+ {'_id' : adminId, ...adminUser.toJson ()..remove ('id' )},
114+ );
115+
116+ // Also create their default settings and preferences documents
117+ final defaultAppSettings = UserAppSettings (
118+ id: adminId.oid,
119+ displaySettings: const DisplaySettings (
120+ baseTheme: AppBaseTheme .system,
121+ accentTheme: AppAccentTheme .defaultBlue,
122+ fontFamily: 'SystemDefault' ,
123+ textScaleFactor: AppTextScaleFactor .medium,
124+ fontWeight: AppFontWeight .regular,
125+ ),
126+ language: 'en' ,
127+ feedPreferences: const FeedDisplayPreferences (
128+ headlineDensity: HeadlineDensity .standard,
129+ headlineImageStyle: HeadlineImageStyle .largeThumbnail,
130+ showSourceInHeadlineFeed: true ,
131+ showPublishDateInHeadlineFeed: true ,
132+ ),
133+ );
134+
135+ await _db.collection ('user_app_settings' ).insertOne (
136+ {'_id' : adminId, ...defaultAppSettings.toJson ()..remove ('id' )},
137+ );
138+
139+ final defaultUserPreferences = UserContentPreferences (
140+ id: adminId.oid,
141+ followedCountries: const [],
142+ followedSources: const [],
143+ followedTopics: const [],
144+ savedHeadlines: const [],
145+ );
146+
147+ await _db.collection ('user_content_preferences' ).insertOne (
148+ {'_id' : adminId, ...defaultUserPreferences.toJson ()..remove ('id' )},
149+ );
150+
151+ _log.info ('Successfully created initial admin user for $adminEmail .' );
152+ }
153+
76154 /// Seeds a specific collection from a given list of fixture data.
77155 Future <void > _seedCollection <T >({
78156 required String collectionName,
0 commit comments