chore: consolidate full database schema into single init_schema.sql
This commit is contained in:
@@ -7,6 +7,15 @@ BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'record_status') THEN
|
||||
CREATE TYPE record_status AS ENUM ('active','inactive');
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'client_status') THEN
|
||||
CREATE TYPE client_status AS ENUM ('active','inactive');
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'scope_type') THEN
|
||||
CREATE TYPE scope_type AS ENUM ('company','site');
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'permission_action') THEN
|
||||
CREATE TYPE permission_action AS ENUM ('view','create','update','delete','manage');
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
@@ -22,6 +31,14 @@ CREATE TABLE IF NOT EXISTS users (
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS auth_sync_state (
|
||||
user_id UUID PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
||||
last_synced_at TIMESTAMPTZ,
|
||||
source_version TEXT,
|
||||
last_error TEXT,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS companies (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
company_key TEXT NOT NULL UNIQUE,
|
||||
@@ -31,6 +48,16 @@ CREATE TABLE IF NOT EXISTS companies (
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sites (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
site_key TEXT NOT NULL UNIQUE,
|
||||
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
status record_status NOT NULL DEFAULT 'active',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS systems (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
system_key TEXT NOT NULL UNIQUE,
|
||||
@@ -49,27 +76,19 @@ CREATE TABLE IF NOT EXISTS modules (
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sites (
|
||||
-- legacy table: 保留相容舊流程
|
||||
CREATE TABLE IF NOT EXISTS permissions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
site_key TEXT NOT NULL UNIQUE,
|
||||
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
status record_status NOT NULL DEFAULT 'active',
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
scope_type VARCHAR(32) NOT NULL,
|
||||
scope_id VARCHAR(128) NOT NULL,
|
||||
module VARCHAR(128) NOT NULL,
|
||||
action VARCHAR(32) NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
CONSTRAINT uq_permissions_user_scope_module_action
|
||||
UNIQUE (user_id, scope_type, scope_id, module, action)
|
||||
);
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'scope_type') THEN
|
||||
CREATE TYPE scope_type AS ENUM ('company','site');
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'permission_action') THEN
|
||||
CREATE TYPE permission_action AS ENUM ('view','create','update','delete','manage');
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_scope_permissions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
@@ -90,14 +109,6 @@ ALTER TABLE user_scope_permissions
|
||||
OR (scope_type = 'site' AND site_id IS NOT NULL AND company_id IS NULL))
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_usp_company
|
||||
ON user_scope_permissions(user_id, module_id, action, scope_type, company_id)
|
||||
WHERE scope_type = 'company';
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_usp_site
|
||||
ON user_scope_permissions(user_id, module_id, action, scope_type, site_id)
|
||||
WHERE scope_type = 'site';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS permission_groups (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
group_key TEXT NOT NULL UNIQUE,
|
||||
@@ -123,17 +134,46 @@ CREATE TABLE IF NOT EXISTS permission_group_permissions (
|
||||
action TEXT NOT NULL,
|
||||
scope_type TEXT NOT NULL,
|
||||
scope_id TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT uq_pgp_group_rule UNIQUE (group_id, system, module, action, scope_type, scope_id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_pgp_group_rule
|
||||
ON permission_group_permissions(group_id, system, module, action, scope_type, scope_id);
|
||||
CREATE TABLE IF NOT EXISTS api_clients (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
client_key TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL,
|
||||
status client_status NOT NULL DEFAULT 'active',
|
||||
api_key_hash TEXT NOT NULL,
|
||||
allowed_origins JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
allowed_ips JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
allowed_paths JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
rate_limit_per_min INTEGER,
|
||||
expires_at TIMESTAMPTZ,
|
||||
last_used_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
INSERT INTO systems (system_key, name, status)
|
||||
VALUES ('member', 'Member Center', 'active')
|
||||
ON CONFLICT (system_key) DO NOTHING;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_users_authentik_sub ON users(authentik_sub);
|
||||
CREATE INDEX IF NOT EXISTS idx_sites_company_id ON sites(company_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_permissions_user_id ON permissions(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_usp_user_id ON user_scope_permissions(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_usp_module_id ON user_scope_permissions(module_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_usp_company_id ON user_scope_permissions(company_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_usp_site_id ON user_scope_permissions(site_id);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_usp_company
|
||||
ON user_scope_permissions(user_id, module_id, action, scope_type, company_id)
|
||||
WHERE scope_type = 'company';
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_usp_site
|
||||
ON user_scope_permissions(user_id, module_id, action, scope_type, site_id)
|
||||
WHERE scope_type = 'site';
|
||||
CREATE INDEX IF NOT EXISTS idx_api_clients_status ON api_clients(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_api_clients_expires_at ON api_clients(expires_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_systems_system_key ON systems(system_key);
|
||||
CREATE INDEX IF NOT EXISTS idx_modules_module_key ON modules(module_key);
|
||||
|
||||
COMMIT;
|
||||
|
||||
Reference in New Issue
Block a user