Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I99349ba4b389b525d66d0109a66243736a6a6964
72 lines
3.2 KiB
SQL
72 lines
3.2 KiB
SQL
-- Migration 008: User Management Core
|
|
-- Adds user accounts, starred jobs, and project membership tables
|
|
|
|
-- User accounts for authentication and personalization
|
|
CREATE TABLE users (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
username VARCHAR(255) NOT NULL UNIQUE,
|
|
email VARCHAR(255) NOT NULL UNIQUE,
|
|
full_name VARCHAR(255),
|
|
password_hash VARCHAR(255), -- NULL for OAuth-only users
|
|
user_type VARCHAR(50) NOT NULL DEFAULT 'local', -- 'local', 'github', 'google'
|
|
role VARCHAR(50) NOT NULL DEFAULT 'read-only',
|
|
enabled BOOLEAN NOT NULL DEFAULT true,
|
|
email_verified BOOLEAN NOT NULL DEFAULT false,
|
|
public_dashboard BOOLEAN NOT NULL DEFAULT false,
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
last_login_at TIMESTAMP WITH TIME ZONE
|
|
);
|
|
|
|
-- Link API keys to users for audit trail
|
|
ALTER TABLE api_keys ADD COLUMN user_id UUID REFERENCES users(id) ON DELETE SET NULL;
|
|
|
|
-- Starred jobs for personalized dashboard
|
|
CREATE TABLE starred_jobs (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
jobset_id UUID REFERENCES jobsets(id) ON DELETE CASCADE,
|
|
job_name VARCHAR(255) NOT NULL,
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
UNIQUE(user_id, project_id, jobset_id, job_name)
|
|
);
|
|
|
|
-- User sessions for persistent authentication across restarts
|
|
CREATE TABLE user_sessions (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
session_token_hash VARCHAR(255) NOT NULL, -- Hashed session token
|
|
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
last_used_at TIMESTAMP WITH TIME ZONE
|
|
);
|
|
|
|
-- Project membership for per-project permissions
|
|
CREATE TABLE project_members (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
role VARCHAR(50) NOT NULL DEFAULT 'member', -- 'member', 'maintainer', 'admin'
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
UNIQUE(project_id, user_id)
|
|
);
|
|
|
|
-- Indexes for performance
|
|
CREATE INDEX idx_users_username ON users(username);
|
|
CREATE INDEX idx_users_email ON users(email);
|
|
CREATE INDEX idx_users_role ON users(role);
|
|
CREATE INDEX idx_users_enabled ON users(enabled);
|
|
CREATE INDEX idx_api_keys_user_id ON api_keys(user_id);
|
|
CREATE INDEX idx_starred_jobs_user_id ON starred_jobs(user_id);
|
|
CREATE INDEX idx_starred_jobs_project_id ON starred_jobs(project_id);
|
|
CREATE INDEX idx_user_sessions_token ON user_sessions(session_token_hash);
|
|
CREATE INDEX idx_user_sessions_user_id ON user_sessions(user_id);
|
|
CREATE INDEX idx_user_sessions_expires ON user_sessions(expires_at);
|
|
CREATE INDEX idx_project_members_project_id ON project_members(project_id);
|
|
CREATE INDEX idx_project_members_user_id ON project_members(user_id);
|
|
|
|
-- Trigger for updated_at on users
|
|
CREATE TRIGGER update_users_updated_at
|
|
BEFORE UPDATE ON users
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|