# 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
