feat: implement user authentication module

- Backend (FastAPI):
  - External API authentication (pj-auth-api.vercel.app)
  - JWT token validation with Redis session storage
  - RBAC with department isolation
  - User, Role, Department models with pjctrl_ prefix
  - Alembic migrations with project-specific version table
  - Complete test coverage (13 tests)

- Frontend (React + Vite):
  - AuthContext for state management
  - Login page with error handling
  - Protected route component
  - Dashboard with user info display

- OpenSpec:
  - 7 capability specs defined
  - add-user-auth change archived

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
beabigegg
2025-12-28 23:41:37 +08:00
commit 1fda7da2c2
77 changed files with 6562 additions and 0 deletions

View File

@@ -0,0 +1,159 @@
# Audit Trail
系統級稽核追蹤,記錄所有關鍵變更操作供合規與追溯需求。
## Requirements
### Requirement: Change Logging
系統 SHALL 記錄所有關鍵變更操作,包含誰在何時改了什麼。
#### Scenario: 任務欄位變更記錄
- **GIVEN** 使用者修改任務的任何欄位(如截止日期、狀態、指派者)
- **WHEN** 變更儲存成功
- **THEN** 系統記錄變更前後的值
- **AND** 記錄操作者、時間、IP 位址
#### Scenario: 專案設定變更記錄
- **GIVEN** 管理者修改專案設定
- **WHEN** 設定變更儲存
- **THEN** 系統記錄所有變更的設定項目
- **AND** 記錄操作者與時間
#### Scenario: 權限變更記錄
- **GIVEN** 管理者修改使用者權限或角色
- **WHEN** 權限變更生效
- **THEN** 系統記錄權限變更詳情
- **AND** 標記為高敏感度操作
### Requirement: Delete Operations Tracking
系統 SHALL 追蹤所有刪除操作,支援軟刪除與追溯。
#### Scenario: 任務刪除記錄
- **GIVEN** 使用者刪除任務
- **WHEN** 刪除操作執行
- **THEN** 系統執行軟刪除(標記 is_deleted = true
- **AND** 記錄刪除操作與原因
#### Scenario: 附件刪除記錄
- **GIVEN** 使用者刪除附件
- **WHEN** 刪除操作執行
- **THEN** 系統保留檔案於存檔區
- **AND** 記錄刪除操作詳情
### Requirement: Audit Log Immutability
系統 SHALL 確保稽核日誌不可竄改。
#### Scenario: 日誌寫入
- **GIVEN** 需要記錄稽核事件
- **WHEN** 日誌寫入
- **THEN** 日誌記錄不可被修改或刪除
- **AND** 包含校驗碼確保完整性
#### Scenario: 日誌完整性驗證
- **GIVEN** 稽核人員需要驗證日誌完整性
- **WHEN** 執行完整性檢查
- **THEN** 系統驗證所有日誌記錄的校驗碼
- **AND** 報告任何異常
### Requirement: Audit Query Interface
系統 SHALL 提供稽核查詢介面供授權人員使用。
#### Scenario: 依時間範圍查詢
- **GIVEN** 稽核人員需要查詢特定時間範圍的操作
- **WHEN** 設定時間範圍並執行查詢
- **THEN** 顯示該時間範圍內的所有稽核記錄
#### Scenario: 依操作者查詢
- **GIVEN** 稽核人員需要查詢特定使用者的操作歷史
- **WHEN** 選擇使用者並執行查詢
- **THEN** 顯示該使用者的所有操作記錄
#### Scenario: 依資源查詢
- **GIVEN** 稽核人員需要查詢特定任務或專案的變更歷史
- **WHEN** 選擇資源並執行查詢
- **THEN** 顯示該資源的完整變更歷程
#### Scenario: 稽核報告匯出
- **GIVEN** 稽核人員需要匯出稽核報告
- **WHEN** 選擇匯出格式CSV/PDF
- **THEN** 系統生成報告檔案供下載
### Requirement: Sensitive Operation Alerts
系統 SHALL 對高敏感度操作發送即時警示。
#### Scenario: 權限提升警示
- **GIVEN** 使用者被授予管理員權限
- **WHEN** 權限變更生效
- **THEN** 系統發送警示給安全管理員
#### Scenario: 大量刪除警示
- **GIVEN** 使用者在短時間內刪除大量資料
- **WHEN** 偵測到異常刪除模式
- **THEN** 系統發送警示並暫停操作
#### Scenario: 異常登入警示
- **GIVEN** 偵測到異常登入行為(如異地登入、非工作時間登入)
- **WHEN** 異常行為發生
- **THEN** 系統記錄並發送警示
## Data Model
```
pjctrl_audit_logs
├── id: UUID (PK)
├── event_type: VARCHAR(50)
│ └── 'task.update', 'task.delete', 'project.update', 'user.permission_change', etc.
├── resource_type: VARCHAR(50)
│ └── 'task', 'project', 'user', 'attachment', 'trigger', etc.
├── resource_id: UUID
├── user_id: UUID (FK -> users)
├── action: ENUM('create', 'update', 'delete', 'restore', 'login', 'logout')
├── changes: JSON
│ └── { "field": "due_date", "old_value": "2024-01-15", "new_value": "2024-01-20" }
├── metadata: JSON
│ └── { "ip_address": "192.168.1.100", "user_agent": "...", "session_id": "..." }
├── sensitivity_level: ENUM('low', 'medium', 'high', 'critical')
├── checksum: VARCHAR(64) (SHA-256 of record content)
├── created_at: TIMESTAMP (immutable)
└── INDEX idx_audit_user (user_id, created_at)
└── INDEX idx_audit_resource (resource_type, resource_id, created_at)
└── INDEX idx_audit_time (created_at)
pjctrl_audit_alerts
├── id: UUID (PK)
├── audit_log_id: UUID (FK -> audit_logs)
├── alert_type: VARCHAR(50)
├── recipients: JSON (array of user IDs)
├── message: TEXT
├── is_acknowledged: BOOLEAN DEFAULT false
├── acknowledged_by: UUID (FK -> users)
├── acknowledged_at: TIMESTAMP
└── created_at: TIMESTAMP
```
## Event Types Reference
| 事件類型 | 說明 | 敏感度 |
|---------|------|--------|
| task.create | 建立任務 | low |
| task.update | 更新任務 | low |
| task.delete | 刪除任務 | medium |
| task.assign | 指派任務 | low |
| task.blocker | 標記阻礙 | medium |
| project.create | 建立專案 | medium |
| project.update | 更新專案 | medium |
| project.delete | 刪除專案 | high |
| user.login | 使用者登入 | low |
| user.logout | 使用者登出 | low |
| user.permission_change | 權限變更 | critical |
| attachment.upload | 上傳附件 | low |
| attachment.download | 下載附件 | low |
| attachment.delete | 刪除附件 | medium |
## Technical Notes
- 稽核日誌表設計為 append-only不允許 UPDATE 或 DELETE
- 使用資料庫觸發器或應用層中間件自動記錄變更
- 日誌保留期限依法規要求設定(建議至少 7 年)
- 考慮使用時間序列資料庫(如 TimescaleDB處理大量日誌
- Checksum 計算包含event_type + resource_id + user_id + changes + created_at