30 KiB
30 KiB
Product Requirements Document: Multi-Content CMS
Overview
Add a comprehensive CMS to the personal portfolio site to manage multiple content types: Projects (Work section), Posts (Universe section), and Photos/Albums (Photos and Universe sections).
Goals
- Enable dynamic content creation across all site sections
- Provide rich text editing for long-form content (Edra)
- Support different content types with appropriate editing interfaces
- Store all content in PostgreSQL database (Railway-compatible)
- Display content instantly after publishing
- Maintain the existing design aesthetic
Technical Constraints
- Hosting: Railway (no direct file system access)
- Database: PostgreSQL add-on available
- Framework: SvelteKit
- Editor: Edra for rich text (https://edra.tsuzat.com/docs), custom forms for structured data
Core Features
1. Database Schema
-- Projects table (for /work)
CREATE TABLE projects (
id SERIAL PRIMARY KEY,
slug VARCHAR(255) UNIQUE NOT NULL,
title VARCHAR(255) NOT NULL,
subtitle VARCHAR(255),
description TEXT,
year INTEGER NOT NULL,
client VARCHAR(255),
role VARCHAR(255),
technologies JSONB, -- Array of tech stack
featured_image VARCHAR(500),
gallery JSONB, -- Array of image URLs
external_url VARCHAR(500),
case_study_content JSONB, -- Edra JSON format
display_order INTEGER DEFAULT 0,
status VARCHAR(50) DEFAULT 'draft',
published_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Posts table (for /universe) - Simplified to 2 types
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
slug VARCHAR(255) UNIQUE NOT NULL,
post_type VARCHAR(50) NOT NULL, -- 'post' or 'essay'
title VARCHAR(255), -- Required for essays, optional for posts
content JSONB, -- Edra JSON content
excerpt TEXT, -- For essays
featured_image VARCHAR(500),
attachments JSONB, -- Array of media IDs for any attachments
tags JSONB, -- Array of tags
status VARCHAR(50) DEFAULT 'draft',
published_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Albums table - Enhanced with photography curation
CREATE TABLE albums (
id SERIAL PRIMARY KEY,
slug VARCHAR(255) UNIQUE NOT NULL,
title VARCHAR(255) NOT NULL,
description TEXT,
date DATE,
location VARCHAR(255),
cover_photo_id INTEGER REFERENCES photos(id),
is_photography BOOLEAN DEFAULT false, -- Show in photos experience
status VARCHAR(50) DEFAULT 'draft',
show_in_universe BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Photos table
CREATE TABLE photos (
id SERIAL PRIMARY KEY,
album_id INTEGER REFERENCES albums(id) ON DELETE CASCADE,
filename VARCHAR(255) NOT NULL,
url VARCHAR(500) NOT NULL,
thumbnail_url VARCHAR(500),
width INTEGER,
height INTEGER,
exif_data JSONB,
caption TEXT,
display_order INTEGER DEFAULT 0,
-- Individual publishing support
slug VARCHAR(255) UNIQUE, -- Only if published individually
title VARCHAR(255), -- Optional title for individual photos
description TEXT, -- Longer description when published solo
status VARCHAR(50) DEFAULT 'draft',
published_at TIMESTAMP,
show_in_photos BOOLEAN DEFAULT true, -- Show in photos page when published solo
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Media table (general uploads) - Enhanced with photography curation
CREATE TABLE media (
id SERIAL PRIMARY KEY,
filename VARCHAR(255) NOT NULL,
original_name VARCHAR(255), -- Original filename from user
mime_type VARCHAR(100) NOT NULL,
size INTEGER NOT NULL,
url TEXT NOT NULL,
thumbnail_url TEXT,
width INTEGER,
height INTEGER,
alt_text TEXT, -- Alt text for accessibility
description TEXT, -- Optional description
is_photography BOOLEAN DEFAULT false, -- Star for photos experience
used_in JSONB DEFAULT '[]', -- Legacy tracking field
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Media usage tracking table
CREATE TABLE media_usage (
id SERIAL PRIMARY KEY,
media_id INTEGER REFERENCES media(id) ON DELETE CASCADE,
content_type VARCHAR(50) NOT NULL, -- 'project', 'post', 'album'
content_id INTEGER NOT NULL,
field_name VARCHAR(100) NOT NULL, -- 'featuredImage', 'logoUrl', 'gallery', 'content', 'attachments'
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(media_id, content_type, content_id, field_name)
);
2. Image Handling Strategy
For Posts (Edra Integration)
- Storage: Images embedded in posts are stored in the
mediatable - Edra Custom Block: Create custom image block that:
- Uploads to
/api/media/uploadon drop/paste - Returns media ID and URL
- Stores reference as
{ type: "image", mediaId: 123, url: "...", alt: "..." }
- Uploads to
- Advantages:
- Images flow naturally with content
- Can add captions, alt text inline
- Supports drag-and-drop repositioning
- No orphaned images (tracked by mediaId)
For Projects
- Featured Image: Single image reference stored in
featured_imagefield - Gallery Images: Array of media IDs stored in
galleryJSONB field - Case Study Content: Uses same Edra approach as Posts
- Storage Pattern:
{ "featured_image": "https://cdn.../image1.jpg", "gallery": [ { "mediaId": 123, "url": "...", "caption": "..." }, { "mediaId": 124, "url": "...", "caption": "..." } ] }
Media Usage Tracking System
The system now uses a dedicated media_usage table for robust tracking:
-- MediaUsage tracks where each media file is used
-- Replaces the simple used_in JSONB field with proper relational tracking
-- Enables complex queries like "show all projects using this media"
-- Supports bulk operations and reference cleanup
Benefits:
- Accurate usage tracking across all content types
- Efficient queries for usage information
- Safe bulk deletion with automatic reference cleanup
- Detailed tracking by field (featuredImage, gallery, content, etc.)
3. Content Type Editors
- Projects: Form-based editor with:
- Metadata fields (title, year, client, role)
- Technology tag selector
- Featured image picker (opens media library)
- Gallery manager (grid view with reordering)
- Optional Edra editor for case studies
- Posts: Full Edra editor with:
- Custom image block implementation
- Drag-and-drop image upload
- Media library integration
- Image optimization on upload
- Auto-save including image references
- Photos/Albums: Media-focused interface with:
- Bulk photo upload
- Drag-and-drop ordering
- EXIF data extraction
- Album metadata editing
4. Edra Custom Image Block
// Custom image block schema for Edra
const ImageBlock = {
type: "image",
content: {
mediaId: number,
url: string,
thumbnailUrl?: string,
alt?: string,
caption?: string,
width?: number,
height?: number,
alignment?: "left" | "center" | "right" | "full"
}
}
// Example Edra content with images
{
"blocks": [
{ "type": "heading", "content": "Project Overview" },
{ "type": "paragraph", "content": "This project..." },
{
"type": "image",
"content": {
"mediaId": 123,
"url": "https://cdn.../full.jpg",
"thumbnailUrl": "https://cdn.../thumb.jpg",
"alt": "Project screenshot",
"caption": "The main dashboard view",
"alignment": "full"
}
},
{ "type": "paragraph", "content": "As shown above..." }
]
}
5. Media Library System
Media Library Component
- Modal Interface: Opens from Edra toolbar, form fields, or Browse Library buttons
- Features:
- Grid and list view modes for uploaded media
- Search by filename and filter by type (image/video/audio/pdf)
- Usage information showing where each media is used
- Alt text editing and accessibility features
- Upload new files directly from modal
- Single and multi-select functionality
- Returns: Media object with ID and URLs
Multiselect & Bulk Operations
- Selection Interface: Checkbox-based selection in both grid and list views
- Bulk Actions:
- Select All / Clear Selection controls
- Bulk delete with confirmation
- Progress indicators and loading states
- Safe Deletion: Automatic reference cleanup across all content types
- Reference Tracking: Shows exactly where each media file is used before deletion
6. Image Processing Pipeline
- Upload: User drops/selects image
- Processing:
- Generate unique filename
- Create multiple sizes:
- Thumbnail (300px)
- Medium (800px)
- Large (1600px)
- Original
- Extract metadata (dimensions, EXIF)
- Storage: Upload to CDN
- Database: Create media record with all URLs
- Association: Update
used_inwhen embedded
7. API Endpoints
// Projects
GET / api / projects
POST / api / projects
GET / api / projects / [slug]
PUT / api / projects / [id]
DELETE / api / projects / [id]
// Posts
GET / api / posts
POST / api / posts
GET / api / posts / [slug]
PUT / api / posts / [id]
DELETE / api / posts / [id]
// Albums & Photos
GET / api / albums
POST / api / albums
GET / api / albums / [slug]
PUT / api / albums / [id]
DELETE / api / albums / [id]
POST / api / albums / [id] / photos
DELETE / api / photos / [id]
PUT / api / photos / [id] / order
// Media Management
POST / api / media / upload // Single file upload
POST / api / media / bulk - upload // Multiple file upload
GET / api / media // Browse with filters, pagination
GET / api / media / [id] // Get single media item
PUT / api / media / [id] // Update media (alt text, description)
DELETE / api / media / [id] // Delete single media item
DELETE / api / media / bulk -
delete (
// Delete multiple media items
GET
) /
api /
media /
[id] /
usage // Check where media is used
POST / api / media / backfill - usage // Backfill usage tracking for existing content
8. Media Management & Cleanup
Advanced Usage Tracking
- MediaUsage Table: Dedicated table for precise tracking of media usage
- Automatic Tracking: All content saves automatically update usage references
- Field-Level Tracking: Tracks specific fields (featuredImage, gallery, content, attachments)
- Content Type Support: Projects, Posts, Albums with full reference tracking
- Real-time Usage Display: Shows exactly where each media file is used
Safe Deletion System
- Usage Validation: Prevents deletion if media is in use (unless forced)
- Reference Cleanup: Automatically removes deleted media from all content
- Bulk Operations: Multi-select deletion with comprehensive reference cleanup
- Rich Text Cleanup: Removes deleted media from Edra editor content (images, galleries)
- Atomic Operations: All-or-nothing deletion ensures data consistency
Edra Integration Details
// Custom upload handler for BlockNote
const handleImageUpload = async (file) => {
const formData = new FormData()
formData.append('file', file)
formData.append('context', 'post') // or 'project'
const response = await fetch('/api/media/upload', {
method: 'POST',
body: formData
})
const media = await response.json()
// Return format expected by Edra
return {
mediaId: media.id,
url: media.url,
thumbnailUrl: media.thumbnail_url,
width: media.width,
height: media.height
}
}
9. Admin Interface
- Route:
/admin(completely separate from public routes) - Dashboard: Overview of all content types with quick stats
- Content Lists:
- Projects with preview thumbnails and status indicators
- Posts with publish status and type badges
- Albums with photo counts and metadata
- Content Editors: Type-specific editing interfaces with rich text support
- Media Library: Comprehensive media management with:
- Grid and list view modes
- Advanced search and filtering
- Usage tracking and reference display
- Alt text editing and accessibility features
- Bulk operations with multiselect interface
- Safe deletion with reference cleanup
10. Public Display Integration
- Work page: Dynamic project grid from database
- Universe page:
- Mixed feed of posts and albums (marked with
show_in_universe) - Chronological ordering
- Different card styles for posts vs photo albums
- Mixed feed of posts and albums (marked with
- Photos page: Album grid with masonry layout
- Individual pages:
/work/[slug],/universe/[slug],/photos/[slug]
Implementation Phases
Phase 1: Foundation (Week 1)
- Set up PostgreSQL database with full schema
- Create database connection utilities
- Implement media upload infrastructure
- Build admin route structure and navigation
Phase 2: Content Types (Week 2-3)
- Posts: Edra integration, CRUD APIs
- Projects: Form builder, gallery management
- Albums/Photos: Bulk upload, EXIF extraction
- Create content type list views in admin
Phase 3: Public Display (Week 4)
- Replace static project data with dynamic
- Build Universe mixed feed (posts + albums)
- Update Photos page with dynamic albums
- Implement individual content pages
Phase 4: Polish & Optimization (Week 5)
- Image optimization and CDN caching
- Admin UI improvements
- Search and filtering
- Performance optimization
Technical Decisions
Database Choice: PostgreSQL
- Native JSON support for Edra content
- Railway provides managed PostgreSQL
- Familiar, battle-tested solution
Media Storage Options
-
Cloudinary (Recommended)
- Free tier sufficient for personal use
- Automatic image optimization
- Easy API integration
-
AWS S3
- More control but requires AWS account
- Additional complexity for signed URLs
Image Integration Summary
- Posts: Use Edra's custom image blocks with inline placement
- Projects:
- Featured image: Single media reference
- Gallery: Array of media IDs with ordering
- Case studies: Edra blocks (same as posts)
- Albums: Direct photos table relationship
- Storage: All images go through media table for consistent handling
- Association: Track usage with
used_inJSONB field to prevent orphans
Authentication (Future)
- Initially: No auth (rely on obscure admin URL)
- Future: Add simple password protection or OAuth
Development Checklist
Infrastructure
- Set up PostgreSQL on Railway
- Create database schema and migrations
- Set up Cloudinary/S3 for media storage
- Configure environment variables
Dependencies
edra(Edra editor) - Integrated and configured@prisma/client- Set up with complete schemacloudinary- SDK integrated for image processing and storage- Form validation with built-in validation
exifrfor EXIF data extraction (needed for photos system)
Admin Interface
- Admin layout and navigation
- Content type switcher (Dashboard, Projects, Universe, Media)
- List views for projects and posts
- Complete form system for Projects (metadata, branding, styling)
- Edra wrapper for Posts with all post types
- Comprehensive admin component library
- Photo uploader with drag-and-drop (for albums system)
- Media library browser modal
APIs
- CRUD endpoints for projects and posts
- Media upload with progress
- Bulk upload operations for media
- Media usage tracking endpoints
- Albums CRUD endpoints (schema ready, UI needed)
- Bulk operations (delete, publish) for content
- Search and filtering endpoints
Public Display
- Dynamic Work page
- Mixed Universe feed
- Photos masonry grid
- Individual content pages
- SEO meta tags
Design Decisions
Based on requirements discussion:
- Albums: No featured flag needed
- Version History: Nice-to-have feature for future implementation
- Photo Publishing: Individual photos can be published separately from albums
- Project Templates: Defer case study layout templates for later phase
- Scheduled Publishing: Not needed initially
- RSS Feeds: Required for all content types (projects, posts, photos)
- Post Types: Simplified to two main types:
- Post: Simple content with optional attachments (replaces microblog, link, photo posts)
- Essay: Full editor with title/metadata + optional attachments (replaces blog posts)
- Albums & Photo Curation: Albums serve dual purposes:
- Regular Albums: Collections for case studies, UI galleries, design process
- Photography Albums: Curated collections for photo-centric experience
- Both album and media levels have
isPhotographyflags for flexible curation
- Photo Curation Strategy: Media items can be "starred for photos" regardless of usage context
- Same photo can exist in posts AND photo collections
- Editorial control over what constitutes "photography" vs "UI screenshots/sketches"
- Photography albums can contain mixed content if editorially appropriate
Current Status (June 2024)
Completed
- ✅ Database setup with Prisma and PostgreSQL
- ✅ Media management system with Cloudinary integration
- ✅ Admin foundation (layout, navigation, auth, forms, data tables)
- ✅ Edra rich text editor integration for case studies and posts
- ✅ Edra image and gallery extensions with MediaLibraryModal integration
- ✅ Local development mode for media uploads (no Cloudinary usage)
- ✅ Project CRUD system with metadata fields and enhanced schema
- ✅ Project list view in admin with enhanced UI
- ✅ Project forms with branding (logo, colors) and styling
- ✅ Posts CRUD system with all post types (blog, microblog, link, photo, album)
- ✅ Posts attachments field for multiple image support
- ✅ Posts list view and editor in admin
- ✅ Complete database schema with MediaUsage tracking table
- ✅ Media API endpoints with upload, bulk upload, and usage tracking
- ✅ Component library for admin interface (buttons, inputs, modals, etc.)
- ✅ MediaLibraryModal for browsing and selecting media
- ✅ Media details modal with alt text editing and usage information
- ✅ Multiselect interface for bulk media operations
- ✅ Safe bulk deletion with automatic reference cleanup
- ✅ UniverseComposer with photo attachment support
- ✅ Form integration with Browse Library functionality (ImageUploader, GalleryUploader)
- ✅ Usage tracking backfill system for existing content
- ✅ Project Password Protection & Visibility System (June 2024)
- ✅ Four project states: Published, List-only, Password-protected, Draft
- ✅ Password protection with session storage
- ✅ Visual indicators in project lists
- ✅ Admin interface updates with status dropdown
- ✅ API filtering for different visibility states
- ✅ RSS Feed Best Practices Implementation (June 2024)
- ✅ Updated all RSS feeds with proper XML namespaces
- ✅ Full content support via content:encoded
- ✅ Enhanced HTTP headers with ETag and caching
- ✅ RFC 822 date formatting throughout
In Progress
- 🔄 Content Simplification & Photo Curation System
Next Steps
-
Content Model Updates (Immediate Priority)
- Add
isPhotographyfield to Media and Album tables via migration - Simplify post types to just "post" and "essay"
- Update post creation UI to use simplified types
- Add photography toggle to media details modal
- Add photography indicator pills in admin interface
- Add
-
Albums & Photos Management Interface
- Album creation and management UI with photography toggle
- Bulk photo upload interface with progress
- Photo ordering within albums
- Album cover selection
- EXIF data extraction and display
- Photography album filtering and management
-
Enhanced Content Features
- Featured image picker for projects (using MediaLibraryModal)
- Technology tag selector for projects
- Auto-save functionality for all editors
- Gallery manager for project images with drag-and-drop
-
Public Display Integration
- Dynamic Work page displaying projects from database
- Universe page with mixed content feed (posts + essays)
- Photos page with photography albums only
- Individual content detail pages
- SEO meta tags and OpenGraph integration
Phased Implementation Plan
Phase 0: Local Development Setup
- Install local PostgreSQL (via Homebrew or Postgres.app)
- Create local database
- Set up local environment variables
- Run Prisma migrations locally
- Create mock data for testing
- Test basic CRUD operations locally
Phase 1: Database & Infrastructure Setup
- Create all database tables with updated schema
- Set up Prisma ORM with models
- Create base API route structure
- Implement database connection utilities
- Set up error handling and logging
- Configure Cloudinary account (deferred to production setup)
- Set up PostgreSQL on Railway (deferred to production setup)
Phase 2: Media Management System
- Create media upload endpoint with Cloudinary integration
- Implement image processing pipeline (multiple sizes)
- Build media library API endpoints with pagination and filtering
- Create advanced MediaUsage tracking system
- Add bulk upload endpoint for photos
- Build MediaLibraryModal component with search and selection
- Implement media details modal with alt text editing
- Create multiselect interface for bulk operations
- Add safe bulk deletion with reference cleanup
- Build usage tracking queries and backfill system
Phase 3: Admin Foundation
- Create admin layout component
- Build admin navigation with content type switcher
- Implement admin authentication (basic for now)
- Create reusable form components (Button, Input, Modal, etc.)
- Build data table component for list views
- Add loading and error states
- Create comprehensive admin UI component library
- Build complete media library system with modals and management
Phase 4: Posts System (All Types)
- Create Edra Svelte wrapper component
- Implement custom image and gallery blocks for Edra
- Build post type selector UI
- Create blog/microblog post editor
- Build link post form
- Create posts list view in admin
- Implement post CRUD APIs with attachments support
- Post editor page with type-specific fields
- Complete posts database schema with attachments field
- Posts administration interface
- UniverseComposer with photo attachment support
- Integrate MediaLibraryModal with Edra editor
- Build album post selector (needs albums system)
- Add auto-save functionality
Phase 5: Projects System
- Build project form with all metadata fields
- Enhanced schema with branding fields (logo, colors)
- Project branding and styling forms with ImageUploader and GalleryUploader
- Add optional Edra editor for case studies with media support
- Create project CRUD APIs with usage tracking
- Build project list view with enhanced UI
- Integrate Browse Library functionality in project forms
- Create technology tag selector
- Build gallery manager with drag-and-drop ordering
- Add project ordering functionality
Phase 6: Content Simplification & Photo Curation
- Add
isPhotographyfield to Media table (migration) - Add
isPhotographyfield to Album table (migration) - Simplify post types to "post" and "essay" only
- Update UniverseComposer to use simplified post types
- Add photography toggle to MediaDetailsModal
- Add photography indicator pills throughout admin interface
- Update media and album APIs to handle photography flags
Phase 7: Photos & Albums System
- Complete database schema for albums and photos
- Photo/album CRUD API endpoints (albums endpoint exists)
- Create album management interface with photography toggle
- Album Photo Management (Core functionality complete)
- Add photos to albums interface using MediaLibraryModal
- Remove photos from albums with confirmation
- Photo grid display with hover overlays
- Album-photo relationship API endpoints (POST /api/albums/[id]/photos, DELETE /api/photos/[id])
- Photo reordering within albums (drag-and-drop)
- Album cover photo selection
- Build bulk photo uploader with progress
- Implement EXIF data extraction for photos
- Add individual photo publishing UI
- Build photo metadata editor
- Add photography album filtering and management
- Add "show in universe" toggle for albums
Phase 8: Public Display Updates
- Replace static Work page with dynamic data
- Update project detail pages
- Build Universe mixed feed component
- Create different card types for each post type
- Update Photos page with dynamic albums/photos
- Implement individual photo pages
- Add Universe post detail pages
- Ensure responsive design throughout
Phase 9: RSS Feeds & Final Polish
- Implement RSS feed for projects
- Create RSS feed for Universe posts
- Add RSS feed for photos/albums
- Implement combined RSS feed
- Add OpenGraph meta tags
- Optimize image loading and caching
- Add search functionality to admin
- Performance optimization pass
Phase 10: Production Deployment
- Set up PostgreSQL on Railway
- Run migrations on production database
- Configure Cloudinary for production
- Set up environment variables on Railway
- Test all endpoints in production
- Set up database backups
- Configure proper authentication
- Monitor logs and performance
Future Enhancements (Post-Launch)
- Version history system
- More robust authentication
- Project case study templates
- Advanced media organization (folders/tags)
- Analytics integration
- Backup system
Albums & Photos System Implementation
Design Decisions Made (May 2024)
-
Simplified Post Types: Reduced from 5 types (blog, microblog, link, photo, album) to 2 types:
- Post: Simple content with optional attachments (handles previous microblog, link, photo use cases)
- Essay: Full editor with title/metadata + attachments (handles previous blog use cases)
-
Photo Curation Strategy: Dual-level curation system:
- Media Level:
isPhotographyboolean - stars individual media for photo experience - Album Level:
isPhotographyboolean - marks entire albums for photo experience - Mixed Content: Photography albums can contain non-photography media (Option A)
- Default Behavior: Both flags default to
falseto prevent accidental photo inclusion
- Media Level:
-
Visual Indicators: Pill-shaped tags to indicate photography status in admin interface
-
Album Flexibility: Albums serve multiple purposes:
- Regular albums for case studies, UI collections, design process
- Photography albums for curated photo experience (Japan Trip, Street Photography)
- Same album system, different curation flags
Implementation Task List
Phase 1: Database Updates
- Create migration to add
isPhotographyfield to Media table - Create migration to add
isPhotographyfield to Album table - Update Prisma schema with new fields
- Test migrations on local database
Phase 2: API Updates
- Update Media API endpoints to handle
isPhotographyflag - Update Album API endpoints to handle
isPhotographyflag - Update media usage tracking to work with new flags
- Add filtering capabilities for photography content
Phase 3: Admin Interface Updates
- Add photography toggle to MediaDetailsModal
- Add photography indicator pills for media items (grid and list views)
- Add photography indicator pills for albums
- Update media library filtering to include photography status
- Add bulk photography operations (mark/unmark multiple items)
Phase 4: Post Type Simplification
- Update UniverseComposer to use only "post" and "essay" types
- Remove complex post type selector UI
- Update post creation flows
- Migrate existing posts to simplified types (if needed)
- Update post display logic to handle simplified types
Phase 5: Album Management System
- Create album creation/editing interface with photography toggle
- Build album list view with photography indicators
- Critical Missing Feature: Album Photo Management
- Add photo management section to album edit page
- Implement "Add Photos from Library" functionality using MediaLibraryModal
- Create photo grid display within album editor
- Add remove photo functionality (individual photos)
- Implement drag-and-drop photo reordering within albums
- Add album cover photo selection interface
- Update album API to handle photo associations
- Create album-photo relationship endpoints
- Add bulk photo upload to albums with automatic photography detection
Phase 6: Photography Experience
- Build photography album filtering in admin
- Create photography-focused views and workflows
- Add batch operations for photo curation
- Implement photography album public display
- Add photography vs regular album distinction in frontend
Success Criteria
- Admin can quickly toggle media items between regular and photography status
- Albums can be easily marked for photography experience
- Post creation is simplified to 2 clear choices
- Photography albums display correctly in public photos section
- Mixed content albums (photography + other) display all content as intended
- Pill indicators clearly show photography status throughout admin interface
Success Metrics
- Can create and publish any content type within 2-3 minutes
- Content appears on site immediately after publishing
- Bulk photo upload handles 50+ images smoothly
- No accidental data loss (auto-save works reliably)
- Page load performance remains fast (<2s)
- Admin interface works well on tablet/desktop
- Media uploads show progress and handle failures gracefully
- RSS feeds update automatically with new content