-- CreateEnum CREATE TYPE "UserStatus" AS ENUM ('PENDING_VERIFICATION', 'ACTIVE', 'DISABLED'); -- CreateEnum CREATE TYPE "AuthTokenPurpose" AS ENUM ('EMAIL_VERIFICATION', 'PASSWORD_RESET'); -- CreateEnum CREATE TYPE "MailStatus" AS ENUM ('PENDING', 'SENT', 'FAILED'); -- CreateTable CREATE TABLE "users" ( "id" TEXT NOT NULL, "username" TEXT NOT NULL, "email" TEXT NOT NULL, "display_name" TEXT NOT NULL, "locale" TEXT NOT NULL DEFAULT 'en', "is_site_admin" BOOLEAN NOT NULL DEFAULT false, "status" "UserStatus" NOT NULL DEFAULT 'PENDING_VERIFICATION', "email_verified_at" TIMESTAMP(3), "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "last_login_at" TIMESTAMP(3), CONSTRAINT "users_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "user_identities" ( "id" TEXT NOT NULL, "user_id" TEXT NOT NULL, "provider" TEXT NOT NULL, "subject" TEXT NOT NULL, "credential" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "user_identities_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "sessions" ( "id" TEXT NOT NULL, "user_id" TEXT NOT NULL, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "expires_at" TIMESTAMP(3) NOT NULL, "last_seen_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "user_agent" TEXT, CONSTRAINT "sessions_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "auth_tokens" ( "id" TEXT NOT NULL, "token_hash" TEXT NOT NULL, "user_id" TEXT NOT NULL, "purpose" "AuthTokenPurpose" NOT NULL, "expires_at" TIMESTAMP(3) NOT NULL, "consumed_at" TIMESTAMP(3), "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "auth_tokens_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "rate_limits" ( "key" TEXT NOT NULL, "window_start" TIMESTAMP(3) NOT NULL, "count" INTEGER NOT NULL DEFAULT 0, CONSTRAINT "rate_limits_pkey" PRIMARY KEY ("key") ); -- CreateTable CREATE TABLE "mail_outbox" ( "id" TEXT NOT NULL, "to_address" TEXT NOT NULL, "subject" TEXT NOT NULL, "text_body" TEXT NOT NULL, "html_body" TEXT NOT NULL, "status" "MailStatus" NOT NULL DEFAULT 'PENDING', "attempts" INTEGER NOT NULL DEFAULT 0, "next_attempt_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "last_error" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "sent_at" TIMESTAMP(3), CONSTRAINT "mail_outbox_pkey" PRIMARY KEY ("id") ); -- CreateIndex CREATE UNIQUE INDEX "users_username_key" ON "users"("username"); -- CreateIndex CREATE UNIQUE INDEX "users_email_key" ON "users"("email"); -- CreateIndex CREATE INDEX "user_identities_user_id_idx" ON "user_identities"("user_id"); -- CreateIndex CREATE UNIQUE INDEX "user_identities_provider_subject_key" ON "user_identities"("provider", "subject"); -- CreateIndex CREATE INDEX "sessions_user_id_idx" ON "sessions"("user_id"); -- CreateIndex CREATE INDEX "sessions_expires_at_idx" ON "sessions"("expires_at"); -- CreateIndex CREATE UNIQUE INDEX "auth_tokens_token_hash_key" ON "auth_tokens"("token_hash"); -- CreateIndex CREATE INDEX "auth_tokens_user_id_purpose_idx" ON "auth_tokens"("user_id", "purpose"); -- CreateIndex CREATE INDEX "mail_outbox_status_next_attempt_at_idx" ON "mail_outbox"("status", "next_attempt_at"); -- AddForeignKey ALTER TABLE "user_identities" ADD CONSTRAINT "user_identities_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "sessions" ADD CONSTRAINT "sessions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "auth_tokens" ADD CONSTRAINT "auth_tokens_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;