# 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=` - 專案同步端點: `GET /ws/projects/{project_id}?token=` ### 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 實作)