Remove local auth and user-management endpoints in favor of Keycloak-backed metadata users, project context, admin metadata APIs, and agent auth context.
63 lines
2.4 KiB
SQL
63 lines
2.4 KiB
SQL
-- Metadata auth management schema patch.
|
|
-- Keycloak owns login credentials; TJWater stores only business identity and access.
|
|
|
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
|
|
|
DO $$
|
|
DECLARE
|
|
users_id_type text;
|
|
BEGIN
|
|
SELECT data_type INTO users_id_type
|
|
FROM information_schema.columns
|
|
WHERE table_schema = 'public'
|
|
AND table_name = 'users'
|
|
AND column_name = 'id';
|
|
|
|
IF users_id_type IS NULL THEN
|
|
CREATE TABLE users (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
keycloak_id UUID UNIQUE NOT NULL,
|
|
username VARCHAR(50) UNIQUE NOT NULL,
|
|
email VARCHAR(100) UNIQUE NOT NULL,
|
|
role VARCHAR(20) DEFAULT 'user' NOT NULL,
|
|
is_active BOOLEAN DEFAULT TRUE NOT NULL,
|
|
is_superuser BOOLEAN DEFAULT FALSE NOT NULL,
|
|
attributes JSONB,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
|
last_login_at TIMESTAMP WITH TIME ZONE
|
|
);
|
|
ELSIF users_id_type <> 'uuid' THEN
|
|
RAISE EXCEPTION
|
|
'Existing public.users.id is %, not uuid. Export old local users, create Keycloak accounts, then migrate to metadata UUID users before applying this patch.',
|
|
users_id_type;
|
|
END IF;
|
|
END $$;
|
|
|
|
ALTER TABLE users
|
|
ADD COLUMN IF NOT EXISTS keycloak_id UUID,
|
|
ADD COLUMN IF NOT EXISTS attributes JSONB,
|
|
ADD COLUMN IF NOT EXISTS last_login_at TIMESTAMP WITH TIME ZONE;
|
|
|
|
ALTER TABLE users
|
|
ALTER COLUMN role SET DEFAULT 'user';
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_keycloak_id ON users(keycloak_id);
|
|
CREATE INDEX IF NOT EXISTS idx_users_role ON users(role);
|
|
CREATE INDEX IF NOT EXISTS idx_users_is_active ON users(is_active);
|
|
|
|
CREATE TABLE IF NOT EXISTS user_project_membership (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL,
|
|
project_id UUID NOT NULL,
|
|
project_role VARCHAR(20) DEFAULT 'viewer' NOT NULL,
|
|
CONSTRAINT user_project_membership_role_check
|
|
CHECK (project_role IN ('owner', 'admin', 'member', 'viewer')),
|
|
CONSTRAINT user_project_membership_unique UNIQUE (user_id, project_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_user_project_membership_user_id
|
|
ON user_project_membership(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_user_project_membership_project_id
|
|
ON user_project_membership(project_id);
|