import { boolean, index, pgEnum, pgTable, timestamp, uuid, varchar, } from "drizzle-orm/pg-core"; import { pgpEncrypted, withAutomaticPgpDecrypt } from "./pgp"; export const userStatus = pgEnum("user_status", [ "active", "verification", "suspended", "pending", "deleted", ]); export const users = pgTable( "users", { uuid: uuid().primaryKey().defaultRandom(), status: userStatus("status").default("pending").notNull(), // Données Personnelles (PII) - Chiffrées nativement email: pgpEncrypted("email").notNull(), emailHash: varchar("email_hash", { length: 64 }).notNull().unique(), // Indexé pour recherche rapide et unicité displayName: varchar("display_name", { length: 32 }), username: varchar("username", { length: 32 }).notNull().unique(), passwordHash: varchar("password_hash", { length: 95 }).notNull(), // Sécurité twoFactorSecret: pgpEncrypted("two_factor_secret"), isTwoFactorEnabled: boolean("is_two_factor_enabled").notNull().default(false), // RGPD & Conformité termsVersion: varchar("terms_version", { length: 16 }), // Version des CGU acceptées privacyVersion: varchar("privacy_version", { length: 16 }), // Version de la Privacy Policy acceptée gdprAcceptedAt: timestamp("gdpr_accepted_at", { withTimezone: true }), // Dates de cycle de vie (Standards Entreprise) lastLoginAt: timestamp("last_login_at", { withTimezone: true }), createdAt: timestamp("created_at", { withTimezone: true }) .notNull() .defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }) .notNull() .defaultNow(), deletedAt: timestamp("deleted_at", { withTimezone: true }), // Soft delete (Droit à l'oubli) }, (table) => ({ uuidIdx: index("users_uuid_idx").on(table.uuid), emailHashIdx: index("users_email_hash_idx").on(table.emailHash), usernameIdx: index("users_username_idx").on(table.username), statusIdx: index("users_status_idx").on(table.status), }), ); // Application du déchiffrement automatique pour les colonnes PGP withAutomaticPgpDecrypt(users.email); withAutomaticPgpDecrypt(users.twoFactorSecret); export type UserInDb = typeof users.$inferSelect; export type NewUserInDb = typeof users.$inferInsert;