# 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 `` 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)