fix(sql): fix sql script
This commit is contained in:
117
scripts/db/migrations/0001_core.sql
Normal file
117
scripts/db/migrations/0001_core.sql
Normal file
@@ -0,0 +1,117 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tenants (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
status VARCHAR(50) DEFAULT 'active',
|
||||
config JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID NOT NULL REFERENCES tenants(id),
|
||||
email VARCHAR(255) NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
full_name VARCHAR(100),
|
||||
phone_number VARCHAR(20),
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
is_verified BOOLEAN DEFAULT FALSE,
|
||||
mfa_enabled BOOLEAN DEFAULT FALSE,
|
||||
mfa_secret VARCHAR(255),
|
||||
last_login_at TIMESTAMP WITH TIME ZONE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_tenant_email ON users(tenant_id, email);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS roles (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID NOT NULL REFERENCES tenants(id),
|
||||
name VARCHAR(50) NOT NULL,
|
||||
description TEXT,
|
||||
is_system BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
UNIQUE(tenant_id, name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS permissions (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
code VARCHAR(100) NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
resource VARCHAR(50),
|
||||
action VARCHAR(50),
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS role_permissions (
|
||||
role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
|
||||
permission_id UUID NOT NULL REFERENCES permissions(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
PRIMARY KEY (role_id, permission_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_roles (
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
PRIMARY KEY (user_id, role_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS refresh_tokens (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
token_hash VARCHAR(255) NOT NULL,
|
||||
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
is_revoked BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
replaced_by_token_hash VARCHAR(255)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user_id ON refresh_tokens(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_token_hash ON refresh_tokens(token_hash);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS audit_logs (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID REFERENCES tenants(id),
|
||||
user_id UUID,
|
||||
action VARCHAR(100) NOT NULL,
|
||||
resource VARCHAR(100),
|
||||
ip_address VARCHAR(45),
|
||||
user_agent TEXT,
|
||||
status VARCHAR(20) NOT NULL,
|
||||
details JSONB,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
INSERT INTO tenants (id, name)
|
||||
VALUES ('11111111-1111-1111-1111-111111111111', 'Default Corp')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO permissions (code, description, resource, action) VALUES
|
||||
('user:read', 'View users', 'user', 'read'),
|
||||
('user:write', 'Create/Update/Delete users', 'user', 'write'),
|
||||
('role:read', 'View roles', 'role', 'read'),
|
||||
('role:write', 'Manage roles', 'role', 'write'),
|
||||
('tenant:read', 'View tenant info', 'tenant', 'read'),
|
||||
('tenant:write', 'Manage tenant settings and status', 'tenant', 'write')
|
||||
ON CONFLICT (code) DO NOTHING;
|
||||
|
||||
INSERT INTO roles (tenant_id, name, description, is_system)
|
||||
VALUES ('11111111-1111-1111-1111-111111111111', 'Admin', 'Administrator with full access', TRUE)
|
||||
ON CONFLICT (tenant_id, name) DO NOTHING;
|
||||
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM roles r, permissions p
|
||||
WHERE r.name = 'Admin'
|
||||
AND r.tenant_id = '11111111-1111-1111-1111-111111111111'
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
COMMIT;
|
||||
|
||||
88
scripts/db/migrations/0002_enabled_apps.sql
Normal file
88
scripts/db/migrations/0002_enabled_apps.sql
Normal file
@@ -0,0 +1,88 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS apps (
|
||||
id VARCHAR(32) PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
description TEXT,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'active',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tenant_entitlements (
|
||||
tenant_id UUID PRIMARY KEY REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
enabled_apps TEXT[] NOT NULL DEFAULT '{}',
|
||||
version INTEGER NOT NULL DEFAULT 0,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tenant_enabled_apps_history (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
version INTEGER NOT NULL,
|
||||
enabled_apps TEXT[] NOT NULL,
|
||||
actor_user_id UUID,
|
||||
reason TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
INSERT INTO tenants (id, name, config)
|
||||
VALUES (
|
||||
'00000000-0000-0000-0000-000000000001',
|
||||
'Platform',
|
||||
jsonb_build_object('enabled_apps', jsonb_build_array(), 'enabled_apps_version', 0)
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO apps (id, name, description) VALUES
|
||||
('iam', 'IAM', 'Identity and Access Management'),
|
||||
('cms', 'CMS', 'Content Management Platform'),
|
||||
('tms', 'TMS', 'Task Management Platform')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO tenant_entitlements (tenant_id, enabled_apps, version)
|
||||
SELECT t.id, '{}'::text[], 0
|
||||
FROM tenants t
|
||||
ON CONFLICT (tenant_id) DO NOTHING;
|
||||
|
||||
UPDATE tenant_entitlements
|
||||
SET enabled_apps = ARRAY['tms']::text[]
|
||||
WHERE tenant_id = '11111111-1111-1111-1111-111111111111'
|
||||
AND enabled_apps = '{}'::text[];
|
||||
|
||||
UPDATE tenants
|
||||
SET config =
|
||||
jsonb_set(
|
||||
jsonb_set(COALESCE(config, '{}'::jsonb), '{enabled_apps}', to_jsonb(te.enabled_apps), true),
|
||||
'{enabled_apps_version}', to_jsonb(te.version), true
|
||||
)
|
||||
FROM tenant_entitlements te
|
||||
WHERE tenants.id = te.tenant_id;
|
||||
|
||||
INSERT INTO permissions (code, description, resource, action) VALUES
|
||||
('iam:tenant:enabled_apps:read', 'Read tenant enabled apps', 'tenant_enabled_apps', 'read'),
|
||||
('iam:tenant:enabled_apps:write', 'Manage tenant enabled apps', 'tenant_enabled_apps', 'write')
|
||||
ON CONFLICT (code) DO NOTHING;
|
||||
|
||||
INSERT INTO roles (tenant_id, name, description, is_system)
|
||||
VALUES ('00000000-0000-0000-0000-000000000001', 'SuperAdmin', 'Platform super administrator', TRUE)
|
||||
ON CONFLICT (tenant_id, name) DO NOTHING;
|
||||
|
||||
DELETE FROM role_permissions rp
|
||||
USING roles r, permissions p
|
||||
WHERE rp.role_id = r.id
|
||||
AND rp.permission_id = p.id
|
||||
AND r.name = 'Admin'
|
||||
AND r.tenant_id <> '00000000-0000-0000-0000-000000000001'
|
||||
AND p.code LIKE 'iam:%';
|
||||
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM roles r, permissions p
|
||||
WHERE r.name = 'SuperAdmin'
|
||||
AND r.tenant_id = '00000000-0000-0000-0000-000000000001'
|
||||
AND p.code IN ('iam:tenant:enabled_apps:read', 'iam:tenant:enabled_apps:write')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
COMMIT;
|
||||
|
||||
Reference in New Issue
Block a user