docs(project): record SPA-mode decision and SvelteKit feature usage

Document that the frontend deliberately runs as a pure client-side SPA
(adapter-static, ssr=false) and that we stay on SvelteKit rather than migrating
to a bare Svelte + router setup: the file-based routing, client router, and —
most importantly — shallow routing (pushState + page.state, on which the
overlay file viewer depends) carry their weight, while the server half (SSR,
endpoints, form actions, hooks) is intentionally unused. Also drop the stale
hooks.* entries from the directory layout, since no such files exist.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 10:28:56 +03:00
parent 1f3bc2acf4
commit e8479ee4fb
+41 -2
View File
@@ -10,6 +10,46 @@
- **Font**: Epilogue (variable weight)
- **Package manager**: npm
## SPA mode — why SvelteKit without the server
This frontend runs as a **pure client-side SPA**: `adapter-static` with
`fallback: 'index.html'` and `ssr = false` globally (see
`src/routes/+layout.ts`). There is no Node server in production — the build is
static assets, and the only backend is the Go API. SvelteKit is used here
purely as an SPA framework: file-based routing, the client router, and build
tooling.
**SvelteKit features we *do* use:**
- File-based routing with nested layouts (`admin/` has its own guard) and
dynamic segments (`[id]`).
- The client router: `goto`, the `page` store/state, `afterNavigate`,
`navigating`.
- **Shallow routing** — `pushState`/`replaceState` + `page.state`. The
Immich-style file viewer in `files/` and `pools/[id]/` opens as an overlay
over the still-mounted list via shallow routing, so the browser back button
dismisses it without reloading the grid. This is the single biggest reason we
stay on SvelteKit rather than a plain router.
- `load` functions, used *only* as client-side route guards (auth redirect,
admin redirect, `/``/files`).
- `$lib` alias, generated `./$types`, Vite/HMR integration.
**SvelteKit features we deliberately do *not* use** (the "server half"):
- SSR / hydration.
- `+page.server.ts`, `+server.ts` endpoints, form actions — all data goes
through the Go API via the `$lib/api` client.
- `hooks.*`, prerendering, server-only modules — no `hooks.server.ts` /
`hooks.client.ts` files exist.
**Decision: stay on SvelteKit, do not migrate to a bare Svelte + router SPA.**
The project already *is* an SPA, so there is no runtime gain from switching
(adapter-static tree-shakes the unused server bits; the client-runtime size
difference is negligible). A migration would mean re-implementing nested
layouts, guards, dynamic params, and — most painfully — shallow routing /
history-state overlays by hand, for zero benefit. New contributors should not
expect SSR, endpoints, or hooks to do anything here; that is intentional.
## Monorepo Layout
```
@@ -49,8 +89,7 @@ frontend/
├── src/
│ ├── app.html # Shell HTML (PWA meta, font preload)
│ ├── app.css # Tailwind directives + CSS custom properties
├── hooks.server.ts # Server hooks (not used in SPA mode)
│ ├── hooks.client.ts # Client hooks (global error handling)
│ # (no hooks.* — see "SPA mode" above)
│ │
│ ├── lib/ # Shared code ($lib/ alias)
│ │ │