feat: implement kanban real-time sync and fix workload cache
## Kanban Real-time Sync (NEW-002)
- Backend:
- WebSocket endpoint: /ws/projects/{project_id}
- Project room management in ConnectionManager
- Redis Pub/Sub: project:{project_id}:tasks channel
- Task CRUD event publishing (5 event types)
- Redis connection retry with exponential backoff
- Race condition fix in broadcast_to_project
- Frontend:
- ProjectSyncContext for WebSocket management
- Reconnection with exponential backoff (max 5 attempts)
- Multi-tab event deduplication via event_id
- Live/Offline connection indicator
- Optimistic updates with rollback
- Spec:
- collaboration spec: +1 requirement (Project Real-time Sync)
- 7 new scenarios for real-time sync
## Workload Cache Fix (NEW-001)
- Added cache invalidation to all task endpoints:
- create_task, update_task, update_task_status
- delete_task, restore_task, assign_task
- Extended to clear heatmap cache as well
## OpenSpec Archive
- 2026-01-05-add-kanban-realtime-sync
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
# Collaboration - Spec Delta
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Project Real-time Sync
|
||||
系統 SHALL 提供專案級即時同步機制,讓多位使用者同時協作時能即時看到任務變更。
|
||||
|
||||
#### Scenario: 訂閱專案即時更新
|
||||
- **GIVEN** 使用者擁有專案的存取權限
|
||||
- **WHEN** 使用者進入專案看板頁面
|
||||
- **THEN** 系統自動建立 WebSocket 連線並訂閱該專案的即時更新
|
||||
- **AND** 連線使用 JWT Token 進行身份驗證
|
||||
|
||||
#### Scenario: 接收任務狀態變更
|
||||
- **GIVEN** 使用者已訂閱專案即時更新
|
||||
- **WHEN** 其他使用者在同一專案中變更任務狀態
|
||||
- **THEN** 系統透過 WebSocket 即時推送 `task_status_changed` 事件
|
||||
- **AND** 看板 UI 自動更新任務位置
|
||||
|
||||
#### Scenario: 接收任務建立事件
|
||||
- **GIVEN** 使用者已訂閱專案即時更新
|
||||
- **WHEN** 其他使用者在同一專案中建立新任務
|
||||
- **THEN** 系統透過 WebSocket 即時推送 `task_created` 事件
|
||||
- **AND** 看板 UI 自動顯示新任務
|
||||
|
||||
#### Scenario: 接收任務刪除事件
|
||||
- **GIVEN** 使用者已訂閱專案即時更新
|
||||
- **WHEN** 其他使用者在同一專案中刪除任務
|
||||
- **THEN** 系統透過 WebSocket 即時推送 `task_deleted` 事件
|
||||
- **AND** 看板 UI 自動移除該任務
|
||||
|
||||
#### Scenario: 取消訂閱專案
|
||||
- **GIVEN** 使用者已訂閱專案即時更新
|
||||
- **WHEN** 使用者離開專案看板頁面
|
||||
- **THEN** 系統自動關閉 WebSocket 連線並取消訂閱
|
||||
- **AND** 釋放相關資源
|
||||
|
||||
#### Scenario: 樂觀更新與衝突處理
|
||||
- **GIVEN** 使用者拖曳任務改變狀態
|
||||
- **WHEN** 本地先套用變更(樂觀更新)但 API 呼叫失敗
|
||||
- **THEN** 系統回滾任務到原本位置
|
||||
- **AND** 顯示錯誤訊息通知使用者
|
||||
|
||||
#### Scenario: 避免重複應用自己的事件
|
||||
- **GIVEN** 使用者變更任務狀態並收到自己發起的事件
|
||||
- **WHEN** WebSocket 收到該事件
|
||||
- **THEN** 系統識別為本地發起的變更
|
||||
- **AND** 不重複應用該變更
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Real-time Notifications
|
||||
系統 SHALL 透過 Redis 推播即時通知。
|
||||
|
||||
#### Scenario: 即時通知推播
|
||||
- **GIVEN** 發生需要通知的事件(如:被指派任務、被 @提及、阻礙標記)
|
||||
- **WHEN** 事件發生
|
||||
- **THEN** 系統透過 WebSocket 即時推播通知給相關使用者
|
||||
- **AND** 未讀通知顯示數量標示
|
||||
|
||||
#### Scenario: 通知已讀標記
|
||||
- **GIVEN** 使用者有未讀通知
|
||||
- **WHEN** 使用者查看通知
|
||||
- **THEN** 系統標記為已讀
|
||||
- **AND** 更新未讀數量
|
||||
|
||||
#### Scenario: 專案事件頻道分離
|
||||
- **GIVEN** 系統運作中
|
||||
- **WHEN** 發生任務變更事件
|
||||
- **THEN** 通知系統使用 `notifications:{user_id}` 頻道推送個人通知
|
||||
- **AND** 即時同步系統使用 `project:{project_id}:tasks` 頻道推送專案事件
|
||||
- **AND** 兩者互不干擾
|
||||
|
||||
## Technical Notes
|
||||
|
||||
### WebSocket 端點
|
||||
- 通知端點: `GET /ws/notifications?token=<jwt>`
|
||||
- 專案同步端點: `GET /ws/projects/{project_id}?token=<jwt>`
|
||||
|
||||
### Redis Pub/Sub Channels
|
||||
- 通知頻道: `notifications:{user_id}` (現有實作)
|
||||
- 專案任務事件頻道: `project:{project_id}:tasks` (新增)
|
||||
|
||||
### 事件訊息格式
|
||||
```json
|
||||
{
|
||||
"type": "task_created | task_updated | task_status_changed | task_deleted | task_assigned",
|
||||
"event_id": "uuid",
|
||||
"data": {
|
||||
"task_id": "uuid",
|
||||
"project_id": "uuid",
|
||||
"title": "string",
|
||||
"status_id": "uuid | null",
|
||||
"status_name": "string | null",
|
||||
"status_color": "string | null",
|
||||
"assignee_id": "uuid | null",
|
||||
"time_estimate": "number | null",
|
||||
/* 其他任務欄位 */
|
||||
},
|
||||
"triggered_by": "user_id",
|
||||
"timestamp": "ISO8601"
|
||||
}
|
||||
```
|
||||
|
||||
**欄位說明**:
|
||||
- `event_id`: 唯一事件識別碼,用於多分頁/多裝置事件去重
|
||||
- `triggered_by`: 觸發事件的使用者 ID,位於頂層便於前端過濾
|
||||
|
||||
### 連線管理
|
||||
- 使用與通知系統相同的心跳機制 (PING/PONG)
|
||||
- 支援同一使用者多個連線 (多分頁/裝置)
|
||||
- 連線中斷自動重連 (Frontend 實作)
|
||||
Reference in New Issue
Block a user