Files
hr-portal/DATABASE-TEST.md
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

417 lines
8.0 KiB
Markdown

# 🧪 資料庫測試指南
## 📋 測試流程
### 前置需求
- ✅ Ubuntu Server (10.1.0.254) 可訪問
- ✅ PostgreSQL 運行中
- ✅ SSH 配置完成
---
## 🚀 快速開始 (推薦)
### Windows PowerShell
```powershell
# 1. 切換到腳本目錄
cd W:\DevOps-Workspace\hr-portal\scripts
# 2. 檢查 PostgreSQL 連接
.\check-postgres.ps1
# 3. 設定資料庫 (會提示輸入密碼)
.\setup-db-simple.ps1
# 4. 驗證設定
# (會在步驟 3 自動執行)
```
### 執行測試資料
```powershell
# 透過 SSH 執行測試資料插入
cd W:\DevOps-Workspace\hr-portal\scripts
# 上傳 SQL 檔案
scp insert-test-data.sql ubuntu@10.1.0.254:/tmp/
# 執行 SQL
ssh ubuntu@10.1.0.254 "docker exec -i postgres psql -U hr_user -d hr_portal < /tmp/insert-test-data.sql"
```
---
## 📝 手動測試步驟
### 步驟 1: 連接到 PostgreSQL
```bash
# SSH 到 Ubuntu Server
ssh ubuntu@10.1.0.254
# 進入 PostgreSQL 容器
docker exec -it postgres psql -U hr_user -d hr_portal
```
### 步驟 2: 驗證資料表
```sql
-- 列出所有資料表
\dt
-- 應該看到:
-- audit_logs
-- business_units
-- divisions
-- email_accounts
-- employees
-- network_drives
-- project_members
-- projects
-- system_permissions
```
### 步驟 3: 查詢基礎資料
```sql
-- 查看事業部
SELECT * FROM business_units;
-- 查看部門
SELECT * FROM divisions;
-- 查看視圖
\dv
-- 測試視圖
SELECT * FROM v_employees_full;
SELECT * FROM v_division_headcount;
```
### 步驟 4: 插入測試資料
```sql
-- 在 psql 中執行
\i /tmp/insert-test-data.sql
```
或從外部執行:
```bash
# 在 Ubuntu Server 上
docker exec -i postgres psql -U hr_user -d hr_portal < /tmp/insert-test-data.sql
```
### 步驟 5: 驗證測試資料
```sql
-- 查看員工
SELECT employee_id, username, chinese_name, email, position
FROM employees
ORDER BY employee_id;
-- 查看完整員工資訊 (含事業部/部門)
SELECT
e.employee_id,
e.chinese_name,
bu.name as business_unit,
d.name as division,
e.position
FROM employees e
LEFT JOIN business_units bu ON e.business_unit_id = bu.id
LEFT JOIN divisions d ON e.division_id = d.id
ORDER BY e.employee_id;
-- 查看員工的資源配置
SELECT
e.username,
e.chinese_name,
(SELECT COUNT(*) FROM email_accounts WHERE employee_id = e.id) as emails,
(SELECT COUNT(*) FROM network_drives WHERE employee_id = e.id) as drives,
(SELECT COUNT(*) FROM system_permissions WHERE employee_id = e.id AND is_active = true) as permissions
FROM employees e;
-- 查看專案與成員
SELECT
p.project_code,
p.project_name,
e.chinese_name as manager,
(SELECT COUNT(*) FROM project_members WHERE project_id = p.id) as members
FROM projects p
LEFT JOIN employees e ON p.project_manager_id = e.id;
```
---
## 🔍 常用查詢
### 查詢特定員工的完整資訊
```sql
-- 以 alice.wang 為例
SELECT
e.*,
bu.name as business_unit_name,
d.name as division_name
FROM employees e
LEFT JOIN business_units bu ON e.business_unit_id = bu.id
LEFT JOIN divisions d ON e.division_id = d.id
WHERE e.username = 'alice.wang';
```
### 查詢員工的郵件帳號
```sql
SELECT
e.username,
e.email,
ea.email_address,
ea.mailbox_quota_mb,
ea.is_active
FROM employees e
LEFT JOIN email_accounts ea ON e.id = ea.employee_id
WHERE e.username = 'alice.wang';
```
### 查詢員工的網路硬碟
```sql
SELECT
e.username,
nd.drive_name,
nd.quota_gb,
nd.webdav_url,
nd.smb_path
FROM employees e
LEFT JOIN network_drives nd ON e.id = nd.employee_id
WHERE e.username = 'alice.wang';
```
### 查詢員工的系統權限
```sql
SELECT
e.username,
sp.system_name,
sp.access_level,
sp.granted_at
FROM employees e
LEFT JOIN system_permissions sp ON e.id = sp.employee_id
WHERE e.username = 'alice.wang'
AND sp.is_active = true;
```
### 部門統計
```sql
SELECT
bu.name as business_unit,
d.name as division,
COUNT(e.id) as employee_count
FROM divisions d
LEFT JOIN business_units bu ON d.business_unit_id = bu.id
LEFT JOIN employees e ON d.id = e.division_id AND e.status = 'active'
GROUP BY bu.name, d.name
ORDER BY bu.name, d.name;
```
---
## 🧪 功能測試
### 測試 1: 新增員工
```sql
INSERT INTO employees (
employee_id,
username,
first_name,
last_name,
chinese_name,
email,
business_unit_id,
division_id,
position,
job_level,
hire_date,
status
) VALUES (
'E9999',
'test.user',
'Test',
'User',
'測試用戶',
'test.user@lab.taipei',
3, -- 智能研發
7, -- 軟體研發部
'Tester',
'Junior',
CURRENT_DATE,
'active'
);
-- 驗證
SELECT * FROM employees WHERE username = 'test.user';
```
### 測試 2: 更新員工資料
```sql
UPDATE employees
SET
job_level = 'Staff',
position = 'Senior Tester',
updated_at = CURRENT_TIMESTAMP
WHERE username = 'test.user';
-- 驗證
SELECT employee_id, username, position, job_level, updated_at
FROM employees
WHERE username = 'test.user';
```
### 測試 3: 關聯查詢
```sql
-- 查詢智能研發服務事業部的所有員工
SELECT
e.employee_id,
e.chinese_name,
d.name as division,
e.position
FROM employees e
JOIN divisions d ON e.division_id = d.id
JOIN business_units bu ON d.business_unit_id = bu.id
WHERE bu.code = 'smart-rd'
AND e.status = 'active'
ORDER BY d.name, e.employee_id;
```
### 測試 4: 聚合統計
```sql
-- 各事業部員工統計
SELECT
bu.name as business_unit,
COUNT(e.id) as total_employees,
COUNT(CASE WHEN e.job_level IN ('C-Level', 'VP', 'Director', 'Manager') THEN 1 END) as managers,
COUNT(CASE WHEN e.job_level NOT IN ('C-Level', 'VP', 'Director', 'Manager') THEN 1 END) as staff
FROM business_units bu
LEFT JOIN divisions d ON bu.id = d.business_unit_id
LEFT JOIN employees e ON d.id = e.division_id AND e.status = 'active'
GROUP BY bu.name
ORDER BY bu.name;
```
---
## 🔧 故障排除
### 問題 1: 無法連接資料庫
```bash
# 檢查 PostgreSQL 容器
docker ps | grep postgres
# 檢查端口
sudo netstat -tlnp | grep 5432
# 檢查防火牆
sudo ufw status
```
### 問題 2: 權限不足
```sql
-- 以 postgres 超級用戶執行
GRANT ALL PRIVILEGES ON DATABASE hr_portal TO hr_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO hr_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO hr_user;
```
### 問題 3: 重置資料庫
```bash
# 刪除並重建資料庫
docker exec postgres psql -U postgres -c "DROP DATABASE hr_portal;"
docker exec postgres psql -U postgres -c "CREATE DATABASE hr_portal OWNER hr_user;"
# 重新執行 Schema
docker exec -i postgres psql -U hr_user -d hr_portal < /path/to/init-db.sql
```
---
## ✅ 測試檢查清單
測試完成後,確認以下項目:
- [ ] 所有 9 個資料表已建立
- [ ] 3 個視圖可正常查詢
- [ ] 事業部資料 (4 筆)
- [ ] 部門資料 (13 筆)
- [ ] 測試員工資料已插入
- [ ] 關聯查詢正常運作
- [ ] 觸發器自動更新 updated_at
- [ ] 外鍵約束正常運作
---
## 📊 效能測試
### 查詢效能
```sql
-- 開啟查詢分析
EXPLAIN ANALYZE
SELECT * FROM v_employees_full;
-- 檢查索引
SELECT
tablename,
indexname,
indexdef
FROM pg_indexes
WHERE schemaname = 'public'
ORDER BY tablename, indexname;
```
### 資料庫大小
```sql
-- 查看資料庫大小
SELECT
pg_size_pretty(pg_database_size('hr_portal')) as database_size;
-- 查看各表大小
SELECT
schemaname,
tablename,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as size
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
```
---
## 🔄 下一步
資料庫測試通過後:
1. ✅ 更新 `backend/.env` 設定 DATABASE_URL
2. ✅ 啟動後端服務測試連接
3. ✅ 使用 Python 測試 ORM 模型
4. ✅ 開發 API 端點
```bash
# 測試後端連接
cd backend
python -c "from app.db.database import engine; print(engine.connect().execute('SELECT version()').fetchone())"
```
---
**資料庫設定與測試完成!** 🎉