Files
Task_Reporter/openspec/specs/realtime-messaging/spec.md
egg 599802b818 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>
2025-12-08 08:20:37 +08:00

340 lines
14 KiB
Markdown

# realtime-messaging Specification
## Purpose
TBD - created by archiving change add-realtime-messaging. Update Purpose after archive.
## Requirements
### Requirement: WebSocket Connection Management
The system SHALL provide WebSocket endpoints for establishing persistent bidirectional connections between clients and server, with automatic reconnection handling and connection state management.
#### Scenario: Establish WebSocket connection
- **WHEN** an authenticated user connects to `ws://localhost:8000/ws/{room_id}`
- **THEN** the system SHALL validate user's room membership
- **AND** establish a WebSocket connection
- **AND** add the connection to the room's active connections pool
- **AND** broadcast a "user joined" event to other room members
#### Scenario: Handle connection authentication
- **WHEN** a WebSocket connection request is made without valid authentication token
- **THEN** the system SHALL reject the connection with status 401
- **AND** close the WebSocket immediately
#### Scenario: Automatic reconnection
- **WHEN** a WebSocket connection is dropped unexpectedly
- **THEN** the client SHALL attempt to reconnect automatically with exponential backoff
- **AND** resume from the last received message sequence number
- **AND** request any missed messages during disconnection
### Requirement: Real-time Message Broadcasting
The system SHALL broadcast messages to all active room members in real-time, ensuring message ordering and delivery acknowledgment.
#### Scenario: Send text message
- **WHEN** a room member sends a message via WebSocket:
```json
{
"type": "message",
"content": "Equipment temperature rising to 85°C",
"message_type": "text"
}
```
- **THEN** the system SHALL:
- Validate user has write permission (OWNER or EDITOR role)
- Assign a unique message_id and timestamp
- Store the message in database
- Broadcast to all active WebSocket connections in the room
- Return acknowledgment to sender with message_id
#### Scenario: Send system notification
- **WHEN** a system event occurs (user joined, room status changed, etc.)
- **THEN** the system SHALL broadcast a system message:
```json
{
"type": "system",
"event": "user_joined",
"user_id": "john.doe@panjit.com.tw",
"timestamp": "2025-11-17T10:00:00Z"
}
```
- **AND** all connected clients SHALL display the notification
#### Scenario: Handle message ordering
- **WHEN** multiple messages are sent simultaneously
- **THEN** the system SHALL ensure FIFO ordering using message sequence numbers
- **AND** clients SHALL display messages in the correct order
### Requirement: Message Persistence and History
The system SHALL persist all messages to database for audit trail, report generation, and history retrieval.
#### Scenario: Store message in database
- **WHEN** a message is sent through WebSocket
- **THEN** the system SHALL create a database record with:
- message_id (UUID)
- room_id (FK to incident_rooms)
- sender_id (user email)
- content (text or JSON for structured messages)
- message_type (text, image_ref, file_ref, system)
- created_at timestamp
- edited_at (nullable for message edits)
- deleted_at (nullable for soft delete)
- sequence_number (for ordering)
#### Scenario: Retrieve message history
- **WHEN** a user joins a room or reconnects
- **THEN** the system SHALL load recent messages via `GET /api/rooms/{room_id}/messages?limit=50&before={timestamp}`
- **AND** return messages in reverse chronological order
- **AND** include pagination metadata for loading more history
#### Scenario: Search messages
- **WHEN** a user searches for messages containing specific keywords
- **THEN** the system SHALL query the database with full-text search
- **AND** return matching messages with highlighted search terms
- **AND** maintain user's access control (only rooms they're members of)
### Requirement: Message Types and Formatting
The system SHALL support various message types including text, image references, file references, and structured data for production incidents.
#### Scenario: Text message with mentions
- **WHEN** a user sends a message with @mentions
```json
{
"content": "@maintenance_team Please check Line 3 immediately",
"mentions": ["maintenance_team@panjit.com.tw"]
}
```
- **THEN** the system SHALL parse and store mentions
- **AND** potentially trigger notifications to mentioned users
#### Scenario: Image reference message
- **WHEN** a user uploads an image and sends reference
```json
{
"type": "message",
"message_type": "image_ref",
"content": "Defect found on product",
"file_id": "550e8400-e29b-41d4-a716-446655440000",
"file_url": "http://localhost:9000/bucket/room-123/image.jpg"
}
```
- **THEN** the system SHALL store the file reference
- **AND** clients SHALL display image preview inline
#### Scenario: Structured incident data
- **WHEN** reporting specific incident metrics
```json
{
"type": "message",
"message_type": "incident_data",
"content": {
"temperature": 85,
"pressure": 120,
"production_rate": 450,
"timestamp": "2025-11-17T10:15:00Z"
}
}
```
- **THEN** the system SHALL store structured data as JSON
- **AND** enable querying/filtering by specific fields later
### Requirement: Connection State Management
The system SHALL track online presence and typing indicators for better collaboration experience.
#### Scenario: Track online users
- **WHEN** users connect/disconnect from a room
- **THEN** the system SHALL maintain a list of online users
- **AND** broadcast presence updates to all room members
- **AND** display online status indicators in UI
#### Scenario: Typing indicators
- **WHEN** a user starts typing a message
- **THEN** the client SHALL send a "typing" event via WebSocket
- **AND** the system SHALL broadcast to other room members
- **AND** automatically clear typing status after 3 seconds of inactivity
#### Scenario: Connection health monitoring
- **WHEN** a WebSocket connection is established
- **THEN** the system SHALL send ping frames every 30 seconds
- **AND** expect pong responses within 10 seconds
- **AND** terminate connection if no response received
### Requirement: Message Operations
The system SHALL support message editing and deletion with proper audit trail and permissions.
#### Scenario: Edit own message
- **WHEN** a user edits their own message within 15 minutes
```json
{
"type": "edit_message",
"message_id": "msg-123",
"content": "Updated: Equipment temperature stabilized at 75°C"
}
```
- **THEN** the system SHALL update the message content
- **AND** set edited_at timestamp
- **AND** broadcast the edit to all connected clients
- **AND** preserve original message in audit log
#### Scenario: Delete message
- **WHEN** a user deletes their own message or admin deletes any message
- **THEN** the system SHALL perform soft delete (set deleted_at)
- **AND** broadcast deletion event to all clients
- **AND** clients SHALL show "message deleted" placeholder
- **AND** preserve message in database for audit
#### Scenario: React to message
- **WHEN** a user adds a reaction emoji to a message
```json
{
"type": "add_reaction",
"message_id": "msg-123",
"emoji": "👍"
}
```
- **THEN** the system SHALL store the reaction
- **AND** broadcast to all connected clients
- **AND** aggregate reaction counts for display
### Requirement: Short-lived Database Sessions for WebSocket
The system SHALL process WebSocket messages using short-lived database sessions that are acquired and released for each individual operation, rather than holding a session for the entire WebSocket connection lifetime.
#### Scenario: Message creation with short session
- **WHEN** a user sends a message via WebSocket
- **THEN** the system acquires a database session
- **AND** creates the message with proper sequence number
- **AND** commits the transaction
- **AND** releases the session immediately
- **AND** broadcasts the message to room members
#### Scenario: Concurrent message handling
- **WHEN** multiple users send messages simultaneously
- **THEN** each message operation uses an independent database session
- **AND** sequence numbers are correctly assigned without duplicates
- **AND** no connection pool exhaustion occurs
### Requirement: Message Sequence Number Integrity
The system SHALL guarantee unique, monotonically increasing sequence numbers per room using database-level locking to prevent race conditions during concurrent message creation.
#### Scenario: Concurrent sequence assignment
- **WHEN** two users send messages to the same room at the exact same time
- **THEN** each message receives a unique sequence number
- **AND** the sequence numbers are consecutive without gaps or duplicates
#### Scenario: High concurrency sequence safety
- **WHEN** 50+ users send messages to the same room simultaneously
- **THEN** all messages receive correct unique sequence numbers
- **AND** the operation does not cause deadlocks
### Requirement: Configurable Database Connection Pool
The system SHALL support environment variable configuration for database connection pool parameters to optimize for different deployment scales.
#### Scenario: Custom pool size configuration
- **WHEN** the application starts with `DB_POOL_SIZE=20` environment variable
- **THEN** the connection pool maintains 20 persistent connections
#### Scenario: Pool overflow configuration
- **WHEN** the application starts with `DB_MAX_OVERFLOW=30` environment variable
- **THEN** the connection pool can expand up to 30 additional connections beyond the pool size
#### Scenario: Pool timeout configuration
- **WHEN** all connections are in use and a new request arrives
- **AND** `DB_POOL_TIMEOUT=10` is configured
- **THEN** the request waits up to 10 seconds for an available connection
- **AND** raises an error if no connection becomes available
#### Scenario: Default configuration
- **WHEN** no database pool environment variables are set
- **THEN** the system uses production-ready defaults (pool_size=20, max_overflow=30, timeout=10, recycle=1800)
### 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
### Requirement: @Mention Support
The messaging system SHALL support @mention functionality to tag specific users in messages.
#### Scenario: Trigger mention autocomplete
- **WHEN** user types `@` in the message input
- **THEN** a dropdown menu appears showing room members
- **AND** the list filters as user continues typing
- **AND** user can select a member using keyboard or mouse
#### Scenario: Insert mention into message
- **WHEN** user selects a member from the mention dropdown
- **THEN** the mention is inserted as `@display_name`
- **AND** the mention is stored with the user_id reference
- **AND** the mention is visually highlighted in the message
#### Scenario: Mention notification
- **WHEN** a message containing @mention is sent
- **THEN** the mentioned user receives a highlighted notification
- **AND** the notification indicates they were mentioned
### Requirement: Browser Push Notifications
The system SHALL support browser push notifications for new messages.
#### Scenario: Request notification permission
- **WHEN** user first visits the chat room
- **THEN** the system prompts for notification permission
- **AND** the permission state is stored locally
#### Scenario: Send push notification
- **WHEN** a new message arrives while the tab is not focused
- **AND** user has granted notification permission
- **THEN** a browser push notification is displayed
- **AND** clicking the notification focuses the chat room
### Requirement: Sound and Vibration Alerts
The system SHALL support audio and haptic feedback for new messages.
#### Scenario: Play notification sound
- **WHEN** a new message arrives
- **AND** sound notifications are enabled
- **THEN** a notification sound is played
#### Scenario: Vibrate on mobile
- **WHEN** a new message arrives on a mobile device
- **AND** vibration is enabled
- **AND** the device supports Vibration API
- **THEN** the device vibrates briefly
### Requirement: Mention Data Storage
Messages with @mentions SHALL store the mention metadata for querying.
#### Scenario: Store mention references
- **WHEN** a message with @mentions is created
- **THEN** the `mentions` field stores an array of mentioned user_ids
- **AND** the message content preserves the @display_name format
#### Scenario: Query messages mentioning user
- **WHEN** fetching messages that mention a specific user
- **THEN** messages with that user_id in `mentions` array are returned