SONUM v7 - Évolution v6 (éditeurs/blocs CRUD, tableau de bord stats) + vue liste alternance couleurs
This commit is contained in:
176
drizzle/schema.ts
Normal file
176
drizzle/schema.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
import {
|
||||
boolean,
|
||||
int,
|
||||
mysqlEnum,
|
||||
mysqlTable,
|
||||
text,
|
||||
timestamp,
|
||||
varchar,
|
||||
} from "drizzle-orm/mysql-core";
|
||||
|
||||
// ─── Utilisateurs ────────────────────────────────────────────────────────────
|
||||
|
||||
export const users = mysqlTable("users", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
// openId peut être null pour les comptes créés manuellement (connexion locale uniquement)
|
||||
openId: varchar("openId", { length: 64 }).unique(),
|
||||
name: text("name"),
|
||||
email: varchar("email", { length: 320 }),
|
||||
loginMethod: varchar("loginMethod", { length: 64 }),
|
||||
role: mysqlEnum("role", ["user", "admin"]).default("user").notNull(),
|
||||
// Profil SONUM :
|
||||
// referent = référent numérique (saisit les logiciels de ses établissements)
|
||||
// gestionnaire = gestionnaire SONUM (accès admin complet)
|
||||
// adherent = adhérent FEHAP (consultation des fiches de ses établissements affectés)
|
||||
sonumRole: mysqlEnum("sonumRole", ["referent", "gestionnaire", "adherent"])
|
||||
.default("referent")
|
||||
.notNull(),
|
||||
// CGU acceptée
|
||||
cguAccepted: boolean("cguAccepted").default(false).notNull(),
|
||||
cguAcceptedAt: timestamp("cguAcceptedAt"),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
|
||||
lastSignedIn: timestamp("lastSignedIn").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export type User = typeof users.$inferSelect;
|
||||
export type InsertUser = typeof users.$inferInsert;
|
||||
|
||||
// ─── Authentification locale ──────────────────────────────────────────────────
|
||||
// Stocke le hash bcrypt du mot de passe pour les comptes créés manuellement.
|
||||
// Un utilisateur OAuth peut aussi avoir un mot de passe local (double connexion possible).
|
||||
|
||||
export const localCredentials = mysqlTable("local_credentials", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
userId: int("userId").notNull().unique(), // FK → users.id
|
||||
passwordHash: varchar("passwordHash", { length: 255 }).notNull(),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
|
||||
});
|
||||
|
||||
export type LocalCredential = typeof localCredentials.$inferSelect;
|
||||
|
||||
// ─── Affectation Adhérents ↔ Établissements ───────────────────────────────────
|
||||
// Permet au gestionnaire SONUM d'affecter des établissements à un adhérent FEHAP.
|
||||
// Un adhérent ne voit que les établissements qui lui sont affectés.
|
||||
|
||||
export const userEtablissements = mysqlTable("user_etablissements", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
userId: int("userId").notNull(), // FK → users.id (adhérent)
|
||||
etablissementId: int("etablissementId").notNull(), // FK → etablissements.id
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export type UserEtablissement = typeof userEtablissements.$inferSelect;
|
||||
|
||||
// ─── Référentiel : Éditeurs ───────────────────────────────────────────────────
|
||||
|
||||
export const editeurs = mysqlTable("editeurs", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
nom: varchar("nom", { length: 255 }).notNull(),
|
||||
estValide: boolean("estValide").default(true).notNull(),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export type Editeur = typeof editeurs.$inferSelect;
|
||||
|
||||
// ─── Référentiel : Blocs Fonctionnels ────────────────────────────────────────
|
||||
|
||||
export const blocsFonctionnels = mysqlTable("blocs_fonctionnels", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
nom: varchar("nom", { length: 255 }).notNull(),
|
||||
estValide: boolean("estValide").default(true).notNull(),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export type BlocFonctionnel = typeof blocsFonctionnels.$inferSelect;
|
||||
|
||||
// ─── Référentiel : Solutions ──────────────────────────────────────────────────
|
||||
|
||||
export const solutions = mysqlTable("solutions", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
nom: varchar("nom", { length: 255 }).notNull(),
|
||||
editeurId: int("editeurId").notNull(),
|
||||
blocFonctionnelId: int("blocFonctionnelId"),
|
||||
estValide: boolean("estValide").default(true).notNull(),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export type Solution = typeof solutions.$inferSelect;
|
||||
|
||||
// ─── Établissements ───────────────────────────────────────────────────────────
|
||||
|
||||
export const etablissements = mysqlTable("etablissements", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
finess: varchar("finess", { length: 20 }),
|
||||
nom: varchar("nom", { length: 255 }).notNull(),
|
||||
region: varchar("region", { length: 100 }),
|
||||
departement: varchar("departement", { length: 100 }),
|
||||
typeActivite: varchar("typeActivite", { length: 100 }),
|
||||
tailleEffectifs: varchar("tailleEffectifs", { length: 50 }),
|
||||
referentId: int("referentId"),
|
||||
visibilite: mysqlEnum("visibilite", ["tous", "gestionnaires"]).default("tous").notNull(),
|
||||
accepteMiseEnRelation: boolean("accepteMiseEnRelation").default(true).notNull(),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
|
||||
});
|
||||
|
||||
export type Etablissement = typeof etablissements.$inferSelect;
|
||||
|
||||
// ─── Logiciels par Établissement ─────────────────────────────────────────────
|
||||
|
||||
export const logicielsEtablissements = mysqlTable("logiciels_etablissements", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
etablissementId: int("etablissementId").notNull(),
|
||||
solutionId: int("solutionId").notNull(),
|
||||
etatDeploiement: mysqlEnum("etatDeploiement", [
|
||||
"demarrage",
|
||||
"en_cours",
|
||||
"operationnel",
|
||||
"en_remplacement",
|
||||
]).notNull(),
|
||||
modeHebergement: mysqlEnum("modeHebergement", ["hds", "on_premise", "hybride"]),
|
||||
modeFacturation: mysqlEnum("modeFacturation", ["saas", "achat_maintenance", "location"]),
|
||||
interoperabilite: mysqlEnum("interoperabilite", ["non", "oui_interface", "oui_eai"]),
|
||||
versionMajeure: varchar("versionMajeure", { length: 50 }),
|
||||
commentaire: text("commentaire"),
|
||||
contactNom: varchar("contactNom", { length: 255 }),
|
||||
contactFonction: varchar("contactFonction", { length: 255 }),
|
||||
contactEmail: varchar("contactEmail", { length: 320 }),
|
||||
saisiePar: int("saisiePar"),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
|
||||
});
|
||||
|
||||
export type LogicielEtablissement = typeof logicielsEtablissements.$inferSelect;
|
||||
|
||||
// ─── Traçabilité : Consultations ──────────────────────────────────────────────
|
||||
|
||||
export const consultations = mysqlTable("consultations", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
etablissementId: int("etablissementId").notNull(),
|
||||
consultePar: int("consultePar").notNull(),
|
||||
consultéParNom: varchar("consulteParNom", { length: 255 }),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export type Consultation = typeof consultations.$inferSelect;
|
||||
|
||||
// ─── Demandes de Contact ──────────────────────────────────────────────────────
|
||||
|
||||
export const demandesContact = mysqlTable("demandes_contact", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
etablissementCibleId: int("etablissementCibleId").notNull(),
|
||||
demandeurId: int("demandeurId").notNull(),
|
||||
demandeurNom: varchar("demandeurNom", { length: 255 }),
|
||||
demandeurEmail: varchar("demandeurEmail", { length: 320 }),
|
||||
message: text("message").notNull(),
|
||||
statut: mysqlEnum("statut", ["en_attente", "repondu", "ferme"]).default("en_attente").notNull(),
|
||||
reponse: text("reponse"),
|
||||
reponsePar: int("reponsePar"),
|
||||
reponduAt: timestamp("reponduAt"),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
|
||||
});
|
||||
|
||||
export type DemandeContact = typeof demandesContact.$inferSelect;
|
||||
Reference in New Issue
Block a user