-- 003_invites.sql — single-use registration invites (issue: user accounts / wallet model).
--
-- An admin mints an invite so a brand-new identity can join the bus allowlist
-- WITHOUT the admin ever handling its private key. The token is the bearer
-- secret that authorizes POST /register: the registering client generates its
-- keypair locally and publishes only its public keys, fixing the link between an
-- invite and the identity it creates via the audit columns below. The handle and
-- role are fixed by the admin at mint time and cannot be changed by the client
-- (no privilege escalation).
--
-- Additive and idempotent: safe to apply repeatedly. Never modify this file;
-- further schema changes go in new numbered migrations (see
-- .claude/rules/db_migrations.md). The embedded copy under
-- pkg/membership/migrations/003_invites.sql mirrors this file byte-for-byte.

CREATE TABLE IF NOT EXISTS invites (
  token         TEXT PRIMARY KEY,                -- 32 random bytes in lowercase hex (the bearer secret)
  handle        TEXT NOT NULL,                   -- handle the new user will get (fixed by admin)
  role          TEXT NOT NULL DEFAULT 'member',  -- 'admin' | 'member' (fixed by admin)
  expires_at    TEXT NOT NULL,                   -- RFC3339; past this the invite is dead
  used          INTEGER NOT NULL DEFAULT 0,      -- 0 pending, 1 consumed (single-use)
  created_at    TEXT NOT NULL,
  used_at       TEXT,                            -- RFC3339 when consumed (NULL until used)
  used_sign_pub TEXT,                            -- Ed25519 key that consumed it (audit; NULL until used)
  used_kex_pub  TEXT                             -- X25519 key presented at registration (audit; NULL until used)
);

CREATE INDEX IF NOT EXISTS idx_invites_used ON invites(used);
