feat: Improve file display, timezone handling, and LOT management

Changes:
- Fix datetime serialization with UTC 'Z' suffix for correct timezone display
- Add PDF upload support with extension fallback for MIME detection
- Fix LOT add/remove by creating new list for SQLAlchemy JSON change detection
- Add file message components (FileMessage, ImageLightbox, UploadPreview)
- Add multi-file upload support with progress tracking
- Link uploaded files to chat messages via message_id
- Include file attachments in AI report generation
- Update specs for file-storage, realtime-messaging, and ai-report-generation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
egg
2025-12-08 12:39:15 +08:00
parent 599802b818
commit 44822a561a
36 changed files with 2252 additions and 156 deletions

View File

@@ -90,7 +90,7 @@ The system SHALL persist all messages to database for audit trail, report genera
- **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.
The system SHALL support various message types including text, image references, file references, and structured data for production incidents, with inline display of file attachments in the chat view.
#### Scenario: Text message with mentions
- **WHEN** a user sends a message with @mentions
@@ -103,19 +103,24 @@ The system SHALL support various message types including text, image references,
- **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: Image reference message display
- **WHEN** a message with `message_type=image_ref` is rendered in the chat
- **THEN** the client SHALL display:
- A thumbnail of the image (max 300px width)
- The message content/caption below the image
- Sender name and timestamp
- A click-to-expand functionality
- **AND** clicking the thumbnail SHALL open a full-size preview lightbox
#### Scenario: File reference message display
- **WHEN** a message with `message_type=file_ref` is rendered in the chat
- **THEN** the client SHALL display:
- A file type icon (PDF, document, log, etc.)
- The filename
- File size in human-readable format
- A download button/link
- The message content/caption
- Sender name and timestamp
#### Scenario: Structured incident data
- **WHEN** reporting specific incident metrics
@@ -265,7 +270,7 @@ The system SHALL include the sender's display name in message responses and broa
### Requirement: GMT+8 Timezone Display
The frontend SHALL display all timestamps in GMT+8 (Asia/Taipei) timezone for consistent user experience across all browsers.
The frontend SHALL display all timestamps in GMT+8 (Asia/Taipei) timezone for consistent user experience across all browsers and all parts of the application.
#### Scenario: Message timestamp in GMT+8
- **WHEN** a message is displayed in the chat room
@@ -277,6 +282,14 @@ The frontend SHALL display all timestamps in GMT+8 (Asia/Taipei) timezone for co
- **WHEN** the room list is displayed
- **THEN** the "last updated" time SHALL be formatted in GMT+8 timezone
#### Scenario: File upload timestamp in GMT+8
- **WHEN** a file is displayed in chat or file drawer
- **THEN** the upload timestamp SHALL be formatted in GMT+8 timezone
#### Scenario: Report generation timestamp in GMT+8
- **WHEN** report metadata is displayed
- **THEN** the "generated at" timestamp SHALL be formatted in GMT+8 timezone
### Requirement: @Mention Support
The messaging system SHALL support @mention functionality to tag specific users in messages.
@@ -337,3 +350,61 @@ Messages with @mentions SHALL store the mention metadata for querying.
- **WHEN** fetching messages that mention a specific user
- **THEN** messages with that user_id in `mentions` array are returned
### Requirement: Image Preview Lightbox
The frontend SHALL provide a lightbox component for viewing full-size images from chat messages.
#### Scenario: Open image lightbox
- **WHEN** user clicks on an image thumbnail in the chat
- **THEN** a modal overlay SHALL appear
- **AND** the full-size image SHALL be displayed centered
- **AND** a loading indicator SHALL show while image loads
- **AND** the image SHALL be constrained to fit the viewport
#### Scenario: Close image lightbox
- **WHEN** the lightbox is open
- **THEN** user can close it by:
- Clicking the X button
- Pressing the ESC key
- Clicking outside the image
- **AND** focus SHALL return to the chat
#### Scenario: Image lightbox with download
- **WHEN** the lightbox is open
- **THEN** a download button SHALL be visible
- **AND** clicking it SHALL download the original file
### Requirement: File Type Icons
The frontend SHALL display appropriate icons for different file types in chat messages and file drawer.
#### Scenario: PDF file icon
- **WHEN** a PDF file is displayed
- **THEN** a PDF icon (red/document style) SHALL be shown
#### Scenario: Log/text file icon
- **WHEN** a .log or .txt file is displayed
- **THEN** a text file icon SHALL be shown
#### Scenario: Excel file icon
- **WHEN** an Excel file (.xlsx, .xls) is displayed
- **THEN** a spreadsheet icon (green) SHALL be shown
#### Scenario: Generic file icon
- **WHEN** a file with unknown type is displayed
- **THEN** a generic document icon SHALL be shown
### Requirement: Upload Preview
The frontend SHALL show a preview of the file being uploaded before the message is sent.
#### Scenario: Image upload preview
- **WHEN** user selects an image file for upload
- **THEN** a preview thumbnail SHALL be displayed in the input area
- **AND** user can add a caption/description
- **AND** user can cancel the upload before sending
- **AND** a send button confirms the upload
#### Scenario: File upload preview
- **WHEN** user selects a non-image file for upload
- **THEN** file info (name, size, type icon) SHALL be displayed
- **AND** user can add a description
- **AND** user can cancel or confirm