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>
This commit is contained in:
322
backend/create_installation_tables.sql
Normal file
322
backend/create_installation_tables.sql
Normal file
@@ -0,0 +1,322 @@
|
||||
-- =========================================
|
||||
-- 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;
|
||||
Reference in New Issue
Block a user