- Backend (FastAPI): - External API authentication (pj-auth-api.vercel.app) - JWT token validation with Redis session storage - RBAC with department isolation - User, Role, Department models with pjctrl_ prefix - Alembic migrations with project-specific version table - Complete test coverage (13 tests) - Frontend (React + Vite): - AuthContext for state management - Login page with error handling - Protected route component - Dashboard with user info display - OpenSpec: - 7 capability specs defined - add-user-auth change archived 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
127 lines
3.9 KiB
Markdown
127 lines
3.9 KiB
Markdown
# Collaboration
|
|
|
|
協作功能系統,提供任務內討論、@提及通知與阻礙處理機制。
|
|
|
|
## Requirements
|
|
|
|
### Requirement: Task Comments
|
|
系統 SHALL 支援任務內部的討論線索,減少 Email 往返。
|
|
|
|
#### Scenario: 新增留言
|
|
- **GIVEN** 使用者擁有任務的存取權限
|
|
- **WHEN** 使用者在任務中新增留言
|
|
- **THEN** 系統儲存留言並顯示在討論區
|
|
- **AND** 記錄留言者與時間戳記
|
|
|
|
#### Scenario: 回覆留言
|
|
- **GIVEN** 任務已有留言
|
|
- **WHEN** 使用者回覆特定留言
|
|
- **THEN** 系統建立巢狀回覆結構
|
|
- **AND** 通知原留言者
|
|
|
|
#### Scenario: 編輯留言
|
|
- **GIVEN** 使用者是留言的作者
|
|
- **WHEN** 使用者編輯自己的留言
|
|
- **THEN** 系統更新留言內容
|
|
- **AND** 標示「已編輯」及編輯時間
|
|
|
|
### Requirement: User Mentions
|
|
系統 SHALL 支援 @相關人員 功能,提及時發送即時通知。
|
|
|
|
#### Scenario: @提及通知
|
|
- **GIVEN** 使用者在留言中使用 @username 提及某人
|
|
- **WHEN** 留言送出
|
|
- **THEN** 被提及者收到即時通知
|
|
- **AND** 通知包含任務連結與留言摘要
|
|
|
|
#### Scenario: @提及自動完成
|
|
- **GIVEN** 使用者輸入 @ 符號
|
|
- **WHEN** 使用者繼續輸入
|
|
- **THEN** 系統顯示符合的使用者名單供選擇
|
|
- **AND** 可用鍵盤或滑鼠選擇
|
|
|
|
### Requirement: Blocker Management
|
|
系統 SHALL 提供阻礙 (Blocker) 機制,強制要求主管介入排解。
|
|
|
|
#### Scenario: 標記阻礙
|
|
- **GIVEN** 工程師的任務遇到阻礙無法進行
|
|
- **WHEN** 工程師將任務標記為 "Blocked"
|
|
- **THEN** 系統設定 Blocker_Flag = true
|
|
- **AND** 強制發送即時通知給該任務所屬專案的主管
|
|
|
|
#### Scenario: 阻礙原因說明
|
|
- **GIVEN** 任務被標記為 Blocked
|
|
- **WHEN** 使用者標記阻礙
|
|
- **THEN** 系統要求填寫阻礙原因
|
|
- **AND** 原因顯示在任務詳情與通知中
|
|
|
|
#### Scenario: 解除阻礙
|
|
- **GIVEN** 主管或被指派者處理完阻礙
|
|
- **WHEN** 使用者解除 Blocked 狀態
|
|
- **THEN** 系統清除 Blocker_Flag
|
|
- **AND** 記錄解除時間與處理說明
|
|
|
|
### Requirement: Real-time Notifications
|
|
系統 SHALL 透過 Redis 推播即時通知。
|
|
|
|
#### Scenario: 即時通知推播
|
|
- **GIVEN** 發生需要通知的事件(如:被指派任務、被 @提及、阻礙標記)
|
|
- **WHEN** 事件發生
|
|
- **THEN** 系統透過 WebSocket 即時推播通知給相關使用者
|
|
- **AND** 未讀通知顯示數量標示
|
|
|
|
#### Scenario: 通知已讀標記
|
|
- **GIVEN** 使用者有未讀通知
|
|
- **WHEN** 使用者查看通知
|
|
- **THEN** 系統標記為已讀
|
|
- **AND** 更新未讀數量
|
|
|
|
## 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
|
|
└── is_notified: BOOLEAN DEFAULT false
|
|
|
|
pjctrl_notifications
|
|
├── id: UUID (PK)
|
|
├── user_id: UUID (FK -> users)
|
|
├── type: ENUM('mention', 'assignment', 'blocker', 'status_change', 'comment')
|
|
├── reference_type: VARCHAR(50) (e.g., 'task', 'comment')
|
|
├── 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
|
|
```
|
|
|
|
## Technical Notes
|
|
|
|
- 使用 Redis Pub/Sub 處理即時通知推播
|
|
- WebSocket 連線管理確保訊息送達
|
|
- 離線使用者登入後補送未讀通知
|