Skip to content

Commit 745ab9d

Browse files
committed
feat(core): integrate database seeding into server startup
Updates `server.dart` to instantiate and run the `DatabaseSeedingService` after the database connection is established. This ensures that tables are created and initial data (global fixtures, admin user, app config) is seeded on every server start. The idempotent nature of the seeding operations makes this process safe and reliable for both development and first-time production deployments.
1 parent dc758e1 commit 745ab9d

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

lib/src/config/server.dart

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:ht_api/src/services/auth_token_service.dart';
88
import 'package:ht_api/src/services/dashboard_summary_service.dart';
99
import 'package:ht_api/src/services/default_user_preference_limit_service.dart';
1010
import 'package:ht_api/src/services/jwt_auth_token_service.dart';
11+
import 'package:ht_api/src/services/database_seeding_service.dart';
1112
import 'package:ht_api/src/services/token_blacklist_service.dart';
1213
import 'package:ht_api/src/services/user_preference_limit_service.dart';
1314
import 'package:ht_api/src/services/verification_code_storage_service.dart';
@@ -92,7 +93,17 @@ Future<HttpServer> run(Handler handler, InternetAddress ip, int port) async {
9293
);
9394
_log.info('PostgreSQL database connection established.');
9495

95-
// 3. Initialize Repositories
96+
// 3. Initialize and run database seeding
97+
// This runs on every startup. The operations are idempotent (`IF NOT EXISTS`,
98+
// `ON CONFLICT DO NOTHING`), so it's safe to run every time. This ensures
99+
// the database is always in a valid state, especially for first-time setup
100+
// in any environment.
101+
final seedingService = DatabaseSeedingService(connection: _connection, log: _log);
102+
await seedingService.createTables();
103+
await seedingService.seedGlobalFixtureData();
104+
await seedingService.seedInitialAdminAndConfig();
105+
106+
// 4. Initialize Repositories
96107
final headlineRepository = _createRepository<Headline>(
97108
tableName: 'headlines',
98109
fromJson: Headline.fromJson,
@@ -135,7 +146,7 @@ Future<HttpServer> run(Handler handler, InternetAddress ip, int port) async {
135146
toJson: (c) => c.toJson(),
136147
);
137148

138-
// 4. Initialize Services
149+
// 5. Initialize Services
139150
const uuid = Uuid();
140151
const emailRepository = HtEmailRepository(
141152
emailClient: HtEmailInMemoryClient(),
@@ -167,7 +178,7 @@ Future<HttpServer> run(Handler handler, InternetAddress ip, int port) async {
167178
appConfigRepository: appConfigRepository,
168179
);
169180

170-
// 5. Create the main handler with all dependencies provided
181+
// 6. Create the main handler with all dependencies provided
171182
final finalHandler = handler
172183
// Foundational utilities
173184
.use(provider<Uuid>((_) => uuid))
@@ -206,15 +217,15 @@ Future<HttpServer> run(Handler handler, InternetAddress ip, int port) async {
206217
),
207218
);
208219

209-
// 6. Start the server
220+
// 7. Start the server
210221
final server = await serve(
211222
finalHandler,
212223
ip,
213224
port,
214225
);
215226
_log.info('Server listening on port ${server.port}');
216227

217-
// 7. Handle graceful shutdown
228+
// 8. Handle graceful shutdown
218229
ProcessSignal.sigint.watch().listen((_) async {
219230
_log.info('Received SIGINT. Shutting down...');
220231
await _connection.close();

0 commit comments

Comments
 (0)