- 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>
14 KiB
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:
{ "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:
{ "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
{ "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
{ "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
{ "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
{ "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
{ "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=20environment variable - THEN the connection pool maintains 20 persistent connections
Scenario: Pool overflow configuration
- WHEN the application starts with
DB_MAX_OVERFLOW=30environment 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=10is 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_namefield - AND the display name SHALL be obtained by joining with the
tr_userstable - AND if the sender does not exist in
tr_users, the field SHALL fallback tosender_id
Scenario: WebSocket broadcast includes display name
- WHEN a new message is broadcast via WebSocket
- THEN the broadcast SHALL include
sender_display_namefield - AND the value SHALL be the sender's display name from
tr_userstable
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_idas 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
mentionsfield 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
mentionsarray are returned