managarten/apps/photos/CLAUDE.md
Till JS 53b3746b98 refactor: rename nutriphi module to food (Essen)
Complete rename across the entire monorepo pre-launch:
- Module, routes, API, i18n, standalone landing app directories
- All code identifiers, display names, logo component
- German user-facing label: "Essen" (English brand stays "Food")
- Dexie table nutriFavorites -> foodFavorites
- Infra configs (docker-compose, cloudflared, nginx, wrangler)

Zero residue of nutriphi remains. No data migration needed (pre-launch).

Follow-up: run pnpm install, update Cloudflare DNS
(food.mana.how), rename Cloudflare Pages project.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:30:07 +02:00

6.7 KiB

Photos Project Guide

Overview

Photos is a unified photo gallery application for the Mana ecosystem. It aggregates photos from all apps (Picture, Chat, Contacts, Food, etc.) via the mana-media service, providing a central place to view, organize, and manage photos.

App Dev Port Prod Port Prod URL
Backend 3019 3039 https://photos-api.mana.how
Web App 5189 5019 https://photos.mana.how

Project Structure

apps/photos/
├── apps/
│   ├── backend/      # NestJS API server (@photos/backend)
│   └── web/          # SvelteKit web application (@photos/web)
├── packages/
│   └── shared/       # Shared types (@photos/shared)
├── package.json
└── CLAUDE.md

Commands

Root Level (from monorepo root)

# All apps
pnpm photos:dev               # Run all photos apps

# Individual apps
pnpm dev:photos:backend       # Start backend server (port 3019)
pnpm dev:photos:web           # Start web app (port 5189)

# Database
pnpm photos:db:push           # Push schema to database
pnpm photos:db:studio         # Open Drizzle Studio

Backend (apps/photos/apps/backend)

pnpm dev                      # Start with hot reload
pnpm build                    # Build for production
pnpm start:prod               # Start production server
pnpm db:push                  # Push schema to database
pnpm db:studio                # Open Drizzle Studio

Technology Stack

Layer Technology
Backend NestJS 10, Drizzle ORM, PostgreSQL
Web SvelteKit 2.x, Svelte 5 (runes mode), Tailwind CSS
Auth Mana Auth (JWT)
Media mana-media service (central media storage)

Core Features

  1. Gallery - View all photos across apps in grid/list view
  2. Albums - Organize photos into custom albums
  3. Favorites - Mark photos as favorites
  4. Tags - Tag photos for organization
  5. EXIF Data - View camera, location, and date metadata
  6. Upload - Upload new photos directly
  7. Smart Albums - Auto-generated albums by date/location/camera

Architecture

┌────────────────┐
│  Photos Web    │  SvelteKit (Port 5189)
│                │  Gallery, Albums, Upload
└───────┬────────┘
        │
        ▼
┌────────────────┐
│ Photos Backend │  NestJS (Port 3019)
│                │  Albums, Favorites, Tags
└───────┬────────┘
        │
        ▼
┌────────────────┐
│  mana-media    │  (Port 3015)
│                │  Central media storage
└────────────────┘

API Endpoints

Photos (proxy to mana-media with enrichment)

Endpoint Method Description
/api/v1/photos GET List photos with filters
/api/v1/photos/:mediaId GET Get photo with metadata
/api/v1/photos/stats GET Get photo statistics

Albums

Endpoint Method Description
/api/v1/albums GET List user's albums
/api/v1/albums POST Create album
/api/v1/albums/:id GET Get album with items
/api/v1/albums/:id PATCH Update album
/api/v1/albums/:id DELETE Delete album
/api/v1/albums/:id/items POST Add photos to album
/api/v1/albums/:id/items/:mediaId DELETE Remove photo from album
/api/v1/albums/:id/cover PATCH Set album cover

Favorites

Endpoint Method Description
/api/v1/favorites GET List favorited photos
/api/v1/favorites/:mediaId POST Add to favorites
/api/v1/favorites/:mediaId DELETE Remove from favorites
/api/v1/favorites/:mediaId/toggle POST Toggle favorite status

Tags

Endpoint Method Description
/api/v1/tags GET List user's tags
/api/v1/tags POST Create tag
/api/v1/tags/:id PATCH Update tag
/api/v1/tags/:id DELETE Delete tag
/api/v1/photos/:mediaId/tags GET Get tags for photo
/api/v1/photos/:mediaId/tags/:tagId POST Add tag to photo
/api/v1/photos/:mediaId/tags/:tagId DELETE Remove tag from photo

Database Schema

albums

  • id (UUID) - Primary key
  • user_id (TEXT) - Owner
  • name (VARCHAR) - Album name
  • description (TEXT) - Description
  • cover_media_id (TEXT) - Cover photo (mana-media ID)
  • is_auto_generated (BOOLEAN) - Smart album flag
  • auto_generate_type (TEXT) - date/location/camera
  • auto_generate_value (TEXT) - Filter value

album_items

  • id (UUID) - Primary key
  • album_id (UUID) - FK to albums
  • media_id (TEXT) - mana-media ID
  • sort_order (INTEGER) - Sort order

favorites

  • id (UUID) - Primary key
  • user_id (TEXT) - Owner
  • media_id (TEXT) - mana-media ID

tags

  • id (UUID) - Primary key
  • user_id (TEXT) - Owner
  • name (VARCHAR) - Tag name
  • color (VARCHAR) - Hex color

photo_tags

  • media_id (TEXT) - mana-media ID
  • tag_id (UUID) - FK to tags

Environment Variables

Backend (.env)

NODE_ENV=development
PORT=3019
DATABASE_URL=postgresql://mana:devpassword@localhost:5432/photos
MANA_AUTH_URL=http://localhost:3001
MANA_MEDIA_URL=http://localhost:3015
CORS_ORIGINS=http://localhost:5173,http://localhost:5189,http://localhost:8081

Web (.env)

PUBLIC_BACKEND_URL=http://localhost:3019
PUBLIC_MANA_AUTH_URL=http://localhost:3001
PUBLIC_MANA_MEDIA_URL=http://localhost:3015

Query Parameters for Photo Listing

Parameter Type Description
apps string Comma-separated app names (picture,chat,food)
mimeType string MIME type filter (image/*, image/jpeg)
dateFrom ISO date Start date filter
dateTo ISO date End date filter
hasLocation boolean Filter photos with GPS data
limit number Results per page (default: 50)
offset number Pagination offset
sortBy string createdAt, dateTaken, size
sortOrder string asc, desc

Integration with mana-media

The Photos backend acts as a proxy to mana-media, enriching responses with local data:

  1. Photos list - Fetches from mana-media /api/v1/media/list/all, adds favorites and tags
  2. Photo detail - Fetches from mana-media /api/v1/media/:id, adds favorites and tags
  3. Stats - Fetches from mana-media /api/v1/media/stats

Local data (albums, favorites, tags) is stored in the Photos database, while media files and EXIF data are stored in mana-media.