Files
itinova-budget-si/server/databaseMigrations.ts

56 lines
1.8 KiB
TypeScript

import { migrate } from "drizzle-orm/mysql2/migrator";
import { drizzle } from "drizzle-orm/mysql2";
import { eq } from "drizzle-orm";
import { createPool } from "mysql2/promise";
import bcrypt from "bcryptjs";
import { users } from "../drizzle/schema";
const INITIAL_ADMIN_LOGIN = "adminItinova";
const INITIAL_ADMIN_PASSWORD = process.env.INITIAL_ADMIN_PASSWORD ?? "Itinova69!";
async function ensureInitialAdmin(pool: ReturnType<typeof createPool>) {
const database = drizzle(pool);
const existingAdmin = await database
.select({ id: users.id })
.from(users)
.where(eq(users.login, INITIAL_ADMIN_LOGIN))
.limit(1);
if (existingAdmin.length > 0) return;
const passwordHash = await bcrypt.hash(INITIAL_ADMIN_PASSWORD, 12);
await database.insert(users).values({
login: INITIAL_ADMIN_LOGIN,
email: "adminItinova@santinova-soft.org",
firstName: "Admin",
lastName: "Itinova",
passwordHash,
role: "admin",
isActive: true,
});
console.log("[Database] Compte administrateur initial créé.");
}
/**
* 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 {
const database = drizzle(pool);
await migrate(database, { migrationsFolder: "./drizzle" });
await ensureInitialAdmin(pool);
console.log("[Database] Migrations Drizzle synchronisées.");
} finally {
await pool.end();
}
}