import { boolean, index, inet, integer, jsonb, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core"; export const adminUsers = pgTable("admin_users", { id: uuid("id").primaryKey().defaultRandom(), username: text("username").notNull().unique(), passwordHash: text("password_hash").notNull(), mustChangePassword: boolean("must_change_password").notNull().default(true), bootstrapped: boolean("bootstrapped").notNull().default(false), totpSecret: text("totp_secret"), failedAttempts: integer("failed_attempts").notNull().default(0), lockedUntil: timestamp("locked_until", { withTimezone: true }), lastLoginAt: timestamp("last_login_at", { withTimezone: true }), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }); export const sessions = pgTable( "sessions", { id: uuid("id").primaryKey().defaultRandom(), tokenHash: text("token_hash").notNull().unique(), userId: uuid("user_id") .notNull() .references(() => adminUsers.id, { onDelete: "cascade" }), csrfSecret: text("csrf_secret").notNull(), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(), lastSeenAt: timestamp("last_seen_at", { withTimezone: true }).notNull().defaultNow(), rotatedFrom: uuid("rotated_from"), ip: inet("ip"), userAgent: text("user_agent"), revokedAt: timestamp("revoked_at", { withTimezone: true }), }, (t) => [index("sessions_user_idx").on(t.userId), index("sessions_expires_idx").on(t.expiresAt)], ); export const passwordChanges = pgTable("password_changes", { id: uuid("id").primaryKey().defaultRandom(), userId: uuid("user_id") .notNull() .references(() => adminUsers.id, { onDelete: "cascade" }), previousHash: text("previous_hash").notNull(), reason: text("reason").notNull(), ip: inet("ip"), changedAt: timestamp("changed_at", { withTimezone: true }).notNull().defaultNow(), }); export const securityEvents = pgTable( "security_events", { id: uuid("id").primaryKey().defaultRandom(), userId: uuid("user_id"), kind: text("kind").notNull(), ip: inet("ip"), detail: jsonb("detail").$type>().notNull().default({}), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), }, (t) => [index("security_events_kind_idx").on(t.kind, t.createdAt)], ); export const auditEvents = pgTable( "audit_events", { id: uuid("id").primaryKey().defaultRandom(), actorType: text("actor_type").notNull(), // admin | worker | system actorId: text("actor_id"), action: text("action").notNull(), targetType: text("target_type"), targetId: text("target_id"), detail: jsonb("detail").$type>().notNull().default({}), ip: inet("ip"), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), }, (t) => [ index("audit_events_target_idx").on(t.targetType, t.targetId), index("audit_events_created_idx").on(t.createdAt), ], ); export const loginAttempts = pgTable( "login_attempts", { id: uuid("id").primaryKey().defaultRandom(), username: text("username").notNull(), ip: inet("ip"), success: boolean("success").notNull(), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), }, (t) => [ index("login_attempts_ip_idx").on(t.ip, t.createdAt), index("login_attempts_user_idx").on(t.username, t.createdAt), ], );