Files
hr-portal/backend/create_installation_tables.sql
Porsche Chen 360533393f feat: HR Portal - Complete Multi-Tenant System with Redis Session Storage
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>
2026-02-23 20:12:43 +08:00

323 lines
10 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- =========================================
-- 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;