- Backend (FastAPI): - Task comments with nested replies and soft delete - @mention parsing with 10-mention limit per comment - Notification system with read/unread tracking - Blocker management with project owner notification - WebSocket endpoint with JWT auth and keepalive - User search API for @mention autocomplete - Alembic migration for 4 new tables - Frontend (React + Vite): - Comments component with @mention autocomplete - NotificationBell with real-time WebSocket updates - BlockerDialog for task blocking workflow - NotificationContext for state management - OpenSpec: - 4 requirements with scenarios defined - add-collaboration change archived 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
126 lines
3.9 KiB
Markdown
126 lines
3.9 KiB
Markdown
## Context
|
||
|
||
協作功能需要整合多個子系統:留言、@提及、阻礙管理、即時通知。這些功能與現有的 Task 模組緊密耦合,且需要引入 WebSocket 即時通訊機制。
|
||
|
||
## Goals / Non-Goals
|
||
|
||
**Goals:**
|
||
- 提供任務內留言討論功能
|
||
- 實作 @提及與即時通知
|
||
- 建立阻礙追蹤與主管通知機制
|
||
- 使用 Redis Pub/Sub 處理即時推播
|
||
|
||
**Non-Goals:**
|
||
- 不實作 Email 通知(未來功能)
|
||
- 不實作離線訊息佇列
|
||
- 不實作留言的 Markdown 編輯器(僅純文字)
|
||
|
||
## Decisions
|
||
|
||
### 1. 留言儲存結構
|
||
- **決策**: 使用巢狀結構(parent_comment_id)支援回覆
|
||
- **理由**: 簡單且符合大多數專案管理工具的 UX 模式
|
||
|
||
### 2. @提及解析
|
||
- **決策**: 後端解析留言內容,提取 `@username` 模式並建立 Mention 記錄
|
||
- **理由**: 前端負責顯示建議,後端負責實際通知邏輯
|
||
|
||
### 3. 即時通知架構
|
||
- **決策**: Redis Pub/Sub + WebSocket (FastAPI WebSocket)
|
||
- **替代方案**:
|
||
- Server-Sent Events (SSE) - 單向,不支援雙向互動
|
||
- Polling - 延遲高,資源浪費
|
||
- **理由**: WebSocket 提供低延遲雙向通訊,Redis 已在架構中使用
|
||
|
||
### 4. 阻礙管理
|
||
- **決策**: 新增獨立 `pjctrl_blockers` 表記錄阻礙詳情
|
||
- **理由**: Task 的 `blocker_flag` 只是布林值,需要追蹤原因、處理人、解除說明
|
||
|
||
## Risks / Trade-offs
|
||
|
||
| 風險 | 緩解措施 |
|
||
|------|----------|
|
||
| WebSocket 連線管理複雜度 | 使用連線池,實作心跳機制 |
|
||
| 通知量過大導致效能問題 | 實作批次處理、設定通知合併策略 |
|
||
| @提及被濫用 | 限制單則留言最多提及 10 人 |
|
||
|
||
## Data Model
|
||
|
||
```
|
||
pjctrl_comments
|
||
├── id: UUID (PK)
|
||
├── task_id: UUID (FK -> tasks)
|
||
├── parent_comment_id: UUID (FK -> comments, nullable)
|
||
├── author_id: UUID (FK -> users)
|
||
├── content: TEXT
|
||
├── is_edited: BOOLEAN DEFAULT false
|
||
├── created_at: TIMESTAMP
|
||
└── updated_at: TIMESTAMP
|
||
|
||
pjctrl_mentions
|
||
├── id: UUID (PK)
|
||
├── comment_id: UUID (FK -> comments)
|
||
├── mentioned_user_id: UUID (FK -> users)
|
||
└── created_at: TIMESTAMP
|
||
|
||
pjctrl_notifications
|
||
├── id: UUID (PK)
|
||
├── user_id: UUID (FK -> users)
|
||
├── type: ENUM('mention', 'assignment', 'blocker', 'status_change', 'comment')
|
||
├── reference_type: VARCHAR(50)
|
||
├── reference_id: UUID
|
||
├── title: VARCHAR(200)
|
||
├── message: TEXT
|
||
├── is_read: BOOLEAN DEFAULT false
|
||
├── created_at: TIMESTAMP
|
||
└── read_at: TIMESTAMP
|
||
|
||
pjctrl_blockers
|
||
├── id: UUID (PK)
|
||
├── task_id: UUID (FK -> tasks)
|
||
├── reported_by: UUID (FK -> users)
|
||
├── reason: TEXT
|
||
├── resolved_by: UUID (FK -> users, nullable)
|
||
├── resolution_note: TEXT
|
||
├── created_at: TIMESTAMP
|
||
└── resolved_at: TIMESTAMP
|
||
```
|
||
|
||
## API Design
|
||
|
||
```
|
||
# Comments
|
||
POST /api/tasks/{task_id}/comments # 新增留言
|
||
GET /api/tasks/{task_id}/comments # 取得任務留言列表
|
||
PUT /api/comments/{comment_id} # 編輯留言
|
||
DELETE /api/comments/{comment_id} # 刪除留言
|
||
|
||
# Notifications
|
||
GET /api/notifications # 取得通知列表
|
||
PUT /api/notifications/{id}/read # 標記已讀
|
||
PUT /api/notifications/read-all # 全部已讀
|
||
GET /api/notifications/unread-count # 取得未讀數量
|
||
|
||
# Blockers
|
||
POST /api/tasks/{task_id}/blockers # 標記阻礙
|
||
PUT /api/blockers/{blocker_id}/resolve # 解除阻礙
|
||
GET /api/tasks/{task_id}/blockers # 取得阻礙歷史
|
||
|
||
# WebSocket
|
||
WS /ws/notifications # 即時通知連線
|
||
|
||
# User Search (for @mention autocomplete)
|
||
GET /api/users/search?q={query} # 搜尋使用者
|
||
```
|
||
|
||
## Migration Plan
|
||
|
||
1. 新增資料表(無 breaking changes)
|
||
2. Task model 新增 comments relationship
|
||
3. User model 新增 notifications relationship
|
||
4. 前端漸進式整合
|
||
|
||
## Open Questions
|
||
|
||
無(已與現有架構對齊)
|