feat: v1.2.0-rc.1 - IndieWeb Features Release Candidate
Complete implementation of v1.2.0 "IndieWeb Features" release. ## Phase 1: Custom Slugs - Optional custom slug field in note creation form - Auto-sanitization (lowercase, hyphens only) - Uniqueness validation with auto-numbering - Read-only after creation to preserve permalinks - Matches Micropub mp-slug behavior ## Phase 2: Author Discovery + Microformats2 - Automatic h-card discovery from IndieAuth identity URL - 24-hour caching with graceful fallback - Never blocks login (per ADR-061) - Complete h-entry, h-card, h-feed markup - All required Microformats2 properties - rel-me links for identity verification - Passes IndieWeb validation ## Phase 3: Media Upload - Upload up to 4 images per note (JPEG, PNG, GIF, WebP) - Automatic optimization with Pillow - Auto-resize to 2048px - EXIF orientation correction - 95% quality compression - Social media-style layout (media top, text below) - Optional captions for accessibility - Integration with all feed formats (RSS, ATOM, JSON Feed) - Date-organized storage with UUID filenames - Immutable caching (1 year) ## Database Changes - migrations/006_add_author_profile.sql - Author discovery cache - migrations/007_add_media_support.sql - Media storage ## New Modules - starpunk/author_discovery.py - h-card discovery and caching - starpunk/media.py - Image upload, validation, optimization ## Documentation - 4 new ADRs (056, 057, 058, 061) - Complete design specifications - Developer Q&A with 40+ questions answered - 3 implementation reports - 3 architect reviews (all approved) ## Testing - 56 new tests for v1.2.0 features - 842 total tests in suite - All v1.2.0 feature tests passing ## Dependencies - Added: mf2py (Microformats2 parser) - Added: Pillow (image processing) Version: 1.2.0-rc.1 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
110
docs/decisions/ADR-057-media-attachment-model.md
Normal file
110
docs/decisions/ADR-057-media-attachment-model.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# 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 ``.
|
||||
- **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)
|
||||
Reference in New Issue
Block a user