-- ============================================================
-- Ether 系统初始化脚本 V1
-- 创建日期: 2026-03-28
-- 说明: 初始化认证授权模块的数据库表结构
-- 包含: 用户、角色、权限、审计日志、系统配置
-- ============================================================

BEGIN;

-- ============================================================
-- 第一部分：用户表 (auth_user)
-- ============================================================

CREATE TABLE IF NOT EXISTS auth_user (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    username VARCHAR(50) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    salt VARCHAR(50),
    real_name VARCHAR(100),
    phone VARCHAR(20),
    email VARCHAR(100),
    avatar VARCHAR(500),
    status VARCHAR(20) DEFAULT 'ACTIVE',
    last_login_time TIMESTAMP,
    last_login_ip VARCHAR(50),
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    created_by UUID,
    CONSTRAINT auth_user_status_check CHECK (status IN ('ACTIVE', 'DISABLED', 'DELETED'))
);

COMMENT ON TABLE auth_user IS '系统用户表';
COMMENT ON COLUMN auth_user.id IS '用户唯一标识';
COMMENT ON COLUMN auth_user.username IS '用户名（登录账号）';
COMMENT ON COLUMN auth_user.password IS '加密后的密码';
COMMENT ON COLUMN auth_user.salt IS '密码盐值';
COMMENT ON COLUMN auth_user.real_name IS '真实姓名';
COMMENT ON COLUMN auth_user.phone IS '手机号码';
COMMENT ON COLUMN auth_user.email IS '电子邮箱';
COMMENT ON COLUMN auth_user.avatar IS '头像URL';
COMMENT ON COLUMN auth_user.status IS '状态：ACTIVE-正常 DISABLED-禁用 DELETED-已删除';
COMMENT ON COLUMN auth_user.last_login_time IS '最后登录时间';
COMMENT ON COLUMN auth_user.last_login_ip IS '最后登录IP';
COMMENT ON COLUMN auth_user.created_at IS '创建时间';
COMMENT ON COLUMN auth_user.updated_at IS '更新时间';
COMMENT ON COLUMN auth_user.created_by IS '创建人ID';

-- 用户索引
CREATE INDEX IF NOT EXISTS idx_auth_user_username ON auth_user(username);
CREATE INDEX IF NOT EXISTS idx_auth_user_status ON auth_user(status);
CREATE INDEX IF NOT EXISTS idx_auth_user_phone ON auth_user(phone);
CREATE INDEX IF NOT EXISTS idx_auth_user_email ON auth_user(email);

-- ============================================================
-- 第二部分：角色表 (auth_role)
-- ============================================================

CREATE TABLE IF NOT EXISTS auth_role (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    code VARCHAR(50) NOT NULL UNIQUE,
    name VARCHAR(100) NOT NULL,
    description VARCHAR(500),
    type VARCHAR(20) NOT NULL DEFAULT 'SYSTEM',
    data_scope VARCHAR(20) NOT NULL DEFAULT 'SELF',
    project_id UUID,
    status VARCHAR(20) NOT NULL DEFAULT 'ENABLED',
    sort_order INT DEFAULT 0,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT auth_role_type_check CHECK (type IN ('SYSTEM', 'PROJECT', 'DEPARTMENT')),
    CONSTRAINT auth_role_data_scope_check CHECK (data_scope IN ('ALL', 'PROJECT', 'DEPARTMENT', 'SELF')),
    CONSTRAINT auth_role_status_check CHECK (status IN ('ENABLED', 'DISABLED'))
);

COMMENT ON TABLE auth_role IS '系统角色表';
COMMENT ON COLUMN auth_role.id IS '角色唯一标识';
COMMENT ON COLUMN auth_role.code IS '角色编码（唯一）';
COMMENT ON COLUMN auth_role.name IS '角色名称';
COMMENT ON COLUMN auth_role.description IS '角色描述';
COMMENT ON COLUMN auth_role.type IS '角色类型：SYSTEM-系统级 PROJECT-项目级 DEPARTMENT-部门级';
COMMENT ON COLUMN auth_role.data_scope IS '数据范围：ALL-全部 PROJECT-项目级 DEPARTMENT-部门级 SELF-仅本人';
COMMENT ON COLUMN auth_role.project_id IS '所属项目ID（项目级角色使用）';
COMMENT ON COLUMN auth_role.status IS '状态：ENABLED-启用 DISABLED-禁用';
COMMENT ON COLUMN auth_role.sort_order IS '排序号';

-- 角色索引
CREATE INDEX IF NOT EXISTS idx_auth_role_code ON auth_role(code);
CREATE INDEX IF NOT EXISTS idx_auth_role_type ON auth_role(type);
CREATE INDEX IF NOT EXISTS idx_auth_role_status ON auth_role(status);

-- ============================================================
-- 第三部分：权限表 (auth_permission)
-- ============================================================

CREATE TABLE IF NOT EXISTS auth_permission (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    code VARCHAR(100) NOT NULL UNIQUE,
    name VARCHAR(100) NOT NULL,
    type VARCHAR(20) NOT NULL DEFAULT 'BUTTON',
    resource VARCHAR(255),
    method VARCHAR(20),
    action VARCHAR(30),
    module VARCHAR(50),
    description VARCHAR(500),
    sort_order INT DEFAULT 0,
    parent_code VARCHAR(100) REFERENCES auth_permission(code),
    status VARCHAR(20) NOT NULL DEFAULT 'ENABLED',
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT auth_permission_type_check CHECK (type IN ('MENU', 'BUTTON', 'API')),
    CONSTRAINT auth_permission_action_check CHECK (action IN ('VIEW', 'CREATE', 'EDIT', 'DELETE', 'EXPORT', 'IMPORT', 'APPROVE', 'ASSIGN'))
);

COMMENT ON TABLE auth_permission IS '系统权限表';
COMMENT ON COLUMN auth_permission.id IS '权限唯一标识';
COMMENT ON COLUMN auth_permission.code IS '权限编码（唯一，格式：模块:资源:操作）';
COMMENT ON COLUMN auth_permission.name IS '权限名称';
COMMENT ON COLUMN auth_permission.type IS '权限类型：MENU-菜单 BUTTON-按钮 API-接口';
COMMENT ON COLUMN auth_permission.resource IS '资源路径';
COMMENT ON COLUMN auth_permission.method IS 'HTTP方法：GET POST PUT DELETE';
COMMENT ON COLUMN auth_permission.action IS '操作类型：VIEW CREATE EDIT DELETE EXPORT IMPORT APPROVE ASSIGN';
COMMENT ON COLUMN auth_permission.module IS '所属模块';
COMMENT ON COLUMN auth_permission.description IS '权限描述';
COMMENT ON COLUMN auth_permission.sort_order IS '排序号';
COMMENT ON COLUMN auth_permission.parent_code IS '父权限编码（用于树形结构）';
COMMENT ON COLUMN auth_permission.status IS '状态：ENABLED-启用 DISABLED-禁用';

-- 权限索引
CREATE INDEX IF NOT EXISTS idx_auth_permission_code ON auth_permission(code);
CREATE INDEX IF NOT EXISTS idx_auth_permission_type ON auth_permission(type);
CREATE INDEX IF NOT EXISTS idx_auth_permission_module ON auth_permission(module);
CREATE INDEX IF NOT EXISTS idx_auth_permission_status ON auth_permission(status);
CREATE INDEX IF NOT EXISTS idx_auth_permission_parent ON auth_permission(parent_code);

-- ============================================================
-- 第四部分：用户角色关联表 (auth_user_role)
-- ============================================================

CREATE TABLE IF NOT EXISTS auth_user_role (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES auth_user(id) ON DELETE CASCADE,
    role_id UUID NOT NULL REFERENCES auth_role(id) ON DELETE CASCADE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT auth_user_role_unique UNIQUE (user_id, role_id)
);

COMMENT ON TABLE auth_user_role IS '用户角色关联表';
COMMENT ON COLUMN auth_user_role.user_id IS '用户ID';
COMMENT ON COLUMN auth_user_role.role_id IS '角色ID';

-- 用户角色关联索引
CREATE INDEX IF NOT EXISTS idx_auth_user_role_user ON auth_user_role(user_id);
CREATE INDEX IF NOT EXISTS idx_auth_user_role_role ON auth_user_role(role_id);

-- ============================================================
-- 第五部分：角色权限关联表 (auth_role_permission)
-- ============================================================

CREATE TABLE IF NOT EXISTS auth_role_permission (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    role_id UUID NOT NULL REFERENCES auth_role(id) ON DELETE CASCADE,
    permission_id UUID NOT NULL REFERENCES auth_permission(id) ON DELETE CASCADE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT auth_role_permission_unique UNIQUE (role_id, permission_id)
);

COMMENT ON TABLE auth_role_permission IS '角色权限关联表';
COMMENT ON COLUMN auth_role_permission.role_id IS '角色ID';
COMMENT ON COLUMN auth_role_permission.permission_id IS '权限ID';

-- 角色权限关联索引
CREATE INDEX IF NOT EXISTS idx_auth_role_permission_role ON auth_role_permission(role_id);
CREATE INDEX IF NOT EXISTS idx_auth_role_permission_permission ON auth_role_permission(permission_id);

-- ============================================================
-- 第六部分：审计日志表 (auth_audit_log)
-- ============================================================

CREATE TABLE IF NOT EXISTS auth_audit_log (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID REFERENCES auth_user(id),
    username VARCHAR(50),
    module VARCHAR(50),
    action VARCHAR(30),
    operation VARCHAR(200),
    resource VARCHAR(255),
    method VARCHAR(20),
    ip_address VARCHAR(50),
    location VARCHAR(200),
    user_agent TEXT,
    request_body TEXT,
    response_status INT,
    error_message TEXT,
    execution_time_ms INT,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

COMMENT ON TABLE auth_audit_log IS '审计日志表';
COMMENT ON COLUMN auth_audit_log.user_id IS '操作用户ID';
COMMENT ON COLUMN auth_audit_log.username IS '操作用户名';
COMMENT ON COLUMN auth_audit_log.module IS '功能模块';
COMMENT ON COLUMN auth_audit_log.action IS '操作类型';
COMMENT ON COLUMN auth_audit_log.operation IS '操作描述';
COMMENT ON COLUMN auth_audit_log.resource IS '资源路径';
COMMENT ON COLUMN auth_audit_log.method IS 'HTTP方法';
COMMENT ON COLUMN auth_audit_log.ip_address IS 'IP地址';
COMMENT ON COLUMN auth_audit_log.location IS '地理位置';
COMMENT ON COLUMN auth_audit_log.user_agent IS '用户代理';
COMMENT ON COLUMN auth_audit_log.request_body IS '请求体';
COMMENT ON COLUMN auth_audit_log.response_status IS '响应状态码';
COMMENT ON COLUMN auth_audit_log.error_message IS '错误信息';
COMMENT ON COLUMN auth_audit_log.execution_time_ms IS '执行时长（毫秒）';
COMMENT ON COLUMN auth_audit_log.created_at IS '操作时间';

-- 审计日志索引
CREATE INDEX IF NOT EXISTS idx_auth_audit_log_user ON auth_audit_log(user_id);
CREATE INDEX IF NOT EXISTS idx_auth_audit_log_module ON auth_audit_log(module);
CREATE INDEX IF NOT EXISTS idx_auth_audit_log_action ON auth_audit_log(action);
CREATE INDEX IF NOT EXISTS idx_auth_audit_log_created ON auth_audit_log(created_at);

-- ============================================================
-- 第七部分：系统配置表 (auth_sys_config)
-- ============================================================

CREATE TABLE IF NOT EXISTS auth_sys_config (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    config_key VARCHAR(128) NOT NULL UNIQUE,
    config_value TEXT,
    description VARCHAR(256),
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

COMMENT ON TABLE auth_sys_config IS '系统配置表';
COMMENT ON COLUMN auth_sys_config.config_key IS '配置键（唯一）';
COMMENT ON COLUMN auth_sys_config.config_value IS '配置值';
COMMENT ON COLUMN auth_sys_config.description IS '配置描述';

-- 系统配置索引
CREATE INDEX IF NOT EXISTS idx_auth_sys_config_key ON auth_sys_config(config_key);

COMMIT;
