trading-platform-database-v2/ddl/schemas/rbac/tables/001_roles.sql
rckrdmrd e520268348 Migración desde trading-platform/apps/database - Estándar multi-repo v2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 08:32:52 -06:00

177 lines
6.0 KiB
PL/PgSQL

-- ============================================================================
-- RBAC Schema: Roles Table
-- Role-Based Access Control for Trading Platform SaaS
-- ============================================================================
-- Create RBAC schema if not exists
CREATE SCHEMA IF NOT EXISTS rbac;
-- Grant usage
GRANT USAGE ON SCHEMA rbac TO trading_user;
-- ============================================================================
-- ROLES TABLE
-- Defines roles within a tenant organization
-- ============================================================================
CREATE TABLE IF NOT EXISTS rbac.roles (
-- Primary key
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
-- Tenant relationship (multi-tenancy)
tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,
-- Role information
name VARCHAR(100) NOT NULL,
slug VARCHAR(100) NOT NULL,
description TEXT,
-- Role type: system (predefined) or custom (tenant-created)
role_type VARCHAR(20) NOT NULL DEFAULT 'custom'
CHECK (role_type IN ('system', 'custom')),
-- Hierarchy level (lower = more permissions, 0 = super admin)
hierarchy_level INTEGER NOT NULL DEFAULT 100,
-- Status
is_active BOOLEAN NOT NULL DEFAULT true,
-- Role settings (JSON for extensibility)
settings JSONB NOT NULL DEFAULT '{}'::jsonb,
-- Audit fields
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_by UUID REFERENCES users.users(id),
updated_by UUID REFERENCES users.users(id),
-- Constraints
CONSTRAINT uq_roles_tenant_slug UNIQUE (tenant_id, slug),
CONSTRAINT uq_roles_tenant_name UNIQUE (tenant_id, name)
);
-- ============================================================================
-- INDEXES
-- ============================================================================
CREATE INDEX IF NOT EXISTS idx_roles_tenant_id ON rbac.roles(tenant_id);
CREATE INDEX IF NOT EXISTS idx_roles_slug ON rbac.roles(slug);
CREATE INDEX IF NOT EXISTS idx_roles_role_type ON rbac.roles(role_type);
CREATE INDEX IF NOT EXISTS idx_roles_is_active ON rbac.roles(is_active);
CREATE INDEX IF NOT EXISTS idx_roles_hierarchy ON rbac.roles(tenant_id, hierarchy_level);
-- ============================================================================
-- ROW LEVEL SECURITY
-- ============================================================================
ALTER TABLE rbac.roles ENABLE ROW LEVEL SECURITY;
-- Policy: Users can only see roles in their tenant
CREATE POLICY roles_tenant_isolation ON rbac.roles
FOR ALL
USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);
-- ============================================================================
-- TRIGGERS
-- ============================================================================
-- Auto-update updated_at timestamp
CREATE OR REPLACE FUNCTION rbac.update_roles_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_roles_updated_at
BEFORE UPDATE ON rbac.roles
FOR EACH ROW
EXECUTE FUNCTION rbac.update_roles_timestamp();
-- ============================================================================
-- DEFAULT SYSTEM ROLES (inserted per tenant)
-- These will be created when a new tenant is created
-- ============================================================================
-- Function to create default roles for a tenant
CREATE OR REPLACE FUNCTION rbac.create_default_roles(p_tenant_id UUID, p_owner_id UUID)
RETURNS void AS $$
BEGIN
-- Owner role (highest level)
INSERT INTO rbac.roles (tenant_id, name, slug, description, role_type, hierarchy_level, created_by)
VALUES (
p_tenant_id,
'Owner',
'owner',
'Full access to all features and settings. Can manage billing and delete organization.',
'system',
0,
p_owner_id
);
-- Admin role
INSERT INTO rbac.roles (tenant_id, name, slug, description, role_type, hierarchy_level, created_by)
VALUES (
p_tenant_id,
'Admin',
'admin',
'Administrative access. Can manage users, roles, and most settings.',
'system',
10,
p_owner_id
);
-- Manager role
INSERT INTO rbac.roles (tenant_id, name, slug, description, role_type, hierarchy_level, created_by)
VALUES (
p_tenant_id,
'Manager',
'manager',
'Can manage team members and view reports.',
'system',
50,
p_owner_id
);
-- Member role
INSERT INTO rbac.roles (tenant_id, name, slug, description, role_type, hierarchy_level, created_by)
VALUES (
p_tenant_id,
'Member',
'member',
'Standard user access. Can use platform features.',
'system',
100,
p_owner_id
);
-- Viewer role (read-only)
INSERT INTO rbac.roles (tenant_id, name, slug, description, role_type, hierarchy_level, created_by)
VALUES (
p_tenant_id,
'Viewer',
'viewer',
'Read-only access. Can view but not modify.',
'system',
200,
p_owner_id
);
END;
$$ LANGUAGE plpgsql;
-- ============================================================================
-- GRANTS
-- ============================================================================
GRANT SELECT, INSERT, UPDATE, DELETE ON rbac.roles TO trading_user;
-- ============================================================================
-- COMMENTS
-- ============================================================================
COMMENT ON TABLE rbac.roles IS 'Roles for Role-Based Access Control within tenant organizations';
COMMENT ON COLUMN rbac.roles.role_type IS 'system = predefined roles, custom = tenant-created roles';
COMMENT ON COLUMN rbac.roles.hierarchy_level IS 'Lower value = higher permissions. Owner=0, Admin=10, etc.';
COMMENT ON COLUMN rbac.roles.settings IS 'JSON settings for role customization';