managarten/apps/photos/CLAUDE.md
Till JS 22a73943e1 chore: complete ManaCore → Mana rename (docs, go modules, plists, images)
Final cleanup of references missed in previous rename commits:

- Dockerfiles: PUBLIC_MANA_CORE_AUTH_URL → PUBLIC_MANA_AUTH_URL
- Go modules: github.com/manacore/* → github.com/mana/* (7 go.mod files)
- launchd plists: com.manacore.* → com.mana.* (14 files renamed + content)
- Image assets: *_Manacore_AI_Credits* → *_Mana_AI_Credits* (11 files)
- .env.example files: ManaCore brand strings → Mana
- .prettierignore: stale apps/manacore/* paths → apps/mana/*
- Markdown docs (CLAUDE.md, /docs/*): mana-core-auth → mana-auth, etc.

Excluded from rename: .claude/, devlog/, manascore/ (historical content),
client testimonials, blueprints, npm package refs (@mana-core/*).

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

212 lines
6.7 KiB
Markdown

# Photos Project Guide
## Overview
**Photos** is a unified photo gallery application for the Mana ecosystem. It aggregates photos from all apps (Picture, Chat, Contacts, NutriPhi, 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)
```bash
# 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)
```bash
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)
```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)
```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,nutriphi) |
| `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.