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>
417 lines
8.0 KiB
Markdown
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())"
|
|
```
|
|
|
|
---
|
|
|
|
**資料庫設定與測試完成!** 🎉
|