mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-17 11:19:38 +02:00
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>
212 lines
6.7 KiB
Markdown
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.
|