feat: update database schema and configuration for Flyway integration and refactor table names

This commit is contained in:
siujamo
2026-03-19 10:54:50 +08:00
parent 7c9f9c35f9
commit 484a9f4a71
10 changed files with 145 additions and 142 deletions
+2
View File
@@ -47,6 +47,8 @@ dependencies {
implementation(libs.spring.boot.starter.security) implementation(libs.spring.boot.starter.security)
implementation(libs.spring.boot.starter.jpa) implementation(libs.spring.boot.starter.jpa)
implementation(libs.mybatis.starter.core) implementation(libs.mybatis.starter.core)
implementation(libs.flyway.core)
implementation(libs.flyway.postgresql)
implementation(libs.jackson.jsr310) implementation(libs.jackson.jsr310)
testImplementation(libs.spring.boot.starter.test) testImplementation(libs.spring.boot.starter.test)
testImplementation(libs.reactor.test) testImplementation(libs.reactor.test)
+2
View File
@@ -43,6 +43,8 @@ hypersistence-core = { group = "io.hypersistence", name = "hypersistence-utils-h
postgres-driver = { group = "org.postgresql", name = "postgresql", version.ref = "postgresDriverVersion" } postgres-driver = { group = "org.postgresql", name = "postgresql", version.ref = "postgresDriverVersion" }
h2-database = { group = "com.h2database", name = "h2", version.ref = "h2Version" } h2-database = { group = "com.h2database", name = "h2", version.ref = "h2Version" }
spring-boot-starter-redis = { group = "org.springframework.boot", name = "spring-boot-starter-data-redis", version.ref = "springBootVersion" } spring-boot-starter-redis = { group = "org.springframework.boot", name = "spring-boot-starter-data-redis", version.ref = "springBootVersion" }
flyway-core = { group = "org.flywaydb", name = "flyway-core" }
flyway-postgresql = { group = "org.flywaydb", name = "flyway-database-postgresql" }
# Spring Boot Core & Web # Spring Boot Core & Web
spring-boot-starter-web = { group = "org.springframework.boot", name = "spring-boot-starter-web" } spring-boot-starter-web = { group = "org.springframework.boot", name = "spring-boot-starter-web" }
+6 -1
View File
@@ -21,12 +21,17 @@ spring:
# No need to use distributed transaction manager for 1 datasource. # No need to use distributed transaction manager for 1 datasource.
platform: org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform platform: org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform
hibernate: hibernate:
ddl-auto: validate ddl-auto: none
open-in-view: false open-in-view: false
datasource: datasource:
hikari: hikari:
minimum-idle: 1 minimum-idle: 1
maximum-pool-size: 10 maximum-pool-size: 10
flyway:
enabled: true
baseline-on-migrate: true
locations: classpath:db/migrations
baseline-version: 0
mybatis: mybatis:
@@ -27,7 +27,7 @@
* please ensure this SQL file is executed by the **corresponding database user**. * please ensure this SQL file is executed by the **corresponding database user**.
* * This is crucial for correctly setting up ownership and default privileges. * * This is crucial for correctly setting up ownership and default privileges.
* * Example: CREATE DATABASE my_database OWNER app_user; * * Example: CREATE DATABASE my_database OWNER app_user;
* * Ensure all necessary user roles and permissions are in place **prior** to * * Ensure all necessary user role and permissions are in place **prior** to
* running this initialisation script. * running this initialisation script.
*/ */
@@ -43,61 +43,61 @@ CREATE TYPE CREDENTIAL_PROVIDER AS ENUM ('LOCAL', 'OIDC', 'MICROSOFT_ENTRA_ID',
CREATE TYPE SETTING_TYPE AS ENUM ('STRING', 'BOOLEAN', 'INT'); CREATE TYPE SETTING_TYPE AS ENUM ('STRING', 'BOOLEAN', 'INT');
--- Departments Table --- --- Departments Table ---
DROP TABLE IF EXISTS departments CASCADE; DROP TABLE IF EXISTS department CASCADE;
CREATE TABLE departments CREATE TABLE department
( (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
name VARCHAR(128) NOT NULL UNIQUE, name VARCHAR(128) NOT NULL UNIQUE,
parent_id BIGINT NULL REFERENCES departments (id), parent_id BIGINT NULL REFERENCES department (id),
sort INT NOT NULL DEFAULT NULL, sort INT NOT NULL DEFAULT NULL,
status STATUS NOT NULL DEFAULT 'ACTIVE'::STATUS, status STATUS NOT NULL DEFAULT 'ACTIVE'::STATUS,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_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 department_name_index ON department (name);
CREATE INDEX departments_parent_id_index ON departments (parent_id); CREATE INDEX department_parent_id_index ON department (parent_id);
--- Departments Data Insertion --- --- Departments Data Insertion ---
WITH company_hq AS ( WITH company_hq AS (
INSERT INTO departments (name, parent_id, sort, status) INSERT INTO department (name, parent_id, sort, status)
VALUES ('Company HQ', NULL, 1, 'ACTIVE'::STATUS) VALUES ('Company HQ', NULL, 1, 'ACTIVE'::STATUS)
RETURNING id), RETURNING id),
human_resources AS ( human_resources AS (
INSERT INTO departments (name, parent_id, sort, status) INSERT INTO department (name, parent_id, sort, status)
SELECT 'Human Resources', company_hq.id, 1, 'ACTIVE'::STATUS SELECT 'Human Resources', company_hq.id, 1, 'ACTIVE'::STATUS
FROM company_hq FROM company_hq
RETURNING id), RETURNING id),
finance AS ( finance AS (
INSERT INTO departments (name, parent_id, sort, status) INSERT INTO department (name, parent_id, sort, status)
SELECT 'Finance', company_hq.id, 2, 'ACTIVE'::STATUS SELECT 'Finance', company_hq.id, 2, 'ACTIVE'::STATUS
FROM company_hq FROM company_hq
RETURNING id), RETURNING id),
technology AS ( technology AS (
INSERT INTO departments (name, parent_id, sort, status) INSERT INTO department (name, parent_id, sort, status)
SELECT 'Technology', company_hq.id, 3, 'ACTIVE'::STATUS SELECT 'Technology', company_hq.id, 3, 'ACTIVE'::STATUS
FROM company_hq FROM company_hq
RETURNING id), RETURNING id),
it_support AS ( it_support AS (
INSERT INTO departments (name, parent_id, sort, status) INSERT INTO department (name, parent_id, sort, status)
SELECT 'IT Support', technology.id, 1, 'ACTIVE'::STATUS SELECT 'IT Support', technology.id, 1, 'ACTIVE'::STATUS
FROM technology FROM technology
RETURNING id), RETURNING id),
software_development AS ( software_development AS (
INSERT INTO departments (name, parent_id, sort, status) INSERT INTO department (name, parent_id, sort, status)
SELECT 'Software Development', technology.id, 2, 'ACTIVE'::STATUS SELECT 'Software Development', technology.id, 2, 'ACTIVE'::STATUS
FROM technology FROM technology
RETURNING id), RETURNING id),
operations AS ( operations AS (
INSERT INTO departments (name, parent_id, sort, status) INSERT INTO department (name, parent_id, sort, status)
SELECT 'Operations', company_hq.id, 4, 'INACTIVE'::STATUS SELECT 'Operations', company_hq.id, 4, 'INACTIVE'::STATUS
FROM company_hq FROM company_hq
RETURNING id) RETURNING id)
SELECT NULL; SELECT NULL;
--- Positions Table --- --- Positions Table ---
DROP TABLE IF EXISTS positions CASCADE; DROP TABLE IF EXISTS position CASCADE;
CREATE TABLE positions CREATE TABLE position
( (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
name VARCHAR(128) NOT NULL UNIQUE, name VARCHAR(128) NOT NULL UNIQUE,
@@ -109,12 +109,12 @@ CREATE TABLE positions
updated_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 position_name_index ON position (name);
CREATE INDEX positions_code_index ON positions (code); CREATE INDEX position_code_index ON position (code);
CREATE INDEX positions_name_code_index ON positions (name, code); CREATE INDEX position_name_code_index ON position (name, code);
--- Positions Data Insertion --- --- Positions Data Insertion ---
INSERT INTO positions (name, code, description, sort, status) INSERT INTO position (name, code, description, sort, status)
VALUES ('HR Manager', 'HR-MGR', VALUES ('HR Manager', 'HR-MGR',
'Responsible for overseeing recruitment, employee relations, and staff wellbeing.', 1, 'Responsible for overseeing recruitment, employee relations, and staff wellbeing.', 1,
'ACTIVE'), 'ACTIVE'),
@@ -131,65 +131,62 @@ VALUES ('HR Manager', 'HR-MGR',
'Assists with day-to-day logistics, procurement, and office organisation.', 5, 'INACTIVE'); 'Assists with day-to-day logistics, procurement, and office organisation.', 5, 'INACTIVE');
--- Users Table --- --- Users Table ---
DROP TABLE IF EXISTS users CASCADE; DROP TABLE IF EXISTS "user" CASCADE;
DROP SEQUENCE IF EXISTS users_id_seq CASCADE; DROP SEQUENCE IF EXISTS user_id_seq CASCADE;
CREATE SEQUENCE users_id_seq START WITH 1; CREATE SEQUENCE user_id_seq START WITH 1;
CREATE TABLE users CREATE TABLE "user"
( (
id BIGINT PRIMARY KEY DEFAULT nextval('users_id_seq'), id BIGSERIAL PRIMARY KEY,
username VARCHAR(64) UNIQUE NOT NULL, username VARCHAR(64) UNIQUE NOT NULL,
password VARCHAR(255),
full_name VARCHAR(128) NOT NULL, full_name VARCHAR(128) NOT NULL,
email VARCHAR(128) NULL UNIQUE, email VARCHAR(128) NULL UNIQUE,
region_abbreviation VARCHAR(10) NULL, region_abbreviation VARCHAR(10) NULL,
phone_number VARCHAR(32) NULL, phone_number VARCHAR(32) NULL,
avatar_url TEXT, avatar_url TEXT,
status USER_STATUS NOT NULL DEFAULT 'ACTIVE', status USER_STATUS NOT NULL DEFAULT 'ACTIVE',
department_id BIGINT REFERENCES departments (id), department_id BIGINT REFERENCES department (id),
position_id BIGINT REFERENCES positions (id), position_id BIGINT REFERENCES position (id),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE (region_abbreviation, phone_number) UNIQUE (region_abbreviation, phone_number)
); );
CREATE INDEX users_username_index ON users (username); CREATE INDEX user_username_index ON "user" (username);
--- Users Data Insertion --- --- Users Data Insertion ---
-- NOTE: All phone numbers are generated by ChatGPT, they should not be connected any real person. -- NOTE: All phone numbers are generated by ChatGPT, they should not be connected any real person.
INSERT INTO users(username, password, full_name, email, region_abbreviation, phone_number, INSERT INTO "user"(username, full_name, email, region_abbreviation, phone_number,
avatar_url, department_id, position_id, created_at, updated_at) avatar_url, department_id, position_id, created_at, updated_at)
SELECT 'helix', SELECT 'helix',
null,
'Helix Admin', 'Helix Admin',
'admin@helix.onixbyte.dev', 'admin@helix.onixbyte.dev',
'GB', 'GB',
'7000000000', '7000000000',
'https://gravatar.com/avatar/6ef4c4033f6aa8e43d06bd5e462a6173cc2a960633473721a6f1289cd1b5146f', 'https://gravatar.com/avatar/6ef4c4033f6aa8e43d06bd5e462a6173cc2a960633473721a6f1289cd1b5146f',
(SELECT id FROM departments WHERE name = 'Company HQ'), (SELECT id FROM department WHERE name = 'Company HQ'),
(SELECT id FROM positions WHERE code = 'HR-MGR'), (SELECT id FROM position WHERE code = 'HR-MGR'),
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP; CURRENT_TIMESTAMP;
INSERT INTO users(username, password, full_name, email, region_abbreviation, phone_number, INSERT INTO "user"(username, full_name, email, region_abbreviation, phone_number,
avatar_url, department_id, position_id, created_at, updated_at) avatar_url, department_id, position_id, created_at, updated_at)
SELECT 'johndoe', SELECT 'johndoe',
null,
'John Doe', 'John Doe',
'johndoe@helix.onixbyte.dev', 'johndoe@helix.onixbyte.dev',
'GB', 'GB',
'7000000001', '7000000001',
'https://gravatar.com/avatar/41bcebddd573747d1bd35ef7fae72ebefd6b47f077d42442a2510d35b0c2db92', 'https://gravatar.com/avatar/41bcebddd573747d1bd35ef7fae72ebefd6b47f077d42442a2510d35b0c2db92',
(SELECT id FROM departments WHERE name = 'Software Development'), (SELECT id FROM department WHERE name = 'Software Development'),
(SELECT id FROM positions WHERE code = 'SWE-ENG'), (SELECT id FROM position WHERE code = 'SWE-ENG'),
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP; CURRENT_TIMESTAMP;
--- User Identities Table --- --- User Identities Table ---
DROP TABLE IF EXISTS user_credentials CASCADE; DROP TABLE IF EXISTS user_credential CASCADE;
CREATE TABLE user_credentials CREATE TABLE user_credential
( (
user_id BIGINT NOT NULL REFERENCES users (id), user_id BIGINT NOT NULL REFERENCES "user" (id),
provider CREDENTIAL_PROVIDER NOT NULL, provider CREDENTIAL_PROVIDER NOT NULL,
credential VARCHAR(255) NOT NULL, credential VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
@@ -198,8 +195,8 @@ CREATE TABLE user_credentials
); );
--- Roles Table --- --- Roles Table ---
DROP TABLE IF EXISTS roles CASCADE; DROP TABLE IF EXISTS role CASCADE;
CREATE TABLE roles CREATE TABLE role
( (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
name VARCHAR(128) NOT NULL UNIQUE, name VARCHAR(128) NOT NULL UNIQUE,
@@ -212,40 +209,40 @@ CREATE TABLE roles
updated_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 role_name_index ON role (name);
CREATE INDEX roles_code_index ON roles (code); CREATE INDEX role_code_index ON role (code);
CREATE INDEX roles_name_code_index ON roles (name, code); CREATE INDEX role_name_code_index ON role (name, code);
--- Roles Data Insertion --- --- Roles Data Insertion ---
INSERT INTO roles (name, code, sort, default_value, description, status, created_at, updated_at) INSERT INTO role (name, code, sort, default_value, description, status, created_at, updated_at)
VALUES ('Admin', 'admin', 1, FALSE, 'Administrator of this system.', 'ACTIVE'::STATUS, VALUES ('Admin', 'admin', 1, FALSE, 'Administrator of this system.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('Normal User', 'user', 2, TRUE, 'Normal user of this system.', 'ACTIVE'::STATUS, ('Normal User', 'user', 2, TRUE, 'Normal user of this system.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP); CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
--- User Roles Table --- --- User Roles Table ---
DROP TABLE IF EXISTS user_roles CASCADE; DROP TABLE IF EXISTS user_role CASCADE;
CREATE TABLE user_roles CREATE TABLE user_role
( (
user_id BIGINT NOT NULL user_id BIGINT NOT NULL
CONSTRAINT user_roles_users_id_fk REFERENCES users, CONSTRAINT user_role_user_id_fk REFERENCES "user",
role_id BIGINT NOT NULL role_id BIGINT NOT NULL
CONSTRAINT user_roles_roles_id_fk REFERENCES roles, CONSTRAINT user_role_role_id_fk REFERENCES role,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
CONSTRAINT user_roles_pk PRIMARY KEY (user_id, role_id) CONSTRAINT user_role_pk PRIMARY KEY (user_id, role_id)
); );
--- User Roles Data Insertion --- --- User Roles Data Insertion ---
INSERT INTO user_roles (user_id, role_id) INSERT INTO user_role (user_id, role_id)
SELECT u.id, r.id SELECT u.id, r.id
FROM users u FROM "user" u
CROSS JOIN roles r CROSS JOIN role r
WHERE (u.username = 'helix' AND r.code = 'admin') WHERE (u.username = 'helix' AND r.code = 'admin')
OR (u.username = 'johndoe' AND r.code = 'user'); OR (u.username = 'johndoe' AND r.code = 'user');
--- Authorities Table --- --- Authorities Table ---
DROP TABLE IF EXISTS authorities CASCADE; DROP TABLE IF EXISTS authority CASCADE;
CREATE TABLE authorities CREATE TABLE authority
( (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
code VARCHAR(128) NOT NULL UNIQUE, code VARCHAR(128) NOT NULL UNIQUE,
@@ -256,10 +253,10 @@ CREATE TABLE authorities
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
); );
CREATE INDEX authorities_code_index ON authorities (code); CREATE INDEX authority_code_index ON authority (code);
--- Authorities Data Insertion --- --- Authorities Data Insertion ---
INSERT INTO authorities(code, name, description, status, created_at, updated_at) INSERT INTO authority(code, name, description, status, created_at, updated_at)
VALUES ('system:dashboard:read', 'Read Dashboard', 'Read dashboard.', 'ACTIVE'::STATUS, VALUES ('system:dashboard:read', 'Read Dashboard', 'Read dashboard.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:user:read', 'Read User', 'Read user.', 'ACTIVE'::STATUS, CURRENT_TIMESTAMP, ('system:user:read', 'Read User', 'Read user.', 'ACTIVE'::STATUS, CURRENT_TIMESTAMP,
@@ -268,49 +265,49 @@ VALUES ('system:dashboard:read', 'Read Dashboard', 'Read dashboard.', 'ACTIVE'::
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:user:write', 'Write User', 'Write user, such as add, edit or delete.', ('system:user:write', 'Write User', 'Write user, such as add, edit or delete.',
'ACTIVE'::STATUS, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), 'ACTIVE'::STATUS, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:department:read', 'Read Department', 'Read departments', 'ACTIVE'::STATUS, ('system:department:read', 'Read Department', 'Read department', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:department:write', 'Write Department', 'Write departments.', 'ACTIVE'::STATUS, ('system:department:write', 'Write Department', 'Write department.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:role:read', 'Read Roles', 'Read roles.', 'ACTIVE'::STATUS, CURRENT_TIMESTAMP, ('system:role:read', 'Read Roles', 'Read role.', 'ACTIVE'::STATUS, CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP), CURRENT_TIMESTAMP),
('system:role:write', 'Write Roles', 'Write roles.', 'ACTIVE'::STATUS, ('system:role:write', 'Write Roles', 'Write role.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:authority:read', 'Read Authorities', 'Read authorities.', 'ACTIVE'::STATUS, ('system:authority:read', 'Read Authorities', 'Read authority.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:authority:write', 'Write Authorities', 'Write authorities.', ('system:authority:write', 'Write Authorities', 'Write authority.',
'ACTIVE'::STATUS, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), 'ACTIVE'::STATUS, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:audit_log:read', 'Read Audit Logs', 'Read audit logs.', 'ACTIVE'::STATUS, ('system:audit_log:read', 'Read Audit Logs', 'Read audit logs.', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:sso:write', 'Manage SSO', ('system:sso:write', 'Manage SSO',
'Manage SSO configurations (such as Microsoft Entra ID, etc.).', 'ACTIVE'::STATUS, 'Manage SSO configurations (such as Microsoft Entra ID, etc.).', 'ACTIVE'::STATUS,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('system:setting:write', 'Write System Settings', 'Write system settings.', ('system:setting:write', 'Write System Settings', 'Write system setting.',
'ACTIVE'::STATUS, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP); 'ACTIVE'::STATUS, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
--- Role Authorities Table --- --- Role Authorities Table ---
DROP TABLE IF EXISTS role_authorities CASCADE; DROP TABLE IF EXISTS role_authority CASCADE;
CREATE TABLE role_authorities CREATE TABLE role_authority
( (
role_id BIGINT NOT NULL REFERENCES roles (id), role_id BIGINT NOT NULL REFERENCES role (id),
authority_id BIGINT NOT NULL REFERENCES authorities (id), authority_id BIGINT NOT NULL REFERENCES authority (id),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (role_id, authority_id) PRIMARY KEY (role_id, authority_id)
); );
--- Role Authorities Data Insertion --- --- Role Authorities Data Insertion ---
-- Admin role gets all authorities -- Admin role gets all authority
INSERT INTO role_authorities (role_id, authority_id, created_at) INSERT INTO role_authority (role_id, authority_id, created_at)
SELECT r.id, a.id, CURRENT_TIMESTAMP SELECT r.id, a.id, CURRENT_TIMESTAMP
FROM roles r FROM role r
CROSS JOIN authorities a CROSS JOIN authority a
WHERE r.code = 'admin'; WHERE r.code = 'admin';
-- Normal user role gets specific authorities -- Normal user role gets specific authority
INSERT INTO role_authorities (role_id, authority_id, created_at) INSERT INTO role_authority (role_id, authority_id, created_at)
SELECT r.id, a.id, CURRENT_TIMESTAMP SELECT r.id, a.id, CURRENT_TIMESTAMP
FROM roles r FROM role r
CROSS JOIN authorities a CROSS JOIN authority a
WHERE r.code = 'user' WHERE r.code = 'user'
AND a.code IN ('system:dashboard:read', AND a.code IN ('system:dashboard:read',
'system:user:read', 'system:user:read',
@@ -320,25 +317,25 @@ WHERE r.code = 'user'
'system:authority:read', 'system:authority:read',
'system:audit_log:read'); 'system:audit_log:read');
DROP TABLE IF EXISTS assets; DROP TABLE IF EXISTS asset;
CREATE TABLE assets CREATE TABLE asset
( (
id BIGSERIAL NOT NULL PRIMARY KEY, id BIGSERIAL NOT NULL PRIMARY KEY,
key VARCHAR(255) NOT NULL UNIQUE, key VARCHAR(255) NOT NULL UNIQUE,
upload_by BIGINT NOT NULL REFERENCES users (id), upload_by BIGINT NOT NULL REFERENCES "user" (id),
upload_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP upload_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
); );
CREATE INDEX assets_key_index ON assets (key); CREATE INDEX asset_key_index ON asset (key);
COMMENT ON TABLE assets IS 'Stores metadata for files or other digital assets within the system.'; COMMENT ON TABLE asset IS 'Stores metadata for files or other digital asset within the system.';
COMMENT ON COLUMN assets.id IS 'The unique identifier for the asset, automatically generated by the database.'; COMMENT ON COLUMN asset.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 asset.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 asset.upload_by IS 'The unique ID of the user who uploaded this asset, referencing the ID in the user table.';
COMMENT ON COLUMN assets.upload_time IS 'The timestamp indicating when the asset was uploaded to the system.'; COMMENT ON COLUMN asset.upload_time IS 'The timestamp indicating when the asset was uploaded to the system.';
DROP TABLE IF EXISTS settings; DROP TABLE IF EXISTS setting;
CREATE TABLE settings CREATE TABLE setting
( (
id BIGSERIAL NOT NULL PRIMARY KEY, id BIGSERIAL NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL,
@@ -350,24 +347,24 @@ CREATE TABLE settings
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
); );
CREATE INDEX settings_name_index ON settings (name); CREATE INDEX setting_name_index ON setting (name);
COMMENT ON TABLE settings IS 'Hot-deployable application settings.'; COMMENT ON TABLE setting IS 'Hot-deployable application setting.';
COMMENT ON COLUMN settings.id IS 'Setting unique identifier.'; COMMENT ON COLUMN setting.id IS 'Setting unique identifier.';
COMMENT ON COLUMN settings.name IS 'Setting name.'; COMMENT ON COLUMN setting.name IS 'Setting name.';
COMMENT ON COLUMN settings.description IS 'Setting description.'; COMMENT ON COLUMN setting.description IS 'Setting description.';
COMMENT ON COLUMN settings.type IS 'The type of the value.'; COMMENT ON COLUMN setting.type IS 'The type of the value.';
COMMENT ON COLUMN settings.value IS 'Setting current value.'; COMMENT ON COLUMN setting.value IS 'Setting current value.';
COMMENT ON COLUMN settings.default_value IS 'Setting default value.'; COMMENT ON COLUMN setting.default_value IS 'Setting default value.';
INSERT INTO settings(name, description, type, value, default_value) INSERT INTO setting(name, description, type, value, default_value)
VALUES ('captcha-enabled', 'Whether captcha is enabled.', 'BOOLEAN'::SETTING_TYPE, 'true', VALUES ('captcha-enabled', 'Whether captcha is enabled.', 'BOOLEAN'::SETTING_TYPE, 'true',
'false'), 'false'),
('register-enabled', 'Whether register is enabled', 'BOOLEAN'::SETTING_TYPE, ('register-enabled', 'Whether register is enabled', 'BOOLEAN'::SETTING_TYPE,
'true', 'false'); 'true', 'false');
DROP TABLE IF EXISTS menus; DROP TABLE IF EXISTS menu;
CREATE TABLE menus CREATE TABLE menu
( (
id BIGSERIAL NOT NULL PRIMARY KEY, id BIGSERIAL NOT NULL PRIMARY KEY,
name VARCHAR(50) NOT NULL, name VARCHAR(50) NOT NULL,
@@ -384,22 +381,22 @@ CREATE TABLE menus
updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
); );
CREATE UNIQUE INDEX menus_code_uindex ON menus (code); CREATE UNIQUE INDEX menu_code_uindex ON menu (code);
WITH system_menu AS ( WITH system_menu AS (
INSERT INTO menus (name, parent_id, code, sort, path, is_external_link, is_visible, status, INSERT INTO menu (name, parent_id, code, sort, path, is_external_link, is_visible, status,
authority_code, icon, created_at, updated_at) authority_code, icon, created_at, updated_at)
VALUES ('系统管理', NULL, 'system-mgmt', 99, NULL, FALSE, TRUE, 'ACTIVE'::STATUS, NULL, VALUES ('系统管理', NULL, 'system-mgmt', 99, NULL, FALSE, TRUE, 'ACTIVE'::STATUS, NULL,
NULL, NOW(), NOW()) NULL, NOW(), NOW())
RETURNING id) RETURNING id)
INSERT INSERT
INTO menus(name, parent_id, code, sort, path, is_external_link, is_visible, status, INTO menu(name, parent_id, code, sort, path, is_external_link, is_visible, status,
authority_code, icon, created_at, updated_at) authority_code, icon, created_at, updated_at)
SELECT '用户管理', SELECT '用户管理',
system_menu.id, system_menu.id,
'user-mgmt', 'user-mgmt',
1, 1,
'/users', '/user',
FALSE, FALSE,
TRUE, TRUE,
'ACTIVE'::STATUS, 'ACTIVE'::STATUS,
@@ -409,7 +406,7 @@ SELECT '用户管理',
NOW() NOW()
FROM system_menu; FROM system_menu;
INSERT INTO menus (name, parent_id, code, sort, path, is_external_link, is_visible, status, INSERT INTO menu (name, parent_id, code, sort, path, is_external_link, is_visible, status,
authority_code, icon, created_at, updated_at) authority_code, icon, created_at, updated_at)
VALUES ('Helix 官网', null, 'helix-official-site', 100, 'https://helix.onixbyte.com', true, true, VALUES ('Helix 官网', null, 'helix-official-site', 100, 'https://helix.onixbyte.com', true, true,
'ACTIVE'::STATUS, null, null, NOW(), NOW()); 'ACTIVE'::STATUS, null, null, NOW(), NOW());
@@ -4,9 +4,9 @@
<mapper namespace="com.onixbyte.helix.mapper.AuthorityMapper"> <mapper namespace="com.onixbyte.helix.mapper.AuthorityMapper">
<select id="selectByUserId" parameterType="long"> <select id="selectByUserId" parameterType="long">
SELECT DISTINCT a.id, a.code, a.name, a.description, a.status, a.created_at, a.updated_at SELECT DISTINCT a.id, a.code, a.name, a.description, a.status, a.created_at, a.updated_at
FROM authorities a FROM authority a
JOIN role_authorities ra ON a.id = ra.authority_id JOIN role_authority ra ON a.id = ra.authority_id
JOIN user_roles ur ON ra.role_id = ur.role_id JOIN user_role ur ON ra.role_id = ur.role_id
WHERE ur.user_id = #{userId} WHERE ur.user_id = #{userId}
</select> </select>
</mapper> </mapper>
+5 -5
View File
@@ -5,10 +5,10 @@
<select id="selectActiveMenusByUserId" parameterType="long" resultType="com.onixbyte.helix.domain.entity.Menu"> <select id="selectActiveMenusByUserId" parameterType="long" resultType="com.onixbyte.helix.domain.entity.Menu">
WITH RECURSIVE WITH RECURSIVE
UserGrantedMenus AS (SELECT DISTINCT m.* UserGrantedMenus AS (SELECT DISTINCT m.*
FROM menus m FROM menu m
JOIN authorities a ON m.authority_code = a.code JOIN authority a ON m.authority_code = a.code
JOIN role_authorities ra ON ra.authority_id = a.id JOIN role_authority ra ON ra.authority_id = a.id
JOIN user_roles ur ON ur.role_id = ra.role_id JOIN user_role ur ON ur.role_id = ra.role_id
WHERE ur.user_id = #{userId} WHERE ur.user_id = #{userId}
AND m.status = 'ACTIVE'::status), AND m.status = 'ACTIVE'::status),
Ancestors AS (SELECT ugm.*, Ancestors AS (SELECT ugm.*,
@@ -17,7 +17,7 @@
UNION ALL UNION ALL
SELECT m.*, SELECT m.*,
FALSE AS is_granted FALSE AS is_granted
FROM menus m FROM menu m
JOIN Ancestors a ON m.id = a.parent_id) JOIN Ancestors a ON m.id = a.parent_id)
SELECT DISTINCT id, SELECT DISTINCT id,
name, name,
@@ -4,7 +4,7 @@
<mapper namespace="com.onixbyte.helix.mapper.RoleAuthorityMapper"> <mapper namespace="com.onixbyte.helix.mapper.RoleAuthorityMapper">
<delete id="deleteByRoleId" parameterType="long"> <delete id="deleteByRoleId" parameterType="long">
DELETE DELETE
FROM role_authorities FROM role_authority
WHERE role_id = #{roleId} WHERE role_id = #{roleId}
</delete> </delete>
</mapper> </mapper>
+3 -3
View File
@@ -15,7 +15,7 @@
) AS input_roles_temp ) AS input_roles_temp
WHERE NOT EXISTS ( WHERE NOT EXISTS (
SELECT 1 SELECT 1
FROM roles r FROM role r
WHERE r.id = input_roles_temp.id WHERE r.id = input_roles_temp.id
) )
) )
@@ -31,7 +31,7 @@
status, status,
created_at, created_at,
updated_at updated_at
FROM roles FROM role
<where> <where>
<if test="wrapper.name != null and wrapper.name != ''"> <if test="wrapper.name != null and wrapper.name != ''">
AND name LIKE '%' || #{wrapper.name} || '%' AND name LIKE '%' || #{wrapper.name} || '%'
@@ -54,7 +54,7 @@
<select id="count" parameterType="com.onixbyte.helix.domain.database.query.wrapper.QueryRoleWrapper"> <select id="count" parameterType="com.onixbyte.helix.domain.database.query.wrapper.QueryRoleWrapper">
SELECT COUNT(*) SELECT COUNT(*)
FROM roles FROM role
<where> <where>
<if test="wrapper.name != null and wrapper.name != ''"> <if test="wrapper.name != null and wrapper.name != ''">
AND name LIKE '%' || #{wrapper.name} || '%' AND name LIKE '%' || #{wrapper.name} || '%'
@@ -25,7 +25,7 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.onixbyte.helix.mapper.UserCredentialMapper"> <mapper namespace="com.onixbyte.helix.mapper.UserCredentialMapper">
<update id="updateUserCredential"> <update id="updateUserCredential">
UPDATE user_credentials UPDATE user_credential
SET credential = #{encodedPassword} SET credential = #{encodedPassword}
WHERE user_id = #{userId} WHERE user_id = #{userId}
AND provider = 'LOCAL'::credential_provider AND provider = 'LOCAL'::credential_provider
+17 -20
View File
@@ -5,7 +5,6 @@
<select id="selectByUsername" parameterType="string"> <select id="selectByUsername" parameterType="string">
SELECT id, SELECT id,
username, username,
password,
full_name, full_name,
email, email,
region_abbreviation, region_abbreviation,
@@ -16,7 +15,7 @@
position_id, position_id,
created_at, created_at,
updated_at updated_at
FROM users FROM "user"
WHERE username = #{username} WHERE username = #{username}
</select> </select>
@@ -24,7 +23,6 @@
resultType="user"> resultType="user">
SELECT id, SELECT id,
username, username,
password,
full_name, full_name,
email, email,
region_abbreviation, region_abbreviation,
@@ -35,7 +33,7 @@
position_id, position_id,
created_at, created_at,
updated_at updated_at
FROM users FROM "user"
<if test="pageable != null and pageable.sort != null"> <if test="pageable != null and pageable.sort != null">
ORDER BY ORDER BY
<foreach collection="pageable.sort" item="order" separator=", "> <foreach collection="pageable.sort" item="order" separator=", ">
@@ -47,13 +45,12 @@
<select id="countAll" resultType="int"> <select id="countAll" resultType="int">
SELECT COUNT(*) SELECT COUNT(*)
FROM users FROM "user"
</select> </select>
<select id="selectList" resultType="user"> <select id="selectList" resultType="user">
SELECT id, SELECT id,
username, username,
password,
full_name, full_name,
email, email,
region_abbreviation, region_abbreviation,
@@ -64,16 +61,16 @@
position_id, position_id,
created_at, created_at,
updated_at updated_at
FROM users FROM "user"
<where> <where>
<if test="wrapper.departmentId != null"> <if test="wrapper.departmentId != null">
AND department_id IN (WITH RECURSIVE SubDepartments AS ( AND department_id IN (WITH RECURSIVE SubDepartments AS (
SELECT id SELECT id
FROM departments FROM department
WHERE id = #{wrapper.departmentId} WHERE id = #{wrapper.departmentId}
UNION ALL UNION ALL
SELECT d.id SELECT d.id
FROM departments d FROM department d
INNER JOIN SubDepartments sd INNER JOIN SubDepartments sd
ON d.parent_id = sd.id) ON d.parent_id = sd.id)
SELECT id SELECT id
@@ -109,16 +106,16 @@
<select id="count" resultType="int"> <select id="count" resultType="int">
SELECT COUNT(*) SELECT COUNT(*)
FROM users FROM "user"
<where> <where>
<if test="wrapper.departmentId != null"> <if test="wrapper.departmentId != null">
AND department_id IN (WITH RECURSIVE SubDepartments AS ( AND department_id IN (WITH RECURSIVE SubDepartments AS (
SELECT id SELECT id
FROM departments FROM department
WHERE id = #{wrapper.departmentId} WHERE id = #{wrapper.departmentId}
UNION ALL UNION ALL
SELECT d.id SELECT d.id
FROM departments d FROM department d
INNER JOIN SubDepartments sd INNER JOIN SubDepartments sd
ON d.parent_id = sd.id) ON d.parent_id = sd.id)
SELECT id SELECT id
@@ -160,9 +157,9 @@
p.name AS position_name, p.name AS position_name,
u.created_at, u.created_at,
u.updated_at u.updated_at
FROM users u FROM "user" u
LEFT JOIN departments d ON u.department_id = d.id LEFT JOIN department d ON u.department_id = d.id
LEFT JOIN positions p ON u.position_id = p.id LEFT JOIN position p ON u.position_id = p.id
WHERE u.id = #{id} WHERE u.id = #{id}
</select> </select>
@@ -181,18 +178,18 @@
p.name AS position_name, p.name AS position_name,
u.created_at, u.created_at,
u.updated_at u.updated_at
FROM users u FROM "user" u
LEFT JOIN departments d ON u.department_id = d.id LEFT JOIN department d ON u.department_id = d.id
LEFT JOIN positions p ON u.position_id = p.id LEFT JOIN position p ON u.position_id = p.id
<where> <where>
<if test="wrapper.departmentId != null"> <if test="wrapper.departmentId != null">
AND department_id IN (WITH RECURSIVE SubDepartments AS ( AND department_id IN (WITH RECURSIVE SubDepartments AS (
SELECT id SELECT id
FROM departments FROM department
WHERE id = #{wrapper.departmentId} WHERE id = #{wrapper.departmentId}
UNION ALL UNION ALL
SELECT d.id SELECT d.id
FROM departments d FROM department d
INNER JOIN SubDepartments sd INNER JOIN SubDepartments sd
ON d.parent_id = sd.id) ON d.parent_id = sd.id)
SELECT id SELECT id