feat: PhotoPrism M0 bring-up — compose stack, web client, sidecar, migrate

Replace the legacy mule-image backend with PhotoPrism plus a thin
SvelteKit client and a Node sidecar for endpoints PhotoPrism doesn't
expose (file rename), and add a two-phase migrator (metadata via PUT,
heaps → albums) for the existing Postgres library.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-17 16:06:58 +02:00
parent 423a73a8a6
commit 8c2526d982
69 changed files with 12048 additions and 0 deletions

43
sidecar/README.md Normal file
View File

@@ -0,0 +1,43 @@
# mule-sidecar
Auxiliary service that handles operations PhotoPrism's REST API does not expose.
## Why this exists
Per the merge plan at `/home/dtoro/.claude/plans/i-want-you-to-twinkly-galaxy.md`,
a Go + Gin + GORM service (matching PhotoPrism's stack) will eventually own:
- Per-user heap sharing with pending invitations
- Folder mutations under `originals/` (create / rename / delete / move)
- **File rename** on disk (PhotoPrism's `OriginalName` is a display-only rename)
The plan picks Go for stack consistency and the option to upstream features.
## What ships today
A **Node.js prototype** (`server.mjs`) covering only the **file rename** endpoint.
The decision to ship Node first is pragmatic — Go isn't installed on this dev
box and `sudo dnf install golang` needs a password. Node is already on PATH for
the SvelteKit dev server, so a single-file Node service unblocks the feature
without changing the host setup.
The endpoint contract is stable: when M4 lands the proper Go service, the
SvelteKit client keeps calling the same paths.
## Endpoints
- `POST /api/sidecar/files/:photoUid/rename` `{ "newName": "newfile.png" }`
Renames the primary file of the photo on disk under `${ORIGINALS_ROOT}`,
then triggers a PhotoPrism reindex of the parent path.
## Run
```
ORIGINALS_ROOT=/home/dtoro/projects/mule-image/photos-sample \
PHOTOPRISM_BASE_URL=http://localhost:2342 \
SIDECAR_PORT=8000 \
node server.mjs
```
The SvelteKit dev server proxies `/api/sidecar/*` to `http://localhost:8000`.