jedmund-svelte/prd/PRD-cms-functionality.md
2025-06-11 00:54:05 -07:00

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 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:
    {
    	"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

  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

// 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
  • 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

  • edra (Edra editor) - Integrated and configured
  • @prisma/client - Set up with complete schema
  • cloudinary - SDK integrated for image processing and storage
  • Form validation with built-in validation
  • exifr for 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:

  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

  • 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 isPhotography field to Media table (migration)
  • Add isPhotography field 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)

  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

  • Create migration to add isPhotography field to Media table
  • Create migration to add isPhotography field to Album table
  • Update Prisma schema with new fields
  • Test migrations on local database

Phase 2: API Updates

  • Update Media API endpoints to handle isPhotography flag
  • Update Album API endpoints to handle isPhotography flag
  • 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