Files
helix-server/database/init.d/init-en_GB.sql
T
2025-12-25 16:08:50 +08:00

324 lines
14 KiB
SQL

/**
* IMPORTANT NOTE ON DATABASE CREATION:
* * If you intend to create the database using a user other than the one specified
* for the application (e.g., 'system_admin' creating a database for 'app_user'),
* please ensure this SQL file is executed by the **corresponding database user**.
* * This is crucial for correctly setting up ownership and default privileges.
* * Example: CREATE DATABASE my_database OWNER app_user;
* * Ensure all necessary user roles and permissions are in place **prior** to
* running this initialisation script.
*/
--- Type Definitions ---
DROP TYPE IF EXISTS USER_STATUS CASCADE;
DROP TYPE IF EXISTS STATUS CASCADE;
DROP TYPE IF EXISTS IDENTITY_PROVIDER CASCADE;
DROP TYPE IF EXISTS SETTING_TYPE CASCADE;
CREATE TYPE USER_STATUS AS ENUM ('ACTIVE', 'INACTIVE', 'LOCKED');
CREATE TYPE STATUS AS ENUM ('ACTIVE', 'INACTIVE');
CREATE TYPE IDENTITY_PROVIDER AS ENUM ('LOCAL', 'OIDC', 'MICROSOFT_ENTRA_ID', 'GOOGLE_OIDC', 'SAML');
CREATE TYPE SETTING_TYPE AS ENUM ('STRING', 'BOOLEAN', 'INT');
--- Departments Table ---
DROP TABLE IF EXISTS departments CASCADE;
CREATE TABLE departments
(
id BIGSERIAL PRIMARY KEY,
name VARCHAR(128) NOT NULL UNIQUE,
parent_id BIGINT NULL REFERENCES departments (id),
sort INT NOT NULL DEFAULT NULL,
status STATUS NOT NULL DEFAULT 'ACTIVE'::STATUS,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX departments_name_index ON departments (name);
CREATE INDEX departments_parent_id_index ON departments (parent_id);
--- Departments Data Insertion ---
INSERT INTO departments (id, name, parent_id, sort, status)
VALUES (1, 'Company HQ', NULL, 1, 'ACTIVE'::STATUS),
(2, 'Human Resources', 1, 1, 'ACTIVE'::STATUS),
(3, 'Finance', 1, 2, 'ACTIVE'::STATUS),
(4, 'Technology', 1, 3, 'ACTIVE'::STATUS),
(5, 'IT Support', 4, 1, 'ACTIVE'::STATUS),
(6, 'Software Development', 4, 2, 'ACTIVE'::STATUS),
(7, 'Operations', 1, 4, 'INACTIVE'::STATUS);
--- Positions Table ---
DROP TABLE IF EXISTS positions CASCADE;
CREATE TABLE positions
(
id BIGSERIAL PRIMARY KEY,
name VARCHAR(128) NOT NULL UNIQUE,
code VARCHAR(64) NULL UNIQUE,
description TEXT,
sort INT NOT NULL DEFAULT 0,
status STATUS NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX positions_name_index ON positions (name);
CREATE INDEX positions_code_index ON positions (code);
CREATE INDEX positions_name_code_index ON positions (name, code);
--- Positions Data Insertion ---
INSERT INTO positions (id, name, code, description, sort, status)
VALUES (1, 'HR Manager', 'HR-MGR',
'Responsible for overseeing recruitment, employee relations, and staff wellbeing.', 1,
'ACTIVE'),
(2, 'Finance Officer', 'FIN-OFC',
'Handles accounts, prepares financial statements, and ensures compliance with regulations.',
2, 'ACTIVE'),
(3, 'IT Support Specialist', 'IT-SPT',
'Provides technical assistance, manages helpdesk queries, and maintains computer systems.',
3, 'ACTIVE'),
(4, 'Software Engineer', 'SWE-ENG',
'Develops and maintains in-house applications, ensuring code quality and system reliability.',
4, 'ACTIVE'),
(5, 'Operations Coordinator', 'OPS-CRD',
'Assists with day-to-day logistics, procurement, and office organisation.', 5, 'INACTIVE');
--- Users Table ---
DROP TABLE IF EXISTS users CASCADE;
CREATE TABLE users
(
id BIGINT PRIMARY KEY,
username VARCHAR(64) UNIQUE NOT NULL,
password VARCHAR(255),
full_name VARCHAR(128) NOT NULL,
email VARCHAR(128) UNIQUE,
region_code VARCHAR(10),
phone_number VARCHAR(32),
avatar_url TEXT,
status USER_STATUS NOT NULL DEFAULT 'ACTIVE',
department_id BIGINT REFERENCES departments (id),
position_id BIGINT REFERENCES positions (id),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX users_username_index ON users (username);
--- Users Table Indexes ---
CREATE UNIQUE INDEX uidx_users_region_abbreviation_phone_number
ON users (region_abbreviation, phone_number);
--- Users Data Insertion ---
-- NOTE: All phone numbers are generated by ChatGPT, they should not be connected any real person.
INSERT INTO users(id, username, password, full_name, email, region_abbreviation, phone_number, avatar_url,
department_id, position_id, created_at, updated_at)
VALUES (1, 'helix', null, 'Helix Admin', 'admin@helix.onixbyte.dev', 'GB', '7000000000',
'https://gravatar.com/avatar/6ef4c4033f6aa8e43d06bd5e462a6173cc2a960633473721a6f1289cd1b5146f',
1, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
(2, 'johndoe', null, 'John Doe', 'johndoe@helix.onixbyte.dev', 'GB', '7000000001',
'https://gravatar.com/avatar/41bcebddd573747d1bd35ef7fae72ebefd6b47f077d42442a2510d35b0c2db92',
6, 4, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
--- User Identities Table ---
DROP TABLE IF EXISTS user_identities CASCADE;
CREATE TABLE user_identities
(
user_id BIGINT NOT NULL REFERENCES users (id),
provider IDENTITY_PROVIDER NOT NULL,
external_id VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, provider, external_id)
);
--- Roles Table ---
DROP TABLE IF EXISTS roles CASCADE;
CREATE TABLE roles
(
id BIGSERIAL PRIMARY KEY,
name VARCHAR(128) NOT NULL UNIQUE,
code VARCHAR(64) NOT NULL UNIQUE,
sort INTEGER NOT NULL,
default_value BOOLEAN NOT NULL DEFAULT FALSE,
description TEXT,
status STATUS NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX roles_name_index ON roles (name);
CREATE INDEX roles_code_index ON roles (code);
CREATE INDEX roles_name_code_index ON roles (name, code);
--- Roles Data Insertion ---
INSERT INTO roles (name, code, sort, default_value, description, status, created_at, updated_at)
VALUES ('Admin', 'admin', 1, FALSE, 'Administrator of this system.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('Normal User', 'user', 2, TRUE, 'Normal user of this system.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
--- User Roles Table ---
DROP TABLE IF EXISTS user_roles CASCADE;
CREATE TABLE user_roles
(
user_id BIGINT NOT NULL
CONSTRAINT user_roles_users_id_fk REFERENCES users,
role_id BIGINT NOT NULL
CONSTRAINT user_roles_roles_id_fk REFERENCES roles,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
CONSTRAINT user_roles_pk PRIMARY KEY (user_id, role_id)
);
--- User Roles Data Insertion ---
INSERT INTO user_roles
VALUES (1, 1),
(2, 2);
--- Authorities Table ---
DROP TABLE IF EXISTS authorities CASCADE;
CREATE TABLE authorities
(
id BIGSERIAL PRIMARY KEY,
code VARCHAR(128) NOT NULL UNIQUE,
name VARCHAR(128) NOT NULL,
description TEXT,
status STATUS NOT NULL DEFAULT 'ACTIVE'::STATUS,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX authorities_code_index ON authorities (code);
--- Authorities Data Insertion ---
INSERT INTO authorities(code, name, description, status, created_at, updated_at)
VALUES ('system:dashboard:read', 'Read Dashboard', 'Read dashboard.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:user:read', 'Read User', 'Read user.', 'ACTIVE'::STATUS, CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP),
('system:user_detail:read', 'Read User', 'Read user detail.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:user:write', 'Write User', 'Write user, such as add, edit or delete.',
'ACTIVE'::STATUS, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:department:read', 'Read Department', 'Read departments', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:department:write', 'Write Department', 'Write departments.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:role:read', 'Read Roles', 'Read roles.', 'ACTIVE'::STATUS, CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP),
('system:role:write', 'Write Roles', 'Write roles.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:authority:read', 'Read Authorities', 'Read authorities.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:authority:write', 'Write Authorities', 'Write authorities.',
'ACTIVE'::STATUS, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:audit_log:read', 'Read Audit Logs', 'Read audit logs.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:sso:write', 'Manage SSO',
'Manage SSO configurations (such as Microsoft Entra ID, etc.).', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:setting:write', 'Write System Settings', 'Write system settings.',
'ACTIVE'::STATUS, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
--- Role Authorities Table ---
DROP TABLE IF EXISTS role_authorities CASCADE;
CREATE TABLE role_authorities
(
role_id BIGINT NOT NULL REFERENCES roles (id),
authority_id BIGINT NOT NULL REFERENCES authorities (id),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (role_id, authority_id)
);
--- Role Authorities Data Insertion ---
INSERT INTO role_authorities
VALUES (1, 1, CURRENT_TIMESTAMP),
(1, 2, CURRENT_TIMESTAMP),
(1, 3, CURRENT_TIMESTAMP),
(1, 4, CURRENT_TIMESTAMP),
(1, 5, CURRENT_TIMESTAMP),
(1, 6, CURRENT_TIMESTAMP),
(1, 7, CURRENT_TIMESTAMP),
(1, 8, CURRENT_TIMESTAMP),
(1, 9, CURRENT_TIMESTAMP),
(1, 10, CURRENT_TIMESTAMP),
(1, 11, CURRENT_TIMESTAMP),
(1, 12, CURRENT_TIMESTAMP),
(1, 13, CURRENT_TIMESTAMP),
(2, 1, CURRENT_TIMESTAMP),
(2, 2, CURRENT_TIMESTAMP),
(2, 3, CURRENT_TIMESTAMP),
(2, 5, CURRENT_TIMESTAMP),
(2, 7, CURRENT_TIMESTAMP),
(2, 9, CURRENT_TIMESTAMP),
(2, 11, CURRENT_TIMESTAMP);
DROP TABLE IF EXISTS assets;
CREATE TABLE assets
(
id BIGSERIAL NOT NULL PRIMARY KEY,
key VARCHAR(255) NOT NULL UNIQUE,
upload_by BIGINT NOT NULL REFERENCES users (id),
upload_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX assets_key_index ON assets (key);
COMMENT ON TABLE assets IS 'Stores metadata for files or other digital assets within the system.';
COMMENT ON COLUMN assets.id IS 'The unique identifier for the asset, automatically generated by the database.';
COMMENT ON COLUMN assets.key IS 'The unique key or path of the asset within the storage system.';
COMMENT ON COLUMN assets.upload_by IS 'The unique ID of the user who uploaded this asset, referencing the ID in the users table.';
COMMENT ON COLUMN assets.upload_time IS 'The timestamp indicating when the asset was uploaded to the system.';
DROP TABLE IF EXISTS settings;
CREATE TABLE settings
(
id BIGSERIAL NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description VARCHAR(255) NULL,
type SETTING_TYPE NOT NULL,
value VARCHAR(255) NULL,
default_value VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX settings_name_index ON settings (name);
COMMENT ON TABLE settings IS 'Hot-deployable application settings.';
COMMENT ON COLUMN settings.id IS 'Setting unique identifier.';
COMMENT ON COLUMN settings.name IS 'Setting name.';
COMMENT ON COLUMN settings.description IS 'Setting description.';
COMMENT ON COLUMN settings.type IS 'The type of the value.';
COMMENT ON COLUMN settings.value IS 'Setting current value.';
COMMENT ON COLUMN settings.default_value IS 'Setting default value.';
INSERT INTO settings(name, description, type, value, default_value)
VALUES ('captcha-setting::enabled', 'Whether captcha is enabled.', 'BOOLEAN'::SETTING_TYPE, 'true',
'false'),
('auth-setting::register-enabled', 'Whether register is enabled', 'BOOLEAN'::SETTING_TYPE,
'true', 'false');
DROP TABLE IF EXISTS menus;
CREATE TABLE menus
(
id BIGSERIAL NOT NULL PRIMARY KEY,
name VARCHAR(50) NOT NULL,
parent_id BIGINT NULL DEFAULT NULL,
code VARCHAR(255) NOT NULL,
sort INTEGER NOT NULL DEFAULT 0,
path VARCHAR(255) NULL DEFAULT NULL,
is_external_link BOOLEAN NOT NULL DEFAULT FALSE,
is_visible BOOLEAN NOT NULL DEFAULT TRUE,
status STATUS NOT NULL DEFAULT 'ACTIVE'::STATUS,
authority_code VARCHAR(128) NULL DEFAULT NULL,
icon VARCHAR(128) NULL DEFAULT NULL,
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE UNIQUE INDEX menus_code_uindex ON menus (code);
INSERT INTO menus(id, name, parent_id, code, sort, path, is_external_link, is_visible, status,
authority_code, icon, create_time, update_time)
VALUES (1, '系统管理', NULL, 'system-manage', 99, NULL, FALSE, TRUE, 'ACTIVE'::STATUS, NULL, NULL,
NOW(), NOW()),
(2, '用户管理', 1, 'user-manage', 1, '/users', FALSE, TRUE, 'ACTIVE'::STATUS,
'system:user:write', NULL, NOW(), NOW());