Checkpoint: Refonte majeure : transformation du système de sessions en séquences avec support de jusqu'à 4 dates par séquence. L'inscription à une séquence inscrit automatiquement l'apprenant à toutes les dates. Mise à jour complète du backend (schéma DB, procédures tRPC, emails, exports) et du frontend (AdminSequences, AdminSequenceInscrits, Inscription, Admin). Toutes les fonctionnalités existantes (filtres, statistiques, exports PDF/Excel, emails automatiques) sont préservées et adaptées au nouveau modèle.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { int, mysqlEnum, mysqlTable, text, timestamp, varchar, boolean, datetime, unique } from "drizzle-orm/mysql-core";
|
||||
import { boolean, datetime, int, mysqlEnum, mysqlTable, text, timestamp, varchar } from "drizzle-orm/mysql-core";
|
||||
|
||||
/**
|
||||
* Core user table backing auth flow.
|
||||
@@ -60,56 +60,61 @@ export type Apprenant = typeof apprenants.$inferSelect;
|
||||
export type InsertApprenant = typeof apprenants.$inferInsert;
|
||||
|
||||
/**
|
||||
* Table des sessions de formation
|
||||
* Table des séquences de formation
|
||||
* Une séquence peut contenir jusqu'à 4 dates de formation
|
||||
*/
|
||||
export const sessions = mysqlTable("sessions", {
|
||||
export const sequences = mysqlTable("sequences", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
formationId: int("formationId").notNull(),
|
||||
nom: varchar("nom", { length: 255 }).notNull(),
|
||||
/** Date de début de la session */
|
||||
dateDebut: datetime("dateDebut").notNull(),
|
||||
/** Date de fin de la session */
|
||||
dateFin: datetime("dateFin").notNull(),
|
||||
/** Lieu de la formation */
|
||||
lieu: varchar("lieu", { length: 500 }).notNull(),
|
||||
/** Capacité maximale (12 par défaut) */
|
||||
capaciteMax: int("capaciteMax").default(12).notNull(),
|
||||
/** Date de blocage des inscriptions (J-15) */
|
||||
/** Date de blocage des inscriptions (J-15 avant la première date) */
|
||||
dateBlocage: datetime("dateBlocage").notNull(),
|
||||
/** Statut de la session */
|
||||
/** Statut de la séquence */
|
||||
statut: mysqlEnum("statut", ["ouverte", "bloquee", "terminee"]).default("ouverte").notNull(),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
|
||||
});
|
||||
|
||||
export type Session = typeof sessions.$inferSelect;
|
||||
export type InsertSession = typeof sessions.$inferInsert;
|
||||
export type Sequence = typeof sequences.$inferSelect;
|
||||
export type InsertSequence = typeof sequences.$inferInsert;
|
||||
|
||||
/**
|
||||
* Table des dates de formation pour chaque séquence
|
||||
* Une séquence peut avoir jusqu'à 4 dates
|
||||
*/
|
||||
export const datesFormation = mysqlTable("datesFormation", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
sequenceId: int("sequenceId").notNull(),
|
||||
/** Date de début de cette journée de formation */
|
||||
dateDebut: datetime("dateDebut").notNull(),
|
||||
/** Date de fin de cette journée de formation */
|
||||
dateFin: datetime("dateFin").notNull(),
|
||||
/** Ordre de la date dans la séquence (1 à 4) */
|
||||
ordre: int("ordre").notNull(),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export type DateFormation = typeof datesFormation.$inferSelect;
|
||||
export type InsertDateFormation = typeof datesFormation.$inferInsert;
|
||||
|
||||
/**
|
||||
* Table des inscriptions
|
||||
* L'inscription à une séquence inscrit automatiquement à toutes ses dates
|
||||
*/
|
||||
export const inscriptions = mysqlTable("inscriptions", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
apprenantId: int("apprenantId").notNull(),
|
||||
sessionId: int("sessionId").notNull(),
|
||||
sequenceId: int("sequenceId").notNull(),
|
||||
/** Statut de l'inscription */
|
||||
statut: mysqlEnum("statut", ["confirmee", "liste_attente", "annulee"]).default("confirmee").notNull(),
|
||||
/** Date d'inscription */
|
||||
statut: mysqlEnum("statut", ["confirmee", "liste_attente", "annulee"]).notNull(),
|
||||
dateInscription: timestamp("dateInscription").defaultNow().notNull(),
|
||||
/** Invitation Outlook envoyée */
|
||||
invitationEnvoyee: boolean("invitationEnvoyee").default(false).notNull(),
|
||||
/** Email de confirmation envoyé */
|
||||
emailConfirmationEnvoye: boolean("emailConfirmationEnvoye").default(false).notNull(),
|
||||
/** Email teaser envoyé */
|
||||
emailTeaserEnvoye: boolean("emailTeaserEnvoye").default(false).notNull(),
|
||||
/** Email rappel J-7 envoyé */
|
||||
emailRappelEnvoye: boolean("emailRappelEnvoye").default(false).notNull(),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
|
||||
}, (table) => ({
|
||||
// Contrainte d'unicité pour éviter les doubles inscriptions
|
||||
uniqueInscription: unique().on(table.apprenantId, table.sessionId),
|
||||
}));
|
||||
});
|
||||
|
||||
export type Inscription = typeof inscriptions.$inferSelect;
|
||||
export type InsertInscription = typeof inscriptions.$inferInsert;
|
||||
|
||||
Reference in New Issue
Block a user