From ffad0051f928395387714e55b3fc5230c91d8966 Mon Sep 17 00:00:00 2001 From: ZGaetano Date: Mon, 18 May 2026 23:23:23 -0400 Subject: [PATCH] feat: migrate groups/tokens schema into auto-run migrations directory Moved from schema_patch_groups_tokens.sql. All statements are idempotent (IF NOT EXISTS / CREATE INDEX IF NOT EXISTS) so safe to re-apply. --- .../src/db/migrations/002-groups-tokens.sql | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 services/mam-api/src/db/migrations/002-groups-tokens.sql diff --git a/services/mam-api/src/db/migrations/002-groups-tokens.sql b/services/mam-api/src/db/migrations/002-groups-tokens.sql new file mode 100644 index 0000000..cd545bd --- /dev/null +++ b/services/mam-api/src/db/migrations/002-groups-tokens.sql @@ -0,0 +1,36 @@ +-- Wild Dragon MAM – Groups & API Tokens +-- Idempotent: safe to re-run (IF NOT EXISTS guards throughout) + +-- User groups +CREATE TABLE IF NOT EXISTS groups ( + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + name TEXT UNIQUE NOT NULL, + description TEXT, + created_at TIMESTAMPTZ DEFAULT NOW() +); + +-- User ↔ group memberships +CREATE TABLE IF NOT EXISTS user_groups ( + user_id UUID NOT NULL REFERENCES users ON DELETE CASCADE, + group_id UUID NOT NULL REFERENCES groups ON DELETE CASCADE, + PRIMARY KEY (user_id, group_id) +); + +-- Personal API tokens (Bearer auth alternative to session cookies) +-- token_hash : SHA-256(raw_token) stored as hex +-- token_prefix: first 8 chars of raw token for display only +CREATE TABLE IF NOT EXISTS api_tokens ( + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + user_id UUID NOT NULL REFERENCES users ON DELETE CASCADE, + name TEXT NOT NULL, + token_hash TEXT NOT NULL UNIQUE, + token_prefix TEXT NOT NULL, + last_used_at TIMESTAMPTZ, + expires_at TIMESTAMPTZ, + created_at TIMESTAMPTZ DEFAULT NOW() +); + +CREATE INDEX IF NOT EXISTS idx_api_tokens_user_id ON api_tokens(user_id); +CREATE INDEX IF NOT EXISTS idx_api_tokens_hash ON api_tokens(token_hash); +CREATE INDEX IF NOT EXISTS idx_user_groups_user ON user_groups(user_id); +CREATE INDEX IF NOT EXISTS idx_user_groups_group ON user_groups(group_id);