diff --git a/src/main/resources/db/migration/V001__create_users_table.sql b/src/main/resources/db/migration/V001__create_users_table.sql new file mode 100644 index 0000000..e828ff1 --- /dev/null +++ b/src/main/resources/db/migration/V001__create_users_table.sql @@ -0,0 +1,12 @@ +CREATE TABLE users ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + email VARCHAR(255) NOT NULL UNIQUE, + password VARCHAR(255) NOT NULL, + name VARCHAR(255) NOT NULL, + status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE', + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE INDEX idx_users_email ON users (email); +CREATE INDEX idx_users_status ON users (status); diff --git a/src/main/resources/db/migration/V002__create_roles_and_permissions.sql b/src/main/resources/db/migration/V002__create_roles_and_permissions.sql new file mode 100644 index 0000000..f2a65d5 --- /dev/null +++ b/src/main/resources/db/migration/V002__create_roles_and_permissions.sql @@ -0,0 +1,25 @@ +CREATE TABLE roles ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + name VARCHAR(50) NOT NULL UNIQUE, + description VARCHAR(255), + built_in BOOLEAN NOT NULL DEFAULT false, + created_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE TABLE permissions ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + name VARCHAR(100) NOT NULL UNIQUE, + description VARCHAR(255) +); + +CREATE TABLE role_permissions ( + role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE, + permission_id UUID NOT NULL REFERENCES permissions(id) ON DELETE CASCADE, + PRIMARY KEY (role_id, permission_id) +); + +CREATE TABLE user_roles ( + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE, + PRIMARY KEY (user_id, role_id) +); diff --git a/src/main/resources/db/migration/V003__seed_default_roles.sql b/src/main/resources/db/migration/V003__seed_default_roles.sql new file mode 100644 index 0000000..bf67750 --- /dev/null +++ b/src/main/resources/db/migration/V003__seed_default_roles.sql @@ -0,0 +1,37 @@ +-- Permissions +INSERT INTO permissions (id, name, description) VALUES + ('00000000-0000-0000-0000-000000000001', 'tenant:manage', 'Full tenant administration'), + ('00000000-0000-0000-0000-000000000002', 'billing:manage', 'Manage billing and subscriptions'), + ('00000000-0000-0000-0000-000000000003', 'team:manage', 'Manage team members and roles'), + ('00000000-0000-0000-0000-000000000004', 'apps:manage', 'Deploy, configure, and manage applications'), + ('00000000-0000-0000-0000-000000000005', 'apps:deploy', 'Deploy and promote applications'), + ('00000000-0000-0000-0000-000000000006', 'secrets:manage', 'Create and rotate secrets'), + ('00000000-0000-0000-0000-000000000007', 'observe:read', 'View traces, topology, dashboards'), + ('00000000-0000-0000-0000-000000000008', 'observe:debug', 'Use debugger and replay'), + ('00000000-0000-0000-0000-000000000009', 'settings:manage', 'Manage tenant settings'); + +-- Roles +INSERT INTO roles (id, name, description, built_in) VALUES + ('10000000-0000-0000-0000-000000000001', 'OWNER', 'Full tenant admin including billing and deletion', true), + ('10000000-0000-0000-0000-000000000002', 'ADMIN', 'Manage apps, secrets, team. No billing.', true), + ('10000000-0000-0000-0000-000000000003', 'DEVELOPER', 'Deploy apps, view traces, use debugger.', true), + ('10000000-0000-0000-0000-000000000004', 'VIEWER', 'Read-only access to dashboards and traces.', true); + +-- Owner: all permissions +INSERT INTO role_permissions (role_id, permission_id) +SELECT '10000000-0000-0000-0000-000000000001', id FROM permissions; + +-- Admin: everything except billing and tenant management +INSERT INTO role_permissions (role_id, permission_id) +SELECT '10000000-0000-0000-0000-000000000002', id FROM permissions +WHERE name NOT IN ('tenant:manage', 'billing:manage'); + +-- Developer: apps, secrets, observe (including debug) +INSERT INTO role_permissions (role_id, permission_id) +SELECT '10000000-0000-0000-0000-000000000003', id FROM permissions +WHERE name IN ('apps:deploy', 'secrets:manage', 'observe:read', 'observe:debug'); + +-- Viewer: observe read-only +INSERT INTO role_permissions (role_id, permission_id) +SELECT '10000000-0000-0000-0000-000000000004', id FROM permissions +WHERE name = 'observe:read';