Files
hr-portal/QUICKSTART.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

6.9 KiB

🚀 HR Portal - 快速開始指南

這份指南將帶您在 15 分鐘內建立並運行 HR Portal。


📋 檢查清單

在開始前,確認以下項目已就緒:

  • Keycloak 運行中 (https://auth.ease.taipei)
  • PostgreSQL 16 可用
  • Docker Mailserver 運行中 (10.1.0.254)
  • NAS 可訪問 (10.1.0.30)
  • Python 3.11+ 已安裝
  • Node.js 18+ 已安裝

步驟 1: 在 Keycloak 創建 Client (5 分鐘)

1.1 登入 Keycloak Admin

訪問: https://auth.ease.taipei/admin

1.2 創建 Client

1. 選擇 porscheworld realm
2. Clients → Create client

General Settings:
  - Client type: OpenID Connect
  - Client ID: hr-portal
  - Name: HR Portal
  - Description: 人資管理系統

點擊 Next

Capability config:
  - Client authentication: ON
  - Authorization: OFF
  - Authentication flow:
    ✓ Standard flow
    ✓ Direct access grants

點擊 Next

Login settings:
  - Root URL: https://hr.porscheworld.tw
  - Home URL: https://hr.porscheworld.tw
  - Valid redirect URIs:
    - https://hr.porscheworld.tw/*
    - http://localhost:3000/* (開發用)
  - Valid post logout redirect URIs: +
  - Web origins:
    - https://hr.porscheworld.tw
    - http://localhost:3000 (開發用)

點擊 Save

1.3 取得 Client Secret

進入剛創建的 hr-portal client
→ Credentials 標籤頁
→ 複製 "Client secret"

1.4 設定 Service Account Roles (用於後端 API)

進入 hr-portal client
→ Service account roles 標籤
→ Assign role
→ Filter by realm roles
→ 選擇並新增:
  - manage-users
  - view-users
  - manage-realm (可選)

步驟 2: 設定資料庫 (3 分鐘)

2.1 創建資料庫

# 方式 1: 使用 psql
createdb -h 10.1.0.254 -U postgres hr_portal

# 方式 2: 使用 SQL
psql -h 10.1.0.254 -U postgres -c "CREATE DATABASE hr_portal;"

2.2 創建資料庫用戶

-- 連接到 PostgreSQL
psql -h 10.1.0.254 -U postgres

-- 創建用戶
CREATE USER hr_user WITH PASSWORD 'your_strong_password';

-- 授予權限
GRANT ALL PRIVILEGES ON DATABASE hr_portal TO hr_user;

-- 退出
\q

2.3 初始化 Schema

cd hr-portal
psql -h 10.1.0.254 -U hr_user -d hr_portal -f scripts/init-db.sql

步驟 3: 設定後端 (3 分鐘)

3.1 安裝 Python 依賴

cd backend

# 建議使用虛擬環境
python -m venv venv

# 啟動虛擬環境
# Windows
venv\Scripts\activate
# Linux/Mac
source venv/bin/activate

# 安裝依賴
pip install -r requirements.txt

3.2 配置環境變數

# 複製範例檔案
cp .env.example .env

# 編輯 .env (使用 VSCode 或記事本)
code .env

填入以下資訊:

# 資料庫 (修改這裡)
DATABASE_URL=postgresql://hr_user:your_strong_password@10.1.0.254:5432/hr_portal

# Keycloak (修改這裡)
KEYCLOAK_URL=https://auth.ease.taipei
KEYCLOAK_REALM=porscheworld
KEYCLOAK_CLIENT_ID=hr-portal
KEYCLOAK_CLIENT_SECRET=【步驟1.3取得的Secret】

# Keycloak Admin (用於創建用戶)
KEYCLOAK_ADMIN_USERNAME=admin
KEYCLOAK_ADMIN_PASSWORD=【你的Keycloak管理員密碼】

# 其他保持預設即可

3.3 啟動後端

uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

成功訊息:

INFO:     Started server process
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000

測試: http://localhost:8000/health


步驟 4: 設定前端 (2 分鐘)

4.1 安裝 Node.js 依賴

# 新開一個終端機
cd frontend

npm install

4.2 配置環境變數

cp .env.example .env
code .env

填入以下資訊:

# API 端點
VITE_API_URL=http://localhost:8000/api/v1

# Keycloak
VITE_KEYCLOAK_URL=https://auth.ease.taipei
VITE_KEYCLOAK_REALM=porscheworld
VITE_KEYCLOAK_CLIENT_ID=hr-portal

4.3 啟動前端

npm run dev

成功訊息:

  VITE v5.0.11  ready in 1234 ms

  ➜  Local:   http://localhost:3000/
  ➜  Network: use --host to expose

步驟 5: 測試系統 (2 分鐘)

5.1 訪問應用

瀏覽器開啟: http://localhost:3000

5.2 測試 SSO 登入

1. 點擊「登入」按鈕
2. 自動跳轉到 Keycloak 登入頁面
3. 使用現有帳號登入 (例如: porsche)
4. 成功返回並顯示個人儀表板

5.3 測試 API

打開 Swagger 文檔: http://localhost:8000/api/docs

1. 點擊右上角「Authorize」按鈕
2. 輸入 Access Token (從瀏覽器開發者工具取得)
3. 測試 API 端點

🎉 完成!

現在您已經成功啟動 HR Portal!

下一步

  1. 創建第一個員工

  2. 探索功能

    • 員工管理
    • 郵件帳號管理
    • 網路硬碟配額
    • 個人儀表板
  3. 客製化

    • 修改樣式和佈局
    • 新增自訂欄位
    • 整合其他系統

🐛 常見問題

Q1: 無法連接到 Keycloak

症狀: 登入時出現網路錯誤

解決方案:

# 檢查 Keycloak 是否運行
curl -k https://auth.ease.taipei

# 檢查 Client 設定是否正確
# - Client ID 是否為 hr-portal
# - Redirect URI 是否包含 http://localhost:3000/*

Q2: 資料庫連接失敗

症狀: 後端啟動時出現 "could not connect to server"

解決方案:

# 檢查資料庫是否運行
psql -h 10.1.0.254 -U hr_user -d hr_portal -c "SELECT 1;"

# 檢查 DATABASE_URL 是否正確
# 格式: postgresql://用戶名:密碼@主機:埠/資料庫名

Q3: CORS 錯誤

症狀: 前端無法呼叫後端 API

解決方案:

# 確認 backend/.env 中的 CORS_ORIGINS 包含前端網址
CORS_ORIGINS=["http://localhost:3000", "https://hr.porscheworld.tw"]

Q4: Token 過期

症狀: API 呼叫返回 401 Unauthorized

解決方案:

  • Keycloak Access Token 預設 5-10 分鐘過期
  • 前端會自動刷新 Token
  • 如果仍有問題,重新登入即可

📚 更多資源


💡 開發技巧

後端熱重載

後端使用 --reload 參數,修改程式碼會自動重啟:

uvicorn app.main:app --reload

前端熱重載

前端使用 Vite,修改程式碼會自動更新瀏覽器:

npm run dev

除錯技巧

# 在後端程式碼中加入
import pdb; pdb.set_trace()  # 斷點除錯

# 或使用 loguru
from loguru import logger
logger.debug(f"變數值: {variable}")

🚀 準備部署?

當開發完成,準備部署到生產環境時:

# 1. 使用 Docker Compose 部署
docker compose up -d

# 2. 或參考部署文檔
# 查看 README.md 的「Docker 部署」章節

祝開發順利! 🎊

有問題隨時在專案 Issue 區提問,或聯絡 IT 團隊。