-- CreateEnum CREATE TYPE "public"."UserRole" AS ENUM ('USER', 'ADMIN'); -- CreateEnum CREATE TYPE "public"."JobStatus" AS ENUM ('PENDING', 'PROCESSING', 'COMPLETED', 'FAILED', 'RETRYING'); -- CreateEnum CREATE TYPE "public"."AuditAction" AS ENUM ('LOGIN_SUCCESS', 'LOGIN_FAILED', 'LOGOUT', 'SIGNUP', 'PASSWORD_RESET', 'PASSWORD_CHANGE', 'ACCOUNT_LOCKED', 'ACCOUNT_UNLOCKED', 'PROFILE_UPDATE', 'MFA_ENABLED', 'MFA_DISABLED', 'API_ACCESS'); -- CreateTable CREATE TABLE "public"."users" ( "id" TEXT NOT NULL, "email" TEXT NOT NULL, "password_hash" TEXT, "first_name" TEXT, "last_name" TEXT, "company" TEXT, "phone" TEXT, "role" "public"."UserRole" NOT NULL DEFAULT 'USER', "mfa_secret" TEXT, "email_verified" BOOLEAN NOT NULL DEFAULT false, "failed_login_attempts" INTEGER NOT NULL DEFAULT 0, "locked_until" TIMESTAMP(3), "last_login_at" TIMESTAMP(3), "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "users_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "public"."id_mappings" ( "user_id" TEXT NOT NULL, "whmcs_client_id" INTEGER NOT NULL, "sf_account_id" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "id_mappings_pkey" PRIMARY KEY ("user_id") ); -- CreateTable CREATE TABLE "public"."invoices_mirror" ( "invoice_id" INTEGER NOT NULL, "user_id" TEXT NOT NULL, "number" TEXT NOT NULL, "status" TEXT NOT NULL, "amount_cents" INTEGER NOT NULL, "currency" CHAR(3) NOT NULL, "due_date" DATE, "issued_at" TIMESTAMP(3), "paid_at" TIMESTAMP(3), "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "invoices_mirror_pkey" PRIMARY KEY ("invoice_id") ); -- CreateTable CREATE TABLE "public"."subscriptions_mirror" ( "service_id" INTEGER NOT NULL, "user_id" TEXT NOT NULL, "product_name" TEXT NOT NULL, "domain" TEXT, "cycle" TEXT NOT NULL, "status" TEXT NOT NULL, "next_due" TIMESTAMP(3), "amount_cents" INTEGER NOT NULL, "currency" CHAR(3) NOT NULL, "registered_at" TIMESTAMP(3) NOT NULL, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "subscriptions_mirror_pkey" PRIMARY KEY ("service_id") ); -- CreateTable CREATE TABLE "public"."idempotency_keys" ( "key" TEXT NOT NULL, "user_id" TEXT NOT NULL, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "idempotency_keys_pkey" PRIMARY KEY ("key") ); -- CreateTable CREATE TABLE "public"."jobs" ( "id" TEXT NOT NULL, "name" TEXT NOT NULL, "data" JSONB NOT NULL, "status" "public"."JobStatus" NOT NULL DEFAULT 'PENDING', "attempts" INTEGER NOT NULL DEFAULT 0, "max_retries" INTEGER NOT NULL DEFAULT 3, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, "processed_at" TIMESTAMP(3), "failed_at" TIMESTAMP(3), "error" TEXT, CONSTRAINT "jobs_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "public"."audit_logs" ( "id" TEXT NOT NULL, "user_id" TEXT, "action" "public"."AuditAction" NOT NULL, "resource" TEXT, "details" JSONB, "ip_address" TEXT, "user_agent" TEXT, "success" BOOLEAN NOT NULL DEFAULT true, "error" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "audit_logs_pkey" PRIMARY KEY ("id") ); -- CreateIndex CREATE UNIQUE INDEX "users_email_key" ON "public"."users"("email"); -- CreateIndex CREATE UNIQUE INDEX "id_mappings_whmcs_client_id_key" ON "public"."id_mappings"("whmcs_client_id"); -- CreateIndex CREATE INDEX "invoices_mirror_user_id_status_idx" ON "public"."invoices_mirror"("user_id", "status"); -- CreateIndex CREATE INDEX "invoices_mirror_user_id_due_date_idx" ON "public"."invoices_mirror"("user_id", "due_date"); -- CreateIndex CREATE INDEX "subscriptions_mirror_user_id_status_idx" ON "public"."subscriptions_mirror"("user_id", "status"); -- CreateIndex CREATE INDEX "subscriptions_mirror_user_id_next_due_idx" ON "public"."subscriptions_mirror"("user_id", "next_due"); -- CreateIndex CREATE INDEX "idempotency_keys_user_id_idx" ON "public"."idempotency_keys"("user_id"); -- CreateIndex CREATE INDEX "idempotency_keys_created_at_idx" ON "public"."idempotency_keys"("created_at"); -- CreateIndex CREATE INDEX "jobs_status_created_at_idx" ON "public"."jobs"("status", "created_at"); -- CreateIndex CREATE INDEX "audit_logs_user_id_action_idx" ON "public"."audit_logs"("user_id", "action"); -- CreateIndex CREATE INDEX "audit_logs_action_created_at_idx" ON "public"."audit_logs"("action", "created_at"); -- CreateIndex CREATE INDEX "audit_logs_created_at_idx" ON "public"."audit_logs"("created_at"); -- AddForeignKey ALTER TABLE "public"."id_mappings" ADD CONSTRAINT "id_mappings_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "public"."invoices_mirror" ADD CONSTRAINT "invoices_mirror_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "public"."subscriptions_mirror" ADD CONSTRAINT "subscriptions_mirror_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "public"."idempotency_keys" ADD CONSTRAINT "idempotency_keys_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "public"."audit_logs" ADD CONSTRAINT "audit_logs_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE SET NULL ON UPDATE CASCADE;