-- CreateSchema
CREATE SCHEMA IF NOT EXISTS "audit";

-- CreateEnum
CREATE TYPE "audit"."AuditAudience" AS ENUM ('workforce', 'customer');

-- CreateEnum
CREATE TYPE "audit"."AuditOutcome" AS ENUM ('success', 'failure', 'denied');

-- CreateTable
CREATE TABLE "audit"."events" (
    "id" UUID NOT NULL,
    "created_at" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "event_type" TEXT NOT NULL,
    "audience" "audit"."AuditAudience" NOT NULL,
    "actor_id_hash" TEXT,
    "trace_id" TEXT,
    "subject" TEXT,
    "outcome" "audit"."AuditOutcome" NOT NULL,
    "payload" JSONB,

    CONSTRAINT "events_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE INDEX "events_created_at_idx" ON "audit"."events"("created_at");

-- CreateIndex
CREATE INDEX "events_event_type_idx" ON "audit"."events"("event_type");

-- CreateIndex
CREATE INDEX "events_trace_id_idx" ON "audit"."events"("trace_id");

-- ============================================================
-- Append-only contract per ADR-0013
-- ============================================================
-- The schema-level DEFAULT PRIVILEGES set in
-- infra/local/init/postgres/01-init.sql only fire when audit_owner
-- creates the object. This migration runs as a privileged migrator
-- (the same login that owns the public schema), so the table is
-- initially owned by that user and audit_writer/reader/archiver
-- have no grants. Re-apply the owner transfer + grants explicitly
-- so the runtime role contract holds.

ALTER TABLE "audit"."events" OWNER TO audit_owner;
ALTER TYPE "audit"."AuditAudience" OWNER TO audit_owner;
ALTER TYPE "audit"."AuditOutcome" OWNER TO audit_owner;

GRANT INSERT ON "audit"."events" TO audit_writer;
GRANT SELECT ON "audit"."events" TO audit_reader;
-- audit_archiver needs both DELETE *and* SELECT: per ADR-0013 it
-- removes rows "older than retention", which means evaluating a
-- WHERE clause on `created_at`. Postgres requires SELECT on every
-- column referenced in DELETE's WHERE, even when the row count is
-- the only thing returned. SELECT here does NOT widen the contract
-- — UPDATE / TRUNCATE remain ungranted to every role.
GRANT SELECT, DELETE ON "audit"."events" TO audit_archiver;

-- USAGE on the enum types is needed by every role that touches the
-- column. Without it, audit_writer's INSERT fails with "permission
-- denied for type audit.AuditAudience".
GRANT USAGE ON TYPE "audit"."AuditAudience" TO audit_writer, audit_reader, audit_archiver;
GRANT USAGE ON TYPE "audit"."AuditOutcome" TO audit_writer, audit_reader, audit_archiver;

-- No GRANT for UPDATE / TRUNCATE to anyone, including audit_owner
-- at runtime — schema migrations alone amend the table going
-- forward.
