jam-cloud/.planning/REQUIREMENTS.md

18 KiB

Requirements: v1.2 Session Attachments

Milestone Goal: Add file attachment capability to music sessions, allowing users to upload files from their computer and view them in the chat window with real-time synchronization across all session participants.

Last Updated: 2026-02-02


1. File Upload & Validation

REQ-1.1: Attach Button in Session Toolbar

Priority: P0 (Critical) Description: Add "Attach" button to session toolbar (top navigation) that opens native OS file dialog when clicked. Acceptance Criteria:

  • Button appears in session toolbar alongside existing controls
  • Clicking button triggers native OS file picker dialog
  • Only visible when user is in an active session
  • Button state indicates if upload is in progress

Implementation Notes:

  • Similar pattern to Backing Track "Open" button
  • May use native file dialog or HTML5 file input styled as button
  • Consider icon + text label for clarity

REQ-1.2: File Type Validation

Priority: P0 (Critical) Description: Restrict file uploads to approved file types only. Acceptance Criteria:

  • Notation files: .pdf, .xml, .mxl, .txt
  • Image files: .png, .jpg, .jpeg, .gif
  • Audio files: .mp3, .wav
  • File dialog shows only these extensions (when possible)
  • Server-side validation rejects disallowed file types
  • Clear error message if user selects invalid type

Implementation Notes:

  • File type list matches legacy app: web/app/views/clients/_sessionSettings.html.haml
  • Use accept attribute on file input: accept=".pdf,.xml,.mxl,.txt,.png,.jpg,.jpeg,.gif,.mp3,.wav"
  • Backend validates via file extension and/or MIME type

REQ-1.3: File Size Limit

Priority: P0 (Critical) Description: Enforce 10 MB maximum file size for uploads. Acceptance Criteria:

  • Files larger than 10 MB (10 * 1024 * 1024 bytes) are rejected
  • Client-side validation shows immediate error before upload starts
  • Server-side validation enforces limit as fallback
  • Error message clearly states: "File size exceeds 10 MB limit"

Implementation Notes:

  • Limit matches legacy app: web/app/assets/javascripts/react-components/stores/AttachmentStore.js.coffee
  • Check file.size property before initiating upload
  • Backend MusicNotation model already validates size

REQ-1.4: Upload Progress Indicator

Priority: P1 (High) Description: Display upload progress in chat window while file is uploading. Acceptance Criteria:

  • Progress indicator appears in chat window immediately when upload starts
  • Shows percentage complete or indeterminate spinner
  • Indicator updates in real-time as upload progresses
  • Indicator disappears when upload completes or fails
  • User can continue using app while upload is in progress

Implementation Notes:

  • Use XMLHttpRequest or fetch with progress events
  • Display progress as temporary message in chat or as overlay
  • Consider showing filename being uploaded

2. Chat Integration & Display

REQ-2.1: Attachment Message Format

Priority: P0 (Critical) Description: Display file attachments as messages in chat window with consistent format. Acceptance Criteria:

  • Message format: "[UserName] attached [FileName]"
  • Example: "John attached Song.pdf"
  • Attachment messages appear in chronological order with regular chat messages
  • Display upload timestamp like regular messages
  • Visually distinguish attachments from text messages (icon, styling)

Implementation Notes:

  • Store attachment info in same messages array as chat messages
  • Message type field indicates attachment vs. text
  • Reuse existing chat message component with conditional rendering for attachments

REQ-2.2: Attachment Metadata Display

Priority: P1 (High) Description: Show relevant metadata about attached files. Acceptance Criteria:

  • Display filename (full name with extension)
  • Display file size in human-readable format (KB/MB)
  • Display uploader name
  • Display upload timestamp
  • No comment/annotation field needed

Implementation Notes:

  • Format file size: formatFileSize(bytes) utility function
  • Metadata comes from MusicNotation model: file_name, size, user, created_at

REQ-2.3: Attachment Icon/Indicator

Priority: P2 (Medium) Description: Visual indicator that distinguishes attachment messages from text messages. Acceptance Criteria:

  • Attachment messages have distinct visual treatment
  • Could be paperclip icon, document icon, or styled differently
  • Icon type optional for v1.2 (text-only acceptable)

Implementation Notes:

  • Defer custom file-type icons to future work
  • Simple paperclip or attachment icon sufficient
  • Use existing icon library in jam-ui

Priority: P0 (Critical) Description: Users can click attachment to view/download file. Acceptance Criteria:

  • Filename is clickable link or button
  • Click opens file in new browser tab
  • Browser handles view vs. download based on file type
  • Link uses attachment file_url from MusicNotation model
  • Works for all supported file types

Implementation Notes:

  • Use <a href={fileUrl} target="_blank" rel="noopener noreferrer">
  • fileUrl is S3 URL from MusicNotation.file_url
  • Browser auto-displays .pdf, .png, .jpg; auto-downloads .xml, .mxl, .mp3, .wav

REQ-2.5: Chat History Includes Attachments

Priority: P0 (Critical) Description: Attachment messages persist in chat history across page refreshes and when joining session. Acceptance Criteria:

  • Attachments stored in database like regular messages
  • Chat history API returns attachments along with text messages
  • User joining session sees all previous attachments
  • Attachments visible after page refresh
  • Attachment order preserved chronologically

Implementation Notes:

  • Backend stores attachments linked to music_session_id
  • Chat history API includes attachments in response
  • Frontend merges attachments with chat messages by timestamp

3. Real-time Communication

REQ-3.1: WebSocket Attachment Broadcast

Priority: P0 (Critical) Description: New attachments broadcast to all session participants in real-time via WebSocket. Acceptance Criteria:

  • When user uploads file, WebSocket message sent to all participants
  • Attachment appears in all users' chat windows immediately
  • No manual refresh needed
  • Works for 2+ users in same session

Implementation Notes:

  • Use existing WebSocket gateway infrastructure
  • Define new message type: ATTACHMENT_ADDED or reuse CHAT_MESSAGE with attachment flag
  • Payload includes: music_session_id, file_name, file_url, user_name, size, timestamp
  • Similar pattern to existing CHAT_MESSAGE handler in JKSessionScreen.js

REQ-3.2: Attachment Deduplication

Priority: P1 (High) Description: Prevent duplicate attachment messages when receiving via WebSocket. Acceptance Criteria:

  • Optimistic update when uploader sends file
  • WebSocket broadcast received by all users including uploader
  • Uploader doesn't see duplicate message
  • Each attachment appears exactly once in chat

Implementation Notes:

  • Assign temporary optimisticId to local upload
  • When WebSocket message received, match against optimistic ID
  • Replace optimistic message with server message
  • Reuse deduplication logic from chat messages in sessionChatSlice.js

4. File Viewing & Download

REQ-4.1: Open in New Browser Tab

Priority: P0 (Critical) Description: Clicking attachment opens file in new browser tab for viewing/downloading. Acceptance Criteria:

  • Click opens in new tab (not same tab, not download dialog)
  • Uses target="_blank" to preserve session page
  • Security: Uses rel="noopener noreferrer"
  • Works for all supported file types

Implementation Notes:

  • Simple <a> tag with correct attributes
  • S3 URLs are public or signed (check existing MusicNotation implementation)

REQ-4.2: Browser-Native Handling

Priority: P0 (Critical) Description: Leverage browser's built-in view/download capabilities for different file types. Acceptance Criteria:

  • PDFs: Open in browser's PDF viewer
  • Images (.png, .jpg, .jpeg, .gif): Display inline in browser
  • Audio (.mp3, .wav): Browser audio player
  • XML/MXL/TXT: Browser may display as text or prompt download
  • No custom preview/player UI needed in jam-ui

Implementation Notes:

  • Browser handles Content-Type headers from S3
  • Ensure S3 serves correct MIME types for each file extension
  • Check if S3 URLs need Content-Disposition header

5. Error Handling & User Feedback

REQ-5.1: File Size Exceeded Error

Priority: P0 (Critical) Description: Show clear error when user selects file larger than 10 MB. Acceptance Criteria:

  • Error appears immediately after file selection (before upload)
  • Toast notification with message: "File size exceeds 10 MB limit"
  • Upload does not start
  • User can select different file

Implementation Notes:

  • Check file.size in file input onChange handler
  • Use existing toast system (likely react-toastify or similar)
  • Don't call backend API if client-side validation fails

REQ-5.2: Invalid File Type Error

Priority: P0 (Critical) Description: Show clear error when user selects unsupported file type. Acceptance Criteria:

  • Error appears immediately after file selection (before upload)
  • Toast notification with message: "File type not supported. Allowed: .pdf, .xml, .mxl, .txt, .png, .jpg, .jpeg, .gif, .mp3, .wav"
  • Upload does not start
  • User can select different file

Implementation Notes:

  • Check file extension against whitelist
  • Use file.name.toLowerCase().endsWith('.ext') or regex
  • Backend validates as fallback

REQ-5.3: Upload Network Error

Priority: P0 (Critical) Description: Handle network failures during file upload. Acceptance Criteria:

  • If upload fails due to network error, show toast: "Upload failed. Please try again."
  • Progress indicator disappears
  • Optimistic message removed from chat (if shown)
  • User can retry upload
  • No partial/corrupted data in chat

Implementation Notes:

  • Catch fetch/XHR errors
  • Remove optimistic update on error
  • Consider retry button in error toast

REQ-5.4: Upload Success Feedback

Priority: P1 (High) Description: Confirm successful upload to user. Acceptance Criteria:

  • Success toast: "File uploaded successfully"
  • Attachment appears in chat window
  • Progress indicator disappears
  • Toast auto-dismisses after 3-5 seconds

Implementation Notes:

  • Show success toast briefly, then auto-dismiss
  • Attachment message in chat is primary confirmation

REQ-5.5: Missing/Deleted File Handling

Priority: P2 (Medium) Description: Gracefully handle case where attachment file no longer exists on S3. Acceptance Criteria:

  • If file deleted from S3, clicking link shows browser error (404)
  • No app crash or unhandled error
  • Consider showing toast: "File no longer available"

Implementation Notes:

  • S3 returns 404 if file missing
  • Browser handles error page
  • Could add error handler to detect 404 and show toast (future enhancement)

6. Backend Integration

REQ-6.1: Use Existing MusicNotation API

Priority: P0 (Critical) Description: Use existing backend infrastructure for file uploads. Acceptance Criteria:

  • POST to existing API endpoint for creating music notations
  • Use existing MusicNotation model with S3 upload
  • No backend code changes required (verify in phase planning)
  • API returns attachment metadata after upload

Implementation Notes:

  • Backend endpoint: POST /api/music_sessions/:id/music_notations (verify exact route)
  • Payload: file (multipart form data), attachment_type (notation or audio)
  • Response: { id, file_name, file_url, size, attachment_type, user_id, created_at }
  • Check ruby/lib/jam_ruby/models/music_notation.rb for model interface

REQ-6.2: Attachment Type Classification

Priority: P1 (High) Description: Set correct attachment_type field when creating MusicNotation record. Acceptance Criteria:

  • Notation files (.pdf, .xml, .mxl, .txt): attachment_type = 'notation'
  • Audio files (.mp3, .wav): attachment_type = 'audio'
  • Images (.png, .jpg, .jpeg, .gif): attachment_type = 'notation' (or new type if needed)

Implementation Notes:

  • MusicNotation model has TYPE_NOTATION = 'notation' and TYPE_AUDIO = 'audio'
  • Client determines type based on file extension
  • Send attachment_type in POST payload

REQ-6.3: Session Association

Priority: P0 (Critical) Description: Associate attachment with correct music session. Acceptance Criteria:

  • Each attachment linked to music_session_id
  • Only session participants can see attachments for that session
  • Attachments do not appear in other sessions

Implementation Notes:

  • Include music_session_id in API request
  • Backend validates user is participant in session
  • Query attachments by session: MusicNotation.where(music_session_id: session_id)

7. Performance & UX

REQ-7.1: Non-blocking Upload

Priority: P1 (High) Description: File upload happens in background without blocking UI. Acceptance Criteria:

  • User can continue chatting while file uploads
  • User can browse other UI elements during upload
  • Upload progress visible but not intrusive
  • Multiple uploads can be queued (nice-to-have)

Implementation Notes:

  • Use async fetch with progress events
  • Don't disable UI during upload
  • Consider upload queue for multiple files (future enhancement)

REQ-7.2: Chat Auto-scroll with Attachments

Priority: P1 (High) Description: Chat window auto-scrolls when new attachment appears. Acceptance Criteria:

  • When attachment uploaded, chat scrolls to show new attachment message
  • Reuses existing auto-scroll logic from chat messages
  • Scroll behavior same as regular chat messages

Implementation Notes:

  • Attachment messages are treated like regular messages
  • Existing auto-scroll logic in JKChatMessageList.js should handle this
  • No special case needed if attachments are in same message array

REQ-7.3: Responsive Layout

Priority: P2 (Medium) Description: Attachment messages display correctly at different window sizes. Acceptance Criteria:

  • Filename truncates if too long (show ellipsis)
  • Layout doesn't break with long filenames
  • Works on typical desktop window sizes (1280x720+)

Implementation Notes:

  • CSS text-overflow: ellipsis for long filenames
  • Consider showing full filename in tooltip on hover
  • Test with very long filenames (255 chars)

Out of Scope (v1.2)

The following are explicitly NOT requirements for v1.2:

  • Attachment from within chat window (only toolbar)
  • Comments/annotations on attachments
  • File icons/thumbnails (text-only display acceptable)
  • Custom file preview UI
  • Attachment deletion
  • Attachment editing/versioning
  • Drag-and-drop file upload
  • Multiple file selection
  • Claimed recordings attachment (only computer files)
  • Music notation-specific rendering
  • Backend API changes (use existing MusicNotation endpoints)

Success Criteria

Milestone v1.2 is complete when:

  1. User can click Attach button in session toolbar
  2. User can select file from OS dialog (approved types only)
  3. File uploads to S3 via existing backend API
  4. Attachment appears in chat window as "[Name] attached [File]"
  5. All session participants see attachment in real-time via WebSocket
  6. User can click attachment to view/download in new tab
  7. Chat history shows attachments after page refresh
  8. File size and type validation work correctly
  9. Upload progress indicator displays during upload
  10. Error handling covers all failure cases (size, type, network)
  11. No backend code changes required
  12. Comprehensive UAT confirms all requirements met

Technical Constraints

  • No backend changes: Use existing MusicNotation model, S3 storage, and API endpoints
  • File size limit: 10 MB (matches legacy app)
  • File types: .pdf, .xml, .mxl, .txt, .png, .jpg, .jpeg, .gif, .mp3, .wav
  • React version: 16.13.1 (cannot use React 18 features)
  • Redux Toolkit: 1.6.1 (existing chat state management patterns)
  • WebSocket: Use existing gateway and Protocol Buffer infrastructure
  • Browser compatibility: Modern evergreen browsers (Chrome, Firefox, Safari, Edge)

Dependencies

  • Chat window (v1.1) - Exists, will display attachments
  • WebSocket integration (v1.1) - Exists, will broadcast attachments
  • Redux state management (v1.1) - Exists, will manage attachment state
  • MusicNotation backend (legacy) - Exists, no changes needed
  • S3 storage (legacy) - Exists, configured for file uploads
  • Toast notification system - Exists in jam-ui for error messages

Traceability

Requirement Phase Status
REQ-1.1 Phase 13 Complete
REQ-1.2 Phase 13 Complete
REQ-1.3 Phase 13 Complete
REQ-1.4 Phase 13 Complete
REQ-2.1 Phase 14 Complete
REQ-2.2 Phase 14 Complete
REQ-2.3 Phase 14 Complete
REQ-2.4 Phase 14 Complete
REQ-2.5 Phase 14 Complete
REQ-3.1 Phase 15 Complete*
REQ-3.2 Phase 15 Complete
REQ-4.1 Phase 14 Complete
REQ-4.2 Phase 14 Complete
REQ-5.1 Phase 16 Pending
REQ-5.2 Phase 16 Pending
REQ-5.3 Phase 16 Pending
REQ-5.4 Phase 16 Pending
REQ-5.5 Phase 16 Pending
REQ-6.1 Phase 13 Complete
REQ-6.2 Phase 13 Complete
REQ-6.3 Phase 13 Complete
REQ-7.1 Phase 13 Complete
REQ-7.2 Phase 14 Complete
REQ-7.3 Phase 14 Complete

Coverage: 24/24 requirements mapped (100%)

Note: Phase 12 is a research phase with no direct requirement mapping.


END OF REQUIREMENTS v1.2