Major Features: - ✅ Multi-tenant architecture (tenant isolation) - ✅ Employee CRUD with lifecycle management (onboarding/offboarding) - ✅ Department tree structure with email domain management - ✅ Company info management (single-record editing) - ✅ System functions CRUD (permission management) - ✅ Email account management (multi-account per employee) - ✅ Keycloak SSO integration (auth.lab.taipei) - ✅ Redis session storage (10.1.0.254:6379) - Solves Cookie 4KB limitation - Cross-system session sharing - Sliding expiration (8 hours) - Automatic token refresh Technical Stack: Backend: - FastAPI + SQLAlchemy - PostgreSQL 16 (10.1.0.20:5433) - Keycloak Admin API integration - Docker Mailserver integration (SSH) - Alembic migrations Frontend: - Next.js 14 (App Router) - NextAuth 4 with Keycloak Provider - Redis session storage (ioredis) - Tailwind CSS Infrastructure: - Redis 7 (10.1.0.254:6379) - Session + Cache - Keycloak 26.1.0 (auth.lab.taipei) - Docker Mailserver (10.1.0.254) Architecture Highlights: - Session管理由 Keycloak + Redis 統一控制 - 支援多系統 (HR/WebMail/Calendar/Drive/Office) 共享 session - Token 自動刷新,異質服務整合 - 未來可無縫遷移到雲端 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
323 lines
10 KiB
SQL
323 lines
10 KiB
SQL
-- =========================================
|
||
-- HR Portal 初始化系統資料表
|
||
-- 根據 app/models/installation.py 建立完整表結構
|
||
-- =========================================
|
||
|
||
-- 1. installation_sessions (安裝會話)
|
||
DROP TABLE IF EXISTS installation_sessions CASCADE;
|
||
CREATE TABLE installation_sessions (
|
||
id SERIAL PRIMARY KEY,
|
||
tenant_id INTEGER,
|
||
session_name VARCHAR(200),
|
||
environment VARCHAR(20), -- development/testing/production
|
||
|
||
-- 狀態追蹤
|
||
started_at TIMESTAMP DEFAULT NOW(),
|
||
completed_at TIMESTAMP,
|
||
status VARCHAR(20) DEFAULT 'in_progress', -- in_progress/completed/failed/paused
|
||
|
||
-- 進度統計
|
||
total_checklist_items INTEGER,
|
||
passed_checklist_items INTEGER DEFAULT 0,
|
||
failed_checklist_items INTEGER DEFAULT 0,
|
||
total_steps INTEGER,
|
||
completed_steps INTEGER DEFAULT 0,
|
||
failed_steps INTEGER DEFAULT 0,
|
||
|
||
executed_by VARCHAR(100),
|
||
|
||
-- 存取控制
|
||
is_locked BOOLEAN DEFAULT FALSE,
|
||
locked_at TIMESTAMP,
|
||
locked_by VARCHAR(100),
|
||
lock_reason VARCHAR(200),
|
||
|
||
is_unlocked BOOLEAN DEFAULT FALSE,
|
||
unlocked_at TIMESTAMP,
|
||
unlocked_by VARCHAR(100),
|
||
unlock_reason VARCHAR(200),
|
||
unlock_expires_at TIMESTAMP,
|
||
|
||
last_viewed_at TIMESTAMP,
|
||
last_viewed_by VARCHAR(100),
|
||
view_count INTEGER DEFAULT 0,
|
||
|
||
created_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
|
||
-- 2. installation_checklist_items (檢查項目定義)
|
||
DROP TABLE IF EXISTS installation_checklist_items CASCADE;
|
||
CREATE TABLE installation_checklist_items (
|
||
id SERIAL PRIMARY KEY,
|
||
category VARCHAR(50) NOT NULL, -- hardware/network/software/container/security
|
||
item_code VARCHAR(100) UNIQUE NOT NULL,
|
||
item_name VARCHAR(200) NOT NULL,
|
||
check_type VARCHAR(50) NOT NULL, -- command/api/config/manual
|
||
check_command TEXT,
|
||
expected_value TEXT,
|
||
min_requirement TEXT,
|
||
recommended_value TEXT,
|
||
is_required BOOLEAN DEFAULT TRUE,
|
||
sequence_order INTEGER NOT NULL,
|
||
description TEXT,
|
||
created_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
|
||
-- 3. installation_checklist_results (檢查結果)
|
||
DROP TABLE IF EXISTS installation_checklist_results CASCADE;
|
||
CREATE TABLE installation_checklist_results (
|
||
id SERIAL PRIMARY KEY,
|
||
tenant_id INTEGER,
|
||
session_id INTEGER REFERENCES installation_sessions(id) ON DELETE CASCADE,
|
||
checklist_item_id INTEGER REFERENCES installation_checklist_items(id) ON DELETE CASCADE NOT NULL,
|
||
status VARCHAR(20) NOT NULL, -- pass/fail/warning/pending/skip
|
||
actual_value TEXT,
|
||
checked_at TIMESTAMP,
|
||
checked_by VARCHAR(100),
|
||
auto_checked BOOLEAN DEFAULT FALSE,
|
||
remarks TEXT,
|
||
created_at TIMESTAMP DEFAULT NOW(),
|
||
updated_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
|
||
-- 4. installation_steps (安裝步驟定義)
|
||
DROP TABLE IF EXISTS installation_steps CASCADE;
|
||
CREATE TABLE installation_steps (
|
||
id SERIAL PRIMARY KEY,
|
||
step_code VARCHAR(50) UNIQUE NOT NULL,
|
||
step_name VARCHAR(200) NOT NULL,
|
||
phase VARCHAR(20) NOT NULL, -- phase1/phase2/...
|
||
sequence_order INTEGER NOT NULL,
|
||
description TEXT,
|
||
execution_type VARCHAR(50), -- auto/manual/script
|
||
execution_script TEXT,
|
||
depends_on_steps VARCHAR[], -- 依賴的步驟代碼
|
||
is_required BOOLEAN DEFAULT TRUE,
|
||
created_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
|
||
-- 5. installation_logs (安裝執行記錄)
|
||
DROP TABLE IF EXISTS installation_logs CASCADE;
|
||
CREATE TABLE installation_logs (
|
||
id SERIAL PRIMARY KEY,
|
||
tenant_id INTEGER,
|
||
step_id INTEGER REFERENCES installation_steps(id) ON DELETE CASCADE NOT NULL,
|
||
session_id INTEGER REFERENCES installation_sessions(id) ON DELETE CASCADE,
|
||
status VARCHAR(20) NOT NULL, -- pending/running/success/failed/skipped
|
||
started_at TIMESTAMP,
|
||
completed_at TIMESTAMP,
|
||
executed_by VARCHAR(100),
|
||
execution_method VARCHAR(50), -- manual/auto/api/script
|
||
result_data JSONB,
|
||
error_message TEXT,
|
||
retry_count INTEGER DEFAULT 0,
|
||
remarks TEXT,
|
||
created_at TIMESTAMP DEFAULT NOW(),
|
||
updated_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
|
||
-- 6. installation_tenant_info (租戶初始化資訊)
|
||
DROP TABLE IF EXISTS installation_tenant_info CASCADE;
|
||
CREATE TABLE installation_tenant_info (
|
||
id SERIAL PRIMARY KEY,
|
||
tenant_id INTEGER UNIQUE,
|
||
session_id INTEGER REFERENCES installation_sessions(id) ON DELETE SET NULL,
|
||
|
||
-- 公司基本資訊
|
||
company_name VARCHAR(200),
|
||
company_name_en VARCHAR(200),
|
||
tenant_code VARCHAR(50),
|
||
tenant_prefix VARCHAR(10),
|
||
tax_id VARCHAR(50),
|
||
industry VARCHAR(100),
|
||
company_size VARCHAR(20), -- small/medium/large
|
||
|
||
-- 聯絡資訊
|
||
tel VARCHAR(20),
|
||
phone VARCHAR(50),
|
||
fax VARCHAR(50),
|
||
email VARCHAR(200),
|
||
website VARCHAR(200),
|
||
add TEXT,
|
||
address TEXT,
|
||
address_en TEXT,
|
||
|
||
-- 郵件網域設定
|
||
domain_set INTEGER DEFAULT 2, -- 1=組織網域, 2=部門網域
|
||
domain VARCHAR(100),
|
||
|
||
-- 負責人資訊
|
||
representative_name VARCHAR(100),
|
||
representative_title VARCHAR(100),
|
||
representative_email VARCHAR(200),
|
||
representative_phone VARCHAR(50),
|
||
|
||
-- 系統管理員資訊
|
||
admin_employee_id VARCHAR(50),
|
||
admin_username VARCHAR(100),
|
||
admin_legal_name VARCHAR(100),
|
||
admin_english_name VARCHAR(100),
|
||
admin_email VARCHAR(200),
|
||
admin_phone VARCHAR(50),
|
||
|
||
-- 初始設定
|
||
default_language VARCHAR(10) DEFAULT 'zh-TW',
|
||
timezone VARCHAR(50) DEFAULT 'Asia/Taipei',
|
||
date_format VARCHAR(20) DEFAULT 'YYYY-MM-DD',
|
||
currency VARCHAR(10) DEFAULT 'TWD',
|
||
|
||
-- 狀態追蹤
|
||
is_completed BOOLEAN DEFAULT FALSE,
|
||
completed_at TIMESTAMP,
|
||
completed_by VARCHAR(100),
|
||
|
||
created_at TIMESTAMP DEFAULT NOW(),
|
||
updated_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
|
||
-- 7. installation_mail_domain_setting (郵件網域設定)
|
||
DROP TABLE IF EXISTS installation_mail_domain_setting CASCADE;
|
||
CREATE TABLE installation_mail_domain_setting (
|
||
id SERIAL PRIMARY KEY,
|
||
session_id INTEGER REFERENCES installation_sessions(id) ON DELETE CASCADE NOT NULL,
|
||
domain_set INTEGER NOT NULL, -- 1=組織網域, 2=部門網域
|
||
domain VARCHAR(100), -- 組織網域(domain_set=1 時使用)
|
||
created_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
|
||
-- 8. installation_department_setup (部門架構設定)
|
||
DROP TABLE IF EXISTS installation_department_setup CASCADE;
|
||
CREATE TABLE installation_department_setup (
|
||
id SERIAL PRIMARY KEY,
|
||
tenant_id INTEGER,
|
||
session_id INTEGER REFERENCES installation_sessions(id) ON DELETE CASCADE,
|
||
department_code VARCHAR(50) NOT NULL,
|
||
department_name VARCHAR(200) NOT NULL,
|
||
department_name_en VARCHAR(200),
|
||
email_domain VARCHAR(100),
|
||
parent_code VARCHAR(50),
|
||
depth INTEGER DEFAULT 0,
|
||
manager_name VARCHAR(100),
|
||
is_created BOOLEAN DEFAULT FALSE,
|
||
created_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
|
||
-- 9. temporary_passwords (臨時密碼)
|
||
DROP TABLE IF EXISTS temporary_passwords CASCADE;
|
||
CREATE TABLE temporary_passwords (
|
||
id SERIAL PRIMARY KEY,
|
||
tenant_id INTEGER,
|
||
employee_id INTEGER,
|
||
username VARCHAR(100) NOT NULL,
|
||
session_id INTEGER REFERENCES installation_sessions(id) ON DELETE SET NULL,
|
||
|
||
-- 密碼資訊
|
||
password_hash VARCHAR(255) NOT NULL,
|
||
plain_password VARCHAR(100),
|
||
password_method VARCHAR(20), -- auto/manual
|
||
is_temporary BOOLEAN DEFAULT TRUE,
|
||
must_change_on_login BOOLEAN DEFAULT TRUE,
|
||
|
||
-- 有效期限
|
||
created_at TIMESTAMP DEFAULT NOW(),
|
||
expires_at TIMESTAMP,
|
||
|
||
-- 使用狀態
|
||
is_used BOOLEAN DEFAULT FALSE,
|
||
used_at TIMESTAMP,
|
||
first_login_at TIMESTAMP,
|
||
password_changed_at TIMESTAMP,
|
||
|
||
-- 查看控制
|
||
is_viewable BOOLEAN DEFAULT TRUE,
|
||
viewable_until TIMESTAMP,
|
||
view_count INTEGER DEFAULT 0,
|
||
last_viewed_at TIMESTAMP,
|
||
first_viewed_at TIMESTAMP,
|
||
|
||
-- 明文密碼清除記錄
|
||
plain_password_cleared_at TIMESTAMP,
|
||
cleared_reason VARCHAR(100)
|
||
);
|
||
|
||
-- 10. installation_access_logs (存取審計日誌)
|
||
DROP TABLE IF EXISTS installation_access_logs CASCADE;
|
||
CREATE TABLE installation_access_logs (
|
||
id SERIAL PRIMARY KEY,
|
||
session_id INTEGER REFERENCES installation_sessions(id) ON DELETE CASCADE NOT NULL,
|
||
action VARCHAR(50) NOT NULL, -- lock/unlock/view/download_pdf
|
||
action_by VARCHAR(100),
|
||
action_method VARCHAR(50), -- database/api/system
|
||
ip_address VARCHAR(50),
|
||
user_agent TEXT,
|
||
access_granted BOOLEAN,
|
||
deny_reason VARCHAR(200),
|
||
sensitive_data_accessed VARCHAR[],
|
||
created_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
|
||
-- 11. installation_environment_config (環境配置記錄)
|
||
DROP TABLE IF EXISTS installation_environment_config CASCADE;
|
||
CREATE TABLE installation_environment_config (
|
||
id SERIAL PRIMARY KEY,
|
||
session_id INTEGER REFERENCES installation_sessions(id) ON DELETE SET NULL,
|
||
config_key VARCHAR(100) UNIQUE NOT NULL,
|
||
config_value TEXT,
|
||
config_category VARCHAR(50) NOT NULL, -- redis/database/keycloak/mailserver/nextcloud/traefik
|
||
is_sensitive BOOLEAN DEFAULT FALSE,
|
||
is_configured BOOLEAN DEFAULT FALSE,
|
||
configured_at TIMESTAMP,
|
||
configured_by VARCHAR(100),
|
||
description TEXT,
|
||
created_at TIMESTAMP DEFAULT NOW(),
|
||
updated_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
CREATE INDEX idx_env_config_key ON installation_environment_config(config_key);
|
||
CREATE INDEX idx_env_config_category ON installation_environment_config(config_category);
|
||
|
||
-- 12. installation_system_status (系統狀態記錄)
|
||
DROP TABLE IF EXISTS installation_system_status CASCADE;
|
||
CREATE TABLE installation_system_status (
|
||
id SERIAL PRIMARY KEY,
|
||
current_phase VARCHAR(20) NOT NULL, -- initialization/operational/transition
|
||
previous_phase VARCHAR(20),
|
||
phase_changed_at TIMESTAMP,
|
||
phase_changed_by VARCHAR(100),
|
||
phase_change_reason TEXT,
|
||
|
||
-- Initialization 階段資訊
|
||
initialized_at TIMESTAMP,
|
||
initialized_by VARCHAR(100),
|
||
initialization_completed BOOLEAN DEFAULT FALSE,
|
||
|
||
-- Operational 階段資訊
|
||
last_health_check_at TIMESTAMP,
|
||
health_check_status VARCHAR(20), -- healthy/degraded/unhealthy
|
||
operational_since TIMESTAMP,
|
||
|
||
-- Transition 階段資訊
|
||
transition_started_at TIMESTAMP,
|
||
transition_approved_by VARCHAR(100),
|
||
env_db_consistent BOOLEAN,
|
||
consistency_checked_at TIMESTAMP,
|
||
inconsistencies TEXT,
|
||
|
||
-- 系統鎖定
|
||
is_locked BOOLEAN DEFAULT FALSE,
|
||
locked_at TIMESTAMP,
|
||
locked_by VARCHAR(100),
|
||
lock_reason VARCHAR(200),
|
||
|
||
created_at TIMESTAMP DEFAULT NOW(),
|
||
updated_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
CREATE INDEX idx_system_status_phase ON installation_system_status(current_phase);
|
||
|
||
-- =========================================
|
||
-- 初始化系統狀態
|
||
-- =========================================
|
||
INSERT INTO installation_system_status (current_phase, initialization_completed)
|
||
VALUES ('initialization', FALSE);
|
||
|
||
COMMIT;
|