-- V1 runtime extension tables. The local fixture adapter mirrors these records -- in Store maps; production repositories must make these tables authoritative. -- payment_events is created by 0004 and reconciled by 0006. Keep this -- migration additive so fresh and upgraded databases share one schema. ALTER TABLE IF EXISTS payment_events ADD COLUMN IF NOT EXISTS external_event_id TEXT; CREATE UNIQUE INDEX IF NOT EXISTS payment_events_provider_external_idx_v1 ON payment_events(provider, external_event_id) WHERE external_event_id IS NOT NULL; CREATE TABLE IF NOT EXISTS admin_idempotency ( actor_id TEXT NOT NULL, route TEXT NOT NULL, idem_key TEXT NOT NULL, request_fingerprint TEXT NOT NULL, state TEXT NOT NULL, status_code INTEGER, response JSONB, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (actor_id, route, idem_key) ); CREATE TABLE IF NOT EXISTS admin_approval_requests ( id UUID PRIMARY KEY, kind TEXT NOT NULL, requester_id TEXT NOT NULL, approver_id TEXT, status TEXT NOT NULL, payload JSONB NOT NULL, reason TEXT NOT NULL, version INTEGER NOT NULL DEFAULT 1, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), expires_at TIMESTAMPTZ NOT NULL, approved_at TIMESTAMPTZ, executed_at TIMESTAMPTZ, CHECK (approver_id IS NULL OR approver_id <> requester_id) ); CREATE TABLE IF NOT EXISTS plan_purchases ( id UUID PRIMARY KEY, user_id UUID NOT NULL, plan_id UUID NOT NULL, plan_version INTEGER NOT NULL, status TEXT NOT NULL, purchase_amount BIGINT NOT NULL, included_balance BIGINT NOT NULL, idempotency_key TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), paid_at TIMESTAMPTZ, UNIQUE (user_id, idempotency_key) ); CREATE TABLE IF NOT EXISTS reserve_allocations ( user_id UUID NOT NULL, reference_id UUID NOT NULL, bucket_id UUID NOT NULL, amount BIGINT NOT NULL, PRIMARY KEY (user_id, reference_id, bucket_id) );