---
phase: 12-attachment-research-&-backend-validation
plan: 01
subsystem: documentation
tags: [file-upload, s3, carrierwave, coffeescript, reflux, formdata, multipart, api-documentation]

# Dependency graph
requires:
  - phase: 06-session-chat-research-design
    provides: Chat component architecture and WebSocket patterns
  - phase: 07-chat-infrastructure
    provides: sessionChatSlice Redux patterns
provides:
  - Comprehensive legacy AttachmentStore CoffeeScript analysis (538 lines)
  - Complete backend API contract documentation (1119 lines)
  - FormData upload patterns for React port
  - S3 signed URL workflow documentation
  - ChatMessage integration patterns
affects: [13-attachment-upload-ui, 14-attachment-message-display, 15-attachment-integration-testing, 16-attachment-finalization]

# Tech tracking
tech-stack:
  added: []
  patterns:
    - "Reflux store event-driven state management (legacy reference)"
    - "FormData multipart upload with processData: false, contentType: false"
    - "Hidden file input trigger pattern with jQuery (legacy) and React ref equivalents"
    - "Client-side validation before upload (10 MB limit)"
    - "S3 signed URL generation with 120-second expiration"
    - "Backend automatic ChatMessage creation with attachment metadata"

key-files:
  created:
    - ".planning/phases/12-attachment-research-&-backend-validation/docs/ATTACHMENT_LEGACY.md"
    - ".planning/phases/12-attachment-research-&-backend-validation/docs/ATTACHMENT_API.md"
  modified: []

key-decisions:
  - "Document legacy implementation for reference, don't port directly - use as pattern guide"
  - "Backend requires NO changes - existing /api/music_notations endpoint is fully functional"
  - "Client-side validation mandatory: 10 MB limit, extension whitelist per requirements"
  - "FormData critical pattern: never set Content-Type manually (browser adds multipart boundary)"
  - "WebSocket delivers attachment messages - don't manually create ChatMessage after upload"
  - "Signed URLs expire in 120 seconds - fetch new URL for each download attempt"

patterns-established:
  - "Pattern 1: Hidden file input with ref-based trigger (React useRef instead of jQuery trigger)"
  - "Pattern 2: Client-side validation before FormData construction prevents wasted uploads"
  - "Pattern 3: Single upload state flag prevents concurrent uploads with simple boolean"
  - "Pattern 4: HTTP 413 gets special user-friendly message (file too large)"
  - "Pattern 5: Backend creates ChatMessage automatically - React waits for WebSocket broadcast"
  - "Pattern 6: Two attachment types (notation/audio) differentiated by attachment_type parameter, same endpoint"

# Metrics
duration: 6min
completed: 2026-02-02
---

# Phase 12 Plan 1: Attachment Research & Backend Validation Summary

**Legacy CoffeeScript upload patterns documented with FormData construction, backend API contract complete for React port with S3 signed URL workflow**

## Performance

- **Duration:** 6 min
- **Started:** 2026-02-02T13:22:08Z
- **Completed:** 2026-02-02T13:27:59Z
- **Tasks:** 2
- **Files created:** 2

## Accomplishments
- Comprehensive analysis of legacy AttachmentStore (538 lines) covering Reflux patterns, FormData construction, client-side validation
- Complete backend API documentation (1119 lines) for all three endpoints (POST/GET/DELETE) with request/response formats
- File validation rules documented (10 MB limit, extension whitelist, attachment type detection)
- S3 storage workflow documented (CarrierWave, signed URLs with 120-second expiration)
- ChatMessage integration patterns documented (automatic creation, WebSocket broadcast)
- React implementation examples provided for upload and download flows

## Task Commits

Each task was committed atomically:

1. **Task 1: Document Legacy AttachmentStore Implementation** - `48ff1dfbb` (docs)
2. **Task 2: Document Backend API Contract** - `7174d9a6d` (docs)

**Plan metadata:** (Will be committed in next step)

## Files Created/Modified

### Created
- `.planning/phases/12-attachment-research-&-backend-validation/docs/ATTACHMENT_LEGACY.md` - Legacy CoffeeScript AttachmentStore analysis with 11 sections covering upload flow, validation, FormData construction, integration points, and React port patterns (538 lines, 42 code examples)
- `.planning/phases/12-attachment-research-&-backend-validation/docs/ATTACHMENT_API.md` - Backend API contract with complete endpoint documentation, request/response formats, file validation rules, ChatMessage integration, S3 storage details, error handling, and React implementation examples (1119 lines, 8 curl examples, 21 ChatMessage references)

## Decisions Made

**1. Legacy as Reference, Not Direct Port**
- Legacy AttachmentStore uses Reflux + CoffeeScript + jQuery patterns
- Decision: Document thoroughly for pattern understanding, but implement fresh in React/Redux
- Rationale: Modern patterns (Redux Toolkit, fetch API, React hooks) are superior and already established in project

**2. Backend Requires Zero Changes**
- Existing `/api/music_notations` endpoint is fully functional
- CarrierWave S3 integration is working
- ChatMessage creation with attachments is automated
- Decision: Use existing backend exactly as-is
- Rationale: Backend is battle-tested, no reason to modify working infrastructure

**3. Client-Side Validation Mandatory**
- 10 MB file size limit
- Extension whitelist validation
- Attachment type detection (notation vs audio)
- Decision: Validate BEFORE FormData construction to prevent wasted uploads
- Rationale: Matches legacy behavior, provides immediate user feedback

**4. FormData Critical Pattern**
- processData: false (jQuery) / don't stringify FormData (fetch)
- contentType: false (jQuery) / don't set Content-Type header (fetch)
- Decision: Document this as critical pattern for React port
- Rationale: Browser must auto-set Content-Type with multipart boundary, manual setting breaks uploads

**5. WebSocket Message Delivery Pattern**
- Backend automatically creates ChatMessage after successful upload
- Backend broadcasts via WebSocket with attachment metadata
- Decision: React waits for WebSocket message, doesn't manually add to chat
- Rationale: Prevents duplicate messages, maintains consistency with other chat messages

**6. S3 Signed URL Workflow**
- Signed URLs expire in 120 seconds
- Must fetch new URL for each download
- Decision: Document expiration behavior and re-fetch pattern
- Rationale: Security feature of S3 signed URLs, can't be changed without backend modification

**7. File Type Whitelist Discrepancy Noted**
- Requirements specify `.mp3, .wav`
- Backend whitelist: `wav flac ogg aiff aifc au` (no .mp3)
- Decision: Document discrepancy for resolution in Phase 13
- Rationale: May need backend update to add .mp3, or client-side restriction to match backend

## Deviations from Plan

None - plan executed exactly as written.

## Issues Encountered

**1. MusicNotationUploader Location**
- Expected location: `ruby/lib/jam_ruby/uploaders/music_notation_uploader.rb`
- Actual location: `ruby/lib/jam_ruby/app/uploaders/music_notation_uploader.rb`
- Resolution: Used `find` command to locate correct file
- Impact: None - file found and documented

**2. .mp3 Extension Missing from Backend Whitelist**
- Requirements (12-RESEARCH.md) specify `.mp3` support
- Backend whitelist only has: `wav flac ogg aiff aifc au`
- Resolution: Documented discrepancy for Phase 13 resolution
- Impact: None for this plan (documentation phase)
- Action needed: Phase 13 must either add .mp3 to backend OR adjust requirements

## User Setup Required

None - no external service configuration required. This is a documentation phase with no code changes.

## Next Phase Readiness

**Ready for Phase 13 (Upload UI Implementation):**
- ✅ Legacy patterns fully documented with React equivalents
- ✅ Backend API contract complete with all endpoints
- ✅ FormData construction patterns documented
- ✅ Error handling patterns documented (413, 422, 403, 404)
- ✅ File validation rules specified
- ✅ ChatMessage integration workflow clear

**Blockers/Concerns:**
- ⚠️ .mp3 extension whitelist discrepancy (backend missing .mp3, requirements include it)
  - Resolution options: Add .mp3 to backend whitelist OR use .wav only
  - Recommendation: Add .mp3 to backend (one-line change in MusicNotationUploader)
  - Decision point: Plan 13 Task 1 should verify and resolve

**Context for Phase 13:**
- ATTACHMENT_LEGACY.md provides 11 implementation patterns for React port
- ATTACHMENT_API.md provides complete API contract with React examples
- sessionChatSlice from Phase 7-11 ready for extension with upload state
- JKChatComposer and JKChatMessage components ready for modification
- WebSocket handler in JKSessionScreen ready for attachment field parsing

**Integration Points Identified:**
1. JKChatComposer: Add attach button with hidden file input
2. JKChatMessage: Add attachment display logic (check message.purpose)
3. sessionChatSlice: Add upload state (uploading, progress, error)
4. WebSocket handler: Extend to parse attachment_id, attachment_type, attachment_name fields
5. REST API: Add uploadMusicNotation() function following documented FormData pattern

---
*Phase: 12-attachment-research-&-backend-validation*
*Completed: 2026-02-02*
