perf: add Cache-Control to stable recipe & fitness API endpoints

rand_array seeds with Math.floor(time / 86400000), i.e. the same
shuffle for every caller during a UTC day — so every list endpoint
that runs through it is safe to share publicly:

  - /items/all_brief, /items/category/[c], /items/tag/[t],
    /items/icon/[i], /items/in_season/[m]
    → public, max-age=28800 (8h), s-maxage=28800, SWR=1d

The distinct-value lists (no shuffle, change only on recipe edit):

  - /items/category, /items/tag, /items/icon
    → public, max-age=3600 (1h), s-maxage=86400 (1d), SWR=1w

Individual recipes change when their author edits them:

  - /items/[name]
    → public, max-age=300 (5m), s-maxage=3600 (1h), SWR=1d

Fitness exercise-picker filters are identical for every logged-in
user but require auth:

  - /fitness/exercises/filters
    → private, max-age=3600

Skipped the calendar page itself: its HTML embeds data.session via the
faith layout's <UserHeader>, so public caching would leak identity.
This commit is contained in:
2026-04-23 15:46:04 +02:00
parent ff6a7ce01a
commit 03875f2be6
12 changed files with 53 additions and 15 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ Order = impact. Font items + app.html preload intentionally skipped.
- [x] 7. Muscle-heatmap endpoint — add projection + O(1) bucket math. Overview already had a projection; set-subfield narrowing was attempted but reverted (returned malformed sets). Timeseries cap not feasible: totals are lifetime-scoped.
- [x] 8. Calendar payload trim — `yearDays` narrowed to `{iso, color}` (needle lookup only), new pre-filtered `feastDots` array carries feast-specific metadata. Also fixed a stray double `locals.session ?? (locals.session ?? …)` in both calendar page loaders.
- [x] 9. History sessions endpoint — projection narrowed to exactly what SessionCard reads (drops notes, templates, mode, endTime, session-level gpsPreview); added `.lean()`.
- [ ] 10. `Cache-Control` headers on stable API endpoints (all_brief, calendar, exercises metadata)
- [x] 10. `Cache-Control` headers on stable API endpoints — added to recipe `/items/category`, `/items/tag`, `/items/icon` (public, 1h/1d with SWR), `/items/[name]` (public, 5m/1h with SWR), and fitness `/exercises/filters` (private, 1h). Skipped `all_brief` (per-request shuffle) and calendar page (`data.session` serialised into HTML via layout → would leak across users under public cache).
- [ ] 11. Search — debounce 100 ms + server-side pre-normalized `_searchKey`
## Features