# ADR-057: Media Attachment Model

## Status
Accepted

## Context
The v1.2.0 media upload feature needed a clear model for how media relates to notes. Initial design assumed inline markdown image insertion (like a blog editor), but user feedback clarified that notes are more like social media posts (tweets, Mastodon toots) where media is attached rather than inline.

Key insights from user:
- "Notes are more like tweets, thread posts, mastodon posts etc. where the media is inserted is kind of irrelevant"
- Media should appear at the TOP of notes when displayed
- Text content should appear BELOW media
- Multiple images per note should be supported

## Decision
We will implement a social media-style attachment model for media:

1. **Database Design**: Use a junction table (`note_media`) to associate media files with notes, allowing:
   - Multiple media per note (max 4)
   - Explicit ordering via `display_order` column
   - Per-attachment metadata (captions)
   - Future reuse of media across notes

2. **Display Model**: Media attachments appear at the TOP of notes:
   - 1 image: Full width display
   - 2 images: Side-by-side layout
   - 3-4 images: Grid layout
   - Text content always appears below media

3. **Syndication Strategy**:
   - RSS: Embed media as HTML in description (universal support)
   - ATOM: Use both `<link rel="enclosure">` and HTML content
   - JSON Feed: Use native `attachments` array (cleanest)

4. **Microformats2**: Multiple `u-photo` properties for multi-photo posts

## Rationale
**Why attachment model over inline markdown?**
- Matches user mental model (social media posts)
- Simplifies UI/UX (no cursor tracking needed)
- Better syndication support (especially JSON Feed)
- Cleaner Microformats2 markup
- Consistent display across all contexts

**Why junction table over array column?**
- Better query performance for feeds
- Supports future media reuse
- Per-attachment metadata
- Explicit ordering control
- Standard relational design

**Why limit to 4 images?**
- Twitter limit is 4 images
- Mastodon limit is 4 images
- Prevents performance issues
- Maintains clean grid layouts
- Sufficient for microblogging use case

## Consequences

### Positive
- Clean separation of media and text content
- Familiar social media UX pattern
- Excellent syndication feed support
- Future-proof for media galleries
- Supports accessibility via captions
- Efficient database queries

### Negative
- No inline images in markdown content
- All media must appear at top
- Cannot mix text and images
- More complex database schema
- Additional JOIN queries needed

### Neutral
- Different from traditional blog CMSs
- Requires grid layout CSS
- Media upload is separate from text editing

## Alternatives Considered

### Alternative 1: Inline Markdown Images
Store media URLs in markdown content as `![alt](url)`.
- **Pros**: Traditional blog approach, flexible positioning
- **Cons**: Poor syndication, complex editing UX, inconsistent display

### Alternative 2: JSON Array in Notes Table
Store media IDs as JSON array column in notes table.
- **Pros**: Simpler schema, fewer tables
- **Cons**: Poor query performance, no per-media metadata, violates 1NF

### Alternative 3: Single Media Per Note
Restrict to one image per note.
- **Pros**: Simplest implementation
- **Cons**: Too limiting, doesn't match social media patterns

## Implementation Notes

1. Migration will create both `media` and `note_media` tables
2. Feed generators must query media via JOIN
3. Template must render media before content
4. Upload UI shows thumbnails, not markdown insertion
5. Consider lazy loading for performance

## References
- [IndieWeb multi-photo posts](https://indieweb.org/multi-photo)
- [Microformats2 u-photo property](https://microformats.org/wiki/h-entry#u-photo)
- [JSON Feed attachments](https://jsonfeed.org/version/1.1#attachments)
- [Twitter photo upload limits](https://help.twitter.com/en/using-twitter/tweeting-gifs-and-pictures)