# 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