import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
import { createRequire } from "node:module";

import type BetterSqlite3 from "better-sqlite3";

import {
  auditRetentionMilliseconds,
  ensureAdminOperationAuditSchema,
  ensurePrivateAccessAuditSchema,
  isSafeAuditRef,
  isSafeAuditSummaryJson,
  serializeAuditSummary,
} from "./audit-policy.js";
import type { ResendAdapter } from "./resend-adapter.js";
import { ExternalServiceUsage } from "./external-service-usage.js";
import {
  RegistrationError,
  type RegistrationErrorReason,
} from "./registration-errors.js";

export { RegistrationError } from "./registration-errors.js";

const require = createRequire(import.meta.url);
const Database = require("better-sqlite3") as typeof BetterSqlite3;
const stageLimit = 10;
const challengeLifetimeMilliseconds = 10 * 60 * 1_000;
const resendDelayMilliseconds = 60 * 1_000;
const sessionLifetimeMilliseconds = 30 * 24 * 60 * 60 * 1_000;
const rateWindowMilliseconds = 10 * 60 * 1_000;
const rateBlockMilliseconds = 10 * 60 * 1_000;
const maximumFailedAttempts = 5;
const maximumSendsPerWindow = 5;

export interface RegistrationTransactionEvent {
  mode: "BEGIN IMMEDIATE";
  operation:
    | "invite_create"
    | "registration_send"
    | "registration_complete"
    | "registration_send_compensation"
    | "local_test_session"
    | "login_send"
    | "login_complete"
    | "admin_login_send"
    | "admin_login_complete"
    | "secure_config_apply"
    | "session_issue"
    | "session_revoke"
    | "account_delete_send"
    | "account_delete_complete"
    | "profile_update"
    | "csrf_issue";
  outcome: "committed" | "rejected" | "idempotent_replay";
}

interface RegistrationServiceOptions {
  adminAllowlistPepper?: Buffer;
  challengePepper: Buffer;
  clock?: () => number;
  codeGenerator?: () => string;
  currentPrivacyNoticeVersion: string;
  databasePath: string;
  inviteCodeGenerator?: () => string;
  invitePepper: Buffer;
  onTransaction?: (event: RegistrationTransactionEvent) => void;
  resend: ResendAdapter;
  sessionPepper: Buffer;
}

interface InviteRow {
  expires_at: number;
  invite_id: string;
  max_uses: number;
  status: "enabled" | "disabled";
  used_count: number;
}

interface ChallengeRow {
  challenge_id: string;
  code_hmac: string;
  consumed_at: number | null;
  email: string;
  expires_at: number;
  invite_id: string | null;
}

interface AttemptRow {
  failure_reason: RegistrationErrorReason | null;
  outcome_code: "success" | "failure";
  request_hash: string;
  session_id: string | null;
  user_id: string | null;
}

interface UserResultRow {
  available_balance: number;
  creator_name: string;
  expires_at: number;
  reserved_balance: number;
  session_id: string;
  social_id: string;
  user_id: string;
}

interface RateLimitRow {
  blocked_until: number | null;
  failed_attempts: number;
  send_count: number;
  window_started_at: number;
}

interface LoginAttemptRow {
  failure_reason: RegistrationErrorReason | null;
  outcome_code: "success" | "failure";
  request_hash: string;
  session_id: string | null;
  user_id: string | null;
}

export interface RegistrationSendResult {
  challengeExpiresAt: number;
  registrationId: string;
  resendAvailableAt: number;
  status: "verification_sent";
}

export interface RegistrationCompleteInput {
  code: string;
  creatorName: string;
  idempotencyKey: string;
  privacyConsentAccepted: boolean;
  privacyNoticeVersion: string;
  registrationId: string;
  socialId: string;
}

export interface RegistrationCompleteResult {
  credits: { availableBalance: number; reservedBalance: number };
  sessionExpiresAt: number;
  sessionToken: string;
  status: "registered";
  user: {
    creatorName: string;
    role: "user";
    socialId: string;
    status: "active";
    userId: string;
  };
}

export interface UserSessionResult {
  audience: "user";
  credits: { availableBalance: number; reservedBalance: number };
  expiresAt: number;
  user: RegistrationCompleteResult["user"];
  userId: string;
}

export interface LoginCompleteInput {
  clientKey: string;
  code: string;
  idempotencyKey: string;
  registrationId: string;
}

export type LoginCompleteResult = Omit<RegistrationCompleteResult, "status"> & {
  audience: "user";
  status: "authenticated";
};

export interface AdminLoginCompleteResult {
  admin: {
    role: "super_admin";
    status: "active";
    userId: string;
  };
  audience: "admin";
  sessionExpiresAt: number;
  sessionToken: string;
  status: "authenticated";
}

export interface SecureConfigCandidate {
  adminAllowlistHashes: string[];
  adminRecoveryHashes: string[];
  secureConfigRevision: number;
}

interface ImmediateResult<T> {
  outcome: RegistrationTransactionEvent["outcome"];
  value: T;
}

function assertSecret(name: string, value: Buffer) {
  if (value.byteLength < 32) throw new Error(`${name} must contain at least 32 bytes.`);
}

function normalizeEmail(email: string) {
  const normalized = email.trim().toLowerCase();
  if (normalized.length > 320 || !/^[^@\s]{1,128}@[^@\s]{1,190}$/.test(normalized)) {
    throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "profile_invalid");
  }
  return normalized;
}

function normalizeProfileValue(value: string, maximumLength: number) {
  const normalized = value.trim();
  if (!normalized || normalized.length > maximumLength) {
    throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "profile_invalid");
  }
  return normalized;
}

function normalizeSocialId(value: string) {
  const body = normalizeProfileValue(value, 80).replace(/^@+/, "");
  if (!body) throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "profile_invalid");
  return `@${body}`;
}

function digest(value: string) {
  return createHash("sha256").update(value, "utf8").digest("hex");
}

function constantTimeTextEqual(left: string, right: string) {
  const leftBuffer = Buffer.from(left, "hex");
  const rightBuffer = Buffer.from(right, "hex");
  return leftBuffer.byteLength === rightBuffer.byteLength && timingSafeEqual(leftBuffer, rightBuffer);
}

export class RegistrationService {
  readonly database: BetterSqlite3.Database;
  readonly serviceUsage: ExternalServiceUsage;
  readonly options: Required<Pick<RegistrationServiceOptions, "clock" | "codeGenerator" | "inviteCodeGenerator">> & RegistrationServiceOptions;
  private adminAllowlistHashes = new Set<string>();
  private privacyPurgeActive = false;
  private privacyPurgeSubject = "";

  constructor(options: RegistrationServiceOptions) {
    assertSecret("invitePepper", options.invitePepper);
    assertSecret("challengePepper", options.challengePepper);
    assertSecret("sessionPepper", options.sessionPepper);
    if (options.adminAllowlistPepper) assertSecret("adminAllowlistPepper", options.adminAllowlistPepper);
    this.options = {
      ...options,
      clock: options.clock ?? Date.now,
      codeGenerator: options.codeGenerator ?? (() => String(randomBytes(4).readUInt32BE(0) % 1_000_000).padStart(6, "0")),
      inviteCodeGenerator: options.inviteCodeGenerator ?? (() => randomBytes(24).toString("base64url")),
    };
    this.database = new Database(options.databasePath);
    this.database.pragma("journal_mode = WAL");
    this.database.pragma("foreign_keys = ON");
    this.database.pragma("synchronous = FULL");
    this.database.pragma("busy_timeout = 5000");
    this.database.function("dada_audit_ref_is_safe", { deterministic: true }, isSafeAuditRef);
    this.database.function("dada_audit_summary_is_safe", { deterministic: true }, isSafeAuditSummaryJson);
    this.database.function("dada_allow_privacy_purge", { deterministic: false }, () => this.privacyPurgeActive ? 1 : 0);
    this.database.function("dada_privacy_purge_subject", { deterministic: false }, () => this.privacyPurgeSubject);
    this.database.function("dada_allow_retention_purge", { deterministic: false }, () => 0);
    this.database.function("dada_retention_purge_now", { deterministic: false }, () => 0);
    this.migrate();
    this.serviceUsage = new ExternalServiceUsage({ database: this.database, clock: this.options.clock });
  }

  close() {
    this.database.close();
  }

  createInvite(input: { expiresAt: number; maxUses: number }) {
    if (!Number.isSafeInteger(input.expiresAt) || !Number.isSafeInteger(input.maxUses) || input.maxUses < 1) {
      throw new Error("Invite fixture is invalid.");
    }
    const code = this.options.inviteCodeGenerator();
    const inviteId = randomUUID();
    const now = this.options.clock();
    this.runImmediate("invite_create", () => {
      this.database.prepare(`
        INSERT INTO invite_codes (
          invite_id, code_hmac, max_uses, used_count, expires_at, status, created_at
        ) VALUES (?, ?, ?, 0, ?, 'enabled', ?)
      `).run(inviteId, this.inviteHmac(code), input.maxUses, input.expiresAt, now);
      return { outcome: "committed", value: undefined };
    });
    return { code, inviteId };
  }

  createAdminInvite(input: { actorId: string; expiresAt: number; maxUses: number }) {
    if (!Number.isSafeInteger(input.expiresAt) || !Number.isSafeInteger(input.maxUses) || input.maxUses < 1) {
      throw new Error("Invite request is invalid.");
    }
    const code = this.options.inviteCodeGenerator();
    const inviteId = randomUUID();
    const now = this.options.clock();
    this.runImmediate("invite_create", () => {
      const admin = this.database.prepare(`
        SELECT u.user_id FROM users u JOIN admin_access a ON a.user_id = u.user_id
        WHERE u.user_id = ? AND u.role = 'super_admin' AND u.status = 'active' AND a.allowed = 1
      `).get(input.actorId);
      if (!admin) throw new RegistrationError("AUTH_SESSION_INVALID", "session_invalid");
      this.database.prepare(`
        INSERT INTO invite_codes (
          invite_id, code_hmac, max_uses, used_count, expires_at, status, created_at
        ) VALUES (?, ?, ?, 0, ?, 'enabled', ?)
      `).run(inviteId, this.inviteHmac(code), input.maxUses, input.expiresAt, now);
      this.recordAdminAudit({
        actorRef: input.actorId,
        actorType: "super_admin",
        afterSummary: { max_uses: input.maxUses, status: "enabled" },
        beforeSummary: null,
        operationType: "invite_create",
        result: "succeeded",
        targetRef: inviteId,
        targetType: "invite",
      }, now);
      return { outcome: "committed", value: undefined };
    });
    return { code, inviteId };
  }

  async sendRegistrationCode(input: { email: string; inviteCode: string }): Promise<RegistrationSendResult> {
    const email = normalizeEmail(input.email);
    const inviteCode = normalizeProfileValue(input.inviteCode, 160);
    const now = this.options.clock();
    const challengeId = randomUUID();
    const code = this.options.codeGenerator();
    if (!/^[0-9]{6}$/.test(code)) throw new Error("Verification code generator must return six digits.");

    const result = this.runImmediate("registration_send", () => {
      const invite = this.database.prepare("SELECT * FROM invite_codes WHERE code_hmac = ?")
        .get(this.inviteHmac(inviteCode)) as InviteRow | undefined;
      this.assertInviteAvailable(invite, now);
      this.assertStageCapacity();
      const existing = this.database.prepare(`
        SELECT user_id, role, status FROM users
        WHERE normalized_email = ? AND status <> 'deleted'
      `).get(email) as { role: "user" | "super_admin"; status: "active" | "suspended" } | undefined;
      if (existing?.status === "suspended") throw new RegistrationError("AUTH_ENTRY_REJECTED", "account_suspended");
      if (existing) throw new RegistrationError("AUTH_ENTRY_REJECTED", "registration_login_required");
      this.assertChallengeSendAllowed(email, "register", "registration", now);
      this.recordRateSend(email, "registration", now);
      this.serviceUsage.claimResendWithinTransaction(now);

      this.database.prepare(`
        INSERT INTO email_challenges (
          challenge_id, email, invite_id, code_hmac, purpose, expires_at,
          resend_available_at, failure_count, consumed_at, created_at
        ) VALUES (?, ?, ?, ?, 'register', ?, ?, 0, NULL, ?)
      `).run(
        challengeId,
        email,
        invite!.invite_id,
        this.challengeHmac(challengeId, code),
        now + challengeLifetimeMilliseconds,
        now + resendDelayMilliseconds,
        now,
      );
      return {
        outcome: "committed",
        value: {
          challengeExpiresAt: now + challengeLifetimeMilliseconds,
          registrationId: challengeId,
          resendAvailableAt: now + resendDelayMilliseconds,
          status: "verification_sent" as const,
        },
      };
    });

    try {
      await this.options.resend.sendVerificationCode({ challengeId, code, email, purpose: "register" });
    } catch {
      this.serviceUsage.markProviderFailure({ serviceId: "resend_email", reason: "provider_unavailable", now });
      this.runImmediate("registration_send_compensation", () => {
        this.database.prepare("DELETE FROM email_challenges WHERE challenge_id = ? AND consumed_at IS NULL").run(challengeId);
        return { outcome: "committed", value: undefined };
      });
      throw new Error("AUTH_SERVICE_UNAVAILABLE");
    }
    return result;
  }

  async sendLoginCode(input: { clientKey: string; email: string }): Promise<RegistrationSendResult> {
    const email = normalizeEmail(input.email);
    const clientKey = normalizeProfileValue(input.clientKey, 160);
    const now = this.options.clock();
    const challengeId = randomUUID();
    const code = this.options.codeGenerator();
    if (!/^[0-9]{6}$/.test(code)) throw new Error("Verification code generator must return six digits.");

    const result = this.runImmediate("login_send", () => {
      const user = this.database.prepare(`
        SELECT user_id, role, status FROM users
        WHERE normalized_email = ? AND status <> 'deleted'
      `).get(email) as { role: "user" | "super_admin"; status: "active" | "suspended"; user_id: string } | undefined;
      if (!user) throw new RegistrationError("AUTH_ENTRY_REJECTED", "login_registration_required");
      if (user.status === "suspended") throw new RegistrationError("AUTH_ENTRY_REJECTED", "account_suspended");
      if (user.role !== "user") throw new RegistrationError("AUTH_ENTRY_REJECTED", "login_admin_required");
      this.assertChallengeSendAllowed(email, "login", clientKey, now);
      this.recordRateSend(email, clientKey, now);
      this.serviceUsage.claimResendWithinTransaction(now);
      this.database.prepare(`
        INSERT INTO email_challenges (
          challenge_id, email, invite_id, code_hmac, purpose, expires_at,
          resend_available_at, failure_count, consumed_at, created_at
        ) VALUES (?, ?, NULL, ?, 'login', ?, ?, 0, NULL, ?)
      `).run(
        challengeId,
        email,
        this.challengeHmac(challengeId, code),
        now + challengeLifetimeMilliseconds,
        now + resendDelayMilliseconds,
        now,
      );
      return {
        outcome: "committed",
        value: {
          challengeExpiresAt: now + challengeLifetimeMilliseconds,
          registrationId: challengeId,
          resendAvailableAt: now + resendDelayMilliseconds,
          status: "verification_sent" as const,
        },
      };
    });

    try {
      await this.options.resend.sendVerificationCode({ challengeId, code, email, purpose: "login" });
    } catch {
      this.serviceUsage.markProviderFailure({ serviceId: "resend_email", reason: "provider_unavailable", now });
      this.runImmediate("registration_send_compensation", () => {
        this.database.prepare("DELETE FROM email_challenges WHERE challenge_id = ? AND consumed_at IS NULL").run(challengeId);
        return { outcome: "committed", value: undefined };
      });
      throw new Error("AUTH_SERVICE_UNAVAILABLE");
    }
    return result;
  }

  completeLogin(input: LoginCompleteInput): LoginCompleteResult {
    if (!/^[0-9]{6}$/.test(input.code)) throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "challenge_invalid");
    const clientKey = normalizeProfileValue(input.clientKey, 160);
    if (input.idempotencyKey.length < 32 || input.idempotencyKey.length > 200 || !/^[A-Za-z0-9_-]+$/.test(input.idempotencyKey)) {
      throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "idempotency_conflict");
    }
    const now = this.options.clock();
    const idempotencyDigest = this.keyedHmac(this.options.sessionPepper, `login-idempotency:${input.idempotencyKey}`);
    const requestHash = this.keyedHmac(this.options.challengePepper, JSON.stringify({
      clientKey,
      code: input.code,
      registrationId: input.registrationId,
    }));

    const outcome = this.runImmediate<LoginCompleteResult | RegistrationError>("login_complete", () => {
      const previous = this.database.prepare(`
        SELECT request_hash, outcome_code, failure_reason, user_id, session_id
        FROM login_attempts WHERE idempotency_key_digest = ?
      `).get(idempotencyDigest) as LoginAttemptRow | undefined;
      if (previous) {
        if (!constantTimeTextEqual(previous.request_hash, requestHash)) {
          throw new RegistrationError("IDEMPOTENCY_KEY_CONFLICT", "idempotency_conflict");
        }
        if (previous.outcome_code === "failure") {
          const reason = previous.failure_reason ?? "challenge_invalid";
          const code = reason === "resend_too_soon" || reason === "too_many_attempts"
            ? "AUTH_RATE_LIMITED"
            : "AUTH_ENTRY_REJECTED";
          return { outcome: "idempotent_replay", value: new RegistrationError(code, reason) };
        }
        return {
          outcome: "idempotent_replay",
          value: this.loginResult(this.readCompletedRegistration(previous.user_id!, previous.session_id!)),
        };
      }

      const challenge = this.database.prepare(`
        SELECT challenge_id, email, invite_id, code_hmac, expires_at, consumed_at
        FROM email_challenges WHERE challenge_id = ? AND purpose = 'login'
      `).get(input.registrationId) as ChallengeRow | undefined;
      if (!challenge || challenge.consumed_at !== null) {
        return this.recordLoginFailure(idempotencyDigest, requestHash, input.registrationId, "challenge_invalid", now);
      }
      const rate = this.readRateLimit(challenge.email, clientKey, now);
      if (rate.blocked_until !== null && rate.blocked_until > now) {
        return this.recordLoginFailure(idempotencyDigest, requestHash, input.registrationId, "too_many_attempts", now);
      }
      if (challenge.expires_at <= now) {
        return this.recordLoginFailure(idempotencyDigest, requestHash, input.registrationId, "challenge_expired", now);
      }
      if (!constantTimeTextEqual(challenge.code_hmac, this.challengeHmac(challenge.challenge_id, input.code))) {
        this.database.prepare("UPDATE email_challenges SET failure_count = failure_count + 1 WHERE challenge_id = ?")
          .run(challenge.challenge_id);
        const failedAttempts = this.recordRateFailure(challenge.email, clientKey, now);
        const reason = failedAttempts >= maximumFailedAttempts ? "too_many_attempts" : "challenge_invalid";
        return this.recordLoginFailure(idempotencyDigest, requestHash, input.registrationId, reason, now);
      }
      const user = this.database.prepare(`
        SELECT user_id, role, status FROM users
        WHERE normalized_email = ? AND status <> 'deleted'
      `).get(challenge.email) as { role: "user" | "super_admin"; status: "active" | "suspended"; user_id: string } | undefined;
      if (!user) return this.recordLoginFailure(idempotencyDigest, requestHash, input.registrationId, "login_registration_required", now);
      if (user.status === "suspended") return this.recordLoginFailure(idempotencyDigest, requestHash, input.registrationId, "account_suspended", now);
      if (user.role !== "user") return this.recordLoginFailure(idempotencyDigest, requestHash, input.registrationId, "login_admin_required", now);

      this.database.prepare("UPDATE email_challenges SET consumed_at = ? WHERE challenge_id = ? AND consumed_at IS NULL")
        .run(now, challenge.challenge_id);
      const issued = this.insertSession(user.user_id, "user", now);
      this.database.prepare(`
        INSERT INTO login_attempts (
          idempotency_key_digest, request_hash, challenge_id, outcome_code,
          failure_reason, user_id, session_id, created_at
        ) VALUES (?, ?, ?, 'success', NULL, ?, ?, ?)
      `).run(idempotencyDigest, requestHash, input.registrationId, user.user_id, issued.sessionId, now);
      return {
        outcome: "committed",
        value: this.loginResult(this.readCompletedRegistration(user.user_id, issued.sessionId)),
      };
    });
    if (outcome instanceof RegistrationError) throw outcome;
    return outcome;
  }

  completeRegistration(input: RegistrationCompleteInput): RegistrationCompleteResult {
    const creatorName = normalizeProfileValue(input.creatorName, 80);
    const socialId = normalizeSocialId(input.socialId);
    if (!/^[0-9]{6}$/.test(input.code)) {
      throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "challenge_invalid");
    }
    if (!input.privacyConsentAccepted) {
      throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "privacy_consent_required");
    }
    if (input.privacyNoticeVersion !== this.options.currentPrivacyNoticeVersion) {
      throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "privacy_notice_version_invalid");
    }
    if (input.idempotencyKey.length < 32 || input.idempotencyKey.length > 200 || !/^[A-Za-z0-9_-]+$/.test(input.idempotencyKey)) {
      throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "idempotency_conflict");
    }
    const now = this.options.clock();
    const idempotencyDigest = this.keyedHmac(this.options.sessionPepper, `idempotency:${input.idempotencyKey}`);
    const requestHash = this.keyedHmac(this.options.challengePepper, JSON.stringify({
      code: input.code,
      creatorName,
      privacyConsentAccepted: input.privacyConsentAccepted,
      privacyNoticeVersion: input.privacyNoticeVersion,
      registrationId: input.registrationId,
      socialId,
    }));

    const outcome = this.runImmediate<RegistrationCompleteResult | RegistrationError>("registration_complete", () => {
      const previous = this.database.prepare(`
        SELECT request_hash, outcome_code, failure_reason, user_id, session_id
        FROM registration_attempts WHERE idempotency_key_digest = ?
      `).get(idempotencyDigest) as AttemptRow | undefined;
      if (previous) {
        if (!constantTimeTextEqual(previous.request_hash, requestHash)) {
          throw new RegistrationError("IDEMPOTENCY_KEY_CONFLICT", "idempotency_conflict");
        }
        if (previous.outcome_code === "failure") {
          return {
            outcome: "idempotent_replay",
            value: new RegistrationError("REGISTRATION_REJECTED", previous.failure_reason ?? "challenge_invalid"),
          };
        }
        return {
          outcome: "idempotent_replay",
          value: this.readCompletedRegistration(previous.user_id!, previous.session_id!),
        };
      }

      const challenge = this.database.prepare(`
        SELECT challenge_id, email, invite_id, code_hmac, expires_at, consumed_at
        FROM email_challenges WHERE challenge_id = ? AND purpose = 'register'
      `).get(input.registrationId) as ChallengeRow | undefined;
      if (!challenge || challenge.consumed_at !== null) {
        return this.recordRejectedAttempt(idempotencyDigest, requestHash, input.registrationId, "challenge_invalid", now);
      }
      const invite = this.database.prepare("SELECT * FROM invite_codes WHERE invite_id = ?")
        .get(challenge.invite_id) as InviteRow | undefined;
      const inviteReason = this.inviteUnavailableReason(invite, now);
      if (inviteReason) return this.recordRejectedAttempt(idempotencyDigest, requestHash, input.registrationId, inviteReason, now);
      if (this.stageIsFull()) {
        return this.recordRejectedAttempt(idempotencyDigest, requestHash, input.registrationId, "stage_limit_reached", now);
      }
      if (challenge.expires_at <= now) {
        return this.recordRejectedAttempt(idempotencyDigest, requestHash, input.registrationId, "challenge_expired", now);
      }
      if (!constantTimeTextEqual(challenge.code_hmac, this.challengeHmac(challenge.challenge_id, input.code))) {
        return this.recordRejectedAttempt(idempotencyDigest, requestHash, input.registrationId, "challenge_invalid", now);
      }
      const existing = this.database.prepare(`
        SELECT user_id FROM users WHERE normalized_email = ? AND status <> 'deleted'
      `).get(challenge.email);
      if (existing) {
        return this.recordRejectedAttempt(idempotencyDigest, requestHash, input.registrationId, "email_already_registered", now);
      }

      const userId = randomUUID();
      const sessionId = randomUUID();
      const sessionToken = this.sessionToken(sessionId);
      const sessionExpiresAt = now + sessionLifetimeMilliseconds;
      this.database.prepare(`
        INSERT INTO users (
          user_id, normalized_email, role, status, counts_toward_stage_limit,
          registration_id, created_at
        ) VALUES (?, ?, 'user', 'active', 1, ?, ?)
      `).run(userId, challenge.email, input.registrationId, now);
      this.database.prepare(`
        INSERT INTO user_profiles (
          user_id, creator_name, social_id, private_content_notice_version,
          private_content_notice_acknowledged_at
        ) VALUES (?, ?, ?, NULL, NULL)
      `).run(userId, creatorName, socialId);
      this.database.prepare(`
        INSERT INTO credit_accounts (user_id, available_balance, reserved_balance, updated_at)
        VALUES (?, 10, 0, ?)
      `).run(userId, now);
      this.database.prepare(`
        INSERT INTO credit_ledger (
          ledger_id, user_id, operation_key, entry_type, amount,
          available_before, available_after, reserved_before, reserved_after, created_at
        ) VALUES (?, ?, ?, 'registration_grant', 10, 0, 10, 0, 0, ?)
      `).run(randomUUID(), userId, `registration:${input.registrationId}`, now);
      this.database.prepare(`
        INSERT INTO privacy_consents (consent_id, user_id, notice_version, consented_at)
        VALUES (?, ?, ?, ?)
      `).run(randomUUID(), userId, input.privacyNoticeVersion, now);
      this.database.prepare(`
        UPDATE invite_codes SET used_count = used_count + 1
        WHERE invite_id = ? AND status = 'enabled' AND used_count < max_uses AND expires_at > ?
      `).run(challenge.invite_id, now);
      this.database.prepare("UPDATE email_challenges SET consumed_at = ? WHERE challenge_id = ? AND consumed_at IS NULL")
        .run(now, challenge.challenge_id);
      this.database.prepare(`
        INSERT INTO sessions (
          session_id, user_id, audience, token_digest, created_at, expires_at, revoked_at
        ) VALUES (?, ?, 'user', ?, ?, ?, NULL)
      `).run(sessionId, userId, digest(sessionToken), now, sessionExpiresAt);
      this.database.prepare(`
        INSERT INTO registration_attempts (
          idempotency_key_digest, request_hash, registration_id, outcome_code,
          failure_reason, user_id, session_id, created_at
        ) VALUES (?, ?, ?, 'success', NULL, ?, ?, ?)
      `).run(idempotencyDigest, requestHash, input.registrationId, userId, sessionId, now);

      return {
        outcome: "committed",
        value: this.result({
          available_balance: 10,
          creator_name: creatorName,
          expires_at: sessionExpiresAt,
          reserved_balance: 0,
          session_id: sessionId,
          social_id: socialId,
          user_id: userId,
        }),
      };
    });
    if (outcome instanceof RegistrationError) throw outcome;
    return outcome;
  }

  createLocalTestSession(): LoginCompleteResult {
    const now = this.options.clock();
    return this.runImmediate("local_test_session", () => {
      const registrationId = "local-test-user-v1";
      const existing = this.database.prepare(`
        SELECT user_id, role, status FROM users WHERE registration_id = ?
      `).get(registrationId) as {
        role: "user" | "super_admin";
        status: "active" | "suspended" | "deleted";
        user_id: string;
      } | undefined;

      if (existing) {
        if (existing.role !== "user" || existing.status !== "active") {
          throw new RegistrationError("AUTH_ENTRY_REJECTED", "account_suspended");
        }
        const session = this.insertSession(existing.user_id, "user", now);
        return {
          outcome: "committed",
          value: this.loginResult(this.readCompletedRegistration(existing.user_id, session.sessionId)),
        };
      }

      const userId = randomUUID();
      this.database.prepare(`
        INSERT INTO users (
          user_id, normalized_email, role, status, counts_toward_stage_limit,
          registration_id, created_at
        ) VALUES (?, 'local-test-user@dada.invalid', 'user', 'active', 0, ?, ?)
      `).run(userId, registrationId, now);
      this.database.prepare(`
        INSERT INTO user_profiles (
          user_id, creator_name, social_id, private_content_notice_version,
          private_content_notice_acknowledged_at
        ) VALUES (?, '本机测试用户', '@dada_local_test', NULL, NULL)
      `).run(userId);
      this.database.prepare(`
        INSERT INTO credit_accounts (user_id, available_balance, reserved_balance, updated_at)
        VALUES (?, 10, 0, ?)
      `).run(userId, now);
      this.database.prepare(`
        INSERT INTO credit_ledger (
          ledger_id, user_id, operation_key, entry_type, amount,
          available_before, available_after, reserved_before, reserved_after, created_at
        ) VALUES (?, ?, 'local-test-registration:v1', 'registration_grant', 10, 0, 10, 0, 0, ?)
      `).run(randomUUID(), userId, now);
      const session = this.insertSession(userId, "user", now);
      return {
        outcome: "committed",
        value: this.loginResult(this.readCompletedRegistration(userId, session.sessionId)),
      };
    });
  }

  applySecureConfig(candidate: SecureConfigCandidate) {
    const now = this.options.clock();
    const fail = (reason: string): never => {
      this.recordConfigApplyFailure(reason, now);
      throw new Error(reason);
    };
    if (!this.options.adminAllowlistPepper) return fail("admin_pepper_not_configured");
    if (!Number.isSafeInteger(candidate.secureConfigRevision) || candidate.secureConfigRevision < 0) {
      return fail("secure_config_revision_invalid");
    }
    const normalizeHashes = (values: string[], name: string) => {
      if (!Array.isArray(values)) return fail(`${name}_invalid`);
      const normalized = [...new Set(values.map((value) => value.toUpperCase()))];
      if (normalized.some((value) => !/^[A-F0-9]{64}$/.test(value))) return fail("hmac_invalid");
      return normalized;
    };
    const allowlist = normalizeHashes(candidate.adminAllowlistHashes, "admin_allowlist");
    const recoveries = normalizeHashes(candidate.adminRecoveryHashes, "admin_recovery");
    const allowlistSet = new Set(allowlist);
    if (recoveries.some((value) => !allowlistSet.has(value))) return fail("admin_recovery_invalid");

    const state = this.database.prepare(`
      SELECT applied_revision FROM secure_config_apply_state WHERE singleton = 1
    `).get() as { applied_revision: number } | undefined;
    const appliedRevision = state?.applied_revision ?? 0;
    if (candidate.secureConfigRevision === appliedRevision) {
      this.adminAllowlistHashes = allowlistSet;
      return { appliedRevision, status: "unchanged" as const };
    }
    if (candidate.secureConfigRevision !== appliedRevision + 1) return fail("secure_config_revision_out_of_sequence");

    const ordinaryUsers = this.database.prepare(`
      SELECT normalized_email FROM users WHERE role = 'user' AND status <> 'deleted'
    `).all() as Array<{ normalized_email: string }>;
    if (ordinaryUsers.some((user) => allowlistSet.has(this.adminAllowlistHmac(user.normalized_email)))) {
      return fail("identity_conflict");
    }

    try {
      const result = this.runImmediate("secure_config_apply", () => {
        const recoverySet = new Set(recoveries);
        const admins = this.database.prepare(`
          SELECT u.user_id, u.normalized_email, u.status, COALESCE(a.allowed, 0) AS allowed
          FROM users u LEFT JOIN admin_access a ON a.user_id = u.user_id
          WHERE u.role = 'super_admin' AND u.status <> 'deleted'
        `).all() as Array<{
          allowed: 0 | 1;
          normalized_email: string;
          status: "active" | "suspended";
          user_id: string;
        }>;
        let revokedSessions = 0;
        let recoveredAdmins = 0;
        for (const admin of admins) {
          const adminHash = this.adminAllowlistHmac(admin.normalized_email);
          const allowed = allowlistSet.has(adminHash);
          this.database.prepare(`
            INSERT INTO admin_access (user_id, allowed) VALUES (?, ?)
            ON CONFLICT(user_id) DO UPDATE SET allowed = excluded.allowed
          `).run(admin.user_id, allowed ? 1 : 0);
          if (!allowed) {
            revokedSessions += this.database.prepare(`
              UPDATE sessions SET revoked_at = ?
              WHERE user_id = ? AND audience = 'admin' AND revoked_at IS NULL
            `).run(now, admin.user_id).changes;
            if (admin.allowed === 1) {
              this.recordAdminAudit({
                actorRef: "backend_secure_config",
                actorType: "system",
                afterSummary: { access: "removed" },
                beforeSummary: { access: "allowed" },
                operationType: "admin_allowlist_remove",
                result: "succeeded",
                targetRef: admin.user_id,
                targetType: "admin_account",
              }, now);
            }
          } else if (admin.status === "suspended" && recoverySet.has(adminHash)) {
            this.database.prepare("UPDATE users SET status = 'active' WHERE user_id = ?").run(admin.user_id);
            this.database.prepare(`
              DELETE FROM email_challenges WHERE email = ? AND purpose = 'admin_login'
            `).run(admin.normalized_email);
            recoveredAdmins += 1;
            this.recordAdminAudit({
              actorRef: "backend_secure_config",
              actorType: "system",
              afterSummary: { status: "active" },
              beforeSummary: { status: "suspended" },
              operationType: "admin_recover",
              result: "succeeded",
              targetRef: admin.user_id,
              targetType: "admin_account",
            }, now);
          }
        }
        this.recordAdminAudit({
          actorRef: "backend_secure_config",
          actorType: "system",
          afterSummary: { allowlist_count: allowlist.length, recovered_admins: recoveredAdmins, revoked_sessions: revokedSessions },
          beforeSummary: { allowlist_count: this.readAppliedAllowlistCount(), revision: appliedRevision },
          operationType: "secure_config_apply",
          result: "succeeded",
          targetRef: `revision:${candidate.secureConfigRevision}`,
          targetType: "secure_config_revision",
        }, now);
        this.database.prepare(`
          INSERT INTO secure_config_apply_state (singleton, applied_revision, allowlist_count, applied_at)
          VALUES (1, ?, ?, ?)
          ON CONFLICT(singleton) DO UPDATE SET
            applied_revision = excluded.applied_revision,
            allowlist_count = excluded.allowlist_count,
            applied_at = excluded.applied_at
        `).run(candidate.secureConfigRevision, allowlist.length, now);
        return {
          outcome: "committed",
          value: { appliedRevision: candidate.secureConfigRevision, status: "applied" as const },
        };
      });
      this.adminAllowlistHashes = allowlistSet;
      return result;
    } catch (error) {
      const reason = error instanceof Error ? error.message : "secure_config_apply_failed";
      this.recordConfigApplyFailure(reason, now);
      throw error;
    }
  }

  async sendAdminLoginCode(input: { clientKey: string; email: string }): Promise<RegistrationSendResult> {
    const email = normalizeEmail(input.email);
    const clientKey = normalizeProfileValue(input.clientKey, 160);
    const now = this.options.clock();
    const challengeId = randomUUID();
    const code = this.options.codeGenerator();
    if (!/^[0-9]{6}$/.test(code)) throw new Error("Verification code generator must return six digits.");

    const outcome = this.runImmediate<RegistrationSendResult | RegistrationError>("admin_login_send", () => {
      if (!this.isAdminAllowlisted(email)) {
        this.recordAdminLoginRejection("not_allowed", now);
        return { outcome: "rejected", value: new RegistrationError("AUTH_ENTRY_REJECTED", "admin_not_allowed") };
      }
      const user = this.database.prepare(`
        SELECT u.user_id, u.role, u.status, COALESCE(a.allowed, 0) AS allowed
        FROM users u LEFT JOIN admin_access a ON a.user_id = u.user_id
        WHERE u.normalized_email = ? AND u.status <> 'deleted'
      `).get(email) as { allowed: 0 | 1; role: "user" | "super_admin"; status: "active" | "suspended"; user_id: string } | undefined;
      if (user?.status === "suspended") {
        this.recordAdminLoginRejection("suspended", now);
        return { outcome: "rejected", value: new RegistrationError("AUTH_ENTRY_REJECTED", "account_suspended") };
      }
      if (user && (user.role !== "super_admin" || user.allowed !== 1)) {
        this.recordAdminLoginRejection("not_allowed", now);
        return { outcome: "rejected", value: new RegistrationError("AUTH_ENTRY_REJECTED", "admin_not_allowed") };
      }
      this.assertChallengeSendAllowed(email, "admin_login", clientKey, now);
      this.recordRateSend(email, clientKey, now);
      this.serviceUsage.claimResendWithinTransaction(now);
      this.database.prepare(`
        INSERT INTO email_challenges (
          challenge_id, email, invite_id, code_hmac, purpose, expires_at,
          resend_available_at, failure_count, consumed_at, created_at
        ) VALUES (?, ?, NULL, ?, 'admin_login', ?, ?, 0, NULL, ?)
      `).run(
        challengeId,
        email,
        this.challengeHmac(challengeId, code),
        now + challengeLifetimeMilliseconds,
        now + resendDelayMilliseconds,
        now,
      );
      return {
        outcome: "committed",
        value: {
          challengeExpiresAt: now + challengeLifetimeMilliseconds,
          registrationId: challengeId,
          resendAvailableAt: now + resendDelayMilliseconds,
          status: "verification_sent" as const,
        },
      };
    });
    if (outcome instanceof RegistrationError) throw outcome;
    try {
      await this.options.resend.sendVerificationCode({ challengeId, code, email, purpose: "admin_login" });
    } catch {
      this.serviceUsage.markProviderFailure({ serviceId: "resend_email", reason: "provider_unavailable", now });
      this.runImmediate("registration_send_compensation", () => {
        this.database.prepare("DELETE FROM email_challenges WHERE challenge_id = ? AND consumed_at IS NULL").run(challengeId);
        this.recordAdminLoginRejection("service_unavailable", now);
        return { outcome: "committed", value: undefined };
      });
      throw new Error("AUTH_SERVICE_UNAVAILABLE");
    }
    return outcome;
  }

  completeAdminLogin(input: LoginCompleteInput): AdminLoginCompleteResult {
    if (!/^[0-9]{6}$/.test(input.code)) throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "challenge_invalid");
    const clientKey = normalizeProfileValue(input.clientKey, 160);
    if (input.idempotencyKey.length < 32 || input.idempotencyKey.length > 200 || !/^[A-Za-z0-9_-]+$/.test(input.idempotencyKey)) {
      throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "idempotency_conflict");
    }
    const now = this.options.clock();
    const idempotencyDigest = this.keyedHmac(this.options.sessionPepper, `admin-login-idempotency:${input.idempotencyKey}`);
    const requestHash = this.keyedHmac(this.options.challengePepper, JSON.stringify({
      clientKey,
      code: input.code,
      registrationId: input.registrationId,
    }));
    const outcome = this.runImmediate<AdminLoginCompleteResult | RegistrationError>("admin_login_complete", () => {
      const previous = this.database.prepare(`
        SELECT request_hash, outcome_code, failure_reason, user_id, session_id
        FROM login_attempts WHERE idempotency_key_digest = ?
      `).get(idempotencyDigest) as LoginAttemptRow | undefined;
      if (previous) {
        if (!constantTimeTextEqual(previous.request_hash, requestHash)) {
          throw new RegistrationError("IDEMPOTENCY_KEY_CONFLICT", "idempotency_conflict");
        }
        if (previous.outcome_code === "failure") {
          return {
            outcome: "idempotent_replay",
            value: new RegistrationError("AUTH_ENTRY_REJECTED", previous.failure_reason ?? "challenge_invalid"),
          };
        }
        return {
          outcome: "idempotent_replay",
          value: this.readAdminLoginResult(previous.user_id!, previous.session_id!),
        };
      }
      const challenge = this.database.prepare(`
        SELECT challenge_id, email, invite_id, code_hmac, expires_at, consumed_at
        FROM email_challenges WHERE challenge_id = ? AND purpose = 'admin_login'
      `).get(input.registrationId) as ChallengeRow | undefined;
      if (!challenge || challenge.consumed_at !== null) {
        return this.recordAdminLoginFailure(idempotencyDigest, requestHash, input.registrationId, "challenge_invalid", now);
      }
      if (!this.isAdminAllowlisted(challenge.email)) {
        return this.recordAdminLoginFailure(idempotencyDigest, requestHash, input.registrationId, "admin_not_allowed", now);
      }
      const rate = this.readRateLimit(challenge.email, clientKey, now);
      if (rate.blocked_until !== null && rate.blocked_until > now) {
        return this.recordAdminLoginFailure(idempotencyDigest, requestHash, input.registrationId, "too_many_attempts", now);
      }
      if (challenge.expires_at <= now) {
        return this.recordAdminLoginFailure(idempotencyDigest, requestHash, input.registrationId, "challenge_expired", now);
      }
      if (!constantTimeTextEqual(challenge.code_hmac, this.challengeHmac(challenge.challenge_id, input.code))) {
        this.database.prepare("UPDATE email_challenges SET failure_count = failure_count + 1 WHERE challenge_id = ?")
          .run(challenge.challenge_id);
        const failedAttempts = this.recordRateFailure(challenge.email, clientKey, now);
        return this.recordAdminLoginFailure(
          idempotencyDigest,
          requestHash,
          input.registrationId,
          failedAttempts >= maximumFailedAttempts ? "too_many_attempts" : "challenge_invalid",
          now,
        );
      }
      let user = this.database.prepare(`
        SELECT u.user_id, u.role, u.status, COALESCE(a.allowed, 0) AS allowed
        FROM users u LEFT JOIN admin_access a ON a.user_id = u.user_id
        WHERE u.normalized_email = ? AND u.status <> 'deleted'
      `).get(challenge.email) as { allowed: 0 | 1; role: "user" | "super_admin"; status: "active" | "suspended"; user_id: string } | undefined;
      if (user && (user.role !== "super_admin" || user.status !== "active" || user.allowed !== 1)) {
        return this.recordAdminLoginFailure(idempotencyDigest, requestHash, input.registrationId, "admin_not_allowed", now);
      }
      if (!user) {
        const userId = randomUUID();
        this.database.prepare(`
          INSERT INTO users (
            user_id, normalized_email, role, status, counts_toward_stage_limit,
            registration_id, created_at
          ) VALUES (?, ?, 'super_admin', 'active', 0, ?, ?)
        `).run(userId, challenge.email, challenge.challenge_id, now);
        this.database.prepare("INSERT INTO admin_access (user_id, allowed) VALUES (?, 1)").run(userId);
        user = { allowed: 1, role: "super_admin", status: "active", user_id: userId };
        this.recordAdminAudit({
          actorRef: userId,
          actorType: "super_admin",
          afterSummary: { role: "super_admin", status: "active" },
          beforeSummary: null,
          operationType: "admin_create",
          result: "succeeded",
          targetRef: userId,
          targetType: "admin_account",
        }, now);
      }
      this.database.prepare("UPDATE email_challenges SET consumed_at = ? WHERE challenge_id = ? AND consumed_at IS NULL")
        .run(now, challenge.challenge_id);
      const issued = this.insertSession(user.user_id, "admin", now);
      this.database.prepare(`
        INSERT INTO login_attempts (
          idempotency_key_digest, request_hash, challenge_id, outcome_code,
          failure_reason, user_id, session_id, created_at
        ) VALUES (?, ?, ?, 'success', NULL, ?, ?, ?)
      `).run(idempotencyDigest, requestHash, input.registrationId, user.user_id, issued.sessionId, now);
      this.recordAdminAudit({
        actorRef: user.user_id,
        actorType: "super_admin",
        afterSummary: { audience: "admin" },
        beforeSummary: null,
        operationType: "admin_login",
        result: "succeeded",
        targetRef: user.user_id,
        targetType: "admin_session",
      }, now);
      return {
        outcome: "committed",
        value: this.readAdminLoginResult(user.user_id, issued.sessionId),
      };
    });
    if (outcome instanceof RegistrationError) throw outcome;
    return outcome;
  }

  issueAuthenticatedSession(userId: string, audience: "user" | "admin") {
    const now = this.options.clock();
    return this.runImmediate("session_issue", () => {
      const user = this.database.prepare("SELECT role, status FROM users WHERE user_id = ?")
        .get(userId) as { role: "user" | "super_admin"; status: "active" | "suspended" | "deleted" } | undefined;
      const role = audience === "user" ? "user" : "super_admin";
      if (!user || user.status !== "active" || user.role !== role) {
        throw new RegistrationError("AUTH_SESSION_INVALID", "session_invalid");
      }
      if (audience === "admin") {
        const access = this.database.prepare("SELECT allowed FROM admin_access WHERE user_id = ?")
          .get(userId) as { allowed: 0 | 1 } | undefined;
        if (access?.allowed !== 1) throw new RegistrationError("AUTH_SESSION_INVALID", "session_invalid");
      }
      const issued = this.insertSession(userId, audience, now);
      return {
        outcome: "committed",
        value: {
          sessionExpiresAt: issued.sessionExpiresAt,
          sessionId: issued.sessionId,
          sessionToken: issued.sessionToken,
        },
      };
    });
  }

  issueUserCsrfToken(sessionToken: string) {
    const now = this.options.clock();
    const csrfToken = randomBytes(32).toString("base64url");
    return this.runImmediate("csrf_issue", () => {
      const session = this.database.prepare(`
        SELECT s.session_id FROM sessions s
        JOIN users u ON u.user_id = s.user_id
        WHERE s.token_digest = ? AND s.audience = 'user' AND s.revoked_at IS NULL
          AND s.expires_at > ? AND u.role = 'user' AND u.status = 'active'
      `).get(digest(sessionToken), now) as { session_id: string } | undefined;
      if (!session) throw new RegistrationError("AUTH_SESSION_INVALID", "session_invalid");
      this.database.prepare("UPDATE sessions SET csrf_token_digest = ? WHERE session_id = ?")
        .run(digest(csrfToken), session.session_id);
      return { outcome: "committed", value: csrfToken };
    });
  }

  issueAdminCsrfToken(sessionToken: string) {
    const now = this.options.clock();
    const csrfToken = randomBytes(32).toString("base64url");
    return this.runImmediate("csrf_issue", () => {
      const session = this.database.prepare(`
        SELECT s.session_id FROM sessions s
        JOIN users u ON u.user_id = s.user_id
        JOIN admin_access a ON a.user_id = u.user_id
        WHERE s.token_digest = ? AND s.audience = 'admin' AND s.revoked_at IS NULL
          AND s.expires_at > ? AND u.role = 'super_admin' AND u.status = 'active' AND a.allowed = 1
      `).get(digest(sessionToken), now) as { session_id: string } | undefined;
      if (!session) throw new RegistrationError("AUTH_SESSION_INVALID", "session_invalid");
      this.database.prepare("UPDATE sessions SET csrf_token_digest = ? WHERE session_id = ?")
        .run(digest(csrfToken), session.session_id);
      return { outcome: "committed", value: csrfToken };
    });
  }

  authorizeUserMutation(input: { csrfToken: string; sessionToken: string }) {
    const session = this.authenticatedUserMutationSession(input.sessionToken, input.csrfToken, this.options.clock());
    return { userId: session.user_id };
  }

  authorizeAdminMutation(input: { csrfToken: string; sessionToken: string }) {
    const session = this.authenticatedAdminMutationSession(input.sessionToken, input.csrfToken, this.options.clock());
    return { userId: session.user_id };
  }

  logoutUser(input: { csrfToken: string; sessionToken: string }) {
    const now = this.options.clock();
    this.runImmediate("session_revoke", () => {
      const session = this.database.prepare(`
        SELECT session_id, user_id, csrf_token_digest FROM sessions
        WHERE token_digest = ? AND audience = 'user' AND revoked_at IS NULL AND expires_at > ?
      `).get(digest(input.sessionToken), now) as { csrf_token_digest: string | null; session_id: string; user_id: string } | undefined;
      if (!session) throw new RegistrationError("AUTH_SESSION_INVALID", "session_invalid");
      const csrfDigest = digest(input.csrfToken);
      if (!session.csrf_token_digest || !constantTimeTextEqual(session.csrf_token_digest, csrfDigest)) {
        throw new RegistrationError("AUTH_CSRF_INVALID", "csrf_invalid");
      }
      this.database.prepare("UPDATE sessions SET revoked_at = ? WHERE user_id = ? AND revoked_at IS NULL")
        .run(now, session.user_id);
      return { outcome: "committed", value: undefined };
    });
  }

  readAccountSettings(sessionToken: string) {
    const now = this.options.clock();
    const row = this.database.prepare(`
      SELECT u.normalized_email, p.creator_name, p.social_id
      FROM sessions s
      JOIN users u ON u.user_id = s.user_id
      JOIN user_profiles p ON p.user_id = u.user_id
      WHERE s.token_digest = ? AND s.audience = 'user' AND s.revoked_at IS NULL
        AND s.expires_at > ? AND u.role = 'user' AND u.status = 'active'
    `).get(digest(sessionToken), now) as { creator_name: string; normalized_email: string; social_id: string } | undefined;
    if (!row) throw new RegistrationError("AUTH_SESSION_INVALID", "session_invalid");
    const storageTable = this.database.prepare(`
      SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = 'local_backend_storage_state'
    `).get();
    const storage = storageTable
      ? this.database.prepare(`
          SELECT hard_limit_bytes, managed_content_bytes, storage_status
          FROM local_backend_storage_state WHERE singleton = 1
        `).get() as { hard_limit_bytes: number; managed_content_bytes: number; storage_status: "active" | "full" | "unavailable" } | undefined
      : undefined;
    const capacityStatus = storage?.storage_status === "active"
      ? (() => {
          const bytes = storage.managed_content_bytes;
          if (bytes >= 4_831_838_208) return "critical" as const;
          if (bytes >= 4_294_967_296) return "warning" as const;
          return "normal" as const;
        })()
      : (storage?.storage_status ?? "unavailable");
    return {
      account: { email: row.normalized_email, status: "active" as const },
      localData: {
        backupEnabled: false as const,
        capacityStatus,
        hardLimitBytes: storage?.hard_limit_bytes ?? 5_368_709_120,
        location: "configured_local_data_root" as const,
        managedContentBytes: storage?.managed_content_bytes ?? 0,
        migrationSupported: false as const,
      },
      profile: { creatorName: row.creator_name, socialId: row.social_id },
    };
  }

  updateAccountProfile(input: { creatorName: string; csrfToken: string; sessionToken: string; socialId: string }) {
    const now = this.options.clock();
    const creatorName = normalizeProfileValue(input.creatorName, 80);
    const socialId = normalizeSocialId(input.socialId);
    if (!creatorName || !socialId) throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "profile_invalid");
    return this.runImmediate("profile_update", () => {
      const session = this.authenticatedUserMutationSession(input.sessionToken, input.csrfToken, now);
      this.database.prepare("UPDATE user_profiles SET creator_name = ?, social_id = ? WHERE user_id = ?")
        .run(creatorName, socialId, session.user_id);
      return { outcome: "committed", value: { creatorName, socialId, status: "saved" as const } };
    });
  }

  async sendAccountDeletionCode(input: { csrfToken: string; sessionToken: string }) {
    const now = this.options.clock();
    const deletionId = randomUUID();
    const code = this.options.codeGenerator();
    if (!/^[0-9]{6}$/.test(code)) throw new Error("Verification code generator must return six digits.");
    const result = this.runImmediate("account_delete_send", () => {
      const session = this.authenticatedUserMutationSession(input.sessionToken, input.csrfToken, now);
      const previous = this.database.prepare(`
        SELECT resend_available_at FROM account_deletion_challenges
        WHERE user_id = ? AND consumed_at IS NULL ORDER BY created_at DESC LIMIT 1
      `).get(session.user_id) as { resend_available_at: number } | undefined;
      if (previous && previous.resend_available_at > now) {
        throw new RegistrationError("AUTH_RATE_LIMITED", "resend_too_soon");
      }
      this.database.prepare("DELETE FROM account_deletion_challenges WHERE user_id = ?").run(session.user_id);
      this.database.prepare(`
        INSERT INTO account_deletion_challenges (
          deletion_id, user_id, email, code_hmac, expires_at, resend_available_at,
          failure_count, consumed_at, created_at
        ) VALUES (?, ?, ?, ?, ?, ?, 0, NULL, ?)
      `).run(
        deletionId,
        session.user_id,
        session.normalized_email,
        this.challengeHmac(deletionId, code),
        now + challengeLifetimeMilliseconds,
        now + resendDelayMilliseconds,
        now,
      );
      this.serviceUsage.claimResendWithinTransaction(now);
      return {
        outcome: "committed",
        value: {
          challengeExpiresAt: now + challengeLifetimeMilliseconds,
          deletionId,
          email: session.normalized_email,
          resendAvailableAt: now + resendDelayMilliseconds,
          status: "verification_sent" as const,
        },
      };
    });
    try {
      await this.options.resend.sendVerificationCode({
        challengeId: deletionId,
        code,
        email: result.email,
        purpose: "account_delete",
      });
    } catch {
      this.serviceUsage.markProviderFailure({ serviceId: "resend_email", reason: "provider_unavailable", now });
      this.runImmediate("registration_send_compensation", () => {
        this.database.prepare("DELETE FROM account_deletion_challenges WHERE deletion_id = ? AND consumed_at IS NULL").run(deletionId);
        return { outcome: "committed", value: undefined };
      });
      throw new Error("AUTH_SERVICE_UNAVAILABLE");
    }
    return {
      challengeExpiresAt: result.challengeExpiresAt,
      deletionId: result.deletionId,
      resendAvailableAt: result.resendAvailableAt,
      status: result.status,
    };
  }

  completeAccountDeletion(input: {
    code: string;
    confirmation: string;
    csrfToken: string;
    deletionId: string;
    idempotencyKey: string;
    sessionToken: string;
  }) {
    const now = this.options.clock();
    const idempotencyDigest = digest(input.idempotencyKey);
    const requestHash = this.keyedHmac(
      this.options.challengePepper,
      JSON.stringify({ confirmation: input.confirmation, deletionId: input.deletionId, verificationCode: input.code }),
    );
    const previous = this.database.prepare(`
      SELECT request_hash FROM account_deletion_receipts WHERE idempotency_key_digest = ?
    `).get(idempotencyDigest) as { request_hash: string } | undefined;
    if (previous) {
      if (!constantTimeTextEqual(previous.request_hash, requestHash)) {
        throw new RegistrationError("IDEMPOTENCY_KEY_CONFLICT", "idempotency_conflict");
      }
      return { status: "deleted" as const };
    }
    const outcome = this.runImmediate<{ status: "deleted" } | RegistrationError>("account_delete_complete", () => {
      const session = this.authenticatedUserMutationSession(input.sessionToken, input.csrfToken, now);
      if (input.confirmation !== "注销账号") {
        throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "deletion_confirmation_invalid");
      }
      const challenge = this.database.prepare(`
        SELECT code_hmac, expires_at FROM account_deletion_challenges
        WHERE deletion_id = ? AND user_id = ? AND consumed_at IS NULL
      `).get(input.deletionId, session.user_id) as { code_hmac: string; expires_at: number } | undefined;
      if (!challenge) throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "challenge_invalid");
      if (challenge.expires_at <= now) throw new RegistrationError("REGISTRATION_REQUEST_INVALID", "challenge_expired");
      if (!constantTimeTextEqual(challenge.code_hmac, this.challengeHmac(input.deletionId, input.code))) {
        this.database.prepare("UPDATE account_deletion_challenges SET failure_count = failure_count + 1 WHERE deletion_id = ?")
          .run(input.deletionId);
        return {
          outcome: "rejected",
          value: new RegistrationError("REGISTRATION_REQUEST_INVALID", "challenge_invalid"),
        };
      }

      const anonymousSubjectId = randomUUID();
      const anonymousExpiresAt = now + 180 * 24 * 60 * 60 * 1_000;
      const ledger = this.database.prepare(`
        SELECT entry_type, amount, created_at FROM credit_ledger WHERE user_id = ? ORDER BY created_at, ledger_id
      `).all(session.user_id) as Array<{ amount: number; created_at: number; entry_type: string }>;
      const insertAnonymous = this.database.prepare(`
        INSERT INTO anonymous_retained_events (
          event_id, anonymous_subject_id, event_type, model_id, outcome,
          error_category, credit_delta, occurred_at, expires_at
        ) VALUES (?, ?, ?, NULL, 'succeeded', NULL, ?, ?, ?)
      `);
      for (const entry of ledger) {
        insertAnonymous.run(randomUUID(), anonymousSubjectId, entry.entry_type, entry.amount, entry.created_at, anonymousExpiresAt);
      }

      this.privacyPurgeActive = true;
      this.privacyPurgeSubject = session.user_id;
      try {
        this.database.prepare("DELETE FROM credit_ledger WHERE user_id = ?").run(session.user_id);
        this.database.prepare(`
          UPDATE private_content_access_logs SET subject_ref = ?, target_ref = ? WHERE subject_ref = ?
        `).run(randomUUID(), randomUUID(), session.user_id);
      } finally {
        this.privacyPurgeActive = false;
        this.privacyPurgeSubject = "";
      }

      this.queueOwnedManagedFiles(session.user_id, now);
      this.database.prepare("DELETE FROM registration_attempts WHERE user_id = ?").run(session.user_id);
      this.database.prepare("DELETE FROM login_attempts WHERE user_id = ?").run(session.user_id);
      this.database.prepare("DELETE FROM privacy_consents WHERE user_id = ?").run(session.user_id);
      this.database.prepare("DELETE FROM credit_accounts WHERE user_id = ?").run(session.user_id);
      this.database.prepare("DELETE FROM user_profiles WHERE user_id = ?").run(session.user_id);
      const projectsTable = this.database.prepare(`
        SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'projects'
      `).get();
      if (projectsTable) this.database.prepare("DELETE FROM projects WHERE owner_id = ?").run(session.user_id);
      const exportReceiptsTable = this.database.prepare(`
        SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'latest_export_receipts'
      `).get();
      if (exportReceiptsTable) this.database.prepare("DELETE FROM latest_export_receipts WHERE owner_id = ?").run(session.user_id);
      this.database.prepare("DELETE FROM account_deletion_challenges WHERE user_id = ?").run(session.user_id);
      this.database.prepare("DELETE FROM email_challenges WHERE email = ?").run(session.normalized_email);
      this.database.prepare("DELETE FROM auth_rate_limits WHERE rate_key = ?")
        .run(this.rateKey(session.normalized_email, "registration"));
      this.database.prepare("DELETE FROM sessions WHERE user_id = ?").run(session.user_id);
      this.database.prepare("DELETE FROM users WHERE user_id = ?").run(session.user_id);
      this.database.prepare(`
        INSERT INTO account_deletion_receipts (idempotency_key_digest, request_hash, deleted_at)
        VALUES (?, ?, ?)
      `).run(idempotencyDigest, requestHash, now);
      return { outcome: "committed", value: { status: "deleted" as const } };
    });
    if (outcome instanceof RegistrationError) throw outcome;
    return outcome;
  }

  changeUserStatus(userId: string, status: "suspended" | "deleted", actorId?: string) {
    const now = this.options.clock();
    this.runImmediate("session_revoke", () => {
      if (actorId) {
        const admin = this.database.prepare(`
          SELECT u.user_id FROM users u JOIN admin_access a ON a.user_id = u.user_id
          WHERE u.user_id = ? AND u.role = 'super_admin' AND u.status = 'active' AND a.allowed = 1
        `).get(actorId);
        if (!admin) throw new RegistrationError("AUTH_SESSION_INVALID", "session_invalid");
      }
      const before = this.database.prepare("SELECT status FROM users WHERE user_id = ? AND role = 'user'")
        .get(userId) as { status: "active" | "suspended" | "deleted" } | undefined;
      const changed = this.database.prepare("UPDATE users SET status = ? WHERE user_id = ? AND role = 'user'")
        .run(status, userId);
      if (changed.changes !== 1) throw new RegistrationError("AUTH_SESSION_INVALID", "session_invalid");
      this.database.prepare("UPDATE sessions SET revoked_at = ? WHERE user_id = ? AND revoked_at IS NULL")
        .run(now, userId);
      if (actorId) {
        this.recordAdminAudit({
          actorRef: actorId,
          actorType: "super_admin",
          afterSummary: { status },
          beforeSummary: { status: before?.status ?? "unknown" },
          operationType: "user_status_change",
          result: "succeeded",
          targetRef: userId,
          targetType: "user_account",
        }, now);
      }
      return { outcome: "committed", value: undefined };
    });
  }

  revokeAdminSessions(userId: string, reason: "logout" | "disabled" | "whitelist_removed") {
    const now = this.options.clock();
    this.runImmediate("session_revoke", () => {
      const user = this.database.prepare("SELECT role FROM users WHERE user_id = ?").get(userId) as { role: string } | undefined;
      if (user?.role !== "super_admin") throw new RegistrationError("AUTH_SESSION_INVALID", "session_invalid");
      if (reason === "disabled") this.database.prepare("UPDATE users SET status = 'suspended' WHERE user_id = ?").run(userId);
      if (reason === "whitelist_removed") this.database.prepare("UPDATE admin_access SET allowed = 0 WHERE user_id = ?").run(userId);
      this.database.prepare("UPDATE sessions SET revoked_at = ? WHERE user_id = ? AND audience = 'admin' AND revoked_at IS NULL")
        .run(now, userId);
      this.recordAdminAudit({
        actorRef: reason === "whitelist_removed" ? "backend_secure_config" : userId,
        actorType: reason === "whitelist_removed" ? "system" : "super_admin",
        afterSummary: { access: reason === "whitelist_removed" ? "removed" : reason },
        beforeSummary: { access: "active" },
        operationType: reason === "disabled" ? "admin_disable" : reason === "logout" ? "admin_logout" : "admin_allowlist_remove",
        result: "succeeded",
        targetRef: userId,
        targetType: "admin_account",
      }, now);
      return { outcome: "committed", value: undefined };
    });
  }

  readAdminSession(token: string) {
    const now = this.options.clock();
    return this.database.prepare(`
      SELECT s.expires_at, u.user_id FROM sessions s
      JOIN users u ON u.user_id = s.user_id
      JOIN admin_access a ON a.user_id = u.user_id
      WHERE s.token_digest = ? AND s.audience = 'admin' AND s.revoked_at IS NULL
        AND s.expires_at > ? AND u.role = 'super_admin' AND u.status = 'active' AND a.allowed = 1
    `).get(digest(token), now) as { expires_at: number; user_id: string } | undefined;
  }

  readUserSession(token: string): UserSessionResult | undefined {
    const now = this.options.clock();
    const row = this.database.prepare(`
      SELECT
        s.expires_at, u.user_id, p.creator_name, p.social_id,
        c.available_balance, c.reserved_balance
      FROM sessions s
      JOIN users u ON u.user_id = s.user_id
      JOIN user_profiles p ON p.user_id = u.user_id
      JOIN credit_accounts c ON c.user_id = u.user_id
      WHERE s.token_digest = ? AND s.audience = 'user' AND s.revoked_at IS NULL
        AND s.expires_at > ? AND u.role = 'user' AND u.status = 'active'
    `).get(digest(token), now) as Omit<UserResultRow, "session_id"> | undefined;
    if (!row) return undefined;
    return {
      audience: "user",
      credits: { availableBalance: row.available_balance, reservedBalance: row.reserved_balance },
      expiresAt: row.expires_at,
      user: {
        creatorName: row.creator_name,
        role: "user",
        socialId: row.social_id,
        status: "active",
        userId: row.user_id,
      },
      userId: row.user_id,
    };
  }

  private migrate() {
    this.database.exec(`
      CREATE TABLE IF NOT EXISTS users (
        user_id TEXT PRIMARY KEY,
        normalized_email TEXT NOT NULL,
        role TEXT NOT NULL CHECK (role IN ('user', 'super_admin')),
        status TEXT NOT NULL CHECK (status IN ('active', 'suspended', 'deleted')),
        counts_toward_stage_limit INTEGER NOT NULL CHECK (counts_toward_stage_limit IN (0, 1)),
        registration_id TEXT NOT NULL UNIQUE,
        created_at INTEGER NOT NULL
      );
      CREATE UNIQUE INDEX IF NOT EXISTS users_current_email_unique
        ON users(normalized_email) WHERE status <> 'deleted';
      CREATE TABLE IF NOT EXISTS user_profiles (
        user_id TEXT PRIMARY KEY REFERENCES users(user_id),
        creator_name TEXT NOT NULL,
        social_id TEXT NOT NULL,
        private_content_notice_version TEXT,
        private_content_notice_acknowledged_at INTEGER
      );
      CREATE TABLE IF NOT EXISTS credit_accounts (
        user_id TEXT PRIMARY KEY REFERENCES users(user_id),
        available_balance INTEGER NOT NULL,
        reserved_balance INTEGER NOT NULL CHECK (reserved_balance >= 0),
        updated_at INTEGER NOT NULL
      );
      CREATE TABLE IF NOT EXISTS credit_ledger (
        ledger_id TEXT PRIMARY KEY,
        user_id TEXT NOT NULL REFERENCES users(user_id),
        operation_key TEXT NOT NULL UNIQUE,
        entry_type TEXT NOT NULL CHECK (entry_type IN (
          'registration_grant', 'generation_reserve', 'generation_commit',
          'generation_release', 'admin_adjustment'
        )),
        amount INTEGER NOT NULL,
        available_before INTEGER NOT NULL,
        available_after INTEGER NOT NULL,
        reserved_before INTEGER NOT NULL CHECK (reserved_before >= 0),
        reserved_after INTEGER NOT NULL CHECK (reserved_after >= 0),
        created_at INTEGER NOT NULL
      );
      CREATE TRIGGER IF NOT EXISTS credit_ledger_no_update
        BEFORE UPDATE ON credit_ledger BEGIN SELECT RAISE(ABORT, 'credit_ledger_immutable'); END;
      DROP TRIGGER IF EXISTS credit_ledger_no_delete;
      CREATE TRIGGER credit_ledger_no_delete
        BEFORE DELETE ON credit_ledger
        WHEN dada_allow_privacy_purge() <> 1
        BEGIN SELECT RAISE(ABORT, 'credit_ledger_immutable'); END;
      CREATE TABLE IF NOT EXISTS privacy_consents (
        consent_id TEXT PRIMARY KEY,
        user_id TEXT NOT NULL REFERENCES users(user_id),
        notice_version TEXT NOT NULL,
        consented_at INTEGER NOT NULL,
        UNIQUE(user_id, notice_version)
      );
      CREATE TABLE IF NOT EXISTS invite_codes (
        invite_id TEXT PRIMARY KEY,
        code_hmac TEXT NOT NULL UNIQUE,
        max_uses INTEGER NOT NULL CHECK (max_uses > 0),
        used_count INTEGER NOT NULL CHECK (used_count >= 0 AND used_count <= max_uses),
        expires_at INTEGER NOT NULL,
        status TEXT NOT NULL CHECK (status IN ('enabled', 'disabled')),
        created_at INTEGER NOT NULL
      );
      CREATE TABLE IF NOT EXISTS email_challenges (
        challenge_id TEXT PRIMARY KEY,
        email TEXT NOT NULL,
        invite_id TEXT REFERENCES invite_codes(invite_id),
        code_hmac TEXT NOT NULL,
        purpose TEXT NOT NULL CHECK (purpose IN ('register', 'login', 'admin_login')),
        expires_at INTEGER NOT NULL,
        resend_available_at INTEGER NOT NULL,
        failure_count INTEGER NOT NULL DEFAULT 0 CHECK (failure_count >= 0),
        consumed_at INTEGER,
        created_at INTEGER NOT NULL
      );
      CREATE TABLE IF NOT EXISTS sessions (
        session_id TEXT PRIMARY KEY,
        user_id TEXT NOT NULL REFERENCES users(user_id),
        audience TEXT NOT NULL CHECK (audience IN ('user', 'admin')),
        token_digest TEXT NOT NULL UNIQUE,
        csrf_token_digest TEXT,
        created_at INTEGER NOT NULL,
        expires_at INTEGER NOT NULL,
        revoked_at INTEGER
      );
      CREATE TABLE IF NOT EXISTS registration_attempts (
        idempotency_key_digest TEXT PRIMARY KEY,
        request_hash TEXT NOT NULL,
        registration_id TEXT NOT NULL,
        outcome_code TEXT NOT NULL CHECK (outcome_code IN ('success', 'failure')),
        failure_reason TEXT,
        user_id TEXT REFERENCES users(user_id),
        session_id TEXT REFERENCES sessions(session_id),
        created_at INTEGER NOT NULL
      );
      CREATE TABLE IF NOT EXISTS admin_access (
        user_id TEXT PRIMARY KEY REFERENCES users(user_id),
        allowed INTEGER NOT NULL CHECK (allowed IN (0, 1))
      );
      CREATE TABLE IF NOT EXISTS secure_config_apply_state (
        singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
        applied_revision INTEGER NOT NULL CHECK (applied_revision >= 0),
        allowlist_count INTEGER NOT NULL CHECK (allowlist_count >= 0),
        applied_at INTEGER NOT NULL
      );
      CREATE TABLE IF NOT EXISTS admin_operation_logs (
        log_id TEXT PRIMARY KEY,
        actor_type TEXT NOT NULL CHECK (actor_type IN ('system', 'super_admin')),
        actor_ref TEXT NOT NULL,
        operation_type TEXT NOT NULL,
        target_type TEXT NOT NULL,
        target_ref TEXT NOT NULL,
        result TEXT NOT NULL CHECK (result IN ('succeeded', 'failed')),
        before_summary TEXT,
        after_summary TEXT,
        occurred_at INTEGER NOT NULL,
        expires_at INTEGER NOT NULL
      );
      CREATE TRIGGER IF NOT EXISTS admin_operation_logs_no_update
        BEFORE UPDATE ON admin_operation_logs BEGIN SELECT RAISE(ABORT, 'admin_operation_logs_immutable'); END;
      CREATE TRIGGER IF NOT EXISTS admin_operation_logs_no_delete
        BEFORE DELETE ON admin_operation_logs BEGIN SELECT RAISE(ABORT, 'admin_operation_logs_immutable'); END;
      CREATE TABLE IF NOT EXISTS auth_rate_limits (
        rate_key TEXT PRIMARY KEY,
        window_started_at INTEGER NOT NULL,
        send_count INTEGER NOT NULL CHECK (send_count >= 0),
        failed_attempts INTEGER NOT NULL CHECK (failed_attempts >= 0),
        blocked_until INTEGER
      );
      CREATE TABLE IF NOT EXISTS login_attempts (
        idempotency_key_digest TEXT PRIMARY KEY,
        request_hash TEXT NOT NULL,
        challenge_id TEXT NOT NULL,
        outcome_code TEXT NOT NULL CHECK (outcome_code IN ('success', 'failure')),
        failure_reason TEXT,
        user_id TEXT REFERENCES users(user_id),
        session_id TEXT REFERENCES sessions(session_id),
        created_at INTEGER NOT NULL
      );
      CREATE TABLE IF NOT EXISTS account_deletion_challenges (
        deletion_id TEXT PRIMARY KEY,
        user_id TEXT NOT NULL REFERENCES users(user_id),
        email TEXT NOT NULL,
        code_hmac TEXT NOT NULL,
        expires_at INTEGER NOT NULL,
        resend_available_at INTEGER NOT NULL,
        failure_count INTEGER NOT NULL DEFAULT 0 CHECK (failure_count >= 0),
        consumed_at INTEGER,
        created_at INTEGER NOT NULL
      );
      CREATE TABLE IF NOT EXISTS account_deletion_receipts (
        idempotency_key_digest TEXT PRIMARY KEY,
        request_hash TEXT NOT NULL,
        deleted_at INTEGER NOT NULL
      );
      CREATE TABLE IF NOT EXISTS private_content_access_logs (
        log_id TEXT PRIMARY KEY,
        actor_ref TEXT NOT NULL,
        subject_ref TEXT NOT NULL,
        target_ref TEXT NOT NULL,
        content_type TEXT NOT NULL CHECK (content_type IN ('image', 'prompt')),
        occurred_at INTEGER NOT NULL,
        expires_at INTEGER NOT NULL
      );
      CREATE TRIGGER IF NOT EXISTS private_content_access_logs_no_update
        BEFORE UPDATE ON private_content_access_logs
        WHEN dada_allow_privacy_purge() <> 1
        BEGIN SELECT RAISE(ABORT, 'private_content_access_logs_immutable'); END;
      CREATE TRIGGER IF NOT EXISTS private_content_access_logs_no_delete
        BEFORE DELETE ON private_content_access_logs
        WHEN dada_allow_retention_purge() <> 1
        BEGIN SELECT RAISE(ABORT, 'private_content_access_logs_immutable'); END;
      CREATE TABLE IF NOT EXISTS anonymous_retained_events (
        event_id TEXT PRIMARY KEY,
        anonymous_subject_id TEXT NOT NULL,
        event_type TEXT NOT NULL,
        model_id TEXT,
        outcome TEXT NOT NULL,
        error_category TEXT,
        credit_delta INTEGER NOT NULL,
        occurred_at INTEGER NOT NULL,
        expires_at INTEGER NOT NULL
      );
      CREATE TRIGGER IF NOT EXISTS anonymous_retained_events_no_update
        BEFORE UPDATE ON anonymous_retained_events
        BEGIN SELECT RAISE(ABORT, 'anonymous_retained_events_immutable'); END;
      CREATE TRIGGER IF NOT EXISTS anonymous_retained_events_no_delete
        BEFORE DELETE ON anonymous_retained_events
        WHEN dada_allow_retention_purge() <> 1
        BEGIN SELECT RAISE(ABORT, 'anonymous_retained_events_immutable'); END;
      INSERT OR IGNORE INTO secure_config_apply_state (
        singleton, applied_revision, allowlist_count, applied_at
      ) VALUES (1, 0, 0, 0);
    `);
    ensureAdminOperationAuditSchema(this.database, this.options.clock());
    ensurePrivateAccessAuditSchema(this.database);
  }

  private runImmediate<T>(
    operation: RegistrationTransactionEvent["operation"],
    action: () => ImmediateResult<T>,
  ): T {
    this.database.exec("BEGIN IMMEDIATE");
    try {
      const result = action();
      this.database.exec("COMMIT");
      this.options.onTransaction?.({ mode: "BEGIN IMMEDIATE", operation, outcome: result.outcome });
      return result.value;
    } catch (error) {
      if (this.database.inTransaction) this.database.exec("ROLLBACK");
      this.options.onTransaction?.({ mode: "BEGIN IMMEDIATE", operation, outcome: "rejected" });
      throw error;
    }
  }

  private authenticatedUserMutationSession(sessionToken: string, csrfToken: string, now: number) {
    const session = this.database.prepare(`
      SELECT s.session_id, s.user_id, s.csrf_token_digest, u.normalized_email
      FROM sessions s JOIN users u ON u.user_id = s.user_id
      WHERE s.token_digest = ? AND s.audience = 'user' AND s.revoked_at IS NULL
        AND s.expires_at > ? AND u.role = 'user' AND u.status = 'active'
    `).get(digest(sessionToken), now) as {
      csrf_token_digest: string | null;
      normalized_email: string;
      session_id: string;
      user_id: string;
    } | undefined;
    if (!session) throw new RegistrationError("AUTH_SESSION_INVALID", "session_invalid");
    if (!session.csrf_token_digest || !constantTimeTextEqual(session.csrf_token_digest, digest(csrfToken))) {
      throw new RegistrationError("AUTH_CSRF_INVALID", "csrf_invalid");
    }
    return session;
  }

  private authenticatedAdminMutationSession(sessionToken: string, csrfToken: string, now: number) {
    const session = this.database.prepare(`
      SELECT s.session_id, s.user_id, s.csrf_token_digest
      FROM sessions s
      JOIN users u ON u.user_id = s.user_id
      JOIN admin_access a ON a.user_id = u.user_id
      WHERE s.token_digest = ? AND s.audience = 'admin' AND s.revoked_at IS NULL
        AND s.expires_at > ? AND u.role = 'super_admin' AND u.status = 'active' AND a.allowed = 1
    `).get(digest(sessionToken), now) as {
      csrf_token_digest: string | null;
      session_id: string;
      user_id: string;
    } | undefined;
    if (!session) throw new RegistrationError("AUTH_SESSION_INVALID", "session_invalid");
    if (!session.csrf_token_digest || !constantTimeTextEqual(session.csrf_token_digest, digest(csrfToken))) {
      throw new RegistrationError("AUTH_CSRF_INVALID", "csrf_invalid");
    }
    return session;
  }

  private queueOwnedManagedFiles(userId: string, now: number) {
    const table = this.database.prepare(`
      SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = 'managed_files'
    `).get();
    if (!table) return 0;
    const columns = this.database.prepare("PRAGMA table_info(managed_files)").all() as Array<{ name: string }>;
    if (!columns.some((column) => column.name === "owner_ref")) return 0;
    const files = this.database.prepare(`
      SELECT file_id, relative_path, byte_size FROM managed_files
      WHERE owner_ref = ? AND status = 'committed'
        AND file_kind IN ('reference', 'generated', 'export', 'derived')
    `).all(userId) as Array<{ byte_size: number; file_id: string; relative_path: string }>;
    const purgedAt = new Date(now).toISOString();
    for (const file of files) {
      this.database.prepare("DELETE FROM project_asset_refs WHERE managed_file_id = ?").run(file.file_id);
      this.database.prepare(`
        UPDATE managed_files SET status = 'purged', purged_at = ?, owner_ref = ? WHERE file_id = ?
      `).run(purgedAt, randomUUID(), file.file_id);
      this.database.prepare(`
        INSERT OR IGNORE INTO file_cleanup_queue (
          cleanup_id, managed_file_id, relative_path, byte_size, counts_toward_managed,
          reason, status, created_at
        ) VALUES (?, ?, ?, ?, 1, 'purge', 'pending', ?)
      `).run(randomUUID(), file.file_id, file.relative_path, file.byte_size, purgedAt);
    }
    return files.length;
  }

  private keyedHmac(key: Buffer, value: string) {
    return createHmac("sha256", key).update(value, "utf8").digest("hex");
  }

  private inviteHmac(code: string) {
    return this.keyedHmac(this.options.invitePepper, code.trim());
  }

  private challengeHmac(challengeId: string, code: string) {
    return this.keyedHmac(this.options.challengePepper, `${challengeId}:${code}`);
  }

  private adminAllowlistHmac(email: string) {
    if (!this.options.adminAllowlistPepper) throw new Error("admin_pepper_not_configured");
    return createHmac("sha256", this.options.adminAllowlistPepper)
      .update(email.trim().toLowerCase(), "utf8")
      .digest("hex")
      .toUpperCase();
  }

  private isAdminAllowlisted(email: string) {
    return Boolean(this.options.adminAllowlistPepper)
      && this.adminAllowlistHashes.has(this.adminAllowlistHmac(email));
  }

  private sessionToken(sessionId: string) {
    return createHmac("sha256", this.options.sessionPepper).update(`session:${sessionId}`, "utf8").digest("base64url");
  }

  private rateKey(email: string, clientKey: string) {
    return this.keyedHmac(this.options.challengePepper, `rate:${email}:${clientKey}`);
  }

  private readRateLimit(email: string, clientKey: string, now: number): RateLimitRow {
    const row = this.database.prepare(`
      SELECT window_started_at, send_count, failed_attempts, blocked_until
      FROM auth_rate_limits WHERE rate_key = ?
    `).get(this.rateKey(email, clientKey)) as RateLimitRow | undefined;
    if (!row || now - row.window_started_at >= rateWindowMilliseconds) {
      return { blocked_until: null, failed_attempts: 0, send_count: 0, window_started_at: now };
    }
    return row;
  }

  private recordRateSend(email: string, clientKey: string, now: number) {
    const key = this.rateKey(email, clientKey);
    const row = this.readRateLimit(email, clientKey, now);
    if (row.blocked_until !== null && row.blocked_until > now) {
      throw new RegistrationError("AUTH_RATE_LIMITED", "too_many_attempts");
    }
    if (row.send_count >= maximumSendsPerWindow) {
      throw new RegistrationError("AUTH_RATE_LIMITED", "too_many_attempts");
    }
    this.database.prepare(`
      INSERT INTO auth_rate_limits (
        rate_key, window_started_at, send_count, failed_attempts, blocked_until
      ) VALUES (?, ?, 1, 0, NULL)
      ON CONFLICT(rate_key) DO UPDATE SET
        window_started_at = excluded.window_started_at,
        send_count = ?,
        failed_attempts = ?,
        blocked_until = ?
    `).run(
      key,
      row.window_started_at,
      row.send_count + 1,
      row.failed_attempts,
      row.blocked_until,
    );
  }

  private recordRateFailure(email: string, clientKey: string, now: number) {
    const key = this.rateKey(email, clientKey);
    const row = this.readRateLimit(email, clientKey, now);
    const failedAttempts = row.failed_attempts + 1;
    const blockedUntil = failedAttempts >= maximumFailedAttempts ? now + rateBlockMilliseconds : row.blocked_until;
    this.database.prepare(`
      INSERT INTO auth_rate_limits (
        rate_key, window_started_at, send_count, failed_attempts, blocked_until
      ) VALUES (?, ?, 0, ?, ?)
      ON CONFLICT(rate_key) DO UPDATE SET
        window_started_at = excluded.window_started_at,
        send_count = ?,
        failed_attempts = excluded.failed_attempts,
        blocked_until = excluded.blocked_until
    `).run(key, row.window_started_at, failedAttempts, blockedUntil, row.send_count);
    return failedAttempts;
  }

  private assertChallengeSendAllowed(
    email: string,
    purpose: "register" | "login" | "admin_login",
    clientKey: string,
    now: number,
  ) {
    const latest = this.database.prepare(`
      SELECT resend_available_at FROM email_challenges
      WHERE email = ? AND purpose = ? ORDER BY created_at DESC LIMIT 1
    `).get(email, purpose) as { resend_available_at: number } | undefined;
    if (latest && latest.resend_available_at > now) {
      throw new RegistrationError("AUTH_RATE_LIMITED", "resend_too_soon");
    }
    const rate = this.readRateLimit(email, clientKey, now);
    if ((rate.blocked_until !== null && rate.blocked_until > now) || rate.send_count >= maximumSendsPerWindow) {
      throw new RegistrationError("AUTH_RATE_LIMITED", "too_many_attempts");
    }
  }

  private insertSession(userId: string, audience: "user" | "admin", now: number) {
    const sessionId = randomUUID();
    const sessionToken = this.sessionToken(sessionId);
    const sessionExpiresAt = now + sessionLifetimeMilliseconds;
    this.database.prepare(`
      INSERT INTO sessions (
        session_id, user_id, audience, token_digest, csrf_token_digest,
        created_at, expires_at, revoked_at
      ) VALUES (?, ?, ?, ?, NULL, ?, ?, NULL)
    `).run(sessionId, userId, audience, digest(sessionToken), now, sessionExpiresAt);
    return { sessionExpiresAt, sessionId, sessionToken };
  }

  private readAdminLoginResult(userId: string, sessionId: string): AdminLoginCompleteResult {
    const row = this.database.prepare(`
      SELECT u.user_id, s.expires_at
      FROM users u
      JOIN admin_access a ON a.user_id = u.user_id
      JOIN sessions s ON s.user_id = u.user_id
      WHERE u.user_id = ? AND u.role = 'super_admin' AND u.status = 'active'
        AND a.allowed = 1 AND s.session_id = ? AND s.audience = 'admin'
    `).get(userId, sessionId) as { expires_at: number; user_id: string } | undefined;
    if (!row) throw new RegistrationError("AUTH_ENTRY_REJECTED", "challenge_invalid");
    return {
      admin: { role: "super_admin", status: "active", userId: row.user_id },
      audience: "admin",
      sessionExpiresAt: row.expires_at,
      sessionToken: this.sessionToken(sessionId),
      status: "authenticated",
    };
  }

  private readAppliedAllowlistCount() {
    const state = this.database.prepare(`
      SELECT allowlist_count FROM secure_config_apply_state WHERE singleton = 1
    `).get() as { allowlist_count: number } | undefined;
    return state?.allowlist_count ?? 0;
  }

  private recordAdminAudit(input: {
    actorRef: string;
    actorType: "system" | "super_admin";
    afterSummary: Record<string, unknown> | null;
    beforeSummary: Record<string, unknown> | null;
    operationType: string;
    result: "succeeded" | "failed";
    targetRef: string;
    targetType: string;
  }, now: number) {
    this.database.prepare(`
      INSERT INTO admin_operation_logs (
        log_id, actor_type, actor_ref, operation_type, target_type, target_ref,
        result, before_summary, after_summary, occurred_at, expires_at
      ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    `).run(
      randomUUID(),
      input.actorType,
      input.actorRef,
      input.operationType,
      input.targetType,
      input.targetRef,
      input.result,
      serializeAuditSummary(input.beforeSummary),
      serializeAuditSummary(input.afterSummary),
      now,
      now + auditRetentionMilliseconds,
    );
  }

  private recordAdminLoginRejection(reason: string, now: number) {
    this.recordAdminAudit({
      actorRef: "admin_auth",
      actorType: "system",
      afterSummary: { reason },
      beforeSummary: null,
      operationType: "admin_login",
      result: "failed",
      targetRef: "admin_login",
      targetType: "admin_session",
    }, now);
  }

  private recordAdminLoginFailure(
    idempotencyKeyDigest: string,
    requestHash: string,
    challengeId: string,
    reason: RegistrationErrorReason,
    now: number,
  ) {
    const failure = this.recordLoginFailure(idempotencyKeyDigest, requestHash, challengeId, reason, now);
    this.recordAdminLoginRejection(reason === "admin_not_allowed" ? "not_allowed" : reason, now);
    return failure;
  }

  private recordConfigApplyFailure(reason: string, now: number) {
    this.database.exec("BEGIN IMMEDIATE");
    try {
      this.recordAdminAudit({
        actorRef: "backend_secure_config",
        actorType: "system",
        afterSummary: { reason: this.safeConfigFailureReason(reason) },
        beforeSummary: { allowlist_count: this.readAppliedAllowlistCount() },
        operationType: "secure_config_apply",
        result: "failed",
        targetRef: "candidate_revision",
        targetType: "secure_config_revision",
      }, now);
      this.database.exec("COMMIT");
    } catch (error) {
      if (this.database.inTransaction) this.database.exec("ROLLBACK");
      throw new Error("secure_config_failed_audit_unavailable", { cause: error });
    }
  }

  private safeConfigFailureReason(reason: string) {
    const allowed = new Set([
      "admin_pepper_not_configured",
      "secure_config_revision_invalid",
      "admin_allowlist_invalid",
      "admin_recovery_invalid",
      "hmac_invalid",
      "secure_config_revision_out_of_sequence",
      "identity_conflict",
    ]);
    return allowed.has(reason) ? reason : "secure_config_apply_failed";
  }

  private recordLoginFailure(
    idempotencyKeyDigest: string,
    requestHash: string,
    challengeId: string,
    reason: RegistrationErrorReason,
    now: number,
  ): ImmediateResult<RegistrationError> {
    this.database.prepare(`
      INSERT INTO login_attempts (
        idempotency_key_digest, request_hash, challenge_id, outcome_code,
        failure_reason, user_id, session_id, created_at
      ) VALUES (?, ?, ?, 'failure', ?, NULL, NULL, ?)
    `).run(idempotencyKeyDigest, requestHash, challengeId, reason, now);
    const code = reason === "resend_too_soon" || reason === "too_many_attempts"
      ? "AUTH_RATE_LIMITED"
      : "AUTH_ENTRY_REJECTED";
    return { outcome: "rejected", value: new RegistrationError(code, reason) };
  }

  private stageIsFull() {
    const row = this.database.prepare(`
      SELECT COUNT(*) AS count FROM users
      WHERE role = 'user' AND counts_toward_stage_limit = 1
        AND status IN ('active', 'suspended')
    `).get() as { count: number };
    return row.count >= stageLimit;
  }

  private assertStageCapacity() {
    if (this.stageIsFull()) throw new RegistrationError("REGISTRATION_REJECTED", "stage_limit_reached");
  }

  private inviteUnavailableReason(invite: InviteRow | undefined, now: number): RegistrationErrorReason | undefined {
    if (!invite) return "invite_not_found";
    if (invite.status !== "enabled") return "invite_disabled";
    if (invite.expires_at <= now) return "invite_expired";
    if (invite.used_count >= invite.max_uses) return "invite_exhausted";
    return undefined;
  }

  private assertInviteAvailable(invite: InviteRow | undefined, now: number): asserts invite is InviteRow {
    const reason = this.inviteUnavailableReason(invite, now);
    if (reason) throw new RegistrationError("REGISTRATION_REJECTED", reason);
  }

  private recordRejectedAttempt(
    idempotencyKeyDigest: string,
    requestHash: string,
    registrationId: string,
    reason: RegistrationErrorReason,
    now: number,
  ): ImmediateResult<RegistrationError> {
    this.database.prepare(`
      INSERT INTO registration_attempts (
        idempotency_key_digest, request_hash, registration_id, outcome_code,
        failure_reason, user_id, session_id, created_at
      ) VALUES (?, ?, ?, 'failure', ?, NULL, NULL, ?)
    `).run(idempotencyKeyDigest, requestHash, registrationId, reason, now);
    return { outcome: "rejected", value: new RegistrationError("REGISTRATION_REJECTED", reason) };
  }

  private readCompletedRegistration(userId: string, sessionId: string) {
    const row = this.database.prepare(`
      SELECT
        u.user_id, p.creator_name, p.social_id, c.available_balance,
        c.reserved_balance, s.session_id, s.expires_at
      FROM users u
      JOIN user_profiles p ON p.user_id = u.user_id
      JOIN credit_accounts c ON c.user_id = u.user_id
      JOIN sessions s ON s.user_id = u.user_id
      WHERE u.user_id = ? AND s.session_id = ?
    `).get(userId, sessionId) as UserResultRow | undefined;
    if (!row) throw new RegistrationError("REGISTRATION_REJECTED", "challenge_invalid");
    return this.result(row);
  }

  private loginResult(result: RegistrationCompleteResult): LoginCompleteResult {
    return {
      audience: "user",
      credits: result.credits,
      sessionExpiresAt: result.sessionExpiresAt,
      sessionToken: result.sessionToken,
      status: "authenticated",
      user: result.user,
    };
  }

  private result(row: UserResultRow): RegistrationCompleteResult {
    return {
      credits: { availableBalance: row.available_balance, reservedBalance: row.reserved_balance },
      sessionExpiresAt: row.expires_at,
      sessionToken: this.sessionToken(row.session_id),
      status: "registered",
      user: {
        creatorName: row.creator_name,
        role: "user",
        socialId: row.social_id,
        status: "active",
        userId: row.user_id,
      },
    };
  }
}
