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>
143 lines
4.4 KiB
Markdown
143 lines
4.4 KiB
Markdown
# V1.2.0 Media Upload - Final Design Summary
|
|
|
|
## Design Status: COMPLETE ✓
|
|
|
|
This document summarizes the finalized design for v1.2.0 media upload feature based on user requirements and architectural decisions.
|
|
|
|
## User Requirements (Confirmed)
|
|
1. **Image limit**: 4 images per note
|
|
2. **Reordering**: Not needed (display order = upload order)
|
|
3. **Image optimization**: Yes, automatic resize for large images
|
|
4. **Captions**: Yes, optional caption field for each image
|
|
|
|
## Architectural Decisions
|
|
|
|
### ADR-057: Media Attachment Model
|
|
- Social media style attachments (not inline markdown)
|
|
- Media displays at TOP of notes
|
|
- Text content appears BELOW media
|
|
- Junction table for flexible associations
|
|
|
|
### ADR-058: Image Optimization Strategy
|
|
- **Max file size**: 10MB per image
|
|
- **Max dimensions**: 4096x4096 pixels
|
|
- **Auto-resize**: Images >2048px resized automatically
|
|
- **Processing library**: Pillow
|
|
- **Formats**: JPEG, PNG, GIF, WebP only
|
|
|
|
## Technical Specifications
|
|
|
|
### Image Processing
|
|
- **Validation**: Size, dimensions, format, integrity
|
|
- **Optimization**: Resize to 2048px max, EXIF correction
|
|
- **Quality**: 95% JPEG quality (high quality)
|
|
- **Storage**: data/media/YYYY/MM/ structure
|
|
|
|
### Database Schema
|
|
```sql
|
|
-- Media table with dimensions
|
|
CREATE TABLE media (
|
|
id INTEGER PRIMARY KEY,
|
|
filename TEXT NOT NULL,
|
|
original_name TEXT NOT NULL,
|
|
path TEXT NOT NULL UNIQUE,
|
|
mime_type TEXT NOT NULL,
|
|
size INTEGER NOT NULL,
|
|
width INTEGER,
|
|
height INTEGER,
|
|
uploaded_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Junction table with captions
|
|
CREATE TABLE note_media (
|
|
id INTEGER PRIMARY KEY,
|
|
note_id INTEGER NOT NULL,
|
|
media_id INTEGER NOT NULL,
|
|
display_order INTEGER NOT NULL DEFAULT 0,
|
|
caption TEXT, -- For accessibility
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (note_id) REFERENCES notes(id) ON DELETE CASCADE,
|
|
FOREIGN KEY (media_id) REFERENCES media(id) ON DELETE CASCADE,
|
|
UNIQUE(note_id, media_id)
|
|
);
|
|
```
|
|
|
|
### User Interface
|
|
- Multiple file input (accept images only)
|
|
- Caption field for each uploaded image
|
|
- Preview thumbnails during upload
|
|
- Remove button per image
|
|
- No drag-and-drop reordering
|
|
- Maximum 4 images enforced
|
|
|
|
### Display Layout
|
|
- 1 image: Full width
|
|
- 2 images: Side by side (50% each)
|
|
- 3 images: Grid layout
|
|
- 4 images: 2x2 grid
|
|
|
|
### Syndication Support
|
|
- **RSS**: HTML with images in description
|
|
- **ATOM**: Both enclosures and HTML content
|
|
- **JSON Feed**: Native attachments array
|
|
- **Microformats2**: Multiple u-photo properties
|
|
|
|
## Implementation Guidance
|
|
|
|
### Dependencies
|
|
- **Pillow**: For image processing and optimization
|
|
|
|
### Processing Pipeline
|
|
1. Check file size (<10MB)
|
|
2. Validate MIME type
|
|
3. Load with Pillow (validates integrity)
|
|
4. Check dimensions (<4096px)
|
|
5. Correct EXIF orientation
|
|
6. Resize if needed (>2048px)
|
|
7. Save optimized version
|
|
8. Store metadata in database
|
|
|
|
### Error Handling
|
|
Clear user-facing messages for:
|
|
- File too large
|
|
- Invalid format
|
|
- Dimensions too large
|
|
- Corrupted file
|
|
- Maximum images reached
|
|
|
|
## Acceptance Criteria
|
|
- ✓ 4 image maximum per note
|
|
- ✓ No reordering interface
|
|
- ✓ Automatic optimization for large images
|
|
- ✓ Caption support for accessibility
|
|
- ✓ JPEG, PNG, GIF, WebP support
|
|
- ✓ 10MB file size limit
|
|
- ✓ 4096x4096 dimension limit
|
|
- ✓ Auto-resize at 2048px
|
|
- ✓ EXIF orientation correction
|
|
- ✓ Display order = upload order
|
|
|
|
## Related Documents
|
|
- `/docs/decisions/ADR-057-media-attachment-model.md`
|
|
- `/docs/decisions/ADR-058-image-optimization-strategy.md`
|
|
- `/docs/design/v1.2.0/feature-specification.md`
|
|
- `/docs/design/v1.2.0/media-implementation-guide.md`
|
|
|
|
## Design Sign-off
|
|
The v1.2.0 media upload feature design is now complete and ready for implementation. All user requirements have been addressed, technical decisions documented, and implementation guidance provided.
|
|
|
|
### Key Highlights
|
|
- **Simple and elegant**: Automatic optimization, no complex UI
|
|
- **Accessible**: Caption support for all images
|
|
- **Standards-compliant**: Full syndication feed support
|
|
- **Performant**: Optimized images, reasonable limits
|
|
- **Secure**: Multiple validation layers, Pillow verification
|
|
|
|
## Next Steps
|
|
1. Implement database migrations
|
|
2. Create MediaProcessor class with Pillow
|
|
3. Add upload endpoint to admin routes
|
|
4. Update note creation/edit forms
|
|
5. Implement media display in templates
|
|
6. Update feed generators for media
|
|
7. Write comprehensive tests |