# 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 ```sql -- 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 `media` table - **Edra Custom Block**: Create custom image block that: - Uploads to `/api/media/upload` on drop/paste - Returns media ID and URL - Stores reference as `{ type: "image", mediaId: 123, url: "...", alt: "..." }` - **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_image` field - **Gallery Images**: Array of media IDs stored in `gallery` JSONB field - **Case Study Content**: Uses same Edra approach as Posts - **Storage Pattern**: ```json { "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: ```sql -- 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 ```typescript // 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 1. **Upload**: User drops/selects image 2. **Processing**: - Generate unique filename - Create multiple sizes: - Thumbnail (300px) - Medium (800px) - Large (1600px) - Original - Extract metadata (dimensions, EXIF) 3. **Storage**: Upload to CDN 4. **Database**: Create media record with all URLs 5. **Association**: Update `used_in` when embedded ### 7. API Endpoints ```typescript // 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 ```javascript // 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 - **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 1. **Cloudinary** (Recommended) - Free tier sufficient for personal use - Automatic image optimization - Easy API integration 2. **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_in` JSONB 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 - [x] `edra` (Edra editor) - Integrated and configured - [x] `@prisma/client` - Set up with complete schema - [x] `cloudinary` - SDK integrated for image processing and storage - [x] Form validation with built-in validation - [ ] `exifr` for EXIF data extraction (needed for photos system) ### Admin Interface - [x] Admin layout and navigation - [x] Content type switcher (Dashboard, Projects, Universe, Media) - [x] List views for projects and posts - [x] Complete form system for Projects (metadata, branding, styling) - [x] Edra wrapper for Posts with all post types - [x] Comprehensive admin component library - [ ] Photo uploader with drag-and-drop (for albums system) - [ ] Media library browser modal ### APIs - [x] CRUD endpoints for projects and posts - [x] Media upload with progress - [x] Bulk upload operations for media - [x] 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: 1. **Albums**: No featured flag needed 2. **Version History**: Nice-to-have feature for future implementation 3. **Photo Publishing**: Individual photos can be published separately from albums 4. **Project Templates**: Defer case study layout templates for later phase 5. **Scheduled Publishing**: Not needed initially 6. **RSS Feeds**: Required for all content types (projects, posts, photos) 7. **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) 8. **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 `isPhotography` flags for flexible curation 9. **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 1. **Content Model Updates** (Immediate Priority) - Add `isPhotography` field 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 2. **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 3. **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 4. **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 - [x] Install local PostgreSQL (via Homebrew or Postgres.app) - [x] Create local database - [x] Set up local environment variables - [x] Run Prisma migrations locally - [x] Create mock data for testing - [x] Test basic CRUD operations locally ### Phase 1: Database & Infrastructure Setup - [x] Create all database tables with updated schema - [x] Set up Prisma ORM with models - [x] Create base API route structure - [x] Implement database connection utilities - [x] 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 - [x] Create media upload endpoint with Cloudinary integration - [x] Implement image processing pipeline (multiple sizes) - [x] Build media library API endpoints with pagination and filtering - [x] Create advanced MediaUsage tracking system - [x] Add bulk upload endpoint for photos - [x] Build MediaLibraryModal component with search and selection - [x] Implement media details modal with alt text editing - [x] Create multiselect interface for bulk operations - [x] Add safe bulk deletion with reference cleanup - [x] Build usage tracking queries and backfill system ### Phase 3: Admin Foundation - [x] Create admin layout component - [x] Build admin navigation with content type switcher - [x] Implement admin authentication (basic for now) - [x] Create reusable form components (Button, Input, Modal, etc.) - [x] Build data table component for list views - [x] Add loading and error states - [x] Create comprehensive admin UI component library - [x] Build complete media library system with modals and management ### Phase 4: Posts System (All Types) - [x] Create Edra Svelte wrapper component - [x] Implement custom image and gallery blocks for Edra - [x] Build post type selector UI - [x] Create blog/microblog post editor - [x] Build link post form - [x] Create posts list view in admin - [x] Implement post CRUD APIs with attachments support - [x] Post editor page with type-specific fields - [x] Complete posts database schema with attachments field - [x] Posts administration interface - [x] UniverseComposer with photo attachment support - [x] Integrate MediaLibraryModal with Edra editor - [ ] Build album post selector (needs albums system) - [ ] Add auto-save functionality ### Phase 5: Projects System - [x] Build project form with all metadata fields - [x] Enhanced schema with branding fields (logo, colors) - [x] Project branding and styling forms with ImageUploader and GalleryUploader - [x] Add optional Edra editor for case studies with media support - [x] Create project CRUD APIs with usage tracking - [x] Build project list view with enhanced UI - [x] 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 - [x] Add `isPhotography` field to Media table (migration) - [x] Add `isPhotography` field to Album table (migration) - [x] Simplify post types to "post" and "essay" only - [x] Update UniverseComposer to use simplified post types - [x] Add photography toggle to MediaDetailsModal - [x] Add photography indicator pills throughout admin interface - [x] Update media and album APIs to handle photography flags ### Phase 7: Photos & Albums System - [x] Complete database schema for albums and photos - [x] Photo/album CRUD API endpoints (albums endpoint exists) - [x] Create album management interface with photography toggle - [x] **Album Photo Management** (Core functionality complete) - [x] Add photos to albums interface using MediaLibraryModal - [x] Remove photos from albums with confirmation - [x] Photo grid display with hover overlays - [x] 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 - [x] Replace static Work page with dynamic data - [x] Update project detail pages - [x] Build Universe mixed feed component - [x] Create different card types for each post type - [x] Update Photos page with dynamic albums/photos - [x] Implement individual photo pages - [x] 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) 1. **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) 2. **Photo Curation Strategy**: Dual-level curation system: - **Media Level**: `isPhotography` boolean - stars individual media for photo experience - **Album Level**: `isPhotography` boolean - marks entire albums for photo experience - **Mixed Content**: Photography albums can contain non-photography media (Option A) - **Default Behavior**: Both flags default to `false` to prevent accidental photo inclusion 3. **Visual Indicators**: Pill-shaped tags to indicate photography status in admin interface 4. **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 - [x] Create migration to add `isPhotography` field to Media table - [x] Create migration to add `isPhotography` field to Album table - [x] Update Prisma schema with new fields - [x] Test migrations on local database #### Phase 2: API Updates - [x] Update Media API endpoints to handle `isPhotography` flag - [x] Update Album API endpoints to handle `isPhotography` flag - [x] Update media usage tracking to work with new flags - [x] Add filtering capabilities for photography content #### Phase 3: Admin Interface Updates - [x] Add photography toggle to MediaDetailsModal - [x] Add photography indicator pills for media items (grid and list views) - [x] Add photography indicator pills for albums - [x] Update media library filtering to include photography status - [x] Add bulk photography operations (mark/unmark multiple items) #### Phase 4: Post Type Simplification - [x] Update UniverseComposer to use only "post" and "essay" types - [x] Remove complex post type selector UI - [x] Update post creation flows - [x] Migrate existing posts to simplified types (if needed) - [x] Update post display logic to handle simplified types #### Phase 5: Album Management System - [x] Create album creation/editing interface with photography toggle - [x] 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