feat: implement audit trail alignment (soft delete & permission audit)

- Task Soft Delete:
  - Add is_deleted, deleted_at, deleted_by fields to Task model
  - Convert DELETE to soft delete with cascade to subtasks
  - Add include_deleted query param (admin only)
  - Add POST /api/tasks/{id}/restore endpoint
  - Exclude deleted tasks from subtask_count

- Permission Change Audit:
  - Add user.role_change event (high sensitivity)
  - Add user.admin_change event (critical, triggers alert)
  - Add PATCH /api/users/{id}/admin endpoint
  - Add role.permission_change event type

- Append-Only Enforcement:
  - Add DB triggers for audit_logs immutability (manual for production)
  - Migration 008 with graceful trigger failure handling

- Tests: 11 new soft delete tests (153 total passing)
- OpenSpec: fix-audit-trail archived, fix-realtime-notifications & fix-weekly-report proposals added

🤖 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-30 06:58:30 +08:00
parent 95c281d8e1
commit 10db2c9d1f
18 changed files with 1455 additions and 12 deletions

View File

@@ -0,0 +1,98 @@
## MODIFIED Requirements
### Requirement: Delete Operations Tracking
系統 SHALL 追蹤所有刪除操作,支援軟刪除與追溯。
#### Scenario: 任務刪除記錄
- **GIVEN** 使用者刪除任務
- **WHEN** 刪除操作執行
- **THEN** 系統執行軟刪除(設定 is_deleted = true, deleted_at, deleted_by
- **AND** 記錄刪除操作至 audit_logs
- **AND** 子任務同步軟刪除
#### Scenario: 附件刪除記錄
- **GIVEN** 使用者刪除附件
- **WHEN** 刪除操作執行
- **THEN** 系統保留檔案於存檔區
- **AND** 記錄刪除操作詳情
#### Scenario: 任務還原
- **GIVEN** 管理員需要還原已刪除任務
- **WHEN** 執行還原操作
- **THEN** 系統設定 is_deleted = false
- **AND** 記錄還原操作
### Requirement: Change Logging
系統 SHALL 記錄所有關鍵變更操作,包含誰在何時改了什麼。
#### Scenario: 任務欄位變更記錄
- **GIVEN** 使用者修改任務的任何欄位(如截止日期、狀態、指派者)
- **WHEN** 變更儲存成功
- **THEN** 系統記錄變更前後的值
- **AND** 記錄操作者、時間、IP 位址
#### Scenario: 專案設定變更記錄
- **GIVEN** 管理者修改專案設定
- **WHEN** 設定變更儲存
- **THEN** 系統記錄所有變更的設定項目
- **AND** 記錄操作者與時間
#### Scenario: 權限變更記錄
- **GIVEN** 管理者修改使用者權限或角色
- **WHEN** 權限變更生效
- **THEN** 系統記錄權限變更詳情
- **AND** 標記為高敏感度操作
#### Scenario: 角色指派變更記錄
- **GIVEN** 管理者變更使用者角色
- **WHEN** role_id 變更儲存
- **THEN** 系統記錄 user.role_change 事件
- **AND** 標記 sensitivity_level = high
#### Scenario: 系統管理員變更記錄
- **GIVEN** 管理者變更使用者 is_system_admin
- **WHEN** 變更生效
- **THEN** 系統記錄 user.admin_change 事件
- **AND** 標記 sensitivity_level = critical
- **AND** 觸發即時警示
### Requirement: Audit Log Immutability
系統 SHALL 確保稽核日誌不可竄改。
#### Scenario: 日誌寫入
- **GIVEN** 需要記錄稽核事件
- **WHEN** 日誌寫入
- **THEN** 日誌記錄不可被修改或刪除
- **AND** 包含校驗碼確保完整性
#### Scenario: 日誌完整性驗證
- **GIVEN** 稽核人員需要驗證日誌完整性
- **WHEN** 執行完整性檢查
- **THEN** 系統驗證所有日誌記錄的校驗碼
- **AND** 報告任何異常
#### Scenario: 防止日誌修改
- **GIVEN** 任何對 audit_logs 表的 UPDATE 操作
- **WHEN** 操作執行
- **THEN** 資料庫 trigger 拒絕操作並拋出錯誤
#### Scenario: 防止日誌刪除
- **GIVEN** 任何對 audit_logs 表的 DELETE 操作
- **WHEN** 操作執行
- **THEN** 資料庫 trigger 拒絕操作並拋出錯誤
## MODIFIED Data Model
```
pjctrl_tasks (新增欄位)
├── is_deleted: BOOLEAN DEFAULT false
├── deleted_at: DATETIME (nullable)
├── deleted_by: UUID (FK -> users, nullable)
└── INDEX idx_task_deleted (is_deleted)
```
## MODIFIED Technical Notes
- 任務刪除改為軟刪除,保留 is_deleted, deleted_at, deleted_by
- 資料庫使用 BEFORE UPDATE/DELETE trigger 強制 append-only
- 查詢 API 預設過濾 is_deleted = true管理員可用 include_deleted 參數