SONUM v7 - Évolution v6 (éditeurs/blocs CRUD, tableau de bord stats) + vue liste alternance couleurs
This commit is contained in:
93
scripts/create-admin.mjs
Normal file
93
scripts/create-admin.mjs
Normal file
@@ -0,0 +1,93 @@
|
||||
import { drizzle } from "drizzle-orm/mysql2";
|
||||
import mysql from "mysql2/promise";
|
||||
import bcrypt from "bcryptjs";
|
||||
import { eq } from "drizzle-orm";
|
||||
import * as schema from "../drizzle/schema.ts";
|
||||
import dotenv from "dotenv";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const { users, localCredentials } = schema;
|
||||
|
||||
const EMAIL = "adminItinova"; // login (utilisé comme email)
|
||||
const PASSWORD = "Itinova69!";
|
||||
const NAME = "Gestionnaire SONUM (Itinova)";
|
||||
const SONUM_ROLE = "gestionnaire";
|
||||
const OPEN_ID = "local-admin-itinova"; // openId unique pour compte local
|
||||
|
||||
async function main() {
|
||||
if (!process.env.DATABASE_URL) {
|
||||
console.error("DATABASE_URL manquant");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const connection = await mysql.createConnection(process.env.DATABASE_URL);
|
||||
const db = drizzle(connection);
|
||||
|
||||
// Vérifier si l'utilisateur existe déjà
|
||||
const existing = await db
|
||||
.select()
|
||||
.from(users)
|
||||
.where(eq(users.openId, OPEN_ID))
|
||||
.limit(1);
|
||||
|
||||
let userId;
|
||||
|
||||
if (existing.length > 0) {
|
||||
userId = existing[0].id;
|
||||
console.log(`Utilisateur existant trouvé (id=${userId}), mise à jour du mot de passe...`);
|
||||
// Mettre à jour le rôle au cas où
|
||||
await db
|
||||
.update(users)
|
||||
.set({ sonumRole: SONUM_ROLE, name: NAME, email: EMAIL, updatedAt: new Date() })
|
||||
.where(eq(users.id, userId));
|
||||
} else {
|
||||
// Créer l'utilisateur
|
||||
const result = await db.insert(users).values({
|
||||
openId: OPEN_ID,
|
||||
name: NAME,
|
||||
email: EMAIL,
|
||||
loginMethod: "local",
|
||||
role: "user",
|
||||
sonumRole: SONUM_ROLE,
|
||||
cguAccepted: true,
|
||||
cguAcceptedAt: new Date(),
|
||||
lastSignedIn: new Date(),
|
||||
});
|
||||
userId = Number(result[0].insertId);
|
||||
console.log(`Utilisateur créé (id=${userId})`);
|
||||
}
|
||||
|
||||
// Hasher le mot de passe
|
||||
const passwordHash = await bcrypt.hash(PASSWORD, 12);
|
||||
|
||||
// Insérer ou mettre à jour les credentials locaux
|
||||
const existingCreds = await db
|
||||
.select()
|
||||
.from(localCredentials)
|
||||
.where(eq(localCredentials.userId, userId))
|
||||
.limit(1);
|
||||
|
||||
if (existingCreds.length > 0) {
|
||||
await db
|
||||
.update(localCredentials)
|
||||
.set({ passwordHash, updatedAt: new Date() })
|
||||
.where(eq(localCredentials.userId, userId));
|
||||
console.log("Mot de passe mis à jour.");
|
||||
} else {
|
||||
await db.insert(localCredentials).values({ userId, passwordHash });
|
||||
console.log("Credentials locaux créés.");
|
||||
}
|
||||
|
||||
console.log("\n✅ Compte générique gestionnaire SONUM prêt :");
|
||||
console.log(` Login : ${EMAIL}`);
|
||||
console.log(` Rôle : ${SONUM_ROLE}`);
|
||||
console.log(` Nom : ${NAME}`);
|
||||
|
||||
await connection.end();
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Erreur :", err);
|
||||
process.exit(1);
|
||||
});
|
||||
71
scripts/seed.mjs
Normal file
71
scripts/seed.mjs
Normal file
@@ -0,0 +1,71 @@
|
||||
import mysql from "mysql2/promise";
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
const BLOCS = [
|
||||
"SI RH","SI Finance","SI Métier","SI Collaboratif","Site internet",
|
||||
"SI Achat","SI Support","SI Infrastructure","SI Sécurité","SI Qualité",
|
||||
"SI Immobilier","SI Décisionnel"
|
||||
];
|
||||
|
||||
const EDITEURS_DEMO = [
|
||||
"Cerner","Oracle Health","Dedalus","Mediware","Infor","SAP","Microsoft",
|
||||
"Sage","Cegid","Berger-Levrault","Maincare","Hopital Manager","Softway Medical",
|
||||
"Medasys","Enovacom","Xperis","Mipih","Sephira","Cegedim","Autre"
|
||||
];
|
||||
|
||||
const SOLUTIONS_DEMO = [
|
||||
{ nom: "DPI (Dossier Patient Informatisé)", editeur: "Dedalus", bloc: "SI Métier" },
|
||||
{ nom: "SIRH", editeur: "Cegid", bloc: "SI RH" },
|
||||
{ nom: "Logiciel de paie", editeur: "Sage", bloc: "SI RH" },
|
||||
{ nom: "Comptabilité générale", editeur: "Sage", bloc: "SI Finance" },
|
||||
{ nom: "Messagerie sécurisée", editeur: "Enovacom", bloc: "SI Collaboratif" },
|
||||
{ nom: "Intranet", editeur: "Microsoft", bloc: "Site internet" },
|
||||
{ nom: "GMAO", editeur: "Infor", bloc: "SI Immobilier" },
|
||||
{ nom: "Système de gestion des achats", editeur: "Berger-Levrault", bloc: "SI Achat" },
|
||||
{ nom: "BI / Reporting", editeur: "Microsoft", bloc: "SI Décisionnel" },
|
||||
{ nom: "Antivirus / EDR", editeur: "Microsoft", bloc: "SI Sécurité" },
|
||||
];
|
||||
|
||||
const ETABLISSEMENTS_DEMO = [
|
||||
{ nom: "Clinique Saint-Joseph", finess: "750123456", region: "Île-de-France", typeActivite: "MCO", tailleEffectifs: "200 - 500 salariés" },
|
||||
{ nom: "EHPAD Les Jardins", finess: "690234567", region: "Auvergne-Rhône-Alpes", typeActivite: "EHPAD", tailleEffectifs: "50 - 200 salariés" },
|
||||
{ nom: "Centre Hospitalier de Bretagne", finess: "290345678", region: "Bretagne", typeActivite: "MCO", tailleEffectifs: "500 - 1000 salariés" },
|
||||
{ nom: "HAD Nouvelle-Aquitaine", finess: "330456789", region: "Nouvelle-Aquitaine", typeActivite: "HAD", tailleEffectifs: "< 50 salariés" },
|
||||
{ nom: "IME Les Pins", finess: "130567890", region: "Provence-Alpes-Côte d'Azur", typeActivite: "IME", tailleEffectifs: "50 - 200 salariés" },
|
||||
];
|
||||
|
||||
async function seed() {
|
||||
const conn = await mysql.createConnection(process.env.DATABASE_URL);
|
||||
console.log("Seeding blocs fonctionnels...");
|
||||
for (const nom of BLOCS) {
|
||||
await conn.execute("INSERT IGNORE INTO blocs_fonctionnels (nom, estValide) VALUES (?, 1)", [nom]);
|
||||
}
|
||||
console.log("Seeding editeurs...");
|
||||
for (const nom of EDITEURS_DEMO) {
|
||||
await conn.execute("INSERT IGNORE INTO editeurs (nom, estValide) VALUES (?, 1)", [nom]);
|
||||
}
|
||||
console.log("Seeding solutions...");
|
||||
for (const s of SOLUTIONS_DEMO) {
|
||||
const [editeurRows] = await conn.execute("SELECT id FROM editeurs WHERE nom = ? LIMIT 1", [s.editeur]);
|
||||
const [blocRows] = await conn.execute("SELECT id FROM blocs_fonctionnels WHERE nom = ? LIMIT 1", [s.bloc]);
|
||||
const editeurId = editeurRows[0]?.id;
|
||||
const blocId = blocRows[0]?.id;
|
||||
if (editeurId) {
|
||||
await conn.execute(
|
||||
"INSERT IGNORE INTO solutions (nom, editeurId, blocFonctionnelId, estValide) VALUES (?, ?, ?, 1)",
|
||||
[s.nom, editeurId, blocId ?? null]
|
||||
);
|
||||
}
|
||||
}
|
||||
console.log("Seeding etablissements demo...");
|
||||
for (const e of ETABLISSEMENTS_DEMO) {
|
||||
await conn.execute(
|
||||
"INSERT IGNORE INTO etablissements (finess, nom, region, typeActivite, tailleEffectifs, visibilite, accepteMiseEnRelation) VALUES (?, ?, ?, ?, ?, 'tous', 1)",
|
||||
[e.finess, e.nom, e.region, e.typeActivite, e.tailleEffectifs]
|
||||
);
|
||||
}
|
||||
console.log("Seed termine !");
|
||||
await conn.end();
|
||||
}
|
||||
seed().catch(console.error);
|
||||
73
scripts/set-local-password.mjs
Normal file
73
scripts/set-local-password.mjs
Normal file
@@ -0,0 +1,73 @@
|
||||
import { drizzle } from "drizzle-orm/mysql2";
|
||||
import mysql from "mysql2/promise";
|
||||
import bcrypt from "bcryptjs";
|
||||
import { eq } from "drizzle-orm";
|
||||
import * as schema from "../drizzle/schema.ts";
|
||||
import dotenv from "dotenv";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const { users, localCredentials } = schema;
|
||||
|
||||
// ─── Paramètres ───────────────────────────────────────────────────────────────
|
||||
const TARGET_EMAIL = "o.pareige@itinova.org";
|
||||
const NEW_PASSWORD = "Itinova69!";
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
async function main() {
|
||||
if (!process.env.DATABASE_URL) {
|
||||
console.error("DATABASE_URL manquant");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const connection = await mysql.createConnection(process.env.DATABASE_URL);
|
||||
const db = drizzle(connection);
|
||||
|
||||
// Trouver l'utilisateur par email
|
||||
const result = await db
|
||||
.select()
|
||||
.from(users)
|
||||
.where(eq(users.email, TARGET_EMAIL))
|
||||
.limit(1);
|
||||
|
||||
if (!result.length) {
|
||||
console.error(`Aucun utilisateur trouvé avec l'email : ${TARGET_EMAIL}`);
|
||||
await connection.end();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const user = result[0];
|
||||
console.log(`Utilisateur trouvé : ${user.name} (id=${user.id}, rôle=${user.sonumRole})`);
|
||||
|
||||
// Hasher le mot de passe
|
||||
const passwordHash = await bcrypt.hash(NEW_PASSWORD, 12);
|
||||
|
||||
// Insérer ou mettre à jour les credentials locaux
|
||||
const existingCreds = await db
|
||||
.select()
|
||||
.from(localCredentials)
|
||||
.where(eq(localCredentials.userId, user.id))
|
||||
.limit(1);
|
||||
|
||||
if (existingCreds.length > 0) {
|
||||
await db
|
||||
.update(localCredentials)
|
||||
.set({ passwordHash, updatedAt: new Date() })
|
||||
.where(eq(localCredentials.userId, user.id));
|
||||
console.log("Mot de passe mis à jour.");
|
||||
} else {
|
||||
await db.insert(localCredentials).values({ userId: user.id, passwordHash });
|
||||
console.log("Credentials locaux créés.");
|
||||
}
|
||||
|
||||
console.log(`\n✅ Connexion locale activée pour ${TARGET_EMAIL}`);
|
||||
console.log(` Login : ${TARGET_EMAIL}`);
|
||||
console.log(` Rôle : ${user.sonumRole}`);
|
||||
|
||||
await connection.end();
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Erreur :", err);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user