# 員工到職流程測試指南 (v3.1) ## 測試環境 - **Migration 版本**: 0012 (已執行) - **資料庫**: hr_portal @ 10.1.0.20:5433 - **後端 API**: http://localhost:10181/api/v1 - **前端**: http://localhost:10180 --- ## API 端點清單 ### 1. 個人化服務管理 ```bash # 取得所有可用服務 GET /api/v1/personal-services/services # 查詢使用者已啟用服務 GET /api/v1/personal-services/users/{keycloak_user_id}/services # 啟用單一服務 POST /api/v1/personal-services/users/{keycloak_user_id}/services { "service_id": 1, "quota_gb": 20, "quota_mb": 5120 } # 批次啟用所有服務 POST /api/v1/personal-services/users/{keycloak_user_id}/services/batch-enable { "storage_quota_gb": 20, "email_quota_mb": 5120 } # 停用服務 DELETE /api/v1/personal-services/users/{keycloak_user_id}/services/{service_id} ``` --- ### 2. 員工到職流程 (完整) ```bash # 員工到職 POST /api/v1/emp-lifecycle/onboard Content-Type: application/json { "resume_id": 1, "keycloak_user_id": "550e8400-e29b-41d4-a716-446655440000", "keycloak_username": "wang.ming", "hire_date": "2026-02-20", "departments": [ { "department_id": 9, "position": "資深工程師", "membership_type": "permanent" }, { "department_id": 12, "position": "專案經理", "membership_type": "project" } ], "role_ids": [1, 2], "storage_quota_gb": 20, "email_quota_mb": 5120 } ``` **預期回應**: ```json { "message": "Employee onboarded successfully", "employee": { "tenant_id": 1, "seq_no": 1, "tenant_emp_code": "PWD0001", "keycloak_user_id": "550e8400-e29b-41d4-a716-446655440000", "keycloak_username": "wang.ming", "name": "王明", "hire_date": "2026-02-20" }, "summary": { "departments_assigned": 2, "roles_assigned": 2, "services_enabled": 5 } } ``` --- ### 3. 查詢員工狀態 ```bash # 查詢完整狀態 GET /api/v1/emp-lifecycle/1/1/status # 回應範例 { "employee": { "tenant_id": 1, "seq_no": 1, "tenant_emp_code": "PWD0001", "name": "王明", "keycloak_user_id": "550e8400-e29b-41d4-a716-446655440000", "keycloak_username": "wang.ming", "hire_date": "2026-02-20", "resign_date": null, "employment_status": "active", "storage_quota_gb": 20, "email_quota_mb": 5120 }, "departments": [ { "department_id": 9, "department_name": "玄鐵風能", "position": "資深工程師", "membership_type": "permanent", "joined_at": "2026-02-20T10:00:00" } ], "roles": [ { "role_id": 1, "role_name": "HR管理員", "role_code": "HR_ADMIN", "assigned_at": "2026-02-20T10:00:00" } ], "services": [ { "service_id": 1, "service_name": "單一簽入", "service_code": "SSO", "quota_gb": null, "quota_mb": null, "enabled_at": "2026-02-20T10:00:00" }, { "service_id": 4, "service_name": "網路硬碟", "service_code": "Drive", "quota_gb": 20, "quota_mb": null, "enabled_at": "2026-02-20T10:00:00" } ] } ``` --- ### 4. 員工離職流程 ```bash # 員工離職 POST /api/v1/emp-lifecycle/1/1/offboard # 回應範例 { "message": "Employee offboarded successfully", "employee": { "tenant_emp_code": "PWD0001", "resign_date": "2026-02-20" }, "summary": { "departments_removed": 2, "roles_revoked": 2, "services_disabled": 5 } } ``` --- ## 資料庫驗證查詢 ### 檢查員工任用設定 ```sql SELECT tenant_id, seq_no, tenant_emp_code, tenant_keycloak_user_id, tenant_keycloak_username, hire_at, storage_quota_gb, email_quota_mb, employment_status, is_active FROM tenant_emp_settings WHERE tenant_id = 1; ``` ### 檢查部門歸屬 ```sql SELECT dm.id, dm.employee_id, dm.department_id, d.name AS department_name, dm.position, dm.membership_type, dm.joined_at, dm.ended_at, dm.assigned_by, dm.is_active FROM tenant_dept_members dm LEFT JOIN tenant_departments d ON dm.department_id = d.id WHERE dm.tenant_id = 1 ORDER BY dm.employee_id, dm.joined_at; ``` ### 檢查角色分配 ```sql SELECT ra.id, ra.keycloak_user_id, ra.role_id, r.role_code, r.role_name, ra.assigned_at, ra.revoked_at, ra.assigned_by, ra.is_active FROM tenant_user_role_assignments ra LEFT JOIN tenant_user_roles r ON ra.role_id = r.id WHERE ra.tenant_id = 1 ORDER BY ra.keycloak_user_id, ra.assigned_at; ``` ### 檢查個人化服務 ```sql SELECT ss.id, ss.tenant_keycloak_user_id, ss.service_id, s.service_name, s.service_code, ss.quota_gb, ss.quota_mb, ss.enabled_at, ss.disabled_at, ss.enabled_by, ss.is_active FROM tenant_emp_personal_service_settings ss LEFT JOIN personal_services s ON ss.service_id = s.id WHERE ss.tenant_id = 1 ORDER BY ss.tenant_keycloak_user_id, ss.service_id; ``` --- ## 測試步驟 ### 前置準備 1. **確認資料庫狀態**: ```bash cd q:/porscheworld_develop/hr-portal/backend python -m alembic current # 應顯示: 0012 (head) ``` 2. **啟動後端服務**: ```bash cd q:/porscheworld_develop/hr-portal START_BACKEND.bat ``` 3. **確認服務運行**: ```bash curl http://localhost:10181/api/v1/docs ``` ### 測試流程 #### Step 1: 建立測試用人員基本資料 ```sql -- 手動建立測試資料 (或透過 API) INSERT INTO tenant_emp_resumes (tenant_id, name_tw, name_eng) VALUES (1, '王明', 'Ming Wang') RETURNING id; -- 假設回傳 id = 1 ``` #### Step 2: 執行到職流程 使用 Postman 或 curl: ```bash curl -X POST http://localhost:10181/api/v1/emp-lifecycle/onboard \ -H "Content-Type: application/json" \ -d '{ "resume_id": 1, "keycloak_user_id": "550e8400-e29b-41d4-a716-446655440000", "keycloak_username": "wang.ming", "hire_date": "2026-02-20", "departments": [ {"department_id": 1, "position": "工程師"} ], "role_ids": [1], "storage_quota_gb": 20, "email_quota_mb": 5120 }' ``` #### Step 3: 驗證資料 ```bash # 查詢狀態 curl http://localhost:10181/api/v1/emp-lifecycle/1/1/status ``` #### Step 4: 執行離職流程 ```bash curl -X POST http://localhost:10181/api/v1/emp-lifecycle/1/1/offboard ``` --- ## 預期結果 ### 到職後應建立的資料 1. ✅ `tenant_emp_settings`: 1 筆記錄 2. ✅ `tenant_dept_members`: N 筆記錄(依 departments 數量) 3. ✅ `tenant_user_role_assignments`: N 筆記錄(依 role_ids 數量) 4. ✅ `tenant_emp_personal_service_settings`: 5 筆記錄(所有服務) ### 離職後應更新的資料 1. ✅ `tenant_emp_settings.employment_status` = 'resigned' 2. ✅ `tenant_emp_settings.resign_date` = 當天日期 3. ✅ `tenant_dept_members.is_active` = false, `ended_at` = 當前時間 4. ✅ `tenant_user_role_assignments.is_active` = false, `revoked_at` = 當前時間 5. ✅ `tenant_emp_personal_service_settings.is_active` = false, `disabled_at` = 當前時間 --- ## 故障排除 ### 問題 1: Port 被占用 ```bash # Windows netstat -ano | findstr :10181 taskkill /PID /F ``` ### 問題 2: 資料庫連線失敗 檢查連線字串: ``` postgresql://admin:DC1qaz2wsx@10.1.0.20:5433/hr_portal ``` ### 問題 3: Migration 版本不對 ```bash cd q:/porscheworld_develop/hr-portal/backend python -m alembic upgrade head ``` --- ## 注意事項 ⚠️ **重要**: - 此為測試環境,請勿在正式資料上測試 - 測試前請備份資料庫 - Keycloak User ID 必須是有效的 UUID 格式 - 部門 ID 和角色 ID 必須在資料庫中存在 --- **測試文件版本**: v1.0 **建立日期**: 2026-02-20 **適用架構**: HR Portal v3.1 (多租戶 + 關聯表)