feat: Add Chat UX improvements with notifications and @mention support
- Add ActionBar component with expandable toolbar for mobile - Add @mention functionality with autocomplete dropdown - Add browser notification system (push, sound, vibration) - Add NotificationSettings modal for user preferences - Add mention badges on room list cards - Add ReportPreview with Markdown rendering and copy/download - Add message copy functionality with hover actions - Add backend mentions field to messages with Alembic migration - Add lots field to rooms, remove templates - Optimize WebSocket database session handling - Various UX polish (animations, accessibility) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# ai-report-generation Specification
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: DIFY Service Health Check
|
||||
|
||||
The system SHALL provide a health check mechanism to verify DIFY AI service connectivity and configuration.
|
||||
|
||||
#### Scenario: Check DIFY configuration on startup
|
||||
- **WHEN** the application starts
|
||||
- **AND** `DIFY_API_KEY` is not configured
|
||||
- **THEN** the system SHALL log a warning message: "DIFY_API_KEY not configured - AI report generation will be unavailable"
|
||||
|
||||
#### Scenario: DIFY health check endpoint
|
||||
- **WHEN** a user sends `GET /api/reports/health`
|
||||
- **AND** `DIFY_API_KEY` is not configured
|
||||
- **THEN** the system SHALL return:
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"message": "DIFY_API_KEY 未設定,請聯繫系統管理員"
|
||||
}
|
||||
```
|
||||
|
||||
#### Scenario: DIFY service unreachable
|
||||
- **WHEN** a user sends `GET /api/reports/health`
|
||||
- **AND** `DIFY_API_KEY` is configured
|
||||
- **BUT** the DIFY service cannot be reached
|
||||
- **THEN** the system SHALL return:
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"message": "無法連接 AI 服務,請稍後再試"
|
||||
}
|
||||
```
|
||||
|
||||
### Requirement: Report Generation Status Polling
|
||||
|
||||
The frontend SHALL implement polling mechanism to ensure report status updates are received even if WebSocket connection is unstable.
|
||||
|
||||
#### Scenario: Poll report status after generation trigger
|
||||
- **WHEN** a user triggers report generation
|
||||
- **AND** receives the initial `report_id`
|
||||
- **THEN** the frontend SHALL poll `GET /api/rooms/{room_id}/reports/{report_id}` every 2 seconds
|
||||
- **AND** continue polling until status is "completed" or "failed"
|
||||
- **AND** timeout after 120 seconds with user-friendly error message
|
||||
|
||||
#### Scenario: Display generation progress
|
||||
- **WHEN** polling returns status "collecting_data"
|
||||
- **THEN** the UI SHALL display "正在收集聊天室資料..."
|
||||
- **WHEN** polling returns status "generating_content"
|
||||
- **THEN** the UI SHALL display "AI 正在分析並生成報告內容..."
|
||||
- **WHEN** polling returns status "assembling_document"
|
||||
- **THEN** the UI SHALL display "正在組裝報告文件..."
|
||||
|
||||
#### Scenario: Display generation error
|
||||
- **WHEN** polling returns status "failed"
|
||||
- **THEN** the UI SHALL display the `error_message` from the response
|
||||
- **AND** provide option to retry generation
|
||||
@@ -0,0 +1,37 @@
|
||||
# realtime-messaging Specification
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Message Sender Display Name
|
||||
|
||||
The system SHALL include the sender's display name in message responses and broadcasts, enabling the UI to show user-friendly names instead of email addresses.
|
||||
|
||||
#### Scenario: Message response includes display name
|
||||
- **WHEN** a message is retrieved via REST API or WebSocket
|
||||
- **THEN** the response SHALL include `sender_display_name` field
|
||||
- **AND** the display name SHALL be obtained by joining with the `tr_users` table
|
||||
- **AND** if the sender does not exist in `tr_users`, the field SHALL fallback to `sender_id`
|
||||
|
||||
#### Scenario: WebSocket broadcast includes display name
|
||||
- **WHEN** a new message is broadcast via WebSocket
|
||||
- **THEN** the broadcast SHALL include `sender_display_name` field
|
||||
- **AND** the value SHALL be the sender's display name from `tr_users` table
|
||||
|
||||
#### Scenario: Historical messages include display name
|
||||
- **WHEN** a client requests message history via `GET /api/rooms/{room_id}/messages`
|
||||
- **THEN** each message in the response SHALL include `sender_display_name`
|
||||
- **AND** messages from unknown users SHALL show their `sender_id` as fallback
|
||||
|
||||
### Requirement: GMT+8 Timezone Display
|
||||
|
||||
The frontend SHALL display all timestamps in GMT+8 (Asia/Taipei) timezone for consistent user experience across all browsers.
|
||||
|
||||
#### Scenario: Message timestamp in GMT+8
|
||||
- **WHEN** a message is displayed in the chat room
|
||||
- **THEN** the timestamp SHALL be formatted in GMT+8 timezone
|
||||
- **AND** use format "HH:mm" for today's messages
|
||||
- **AND** use format "MM/DD HH:mm" for older messages
|
||||
|
||||
#### Scenario: Room list timestamps in GMT+8
|
||||
- **WHEN** the room list is displayed
|
||||
- **THEN** the "last updated" time SHALL be formatted in GMT+8 timezone
|
||||
Reference in New Issue
Block a user