-- WBX Spring Framework — PostgreSQL 스키마

CREATE TABLE IF NOT EXISTS wbx_users (
    id                    BIGSERIAL PRIMARY KEY,
    email                 VARCHAR(255) NOT NULL UNIQUE,
    username              VARCHAR(100) NOT NULL UNIQUE,
    hashed_password       VARCHAR(500),
    full_name             VARCHAR(255),
    phone                 VARCHAR(50),
    department_id         BIGINT,
    position_title        VARCHAR(100),
    employee_number       VARCHAR(50) UNIQUE,
    is_active             BOOLEAN DEFAULT TRUE,
    is_admin              BOOLEAN DEFAULT FALSE,
    mfa_enabled           BOOLEAN DEFAULT FALSE,
    azure_oid             VARCHAR(255),
    sso_provider          VARCHAR(50),
    failed_login_attempts INT DEFAULT 0,
    last_failed_login     TIMESTAMP,
    locked_until          TIMESTAMP,
    password_changed_at   TIMESTAMP,
    must_change_password  BOOLEAN DEFAULT FALSE,
    last_login_at         TIMESTAMP,
    created_at            TIMESTAMP DEFAULT NOW(),
    updated_at            TIMESTAMP DEFAULT NOW(),
    created_by            BIGINT,
    updated_by            BIGINT
);

CREATE TABLE IF NOT EXISTS wbx_roles (
    id          BIGSERIAL PRIMARY KEY,
    code        VARCHAR(50) NOT NULL UNIQUE,
    name        VARCHAR(100) NOT NULL,
    description VARCHAR(500),
    is_system   BOOLEAN DEFAULT FALSE,
    created_at  TIMESTAMP DEFAULT NOW(),
    updated_at  TIMESTAMP DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS wbx_user_roles (
    id      BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL REFERENCES wbx_users(id),
    role_id BIGINT NOT NULL REFERENCES wbx_roles(id),
    UNIQUE (user_id, role_id)
);

CREATE TABLE IF NOT EXISTS wbx_role_permissions (
    id         BIGSERIAL PRIMARY KEY,
    role_id    BIGINT NOT NULL REFERENCES wbx_roles(id),
    module     VARCHAR(100) NOT NULL,
    action     VARCHAR(50) NOT NULL,
    dept_scope VARCHAR(20) DEFAULT 'OWN',
    UNIQUE (role_id, module, action)
);

CREATE TABLE IF NOT EXISTS wbx_refresh_tokens (
    id          BIGSERIAL PRIMARY KEY,
    user_id     BIGINT NOT NULL REFERENCES wbx_users(id),
    token_hash  VARCHAR(500) NOT NULL,
    device_info VARCHAR(500),
    ip_address  VARCHAR(50),
    expires_at  TIMESTAMP NOT NULL,
    created_at  TIMESTAMP DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS wbx_totp_secrets (
    id               BIGSERIAL PRIMARY KEY,
    user_id          BIGINT NOT NULL UNIQUE REFERENCES wbx_users(id),
    encrypted_secret VARCHAR(500) NOT NULL,
    verified         BOOLEAN DEFAULT FALSE,
    backup_codes     VARCHAR(2000),
    created_at       TIMESTAMP DEFAULT NOW(),
    updated_at       TIMESTAMP DEFAULT NOW(),
    created_by       BIGINT,
    updated_by       BIGINT
);

CREATE TABLE IF NOT EXISTS wbx_login_history (
    id             BIGSERIAL PRIMARY KEY,
    user_id        BIGINT,
    email          VARCHAR(255),
    action         VARCHAR(50),
    auth_method    VARCHAR(50),
    ip_address     VARCHAR(50),
    user_agent     VARCHAR(500),
    failure_reason VARCHAR(500),
    created_at     TIMESTAMP DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS wbx_notifications (
    id         BIGSERIAL PRIMARY KEY,
    user_id    BIGINT NOT NULL REFERENCES wbx_users(id),
    title      VARCHAR(500),
    message    TEXT,
    type       VARCHAR(50),
    is_read    BOOLEAN DEFAULT FALSE,
    link       VARCHAR(1000),
    created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS wbx_audit_logs (
    id          BIGSERIAL PRIMARY KEY,
    user_id     BIGINT,
    username    VARCHAR(255),
    action      VARCHAR(50) NOT NULL,
    resource    VARCHAR(100) NOT NULL,
    resource_id BIGINT,
    detail      VARCHAR(4000),
    ip_address  VARCHAR(50),
    created_at  TIMESTAMP DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS wbx_file_uploads (
    id            BIGSERIAL PRIMARY KEY,
    user_id       BIGINT,
    original_name VARCHAR(500),
    stored_name   VARCHAR(500),
    file_key      VARCHAR(500),
    content_type  VARCHAR(200),
    file_size     BIGINT,
    category      VARCHAR(100),
    created_at    TIMESTAMP DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS wbx_system_config (
    id           BIGSERIAL PRIMARY KEY,
    config_key   VARCHAR(100) NOT NULL UNIQUE,
    config_value VARCHAR(4000),
    value_type   VARCHAR(20) DEFAULT 'STRING',
    description  VARCHAR(500),
    is_editable  BOOLEAN DEFAULT TRUE,
    updated_at   TIMESTAMP DEFAULT NOW(),
    updated_by   BIGINT
);
