migrate public pages to server loads + direct prisma
Created by: jedmund
Follow-up to #72. Addresses audit items #6, #7, and #13: public page loads stop self-HTTP-hopping through /api/* and read from Prisma directly via a shared query layer.
What changed
-
New
$lib/server/queries/— one file per entity (albums,photos,garden,projects) holdingfindMany/findUniquewrappers plus the sharedinclude/select/orderByconstants. API routes and server loads both consume this layer, so the Prisma shape lives in one place. -
6 public pages migrated to
+page.server.ts:/,/albums,/photos,/garden,/labs,/work/[slug]. Each page now reads directly from Prisma instead of fetching its own API. -
Homepage parallelized —
Promise.all([lastfm, projects])instead of sequential awaits. -
Cache headers —
cache-control: public, max-age=1800, stale-while-revalidate=86400on public pages (homepage usesmax-age=300since now-playing is hotter). - API routes kept intact for writes, admin, and external consumers (RSS, client-side infinite scroll on albums/photos). They now route through the same query layer too — no duplicated Prisma shapes.
Trade-offs worth noting
-
Query logic is duplicated across page loads and API routes at the caller level. Factored into the query layer so the
where/include/orderByshapes live in one spot; callers just pick the function. - Redis caching on API routes is bypassed for page loads (direct Prisma). For this traffic shape it's a non-issue; cache headers let the browser/CDN handle it at the edge.
-
Prerendering still requires
DATABASE_URLat build time if you ever want to opt in per-page — not doing that here.
Commit sequence
One commit per concern for review:
-
extract prisma queries into shared query layer— refactor only, no behavior change migrate /albums to server loadmigrate /photos to server loadmigrate /garden to server loadmigrate /labs to server loadmigrate /work/[slug] to server loadmigrate homepage to server load, parallelize data fetchingfix formatting
Test plan
-
Home, /albums,/photos,/garden,/labs,/work/[slug]render with SSR'd data (no loading flash, no client fetch visible in Network tab on first load) -
Homepage Network tab shows LastFM and projects loading in parallel, not serially -
/albumsand/photosinfinite-scroll still fetches more pages from/api/albumsand/api/photos -
Admin album/project/garden list pages still work (they still go through /api/*) -
/work/[slug]?preview=<token>previews a draft project correctly -
A password-protected project shows locked state to non-unlocked viewers -
RSS/external consumers of /api/*still get identical payloads -
curl -Ion any migrated page shows the expectedcache-controlheader