-- migrate:no-foreign-keys
--
-- §22 three-tier — S3. Admit a *global*-scope grant to the memberships table.
--
-- §B.2's resolver folds four layers (global → project → collection → per-entry).
-- Migration 029 created `memberships` with scope_type ∈ {project, collection}
-- only; the global tier was left to S3. A global grant is how a "global RFC
-- Contributor" (a contributor who may propose in every collection of every
-- project, distinct from a deployment owner/admin) is represented — see
-- docs/design/2026-06-05-three-tier-projects-collections.md §B.2/§B.3 and the
-- C.1 "cleo" scenario.
--
-- SQLite can't ALTER a CHECK constraint in place, so the table is rebuilt by the
-- create-copy-drop-rename procedure (the 028/029 pattern). The global scope uses
-- a stable sentinel scope_id of '*' (one global tier per deployment); the
-- UNIQUE(scope_type, scope_id, user_id) then admits exactly one global grant per
-- user, mirroring the project/collection rows.

CREATE TABLE memberships__new (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    scope_type  TEXT NOT NULL CHECK (scope_type IN ('global', 'project', 'collection')),
    scope_id    TEXT NOT NULL,
    user_id     INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    role        TEXT NOT NULL CHECK (role IN ('owner', 'contributor')),
    granted_by  INTEGER REFERENCES users(id) ON DELETE SET NULL,
    granted_at  TEXT NOT NULL DEFAULT (datetime('now')),
    UNIQUE (scope_type, scope_id, user_id)
);
INSERT INTO memberships__new (id, scope_type, scope_id, user_id, role, granted_by, granted_at)
SELECT id, scope_type, scope_id, user_id, role, granted_by, granted_at FROM memberships;
DROP TABLE memberships;
ALTER TABLE memberships__new RENAME TO memberships;
CREATE INDEX idx_memberships_user ON memberships(user_id);
CREATE INDEX idx_memberships_scope ON memberships(scope_type, scope_id);
