mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 05:42:19 +00:00
feat(workouts): attach a heart-rate series to a workout already stored
A batch entry matching a stored workout stays first-write-wins for the workout row. What it can do now is hand over a heart-rate series the stored workout does not have yet: the series is attached, the row itself is not written at all, and the entry reports back as `enriched`. A workout that already carries a series is a no-op, so a client can walk its whole history as often as it likes. - The pre-flight probe now answers both questions at once, whether the row exists and whether it already has a series, and carries the id so the attach addresses the stored workout without a second round trip. - The attach rides the same child write as a fresh workout's series. RETURNING names the rows that landed, so a workout that gained a series between probe and write reports as the duplicate it is instead of claiming an attach that never happened. - A `samples` array that fails validation is refused per entry with `reason: "invalid_samples"` rather than failing the batch. One unusable session out of a hundred must not stall a history sweep the client cannot repair by retrying; every other validation failure keeps failing the batch. - The wide event and the audit row tally enrichments. Counts only, the series never reaches either. - `enriched` is the one contract movement: additive on the per-entry status, request shape unchanged. OpenAPI regenerated. Integration coverage against a real Postgres pins the attach, the repeat as a no-op, the refusal of a bad series alongside entries that land, a mixed batch reporting each status, and the stored workout row compared whole before and after, `updated_at` included.
This commit is contained in:
1 parent
2f68b3dc79
commit
3d55289ba3
8 files changed
+787
-105
No files matched your search
@@ -3405,12 +3405,16 @@ paths:
|
||||
tags:
|
||||
- Measurements
|
||||
summary: Typed workout batch ingest (v1.4.25 W16b)
|
||||
description: Server-side ingest endpoint for HKWorkout records (iOS) and Withings activity rows (server-to-server). Up
|
||||
description: 'Server-side ingest endpoint for HKWorkout records (iOS) and Withings activity rows (server-to-server). Up
|
||||
to 100 workouts per call; nested route geometry (GeoJSON LineString) is capped at 20 000 points and stored in a
|
||||
1:1 `WorkoutRoute` row keyed by `workoutId`. Idempotent via the `Idempotency-Key` header (replay window 24h).
|
||||
Per-entry status (`inserted | duplicate | skipped`) lets the iOS sync cursor checkpoint accurately. The request
|
||||
body ceiling is 5 MB enforced at the HTTP layer — clients above the ceiling receive a 413 with
|
||||
`workout.batch.payload_too_large`.
|
||||
Per-entry status (`inserted | duplicate | enriched | skipped`) lets the iOS sync cursor checkpoint accurately.
|
||||
An entry matching a stored workout is first-write-wins for the workout row; when it carries a `samples` array
|
||||
and the stored workout has no heart-rate series, the series is attached and the entry reports `enriched`
|
||||
(repeatable: a workout that already has a series is a no-op). An entry whose `samples` array fails validation is
|
||||
refused on its own with `reason: "invalid_samples"` — the rest of the batch still lands. The request body
|
||||
ceiling is 5 MB enforced at the HTTP layer — clients above the ceiling receive a 413 with
|
||||
`workout.batch.payload_too_large`.'
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
@@ -21721,6 +21725,7 @@ components:
|
||||
enum:
|
||||
- inserted
|
||||
- duplicate
|
||||
- enriched
|
||||
- skipped
|
||||
reason:
|
||||
type: string
|
||||
|
||||
Reference in new issue
Block a user