Harden auth/upload, fix PR-delete cascade and sync backfill
Build and push images / validate (push) Successful in 3s
Build and push images / build-backend (push) Successful in 6s
Build and push images / build-worker (push) Successful in 4s
Build and push images / build-frontend (push) Successful in 8s

- OIDC: require signed short-lived state on login callback; reject
  missing userinfo sub (account-takeover guard); validate token
  exchange + userinfo responses
- Upload: safe zip extraction (path-traversal + zip-bomb cap),
  streamed size-capped writes, sanitised filenames
- Garmin: increasing lookback resets last_sync_at for one-time backfill
- Activities: delete/reprocess remove PersonalRecord rows (no FK cascade)
- Profile: validate /weight limit; sync lookback UI copy
- Dashboard: sleep shading uses same day as charted body battery

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-09 20:24:24 +01:00
parent 04689a29bd
commit bdd5f80c7e
8 changed files with 158 additions and 46 deletions
+5 -2
View File
@@ -168,8 +168,11 @@ export default function DashboardPage() {
date: rows[0]?.date ? rows[0].date.slice(0, 10) : null, // intraday endpoint wants YYYY-MM-DD
resting_hr: pick('resting_hr'),
sleep_duration_s: pick('sleep_duration_s'),
sleep_start: pick('sleep_start'),
sleep_end: pick('sleep_end'),
// Sleep window must come from the SAME day as `date` (the day whose intraday
// body battery we chart), not the latest non-null — otherwise the sleep
// shading is aligned to a different night. Null here just means "no shading".
sleep_start: rows[0]?.sleep_start ?? null,
sleep_end: rows[0]?.sleep_end ?? null,
hrv_nightly_avg: pick('hrv_nightly_avg'),
sleep_score: pick('sleep_score'),
steps: pick('steps'),