Long-overdue prettier sweep; prettier had drifted vs. checked-in code
across ~130 files (mostly long-argument line-break wrapping in TS and
table-padding in markdown). Pure formatting — no semantic changes —
and required to clear the v1.4.6 release gate's `pnpm format:check`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three fixes from the 5-way review on PR #117:
1. Insights cards: replace per-medication N+1 query with single batched
findMany + JS bucketing. For users with many active medications this
collapses 10+ sequential round-trips into one.
2. Idempotency cache: only persist 2xx/3xx and validation 4xx responses.
401/403/408/429/5xx are now skipped — a stale 401 (token expired
mid-flight) or transient 5xx must not be replayed for 24h. Adds a
defence-in-depth check that refuses to cache any body containing
"hlk_" so a future caller wrapping an auth route in withIdempotency
cannot leak a freshly-issued bearer token through the cache.
3. Devices: reject cross-user token re-registration with 409. Prior
behaviour silently transferred ownership on findUnique-by-token,
which would let anyone who learns/guesses an APNs token redirect
another user's pushes. Audit-logs the denial with reason.
Tests adjusted: device-hijack test now expects 409, plus a new test
for same-user re-registration. 279/279 tests passing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds seven read/write endpoints that aggregate or adapt existing data
into shapes more practical for non-browser consumers. None of the
pre-existing endpoints are touched.
• `GET /api/dashboard/summary` — greeting + streak + today compliance
+ per-metric latest value with 7-day sparkline. Single round-trip
for a "home" view instead of fanning out across 6 endpoints.
• `GET /api/measurements/series?kind=&days=` — pre-aggregated series +
stats (mean, min, max, stdDev, count) reusing
`src/lib/analytics/trends.ts`.
• `GET/PATCH /api/integrations/healthkit` — opt-in per-metric sync
config (entries[] of `{ id, kind, direction, enabled }`). Stored in
the new `users.healthkit_config_json` column.
• `POST /api/devices` — APNs/FCM token registration only; no push
sender wired up here. Upsert on `token`.
• `GET /api/medications/intake?scope=today|compliance` — top-level
aggregator over all of a user's medications, plus a sibling
`POST /api/medications/intake` accepting `{ intakeId, status, takenAt }`
for clients that don't want to maintain medication-id state.
• `GET /api/insights/cards` — adapter that maps the rule-based alerts
from `/api/insights/comprehensive` into card-shaped `Insight[]`.
• `GET /api/insights/correlations` — placeholder array today; flagged
in audit log as `insights.correlations.empty` until a real engine
lands.
All endpoints honour `requireAuth()` (cookie or bearer) and the existing
audit/Wide-Event pipeline.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>