feat: implement custom fields, gantt view, calendar view, and file encryption
- Custom Fields (FEAT-001): - CustomField and TaskCustomValue models with formula support - CRUD API for custom field management - Formula engine for calculated fields - Frontend: CustomFieldEditor, CustomFieldInput, ProjectSettings page - Task list API now includes custom_values - KanbanBoard displays custom field values - Gantt View (FEAT-003): - TaskDependency model with FS/SS/FF/SF dependency types - Dependency CRUD API with cycle detection - start_date field added to tasks - GanttChart component with Frappe Gantt integration - Dependency type selector in UI - Calendar View (FEAT-004): - CalendarView component with FullCalendar integration - Date range filtering API for tasks - Drag-and-drop date updates - View mode switching in Tasks page - File Encryption (FEAT-010): - AES-256-GCM encryption service - EncryptionKey model with key rotation support - Admin API for key management - Encrypted upload/download for confidential projects - Migrations: 011 (custom fields), 012 (encryption keys), 013 (task dependencies) - Updated issues.md with completion status 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
111
openspec/changes/archive/2026-01-05-add-gantt-view/proposal.md
Normal file
111
openspec/changes/archive/2026-01-05-add-gantt-view/proposal.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# Proposal: Add Gantt View
|
||||
|
||||
**Change ID:** `add-gantt-view`
|
||||
**Issue Reference:** `FEAT-003` (issues.md)
|
||||
**Status:** Draft
|
||||
**Author:** Claude
|
||||
**Date:** 2026-01-05
|
||||
|
||||
## Summary
|
||||
|
||||
實作甘特圖視角,以時間軸方式呈現專案任務,顯示任務期間、依賴關係和里程碑。
|
||||
|
||||
## Motivation
|
||||
|
||||
甘特圖是專案管理的核心視覺化工具,可幫助團隊:
|
||||
- 了解任務時程與排程
|
||||
- 識別關鍵路徑
|
||||
- 發現資源衝突和瓶頸
|
||||
- 追蹤進度與延遲
|
||||
|
||||
目前系統僅有看板和列表視角,缺少時間軸視圖,無法直觀地規劃和追蹤專案進度。
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope
|
||||
- Backend: Task model 新增 start_date 欄位
|
||||
- Backend: TaskDependency model(前置任務關係)
|
||||
- Backend: 依賴關係 CRUD API
|
||||
- Frontend: Gantt chart 元件(使用第三方函式庫)
|
||||
- Frontend: 任務時程編輯(拖拉調整日期)
|
||||
- Frontend: 依賴關係視覺化(箭頭連線)
|
||||
|
||||
### Out of Scope
|
||||
- 關鍵路徑計算
|
||||
- 資源分配視圖
|
||||
- 基線對比功能
|
||||
- 匯出為圖片/PDF
|
||||
|
||||
## Design Decisions
|
||||
|
||||
### 任務依賴類型
|
||||
| Type | 說明 | 範例 |
|
||||
|------|------|------|
|
||||
| finish_to_start (FS) | 前置任務完成後才能開始 | 設計完成 → 開發開始 |
|
||||
| start_to_start (SS) | 前置任務開始後才能開始 | 設計開始 → 文件開始 |
|
||||
| finish_to_finish (FF) | 前置任務完成後才能完成 | 開發完成 → 測試完成 |
|
||||
| start_to_finish (SF) | 前置任務開始後才能完成 | 較少使用 |
|
||||
|
||||
**預設**: finish_to_start (FS) 為最常見類型
|
||||
|
||||
### Data Model 變更
|
||||
```sql
|
||||
-- Task 新增欄位
|
||||
ALTER TABLE pjctrl_tasks ADD COLUMN start_date DATETIME;
|
||||
|
||||
-- 新增依賴關係表
|
||||
CREATE TABLE pjctrl_task_dependencies (
|
||||
id UUID PRIMARY KEY,
|
||||
predecessor_id UUID REFERENCES pjctrl_tasks(id),
|
||||
successor_id UUID REFERENCES pjctrl_tasks(id),
|
||||
dependency_type ENUM('FS', 'SS', 'FF', 'SF') DEFAULT 'FS',
|
||||
lag_days INT DEFAULT 0,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
```
|
||||
|
||||
### 前端函式庫選擇
|
||||
建議使用 **DHTMLX Gantt** 或 **Frappe Gantt**:
|
||||
|
||||
| 函式庫 | 優點 | 缺點 |
|
||||
|--------|------|------|
|
||||
| DHTMLX Gantt | 功能完整、效能好 | 商業授權 |
|
||||
| Frappe Gantt | 開源、輕量 | 功能較少 |
|
||||
| React-Gantt-Chart | React 原生 | 社群較小 |
|
||||
|
||||
**建議**: 使用 Frappe Gantt(MIT 授權),足夠基本需求
|
||||
|
||||
### API 設計
|
||||
```
|
||||
# 依賴關係 API
|
||||
POST /api/tasks/{task_id}/dependencies # 新增依賴
|
||||
GET /api/tasks/{task_id}/dependencies # 取得依賴
|
||||
DELETE /api/task-dependencies/{dependency_id} # 刪除依賴
|
||||
|
||||
# 任務日期更新(使用現有 API)
|
||||
PUT /api/tasks/{task_id} # body 包含 start_date, due_date
|
||||
```
|
||||
|
||||
### 日期驗證規則
|
||||
- start_date 不可晚於 due_date
|
||||
- 有依賴關係時,根據 dependency_type 驗證日期合理性
|
||||
- 循環依賴檢測
|
||||
|
||||
## Affected Specs
|
||||
|
||||
| Spec | Change Type |
|
||||
|------|-------------|
|
||||
| task-management | MODIFIED (Multiple Views requirement 甘特圖細節) |
|
||||
|
||||
## Risks & Mitigations
|
||||
|
||||
| Risk | Mitigation |
|
||||
|------|------------|
|
||||
| 複雜依賴關係影響效能 | 限制單任務最多 10 個直接依賴 |
|
||||
| 循環依賴 | 新增/修改依賴時進行循環檢測 |
|
||||
| 大型專案載入慢 | 分頁載入或虛擬滾動 |
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Frappe Gantt(或其他甘特圖函式庫)
|
||||
- 需要 Task model 已有 due_date 欄位(✓ 已存在)
|
||||
@@ -0,0 +1,67 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Multiple Views
|
||||
系統 SHALL 支援多維視角:看板 (Kanban)、甘特圖 (Gantt)、列表 (List)、行事曆 (Calendar)。
|
||||
|
||||
#### Scenario: 甘特圖視角
|
||||
- **GIVEN** 使用者選擇甘特圖視角
|
||||
- **WHEN** 系統載入專案任務
|
||||
- **THEN** 任務依時間軸顯示為水平條狀
|
||||
- **AND** 顯示任務相依關係與里程碑
|
||||
|
||||
#### Scenario: 甘特圖時間軸縮放
|
||||
- **GIVEN** 使用者正在查看甘特圖
|
||||
- **WHEN** 使用者切換縮放層級(日、週、月)
|
||||
- **THEN** 時間軸相應調整顯示密度
|
||||
- **AND** 任務條保持正確的相對位置
|
||||
|
||||
#### Scenario: 拖拉調整任務日期
|
||||
- **GIVEN** 使用者正在查看甘特圖
|
||||
- **WHEN** 使用者拖拉任務條改變位置或長度
|
||||
- **THEN** 系統更新任務的 start_date 和 due_date
|
||||
- **AND** 驗證日期合理性(start_date <= due_date)
|
||||
|
||||
#### Scenario: 顯示任務依賴關係
|
||||
- **GIVEN** 任務之間存在依賴關係
|
||||
- **WHEN** 使用者查看甘特圖
|
||||
- **THEN** 系統顯示連接任務的箭頭
|
||||
- **AND** 箭頭方向表示依賴方向(前置任務 → 後續任務)
|
||||
|
||||
#### Scenario: 新增任務依賴
|
||||
- **GIVEN** 使用者在甘特圖上選擇兩個任務
|
||||
- **WHEN** 使用者建立依賴關係
|
||||
- **THEN** 系統儲存依賴關係
|
||||
- **AND** 顯示連接箭頭
|
||||
|
||||
#### Scenario: 刪除任務依賴
|
||||
- **GIVEN** 任務之間存在依賴關係
|
||||
- **WHEN** 使用者刪除該依賴
|
||||
- **THEN** 系統移除依賴記錄
|
||||
- **AND** 連接箭頭消失
|
||||
|
||||
#### Scenario: 循環依賴檢測
|
||||
- **GIVEN** 使用者嘗試建立依賴關係
|
||||
- **WHEN** 該依賴會形成循環(A → B → C → A)
|
||||
- **THEN** 系統拒絕建立並顯示錯誤訊息
|
||||
- **AND** 現有依賴關係保持不變
|
||||
|
||||
#### Scenario: 依賴類型支援
|
||||
- **GIVEN** 使用者建立任務依賴
|
||||
- **WHEN** 使用者選擇依賴類型
|
||||
- **THEN** 系統支援以下類型:
|
||||
- Finish-to-Start (FS): 前置完成後開始
|
||||
- Start-to-Start (SS): 前置開始後開始
|
||||
- Finish-to-Finish (FF): 前置完成後完成
|
||||
- Start-to-Finish (SF): 前置開始後完成
|
||||
|
||||
## ADDED Data Model
|
||||
|
||||
```
|
||||
pjctrl_task_dependencies
|
||||
├── id: UUID (PK)
|
||||
├── predecessor_id: UUID (FK -> tasks)
|
||||
├── successor_id: UUID (FK -> tasks)
|
||||
├── dependency_type: ENUM('FS', 'SS', 'FF', 'SF') DEFAULT 'FS'
|
||||
├── lag_days: INT DEFAULT 0
|
||||
└── created_at: TIMESTAMP
|
||||
```
|
||||
92
openspec/changes/archive/2026-01-05-add-gantt-view/tasks.md
Normal file
92
openspec/changes/archive/2026-01-05-add-gantt-view/tasks.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Tasks: Add Gantt View
|
||||
|
||||
## Backend Tasks
|
||||
|
||||
### 1. Add start_date to Task model
|
||||
- [x] Add `start_date` column to Task model
|
||||
- [x] Create Alembic migration
|
||||
- [x] Update TaskCreate/TaskUpdate schemas to include start_date
|
||||
- [x] Update TaskResponse schema
|
||||
- **驗證**: Migration 成功,API 可設定 start_date
|
||||
|
||||
### 2. Create TaskDependency model
|
||||
- [x] Create `backend/app/models/task_dependency.py`
|
||||
- [x] Define predecessor_id, successor_id, dependency_type, lag_days
|
||||
- [x] Update `backend/app/models/__init__.py`
|
||||
- [x] Create Alembic migration
|
||||
- **驗證**: Migration 成功
|
||||
|
||||
### 3. Implement dependency CRUD API
|
||||
- [x] Create `backend/app/api/task_dependencies/router.py`
|
||||
- [x] Implement `POST /api/tasks/{task_id}/dependencies` - 新增依賴
|
||||
- [x] Implement `GET /api/tasks/{task_id}/dependencies` - 取得依賴
|
||||
- [x] Implement `DELETE /api/task-dependencies/{dependency_id}` - 刪除依賴
|
||||
- [x] Add circular dependency detection
|
||||
- [x] Register router in main.py
|
||||
- **驗證**: 依賴關係 CRUD 可正常操作,循環依賴被拒絕
|
||||
|
||||
### 4. Add date validation
|
||||
- [x] Validate start_date <= due_date
|
||||
- [x] Validate dependency constraints on date change
|
||||
- [x] Add validation tests
|
||||
- **驗證**: 不合理日期被拒絕
|
||||
|
||||
### 5. Add backend tests
|
||||
- [x] Test TaskDependency CRUD
|
||||
- [x] Test circular dependency detection
|
||||
- [x] Test date validation
|
||||
- **驗證**: 所有測試通過
|
||||
|
||||
## Frontend Tasks
|
||||
|
||||
### 6. Install and configure Gantt library
|
||||
- [x] Install Frappe Gantt (or chosen library)
|
||||
- [x] Create wrapper component for React integration
|
||||
- [x] Configure styling to match application theme
|
||||
- **驗證**: Gantt 元件可正常渲染
|
||||
|
||||
### 7. Create GanttChart component
|
||||
- [x] Create `frontend/src/components/GanttChart.tsx`
|
||||
- [x] Load tasks with start_date and due_date
|
||||
- [x] Display tasks as horizontal bars on timeline
|
||||
- [x] Show task title, assignee, progress
|
||||
- [x] Support zoom levels (day, week, month)
|
||||
- **驗證**: 任務正確顯示在時間軸上
|
||||
|
||||
### 8. Implement drag-to-edit dates
|
||||
- [x] Handle bar drag to move task dates
|
||||
- [x] Handle bar resize to change duration
|
||||
- [x] Call API to update task dates
|
||||
- [x] Show optimistic update, rollback on error
|
||||
- **驗證**: 拖拉調整日期可正確更新
|
||||
|
||||
### 9. Implement dependency visualization
|
||||
- [x] Add dependency arrows between tasks
|
||||
- [x] Create dependency API service
|
||||
- [x] Implement add/remove dependency UI (right-click or toolbar)
|
||||
- [x] Validate and show error for circular dependencies
|
||||
- **驗證**: 依賴關係正確顯示和編輯
|
||||
|
||||
### 10. Integrate Gantt view into Tasks page
|
||||
- [x] Add "Gantt" option to view toggle
|
||||
- [x] Store view preference in localStorage
|
||||
- [x] Handle view switching
|
||||
- **驗證**: 可在 List/Kanban/Gantt 之間切換
|
||||
|
||||
## Task Dependencies
|
||||
|
||||
```
|
||||
[1] start_date 欄位
|
||||
↓
|
||||
[2] TaskDependency Model → [3] Dependency API → [4] Date Validation → [5] Tests
|
||||
↓
|
||||
[6] Gantt Library Setup → [7] GanttChart Component
|
||||
↓
|
||||
[8] Drag Edit → [9] Dependency UI
|
||||
↓
|
||||
[10] View Integration
|
||||
```
|
||||
|
||||
- Tasks 1-5 (Backend) 可平行於 Tasks 6-10 (Frontend) 開發
|
||||
- Task 7 需要 Task 1 完成(需要 start_date 欄位)
|
||||
- Task 9 需要 Task 3 完成(需要依賴 API)
|
||||
Reference in New Issue
Block a user