add photos, an immich-backed library behind its own sidecar
officer-photos owns the whole Immich contract: the instance URL and the API key live there and nowhere else, and the platform side is an auth-gated forwarder holding no credentials. The route surface is an allow-list keyed on the first path segment, so admin, auth, api-keys, sessions, jobs, system-config and libraries are unreachable by construction rather than by enumeration. The UI mirrors Immich's own sidebar — timeline, explore, map, search, albums, people, favorites, sharing, archive, trash — because the point of a sidecar screen is to reproduce what the upstream already ships, then extend it. The timeline reads Immich's columnar time-bucket format directly; selection lives in the URL per docs/navigation-audit.md. Two things worth knowing for anyone touching this later: - `duration` is an integer count of milliseconds in Immich 3.0. It was an HH:MM:SS.mmm string before, and every stale example still shows that form. - the map container is sized with h-full/w-full, never `absolute inset-0`. maplibre's stylesheet sets `position: relative; overflow: hidden` on the element it is given, and an unlayered vendor rule beats Tailwind 4's layered `.absolute` regardless of source order — so the div collapses to height 0 and clips its own canvas away. Nothing errors: the GL context is healthy, tiles download and pixels are drawn into a buffer nobody ever composites. maplibre-gl is pinned to 5.x deliberately; 6.0 resolves a separate worker file from import.meta.url, which Officer's index.html fallback answers with HTML. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,7 @@ import { slskdRouter } from './api/slskd/router';
|
||||
import { headscaleRouter } from './api/headscale/router';
|
||||
import { transmissionRouter } from './api/transmission/router';
|
||||
import { invoiceshelfRouter } from './api/invoiceshelf/router';
|
||||
import { photosRouter } from './api/photos/router';
|
||||
import { walletRouter } from './api/wallet/router';
|
||||
import { vpnRouter } from './api/vpn/router';
|
||||
import { terminalRouter } from './api/terminal/sidecar-server';
|
||||
@@ -118,6 +119,7 @@ protectedRouter.route('/notify', notifyRouter);
|
||||
protectedRouter.route('/headscale', headscaleRouter);
|
||||
protectedRouter.route('/transmission', transmissionRouter);
|
||||
protectedRouter.route('/invoiceshelf', invoiceshelfRouter);
|
||||
protectedRouter.route('/photos', photosRouter);
|
||||
protectedRouter.route('/wallet', walletRouter);
|
||||
protectedRouter.route('/vpn', vpnRouter);
|
||||
protectedRouter.route('/system-monitor', systemMonitorRouter);
|
||||
|
||||
Reference in New Issue
Block a user