This commit is contained in:
2026-03-19 18:00:46 +07:00
commit f72ad2769f
98 changed files with 9299 additions and 0 deletions

137
infra/init/001-control.sql Normal file
View File

@@ -0,0 +1,137 @@
create extension if not exists "pgcrypto";
create table if not exists users (
id uuid primary key default gen_random_uuid(),
username text unique not null,
password_hash text not null,
is_active boolean not null default true,
is_locked boolean not null default false,
created_at timestamptz not null default now()
);
create table if not exists roles (
id uuid primary key default gen_random_uuid(),
slug text unique not null,
name text not null,
description text not null default '',
created_at timestamptz not null default now()
);
create table if not exists permissions (
id uuid primary key default gen_random_uuid(),
resource text not null,
action text not null,
unique (resource, action)
);
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,
scope_type text not null default 'global',
scope_value text null
);
create unique index if not exists role_permissions_scope_uidx
on role_permissions (role_id, permission_id, scope_type, coalesce(scope_value, ''));
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,
primary key (user_id, role_id)
);
create table if not exists resource_groups (
id uuid primary key default gen_random_uuid(),
slug text unique not null,
name text not null
);
create table if not exists resource_group_tables (
group_id uuid not null references resource_groups(id) on delete cascade,
table_name text not null,
primary key (group_id, table_name)
);
create table if not exists sessions (
id uuid primary key default gen_random_uuid(),
user_id uuid not null references users(id) on delete cascade,
token_hash text not null unique,
expires_at timestamptz not null,
ip text null,
user_agent text null,
created_at timestamptz not null default now()
);
create table if not exists audit_events (
id uuid primary key default gen_random_uuid(),
created_at timestamptz not null default now(),
actor_user_id uuid null references users(id) on delete set null,
action text not null,
resource_type text not null,
resource_name text null,
group_id text null,
target_connection_id text null,
sql_text_masked text null,
payload_before jsonb null,
payload_after jsonb null,
ip text null,
user_agent text null,
status text not null
);
create table if not exists db_connections (
id uuid primary key default gen_random_uuid(),
name text not null,
host text not null,
port integer not null,
database_name text not null,
is_default boolean not null default false,
created_at timestamptz not null default now()
);
insert into permissions (resource, action) values
('database', 'read'),
('database', 'write'),
('database', 'delete'),
('database', 'schema_change'),
('group', 'read'),
('group', 'write'),
('group', 'delete'),
('group', 'schema_change'),
('table', 'read'),
('table', 'write'),
('table', 'delete'),
('table', 'schema_change'),
('sql_console', 'execute_sql'),
('logs', 'view_logs'),
('users', 'manage_users'),
('roles', 'manage_roles'),
('audit', 'read')
on conflict do nothing;
insert into roles (slug, name, description) values
('root', 'Root', 'Full access to the control plane'),
('folder_admin', 'Folder Admin', 'Admin for selected groups'),
('user', 'User', 'Read-only or restricted access')
on conflict do nothing;
insert into resource_groups (slug, name) values
('finance', 'Finance'),
('users', 'Users'),
('logs', 'Logs')
on conflict do nothing;
insert into resource_group_tables (group_id, table_name)
select g.id, x.table_name
from (
values
('finance', 'finance__invoices'),
('users', 'users__accounts'),
('logs', 'logs__events')
) as x(group_slug, table_name)
join resource_groups g on g.slug = x.group_slug
on conflict do nothing;
insert into db_connections (name, host, port, database_name, is_default)
values ('Default Target DB', 'postgres-target', 5432, 'appdb', true)
on conflict do nothing;

View File

@@ -0,0 +1,25 @@
do $$
declare
root_role_id uuid;
root_user_id uuid;
begin
select id into root_role_id from roles where slug = 'root';
insert into users (username, password_hash)
values (
'root',
'pbkdf2$sha256$210000$pgadmin-root-seed$2dd2c2adeb3a7f89d8dac01f5f991bdf8d674231ac200f4281552e506452df95'
)
on conflict (username) do nothing;
select id into root_user_id from users where username = 'root';
insert into user_roles (user_id, role_id)
values (root_user_id, root_role_id)
on conflict do nothing;
insert into role_permissions (role_id, permission_id, scope_type, scope_value)
select root_role_id, id, 'global', null
from permissions
on conflict do nothing;
end $$;

43
infra/init/010-target.sql Normal file
View File

@@ -0,0 +1,43 @@
create extension if not exists "pgcrypto";
create table if not exists finance__invoices (
id uuid primary key default gen_random_uuid(),
customer_name text not null,
amount numeric(12,2) not null,
status text not null default 'draft',
created_at timestamptz not null default now()
);
create table if not exists users__accounts (
id uuid primary key default gen_random_uuid(),
email text not null unique,
full_name text not null,
is_active boolean not null default true,
created_at timestamptz not null default now()
);
create table if not exists logs__events (
id uuid primary key default gen_random_uuid(),
source text not null,
level text not null,
message text not null,
created_at timestamptz not null default now()
);
insert into finance__invoices (customer_name, amount, status)
values
('Acme Corp', 1200.50, 'paid'),
('Northwind', 340.00, 'draft')
on conflict do nothing;
insert into users__accounts (email, full_name, is_active)
values
('root@example.com', 'Root Operator', true),
('analyst@example.com', 'Financial Analyst', true)
on conflict do nothing;
insert into logs__events (source, level, message)
values
('system', 'info', 'Bootstrap completed'),
('postgres', 'warn', 'Autovacuum threshold reached')
on conflict do nothing;