Checkpoint: Correctif de production : le serveur exécute désormais les migrations Drizzle versionnées avant l'ouverture HTTP, ce qui initialise une base vide lors du premier déploiement. Test de régression ajouté. Validation complète réussie : 61 tests, TypeScript et build.
All checks were successful
Validation applicative / TypeScript, tests et build (push) Successful in 4m45s

This commit is contained in:
Manus
2026-08-30 09:40:46 +00:00
parent 6447389cb8
commit b2c8580382
5 changed files with 58 additions and 5 deletions

View File

@@ -7,6 +7,7 @@ import { registerOAuthRoutes } from "./oauth";
import { registerStorageProxy } from "./storageProxy";
import { appRouter } from "../routers";
import { registerSalairesHttpRoutes } from "../salairesHttp";
import { runDatabaseMigrations } from "../databaseMigrations";
import { createContext } from "./context";
import { serveStatic, setupVite } from "./vite";
@@ -30,6 +31,8 @@ async function findAvailablePort(startPort: number = 3000): Promise<number> {
}
async function startServer() {
// Une instance ne devient disponible qu'après la synchronisation du schéma.
await runDatabaseMigrations();
const app = express();
const server = createServer(app);
// Configure body parser with larger size limit for file uploads

View File

@@ -0,0 +1,24 @@
import { migrate } from "drizzle-orm/mysql2/migrator";
import { drizzle } from "drizzle-orm/mysql2";
import { createPool } from "mysql2/promise";
/**
* Synchronise la base avec les migrations versionnées avant d'exposer l'API.
* Une base sans DATABASE_URL reste utilisable en développement statique, mais
* un déploiement connecté échoue explicitement si la migration ne peut aboutir.
*/
export async function runDatabaseMigrations() {
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
console.warn("[Database] DATABASE_URL absent : migrations ignorées.");
return;
}
const pool = createPool(databaseUrl);
try {
await migrate(drizzle(pool), { migrationsFolder: "./drizzle" });
console.log("[Database] Migrations Drizzle synchronisées.");
} finally {
await pool.end();
}
}

View File

@@ -0,0 +1,14 @@
import { readFile } from "node:fs/promises";
import { resolve } from "node:path";
import { describe, expect, it } from "vitest";
describe("bootstrap de migrations Docker", () => {
it("exécute les migrations Drizzle avant de lancer le serveur", async () => {
const server = await readFile(resolve(process.cwd(), "server/_core/index.ts"), "utf8");
const migrationBootstrap = await readFile(resolve(process.cwd(), "server/databaseMigrations.ts"), "utf8");
expect(server).toContain("await runDatabaseMigrations()");
expect(migrationBootstrap).toContain("migrate(");
expect(migrationBootstrap).toContain("migrationsFolder: \"./drizzle\"");
});
});