import { Migration } from '../migrate.js' /** * API keys table for client/partner API access (key hash, tenant_id, scopes). * Used by X-API-Key auth for /api/v1/* and Phoenix API Railing. */ export const up: Migration['up'] = async (db) => { await db.query(` CREATE TABLE IF NOT EXISTS api_keys ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), name VARCHAR(255) NOT NULL, key_prefix VARCHAR(20) NOT NULL, key_hash VARCHAR(255) NOT NULL UNIQUE, user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, tenant_id UUID REFERENCES tenants(id) ON DELETE SET NULL, permissions JSONB DEFAULT '["read", "write"]'::jsonb, last_used_at TIMESTAMP WITH TIME ZONE, expires_at TIMESTAMP WITH TIME ZONE, revoked BOOLEAN NOT NULL DEFAULT false, revoked_at TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ) `) await db.query(`CREATE INDEX IF NOT EXISTS idx_api_keys_user_id ON api_keys(user_id)`) await db.query(`CREATE INDEX IF NOT EXISTS idx_api_keys_tenant_id ON api_keys(tenant_id)`) await db.query(`CREATE INDEX IF NOT EXISTS idx_api_keys_key_hash ON api_keys(key_hash)`) await db.query(`CREATE INDEX IF NOT EXISTS idx_api_keys_revoked ON api_keys(revoked) WHERE revoked = false`) await db.query(` DROP TRIGGER IF EXISTS update_api_keys_updated_at ON api_keys `) await db.query(` CREATE TRIGGER update_api_keys_updated_at BEFORE UPDATE ON api_keys FOR EACH ROW EXECUTE FUNCTION update_updated_at_column() `) } export const down: Migration['down'] = async (db) => { await db.query(`DROP TRIGGER IF EXISTS update_api_keys_updated_at ON api_keys`) await db.query(`DROP INDEX IF EXISTS idx_api_keys_revoked`) await db.query(`DROP INDEX IF EXISTS idx_api_keys_key_hash`) await db.query(`DROP INDEX IF EXISTS idx_api_keys_tenant_id`) await db.query(`DROP INDEX IF EXISTS idx_api_keys_user_id`) await db.query(`DROP TABLE IF EXISTS api_keys`) }