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:
2026-02-23 20:12:43 +08:00
commit 360533393f
386 changed files with 70353 additions and 0 deletions

325
README_DEVELOPMENT.md Normal file
View File

@@ -0,0 +1,325 @@
# HR Portal 開發環境指南
## 環境架構
```
┌─────────────────────────────────────────────────────────────┐
│ 10.1.0.254 (Ubuntu Server - home) │
│ 角色: 開發 + 測試環境 │
├─────────────────────────────────────────────────────────────┤
│ - Keycloak (SSO): https://auth.ease.taipei │
│ - Gitea (Git): https://git.lab.taipei │
│ - Traefik (反向代理) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 10.1.0.20 (小的 NAS - DS716+II) │
│ 角色: 開發資料庫 │
├─────────────────────────────────────────────────────────────┤
│ - PostgreSQL 16 (port 5433) │
│ - pa64_dev │
│ - hr_portal (HR Portal 開發資料庫) │
│ - pcdm_db │
│ - liwei_inventory │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 10.1.0.245 (Windows 開發機) │
│ 角色: 開發工作站 │
├─────────────────────────────────────────────────────────────┤
│ - 前端開發: http://localhost:10180 (固定 port) │
│ - 後端開發: http://localhost:10181 (固定 port) │
└─────────────────────────────────────────────────────────────┘
```
---
## 快速啟動
### 1. 前置檢查
**檢查 Port 是否被占用**:
```bash
netstat -ano | findstr ":10180" # 前端
netstat -ano | findstr ":10181" # 後端
```
⚠️ **如果 Port 被占用**: 找出 PID 並停止該程序
```bash
taskkill /PID <PID> /F
```
**檢查資料庫連接**:
```bash
python test_db_connection.py
```
### 2. 啟動後端
**方法 A: 使用啟動腳本** (推薦)
```bash
START_BACKEND.bat
```
**方法 B: 手動啟動**
```bash
cd backend
uvicorn app.main:app --host 0.0.0.0 --port 10181 --reload
```
**驗證後端**:
- API 文件: http://localhost:10181/docs
- ReDoc: http://localhost:10181/redoc
- 健康檢查: http://localhost:10181/health
### 3. 啟動前端
**方法 A: 使用啟動腳本** (推薦)
```bash
START_FRONTEND.bat
```
**方法 B: 手動啟動**
```bash
cd frontend
npm run dev -- -p 10180
```
**訪問應用**:
- 首頁: http://localhost:10180
- 登入: http://localhost:10180/auth/signin
---
## 資料庫配置
### 連接資訊
- **主機**: 10.1.0.20
- **Port**: 5433
- **資料庫**: hr_portal
- **用戶**: admin
- **密碼**: DC1qaz2wsx
### 資料庫 URL
```
postgresql+psycopg2://admin:DC1qaz2wsx@10.1.0.20:5433/hr_portal
```
### 資料表結構 (7 個)
1. alembic_version - 版本控制
2. audit_logs - 審計日誌
3. business_units - 事業單位
4. departments - 部門
5. employee_identities - 員工身份 (郵件/NAS/Keycloak)
6. employees - 員工資料
7. network_drives - 網路磁碟配額
---
## Keycloak SSO 配置
### Keycloak 資訊
- **URL**: https://auth.ease.taipei
- **Realm**: porscheworld
- **管理員登入**: https://auth.ease.taipei/admin
### 需要的 Clients
#### hr-portal-web (前端)
- **Client ID**: hr-portal-web
- **Client Type**: Public
- **Valid Redirect URIs**:
- `http://localhost:10180/*`
- `http://10.1.0.245:10180/*`
- `https://hr.ease.taipei/*`
#### hr-backend (後端)
- **Client ID**: hr-backend
- **Client Type**: Confidential
- **Valid Redirect URIs**:
- `http://localhost:10181/*`
- `https://hr-api.ease.taipei/*`
### 檢查 Clients 是否存在
1. 登入 Keycloak Admin Console: https://auth.ease.taipei/admin
2. 選擇 Realm: **porscheworld**
3. 點選左側選單 **Clients**
4. 搜尋 `hr-portal-web``hr-backend`
如果不存在,需要創建這兩個 Clients (參考 [check_keycloak_clients.md](check_keycloak_clients.md))
---
## 開發規範
### Port 規定 ⚠️
**嚴格遵守以下規定**:
- ✅ 前端固定 **port 10180** (不可變更)
- ✅ 後端固定 **port 10181** (不可變更)
- ❌ 不可隨意開啟其他 port (3000, 3001, 8000, 8001...)
- ❌ 遇到 port 衝突時,應停止占用程序,不是改 port
### 資料庫用戶統一
**所有開發都使用 admin 用戶**:
- 用戶: admin
- 密碼: DC1qaz2wsx
- ⚠️ 密碼不含 `!` 符號 (避免 shell 特殊字元問題)
### 環境變數
**後端** (`backend/.env`):
- 已配置完成
- 資料庫使用 admin 用戶
- Keycloak 指向 auth.ease.taipei
**前端** (`frontend/.env.local`):
- 已配置完成
- API 指向 localhost:10181
- Keycloak 指向 auth.ease.taipei
---
## 測試流程
### 1. 後端測試
```bash
# 測試資料庫連接
python test_db_connection.py
# 測試模組載入
python test_simple.py
# 啟動後端
START_BACKEND.bat
# 訪問 API 文件
# http://localhost:10181/docs
```
### 2. 前端測試
```bash
# 安裝依賴 (首次)
cd frontend
npm install
# 啟動前端
cd ..
START_FRONTEND.bat
# 訪問應用
# http://localhost:10180
```
### 3. SSO 登入測試
1. 訪問 http://localhost:10180
2. 點擊登入按鈕
3. 應該會跳轉到 https://auth.ease.taipei
4. 使用 Keycloak 帳號登入
5. 登入成功後跳轉回 HR Portal
⚠️ **如果登入失敗**: 檢查 Keycloak Clients 是否正確配置
---
## 常見問題
### Q1: Port 被占用怎麼辦?
**檢查占用程序**:
```bash
netstat -ano | findstr ":10180"
netstat -ano | findstr ":10181"
```
**停止占用程序**:
```bash
taskkill /PID <PID> /F
```
**原則**: 找出並停止占用程序,不要改 port
### Q2: 資料庫連接失敗?
**檢查**:
1. PostgreSQL 是否運行? `ssh porsche@10.1.0.20 "sudo docker ps | grep postgres1"`
2. 密碼是否正確? `DC1qaz2wsx` (無 `!`)
3. 網路是否通? `ping 10.1.0.20`
### Q3: Keycloak 登入失敗?
**檢查**:
1. Clients 是否存在? (登入 https://auth.ease.taipei/admin 檢查)
2. Redirect URIs 是否包含 `http://localhost:10180/*`
3. Client Secret 是否正確?
### Q4: npm install 失敗?
**清除快取重試**:
```bash
cd frontend
rm -rf node_modules package-lock.json
npm cache clean --force
npm install
```
---
## 開發工具
### 資料庫管理
- **pgAdmin**: http://10.1.0.20:5050
- Email: admin@lab.taipei
- Password: admin
- 連接到 postgres1 容器 (10.1.0.20:5433)
### API 測試
- **Swagger UI**: http://localhost:10181/docs
- **ReDoc**: http://localhost:10181/redoc
### SSO 管理
- **Keycloak Admin**: https://auth.ease.taipei/admin
---
## 部署到測試環境
### 1. 使用 Gitea 推送代碼
```bash
git add .
git commit -m "描述變更內容"
git push origin main
```
### 2. CI/CD 自動部署
推送到 Gitea 後,.gitea/workflows/ci-cd.yml 會自動:
1. 執行測試
2. 建立 Docker 映像
3. 部署到測試環境
4. 更新服務
### 3. 訪問測試環境
- **前端**: https://hr.ease.taipei
- **後端 API**: https://hr-api.ease.taipei
---
## 文件參考
- [HR Portal 設計文件](../../2.專案設計區/4.HR_Portal/HR Portal設計文件.md)
- [資料庫遷移報告](../../4.DevTool/database-migration/)
- [Keycloak Client 檢查](check_keycloak_clients.md)
- [驗證報告](HR_PORTAL_VERIFICATION_REPORT.md)
---
**最後更新**: 2026-02-15
**維護人員**: Claude AI