Complete implementation of the production line incident response system (生產線異常即時反應系統) including: Backend (FastAPI): - User authentication with AD integration and session management - Chat room management (create, list, update, members, roles) - Real-time messaging via WebSocket (typing indicators, reactions) - File storage with MinIO (upload, download, image preview) Frontend (React + Vite): - Authentication flow with token management - Room list with filtering, search, and pagination - Real-time chat interface with WebSocket - File upload with drag-and-drop and image preview - Member management and room settings - Breadcrumb navigation - 53 unit tests (Vitest) Specifications: - authentication: AD auth, sessions, JWT tokens - chat-room: rooms, members, templates - realtime-messaging: WebSocket, messages, reactions - file-storage: MinIO integration, file management - frontend-core: React SPA structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
603 lines
11 KiB
Markdown
603 lines
11 KiB
Markdown
# Chat Room Management API Documentation
|
||
|
||
## 概述
|
||
|
||
此 API 提供生產線異常事件室管理功能,支援建立、管理與協作處理生產線異常事件。
|
||
|
||
**Base URL**: `/api/rooms`
|
||
|
||
**認證**: 所有端點需要 Bearer Token 認證(除非另有說明)
|
||
|
||
---
|
||
|
||
## 端點列表
|
||
|
||
### 1. 房間管理 (Room CRUD)
|
||
|
||
#### 1.1 建立新房間
|
||
```http
|
||
POST /api/rooms
|
||
```
|
||
|
||
**請求體**:
|
||
```json
|
||
{
|
||
"title": "設備故障 - A線",
|
||
"incident_type": "EQUIPMENT_FAILURE",
|
||
"severity": "HIGH",
|
||
"location": "生產線 A",
|
||
"description": "主要輸送帶停止運作",
|
||
"template": "equipment_failure" // 可選:使用範本建立
|
||
}
|
||
```
|
||
|
||
**回應** (201 Created):
|
||
```json
|
||
{
|
||
"room_id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"title": "設備故障 - A線",
|
||
"incident_type": "EQUIPMENT_FAILURE",
|
||
"severity": "HIGH",
|
||
"status": "ACTIVE",
|
||
"location": "生產線 A",
|
||
"description": "主要輸送帶停止運作",
|
||
"created_by": "user@panjit.com.tw",
|
||
"created_at": "2025-11-17T08:00:00Z",
|
||
"last_activity_at": "2025-11-17T08:00:00Z",
|
||
"member_count": 1,
|
||
"current_user_role": "OWNER"
|
||
}
|
||
```
|
||
|
||
**incident_type 列舉值**:
|
||
- `EQUIPMENT_FAILURE` - 設備故障
|
||
- `MATERIAL_SHORTAGE` - 物料短缺
|
||
- `QUALITY_ISSUE` - 品質問題
|
||
- `OTHER` - 其他
|
||
|
||
**severity 列舉值**:
|
||
- `LOW` - 低
|
||
- `MEDIUM` - 中
|
||
- `HIGH` - 高
|
||
- `CRITICAL` - 緊急
|
||
|
||
---
|
||
|
||
#### 1.2 列出房間
|
||
```http
|
||
GET /api/rooms?status=ACTIVE&limit=20&offset=0
|
||
```
|
||
|
||
**查詢參數**:
|
||
- `status` (可選): ACTIVE | RESOLVED | ARCHIVED
|
||
- `incident_type` (可選): 事件類型篩選
|
||
- `severity` (可選): 嚴重程度篩選
|
||
- `search` (可選): 搜尋關鍵字(搜尋標題、描述、地點)
|
||
- `all` (可選, 僅管理員): true 時顯示所有房間(非僅自己的)
|
||
- `limit` (預設: 20): 每頁筆數 (1-100)
|
||
- `offset` (預設: 0): 分頁偏移
|
||
|
||
**回應** (200 OK):
|
||
```json
|
||
{
|
||
"rooms": [
|
||
{
|
||
"room_id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"title": "設備故障 - A線",
|
||
"incident_type": "EQUIPMENT_FAILURE",
|
||
"severity": "HIGH",
|
||
"status": "ACTIVE",
|
||
"current_user_role": "OWNER",
|
||
"member_count": 3,
|
||
"created_at": "2025-11-17T08:00:00Z"
|
||
}
|
||
],
|
||
"total": 1,
|
||
"limit": 20,
|
||
"offset": 0
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### 1.3 取得房間詳情
|
||
```http
|
||
GET /api/rooms/{room_id}
|
||
```
|
||
|
||
**回應** (200 OK):
|
||
```json
|
||
{
|
||
"room_id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"title": "設備故障 - A線",
|
||
"incident_type": "EQUIPMENT_FAILURE",
|
||
"severity": "HIGH",
|
||
"status": "ACTIVE",
|
||
"location": "生產線 A",
|
||
"description": "主要輸送帶停止運作",
|
||
"resolution_notes": null,
|
||
"created_by": "user@panjit.com.tw",
|
||
"created_at": "2025-11-17T08:00:00Z",
|
||
"resolved_at": null,
|
||
"archived_at": null,
|
||
"last_activity_at": "2025-11-17T08:30:00Z",
|
||
"member_count": 3,
|
||
"ownership_transferred_at": null,
|
||
"ownership_transferred_by": null,
|
||
"current_user_role": "OWNER",
|
||
"members": [
|
||
{
|
||
"user_id": "user@panjit.com.tw",
|
||
"role": "OWNER",
|
||
"added_by": "system",
|
||
"added_at": "2025-11-17T08:00:00Z"
|
||
},
|
||
{
|
||
"user_id": "engineer@panjit.com.tw",
|
||
"role": "EDITOR",
|
||
"added_by": "user@panjit.com.tw",
|
||
"added_at": "2025-11-17T08:15:00Z"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
**錯誤回應**:
|
||
- `404 Not Found`: 房間不存在或無存取權限
|
||
|
||
---
|
||
|
||
#### 1.4 更新房間
|
||
```http
|
||
PATCH /api/rooms/{room_id}
|
||
```
|
||
|
||
**權限**: OWNER 或 ADMIN
|
||
|
||
**請求體** (所有欄位可選):
|
||
```json
|
||
{
|
||
"title": "設備故障 - A線(已修復)",
|
||
"severity": "MEDIUM",
|
||
"status": "RESOLVED",
|
||
"description": "更新的描述",
|
||
"resolution_notes": "更換了傳動皮帶"
|
||
}
|
||
```
|
||
|
||
**回應** (200 OK): 同 1.3
|
||
|
||
**錯誤回應**:
|
||
- `403 Forbidden`: 無權限更新
|
||
- `404 Not Found`: 房間不存在
|
||
|
||
---
|
||
|
||
#### 1.5 刪除房間(軟刪除/封存)
|
||
```http
|
||
DELETE /api/rooms/{room_id}
|
||
```
|
||
|
||
**權限**: OWNER 或 ADMIN
|
||
|
||
**回應** (200 OK):
|
||
```json
|
||
{
|
||
"message": "Room archived successfully"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 成員管理 (Membership)
|
||
|
||
#### 2.1 列出房間成員
|
||
```http
|
||
GET /api/rooms/{room_id}/members
|
||
```
|
||
|
||
**權限**: 房間成員
|
||
|
||
**回應** (200 OK):
|
||
```json
|
||
[
|
||
{
|
||
"user_id": "user@panjit.com.tw",
|
||
"role": "OWNER",
|
||
"added_by": "system",
|
||
"added_at": "2025-11-17T08:00:00Z"
|
||
},
|
||
{
|
||
"user_id": "engineer@panjit.com.tw",
|
||
"role": "EDITOR",
|
||
"added_by": "user@panjit.com.tw",
|
||
"added_at": "2025-11-17T08:15:00Z"
|
||
}
|
||
]
|
||
```
|
||
|
||
**role 列舉值**:
|
||
- `OWNER` - 擁有者(完全控制權)
|
||
- `EDITOR` - 編輯者(可讀寫、新增檢視者)
|
||
- `VIEWER` - 檢視者(僅可讀)
|
||
|
||
---
|
||
|
||
#### 2.2 新增成員
|
||
```http
|
||
POST /api/rooms/{room_id}/members
|
||
```
|
||
|
||
**權限**:
|
||
- OWNER 可新增任何角色
|
||
- EDITOR 可新增 VIEWER
|
||
|
||
**請求體**:
|
||
```json
|
||
{
|
||
"user_id": "engineer@panjit.com.tw",
|
||
"role": "EDITOR"
|
||
}
|
||
```
|
||
|
||
**回應** (200 OK):
|
||
```json
|
||
{
|
||
"user_id": "engineer@panjit.com.tw",
|
||
"role": "EDITOR",
|
||
"added_by": "user@panjit.com.tw",
|
||
"added_at": "2025-11-17T08:15:00Z"
|
||
}
|
||
```
|
||
|
||
**錯誤回應**:
|
||
- `400 Bad Request`: 使用者已是成員
|
||
- `403 Forbidden`: 無權限新增成員
|
||
|
||
---
|
||
|
||
#### 2.3 更新成員角色
|
||
```http
|
||
PATCH /api/rooms/{room_id}/members/{user_id}
|
||
```
|
||
|
||
**權限**: OWNER 或 ADMIN
|
||
|
||
**請求體**:
|
||
```json
|
||
{
|
||
"role": "EDITOR"
|
||
}
|
||
```
|
||
|
||
**回應** (200 OK):
|
||
```json
|
||
{
|
||
"user_id": "engineer@panjit.com.tw",
|
||
"role": "EDITOR",
|
||
"added_by": "user@panjit.com.tw",
|
||
"added_at": "2025-11-17T08:15:00Z"
|
||
}
|
||
```
|
||
|
||
**錯誤回應**:
|
||
- `403 Forbidden`: 僅 OWNER 可變更角色
|
||
- `404 Not Found`: 成員不存在
|
||
|
||
---
|
||
|
||
#### 2.4 移除成員
|
||
```http
|
||
DELETE /api/rooms/{room_id}/members/{user_id}
|
||
```
|
||
|
||
**權限**:
|
||
- OWNER 可移除任何成員
|
||
- EDITOR 可移除 VIEWER
|
||
- 不可移除最後一個 OWNER
|
||
|
||
**回應** (200 OK):
|
||
```json
|
||
{
|
||
"message": "Member removed successfully"
|
||
}
|
||
```
|
||
|
||
**錯誤回應**:
|
||
- `400 Bad Request`: 無法移除最後一個 OWNER
|
||
- `403 Forbidden`: 無權限移除
|
||
- `404 Not Found`: 成員不存在
|
||
|
||
---
|
||
|
||
#### 2.5 轉移所有權 ⭐
|
||
```http
|
||
POST /api/rooms/{room_id}/transfer-ownership
|
||
```
|
||
|
||
**權限**: 僅限當前 OWNER
|
||
|
||
**請求體**:
|
||
```json
|
||
{
|
||
"new_owner_id": "engineer@panjit.com.tw"
|
||
}
|
||
```
|
||
|
||
**行為**:
|
||
- 新 owner 必須是現有房間成員
|
||
- 原 owner 自動降級為 EDITOR
|
||
- 新 owner 升級為 OWNER
|
||
- 記錄轉移時間與操作者
|
||
|
||
**回應** (200 OK):
|
||
```json
|
||
{
|
||
"message": "Ownership transferred successfully"
|
||
}
|
||
```
|
||
|
||
**錯誤回應**:
|
||
- `400 Bad Request`: 新 owner 不是房間成員
|
||
- `403 Forbidden`: 僅 OWNER 可轉移所有權
|
||
|
||
---
|
||
|
||
### 3. 權限查詢
|
||
|
||
#### 3.1 取得當前使用者權限
|
||
```http
|
||
GET /api/rooms/{room_id}/permissions
|
||
```
|
||
|
||
**回應** (200 OK):
|
||
```json
|
||
{
|
||
"role": "OWNER",
|
||
"is_admin": false,
|
||
"can_read": true,
|
||
"can_write": true,
|
||
"can_manage_members": true,
|
||
"can_transfer_ownership": true,
|
||
"can_update_status": true,
|
||
"can_delete": true
|
||
}
|
||
```
|
||
|
||
**管理員回應** (ymirliu@panjit.com.tw):
|
||
```json
|
||
{
|
||
"role": "OWNER",
|
||
"is_admin": true,
|
||
"can_read": true,
|
||
"can_write": true,
|
||
"can_manage_members": true,
|
||
"can_transfer_ownership": true,
|
||
"can_update_status": true,
|
||
"can_delete": true
|
||
}
|
||
```
|
||
|
||
**權限矩陣**:
|
||
|
||
| 權限 | OWNER | EDITOR | VIEWER | ADMIN |
|
||
|-----|-------|--------|--------|-------|
|
||
| can_read | ✓ | ✓ | ✓ | ✓ |
|
||
| can_write | ✓ | ✓ | ✗ | ✓ |
|
||
| can_manage_members | ✓ | 部分¹ | ✗ | ✓ |
|
||
| can_transfer_ownership | ✓ | ✗ | ✗ | ✓ |
|
||
| can_update_status | ✓ | ✗ | ✗ | ✓ |
|
||
| can_delete | ✓ | ✗ | ✗ | ✓ |
|
||
|
||
¹ EDITOR 僅可新增 VIEWER
|
||
|
||
---
|
||
|
||
### 4. 範本
|
||
|
||
#### 4.1 列出可用範本
|
||
```http
|
||
GET /api/rooms/templates
|
||
```
|
||
|
||
**回應** (200 OK):
|
||
```json
|
||
[
|
||
{
|
||
"template_id": "1",
|
||
"name": "equipment_failure",
|
||
"description": "設備故障事件需要立即處理",
|
||
"incident_type": "EQUIPMENT_FAILURE",
|
||
"default_severity": "HIGH",
|
||
"default_members": [
|
||
{
|
||
"user_id": "maintenance_team@panjit.com.tw",
|
||
"role": "EDITOR"
|
||
},
|
||
{
|
||
"user_id": "engineering@panjit.com.tw",
|
||
"role": "VIEWER"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"template_id": "2",
|
||
"name": "material_shortage",
|
||
"description": "物料短缺影響生產",
|
||
"incident_type": "MATERIAL_SHORTAGE",
|
||
"default_severity": "MEDIUM",
|
||
"default_members": [
|
||
{
|
||
"user_id": "procurement@panjit.com.tw",
|
||
"role": "EDITOR"
|
||
},
|
||
{
|
||
"user_id": "logistics@panjit.com.tw",
|
||
"role": "EDITOR"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"template_id": "3",
|
||
"name": "quality_issue",
|
||
"description": "品質問題需要調查",
|
||
"incident_type": "QUALITY_ISSUE",
|
||
"default_severity": "HIGH",
|
||
"default_members": [
|
||
{
|
||
"user_id": "quality_team@panjit.com.tw",
|
||
"role": "EDITOR"
|
||
},
|
||
{
|
||
"user_id": "production_manager@panjit.com.tw",
|
||
"role": "VIEWER"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
```
|
||
|
||
---
|
||
|
||
## 錯誤碼
|
||
|
||
所有錯誤回應格式:
|
||
```json
|
||
{
|
||
"detail": "錯誤訊息"
|
||
}
|
||
```
|
||
|
||
### 常見錯誤碼
|
||
|
||
| HTTP 狀態碼 | 說明 |
|
||
|-----------|-----|
|
||
| 400 Bad Request | 請求資料無效或不符合業務規則 |
|
||
| 401 Unauthorized | 未認證或 Token 無效 |
|
||
| 403 Forbidden | 無權限執行此操作 |
|
||
| 404 Not Found | 資源不存在或無存取權限 |
|
||
| 500 Internal Server Error | 伺服器內部錯誤 |
|
||
|
||
### 範例錯誤訊息
|
||
|
||
```json
|
||
// 無權限
|
||
{
|
||
"detail": "Insufficient permissions"
|
||
}
|
||
|
||
// 房間不存在
|
||
{
|
||
"detail": "Room not found"
|
||
}
|
||
|
||
// 認證失敗
|
||
{
|
||
"detail": "Authentication required"
|
||
}
|
||
|
||
// 重複成員
|
||
{
|
||
"detail": "User is already a member"
|
||
}
|
||
|
||
// 無效的所有權轉移
|
||
{
|
||
"detail": "New owner must be an existing room member"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 系統管理員特權
|
||
|
||
**管理員帳號**: `ymirliu@panjit.com.tw`
|
||
|
||
### 管理員權限:
|
||
1. **覆寫所有權限限制** - 無視角色限制執行任何操作
|
||
2. **查看所有房間** - 使用 `?all=true` 參數查看系統中所有房間
|
||
3. **強制更新任何房間** - 即使不是成員也可更新
|
||
4. **刪除任何房間** - 無需為 OWNER
|
||
5. **管理所有成員** - 新增/移除/變更任何成員角色
|
||
|
||
### 稽核追蹤:
|
||
所有管理員操作都會記錄在 `last_updated_at` 和相關稽核欄位中。
|
||
|
||
---
|
||
|
||
## 狀態轉換規則
|
||
|
||
房間狀態必須按照以下順序轉換:
|
||
|
||
```
|
||
ACTIVE (活躍)
|
||
↓
|
||
RESOLVED (已解決)
|
||
↓
|
||
ARCHIVED (已封存)
|
||
```
|
||
|
||
- ✓ ACTIVE → RESOLVED
|
||
- ✓ RESOLVED → ARCHIVED
|
||
- ✗ ACTIVE → ARCHIVED (不允許跳過)
|
||
- ✗ 反向轉換 (不允許)
|
||
|
||
---
|
||
|
||
## 範例使用流程
|
||
|
||
### 流程 1: 建立並處理設備故障事件
|
||
|
||
```bash
|
||
# 1. 使用範本建立房間
|
||
POST /api/rooms
|
||
{
|
||
"title": "CNC 機台 A 故障",
|
||
"location": "廠區 B",
|
||
"description": "主軸無法正常運轉",
|
||
"template": "equipment_failure"
|
||
}
|
||
|
||
# 2. 新增工程師到房間
|
||
POST /api/rooms/{room_id}/members
|
||
{
|
||
"user_id": "engineer_john@panjit.com.tw",
|
||
"role": "EDITOR"
|
||
}
|
||
|
||
# 3. 更新事件狀態為已解決
|
||
PATCH /api/rooms/{room_id}
|
||
{
|
||
"status": "RESOLVED",
|
||
"resolution_notes": "更換主軸軸承,測試正常"
|
||
}
|
||
|
||
# 4. 封存事件
|
||
DELETE /api/rooms/{room_id}
|
||
```
|
||
|
||
### 流程 2: 所有權轉移
|
||
|
||
```bash
|
||
# 1. 原 owner 將所有權轉移給其他成員
|
||
POST /api/rooms/{room_id}/transfer-ownership
|
||
{
|
||
"new_owner_id": "new_owner@panjit.com.tw"
|
||
}
|
||
|
||
# 結果:
|
||
# - new_owner@panjit.com.tw 成為 OWNER
|
||
# - 原 owner 降級為 EDITOR
|
||
# - 記錄轉移時間與操作者
|
||
```
|
||
|
||
---
|
||
|
||
## 自動生成的 API 文檔
|
||
|
||
FastAPI 自動生成互動式 API 文檔:
|
||
|
||
- **Swagger UI**: `http://localhost:8000/docs`
|
||
- **ReDoc**: `http://localhost:8000/redoc`
|
||
- **OpenAPI Schema**: `http://localhost:8000/openapi.json`
|