Files
PROJECT-CONTORL/openspec/specs/resource-management/spec.md
beabigegg 3bdc6ff1c9 feat: implement 8 OpenSpec proposals for security, reliability, and UX improvements
## Security Enhancements (P0)
- Add input validation with max_length and numeric range constraints
- Implement WebSocket token authentication via first message
- Add path traversal prevention in file storage service

## Permission Enhancements (P0)
- Add project member management for cross-department access
- Implement is_department_manager flag for workload visibility

## Cycle Detection (P0)
- Add DFS-based cycle detection for task dependencies
- Add formula field circular reference detection
- Display user-friendly cycle path visualization

## Concurrency & Reliability (P1)
- Implement optimistic locking with version field (409 Conflict on mismatch)
- Add trigger retry mechanism with exponential backoff (1s, 2s, 4s)
- Implement cascade restore for soft-deleted tasks

## Rate Limiting (P1)
- Add tiered rate limits: standard (60/min), sensitive (20/min), heavy (5/min)
- Apply rate limits to tasks, reports, attachments, and comments

## Frontend Improvements (P1)
- Add responsive sidebar with hamburger menu for mobile
- Improve touch-friendly UI with proper tap target sizes
- Complete i18n translations for all components

## Backend Reliability (P2)
- Configure database connection pool (size=10, overflow=20)
- Add Redis fallback mechanism with message queue
- Add blocker check before task deletion

## API Enhancements (P3)
- Add standardized response wrapper utility
- Add /health/ready and /health/live endpoints
- Implement project templates with status/field copying

## Tests Added
- test_input_validation.py - Schema and path traversal tests
- test_concurrency_reliability.py - Optimistic locking and retry tests
- test_backend_reliability.py - Connection pool and Redis tests
- test_api_enhancements.py - Health check and template tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 22:13:43 +08:00

212 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Resource Management
## Purpose
資源管理系統,提供負載熱圖與人員容量追蹤,協助主管進行資源分配決策。讓主管能即時掌握團隊成員的工作負載狀況,及早發現超載或閒置問題,優化資源分配。
## Requirements
### Requirement: Workload Heatmap
系統 SHALL 提供負載熱圖 API自動統計每人每週分配的任務總時數並以顏色等級表示負載狀態。
#### Scenario: 負載正常顯示
- **GIVEN** 某人員本週被指派的任務總時數低於其容量的 80%
- **WHEN** 主管查詢負載熱圖 API
- **THEN** 該人員的 `load_level``normal`
- **AND** 回傳包含 `load_percentage``allocated_hours``capacity_hours`
#### Scenario: 負載警告顯示
- **GIVEN** 某人員本週被指派的任務總時數達到其容量的 80%-99%
- **WHEN** 主管查詢負載熱圖 API
- **THEN** 該人員的 `load_level``warning`
#### Scenario: 負載超載顯示
- **GIVEN** 某人員本週被指派的任務總時數達到或超過其容量的 100%
- **WHEN** 主管查詢負載熱圖 API
- **THEN** 該人員的 `load_level``overloaded`
#### Scenario: 查詢特定週的負載
- **GIVEN** 主管需要查看非當週的負載
- **WHEN** 主管以 `week_start` 參數查詢負載熱圖 API
- **THEN** 系統回傳該週的負載資料
#### Scenario: 快取機制
- **GIVEN** 負載資料已被計算並快取
- **WHEN** 相同查詢在 1 小時內再次發生
- **THEN** 系統從 Redis 快取回傳結果
### Requirement: Capacity Planning
系統 SHALL 支援人員容量規劃,包含預設容量與臨時調整。
#### Scenario: 設定人員預設容量
- **GIVEN** 管理者需要設定人員的週工時上限
- **WHEN** 管理者更新使用者的 `capacity`
- **THEN** 系統儲存新的容量設定
- **AND** 後續負載計算使用新容量值
#### Scenario: 容量為零處理
- **GIVEN** 使用者的容量設為 0
- **WHEN** 系統計算該使用者的負載
- **THEN** `load_percentage` 顯示為 `null`
- **AND** `load_level` 顯示為 `unavailable`
#### Scenario: 容量更新 API
- **GIVEN** 管理者需要更新團隊成員的容量
- **WHEN** 管理者呼叫 `PUT /api/users/{user_id}/capacity` 並提供新容量值
- **THEN** 系統驗證容量值在有效範圍內 (0-168 小時)
- **AND** 更新使用者的 capacity 欄位
- **AND** 記錄變更至稽核日誌
#### Scenario: 容量更新權限控制
- **GIVEN** 一般使用者嘗試更新他人容量
- **WHEN** 使用者呼叫 `PUT /api/users/{other_id}/capacity`
- **THEN** 系統拒絕請求並回傳 403 Forbidden
### Requirement: Multi-Project Health Dashboard
系統 SHALL 提供多專案健康看板,讓主管一覽所有專案狀態。
#### Scenario: 專案健康總覽
- **GIVEN** 主管負責多個專案
- **WHEN** 主管開啟健康看板
- **THEN** 顯示所有專案的進度、風險指標、延遲任務數
- **AND** 可依風險程度排序
#### Scenario: 專案延遲警示
- **GIVEN** 專案有任務超過截止日期
- **WHEN** 主管查看健康看板
- **THEN** 該專案標示為延遲狀態
- **AND** 顯示延遲任務數量與影響
#### Scenario: 專案健康 API
- **GIVEN** 後端系統運行中
- **WHEN** 客戶端請求 `GET /api/projects/health`
- **THEN** 系統回傳所有可存取專案的健康數據
- **AND** 包含 `total_tasks`, `completed_tasks`, `overdue_tasks`, `blocked_tasks`, `risk_score`
#### Scenario: 單一專案健康詳情
- **GIVEN** 主管需要查看特定專案詳情
- **WHEN** 客戶端請求 `GET /api/projects/{id}/health`
- **THEN** 系統回傳該專案的詳細健康數據
- **AND** 包含任務分類統計與風險評估
### Requirement: Team Workload Distribution
系統 SHALL 提供團隊工作分配查詢功能。
#### Scenario: 部門負載總覽
- **GIVEN** 主管需要了解部門整體負載
- **WHEN** 主管以 `department_id` 參數查詢負載熱圖 API
- **THEN** 僅顯示該部門成員的負載狀況
#### Scenario: 使用者負載詳情
- **GIVEN** 主管需要了解某人的詳細任務分配
- **WHEN** 主管查詢使用者負載詳情 API
- **THEN** 回傳該週指派給該使用者的所有任務
- **AND** 包含每個任務的 `original_estimate``due_date`
### Requirement: Workload Data Access Control
系統 SHALL 限制負載資料的存取權限。
#### Scenario: 系統管理員查看所有人
- **GIVEN** 登入者為 `super_admin`
- **WHEN** 查詢負載熱圖 API
- **THEN** 可查看所有使用者的負載資料
#### Scenario: 一般使用者查看自己
- **GIVEN** 登入者為一般使用者
- **WHEN** 查詢負載熱圖 API 未指定 `user_ids`
- **THEN** 僅回傳自己的負載資料
#### Scenario: 跨部門存取拒絕
- **GIVEN** 登入者非系統管理員
- **WHEN** 查詢其他部門使用者的負載
- **THEN** 系統拒絕存取並回傳 403 Forbidden
### Requirement: Workload Heatmap UI
The system SHALL provide a visual workload heatmap interface for managers.
#### Scenario: View workload heatmap
- **GIVEN** user is logged in as manager or admin
- **WHEN** user navigates to /workload page
- **THEN** system displays a heatmap showing all accessible users' workload
- **AND** each user cell is color-coded by load level (green/yellow/red)
#### Scenario: Navigate between weeks
- **GIVEN** user is viewing the workload page
- **WHEN** user clicks previous/next week buttons
- **THEN** the heatmap updates to show that week's workload data
#### Scenario: View user workload details
- **GIVEN** user is viewing the workload heatmap
- **WHEN** user clicks on a specific user's cell
- **THEN** a modal/drawer opens showing that user's task breakdown
- **AND** tasks show title, project, time estimate, and due date
#### Scenario: Filter by department
- **GIVEN** user is a system admin
- **WHEN** user selects a department from the filter
- **THEN** the heatmap shows only users from that department
### Requirement: Manager Workload Visibility
The system SHALL allow department managers to view workload data for all members within their department.
#### Scenario: Manager views department member workload
- **WHEN** a department manager requests workload data for a user in their department
- **THEN** system returns the workload data for that user
#### Scenario: Manager denied access to other department workload
- **WHEN** a department manager requests workload data for a user in a different department
- **THEN** system returns 403 Forbidden error
#### Scenario: Regular user cannot view others' workload
- **WHEN** a non-manager user requests workload data for another user
- **THEN** system returns 403 Forbidden error
### Requirement: Cross-Department Project Membership
The system SHALL support explicit project membership to enable cross-department collaboration.
#### Scenario: Add cross-department member to project
- **WHEN** project owner adds a user from another department as project member
- **THEN** user gains access to the project regardless of department
#### Scenario: Project member accesses cross-department project
- **WHEN** a project member from another department accesses project resources
- **THEN** system grants access based on project membership
#### Scenario: Non-member denied access despite same department
- **WHEN** a user not in project membership list attempts to access confidential project
- **THEN** system denies access unless user is in the project's department
## Data Model
```
pjctrl_workload_snapshots
├── id: UUID (PK)
├── user_id: UUID (FK -> users)
├── week_start: DATE
├── allocated_hours: DECIMAL
├── capacity_hours: DECIMAL
├── load_percentage: DECIMAL
├── created_at: TIMESTAMP
└── updated_at: TIMESTAMP
pjctrl_project_health
├── id: UUID (PK)
├── project_id: UUID (FK -> projects)
├── snapshot_date: DATE
├── total_tasks: INT
├── completed_tasks: INT
├── overdue_tasks: INT
├── blocked_tasks: INT
├── risk_score: DECIMAL
├── created_at: TIMESTAMP
└── updated_at: TIMESTAMP
```
## Calculation Rules
- **負載百分比** = (allocated_hours / capacity_hours) × 100
- **風險評分** = f(overdue_tasks, blocked_tasks, timeline_remaining)
- 快取計算結果於 Redis每小時更新或任務變更時即時更新