BEGIN;

CREATE TABLE IF NOT EXISTS tenants (
  tenant_id TEXT PRIMARY KEY,
  identifier TEXT UNIQUE NOT NULL,
  grouping_name TEXT NOT NULL,
  display_name TEXT,
  contact_email TEXT,
  lifecycle TEXT NOT NULL DEFAULT 'active'
    CHECK (lifecycle IN ('active', 'retired')),
  version BIGINT NOT NULL DEFAULT 1 CHECK (version > 0),
  -- Pre-lifecycle SQLite rows legitimately carry no timestamp. Nullable here
  -- preserves them exactly during the store move; new domain writes set both.
  created_at TIMESTAMPTZ,
  updated_at TIMESTAMPTZ,
  retired_at TIMESTAMPTZ,
  reactivated_at TIMESTAMPTZ
);

CREATE TABLE IF NOT EXISTS grants (
  grant_id TEXT PRIMARY KEY,
  tenant_id TEXT NOT NULL REFERENCES tenants(tenant_id),
  role TEXT NOT NULL,
  grant_reason TEXT NOT NULL,
  plan_id TEXT,
  granted_by TEXT NOT NULL,
  granted_at TIMESTAMPTZ NOT NULL,
  correlation_id TEXT NOT NULL,
  revoked_at TIMESTAMPTZ
);
CREATE INDEX IF NOT EXISTS grants_tenant_active_idx
  ON grants (tenant_id) WHERE revoked_at IS NULL;

CREATE TABLE IF NOT EXISTS plans (
  tenant_id TEXT PRIMARY KEY REFERENCES tenants(tenant_id),
  plan_id TEXT NOT NULL,
  assigned_at TIMESTAMPTZ NOT NULL
);

CREATE TABLE IF NOT EXISTS events (
  seq BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  event_type TEXT NOT NULL,
  tenant_id TEXT NOT NULL REFERENCES tenants(tenant_id),
  at TIMESTAMPTZ NOT NULL,
  payload JSONB NOT NULL
);
CREATE INDEX IF NOT EXISTS events_tenant_seq_idx ON events (tenant_id, seq);

CREATE TABLE IF NOT EXISTS idempotency_receipts (
  tenant_id TEXT NOT NULL REFERENCES tenants(tenant_id),
  idempotency_key TEXT NOT NULL,
  request_fingerprint TEXT NOT NULL,
  result JSONB NOT NULL,
  recorded_at TIMESTAMPTZ NOT NULL,
  PRIMARY KEY (tenant_id, idempotency_key)
);

CREATE TABLE IF NOT EXISTS guardrail_overrides (
  tenant_id TEXT NOT NULL REFERENCES tenants(tenant_id),
  limit_key TEXT NOT NULL,
  kind TEXT NOT NULL,
  amount TEXT NOT NULL,
  currency TEXT,
  period TEXT,
  PRIMARY KEY (tenant_id, limit_key)
);

CREATE TABLE IF NOT EXISTS guardrail_changes (
  change_id TEXT PRIMARY KEY,
  tenant_id TEXT NOT NULL REFERENCES tenants(tenant_id),
  limit_key TEXT NOT NULL,
  previous JSONB,
  current JSONB,
  changed_by TEXT NOT NULL,
  reason TEXT NOT NULL,
  correlation_id TEXT NOT NULL,
  changed_at TIMESTAMPTZ NOT NULL
);
CREATE INDEX IF NOT EXISTS guardrail_changes_tenant_time_idx
  ON guardrail_changes (tenant_id, changed_at, change_id);

COMMIT;
