diff --git a/ddl/schemas/users/tables/02-roles.sql b/ddl/schemas/users/tables/02-roles.sql index 63d3e59..932380b 100644 --- a/ddl/schemas/users/tables/02-roles.sql +++ b/ddl/schemas/users/tables/02-roles.sql @@ -10,11 +10,13 @@ CREATE TABLE users.roles ( tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE, name VARCHAR(100) NOT NULL, + code VARCHAR(50) NOT NULL, -- Short code for programmatic use slug VARCHAR(100) NOT NULL, description TEXT, -- System role (cannot be deleted) is_system BOOLEAN DEFAULT FALSE, + is_active BOOLEAN DEFAULT TRUE, -- Permissions (JSONB array) permissions JSONB DEFAULT '[]'::jsonb, @@ -24,13 +26,18 @@ CREATE TABLE users.roles ( parent_role_id UUID REFERENCES users.roles(id), level INT DEFAULT 0, -- 0 = lowest, higher = more permissions + -- Metadata + metadata JSONB DEFAULT '{}'::jsonb, + -- Audit created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL, updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL, created_by UUID, -- Constraints + CONSTRAINT unique_role_code_per_tenant UNIQUE (tenant_id, code), CONSTRAINT unique_role_slug_per_tenant UNIQUE (tenant_id, slug), + CONSTRAINT valid_role_code CHECK (code ~ '^[A-Z][A-Z0-9_]*$'), CONSTRAINT valid_role_slug CHECK (slug ~ '^[a-z][a-z0-9_]*$') ); @@ -71,7 +78,9 @@ CREATE TABLE users.permissions ( -- Indexes CREATE INDEX idx_roles_tenant ON users.roles(tenant_id); +CREATE INDEX idx_roles_code ON users.roles(tenant_id, code); CREATE INDEX idx_roles_slug ON users.roles(tenant_id, slug); +CREATE INDEX idx_roles_active ON users.roles(tenant_id, is_active) WHERE is_active = TRUE; CREATE INDEX idx_user_roles_user ON users.user_roles(user_id); CREATE INDEX idx_user_roles_role ON users.user_roles(role_id); CREATE INDEX idx_user_roles_tenant ON users.user_roles(tenant_id);