Log a workout by hand - #1089
Merged
Merged
Conversation
DELETE /api/workouts/{id} removes a MANUAL workout outright, with its
child rows and the personal records keyed on it, then queues a silent
detection pass so the previous best comes back. Any other source answers
409: the next sync would write it back. Own record only, 404 for another
user's row.
Refs #1085
A small sheet with sport, start, duration and optionally distance and active energy, nothing else. The start is read in the profile timezone, distance in the reader's unit and stored in metres. It saves through POST /api/workouts/batch as source MANUAL with an external id minted once per opened form, so a second tap lands as a duplicate, not a second row. The workouts page carries the action in its header and in the empty state; the detail page offers delete for a hand-entered workout. Refs #1085
The dashboard add menu and the bottom bar's capture picker gain a workout entry next to measurement, mood and medication. It belongs to the workouts module (capture:workout) and is offered in one's own record only, because the batch ingest resolves the caller and no grant reaches it. Refs #1085
Builds the entry the form sends, posts it through the batch route, reads it back from the list, re-posts it as a duplicate, and deletes it; a synced workout is refused. Refs #1085
…ister the delete A repeated submit that wrote nothing reads as a neutral notice rather than a success. The delete control is entered in the destructive-control registry, and its 409 code in the published error catalogue. Refs #1085
…re picker does The dashboard add menu asked only whether the record's section was writable, so a switched-off mood or medications module still offered its entry here while the bottom bar's picker hid it. The menu now renders from the picker's own visibleCaptureKinds, so the two cannot disagree. Refs #1085
…entry Main measured 3718 KB gz after v1.39.7 and v1.39.8, almost all of it new copy in the seven lazy locale catalogs; the workout form, its sheet, the delete action and their copy add about 7 KB (3725). The cap moves from 3724 to 3749, the same 24 KB headroom as before; the eager routes stay inside their drift allowances. Refs #1085
…feat/manual-workout-entry
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #1085. Deliberately small: HealthLog is a health record, not a training app.
workouts, surfacecapture:workout, own record only, since the batch route writes only the caller's account), and as a header action and empty-state action on/insights/workouts.ResponsiveSheet: sport type (existing enum, translated, sorted), start (profile time zone), duration (hours, minutes), optional distance (km/mi per unit preference, stored in metres), optional energy (kcal). Inline validation viaFieldError(start not in the future, duration 1 min to 24 h, sane maxima).POST /api/workouts/batchwithsource: "MANUAL"and anexternalIdminted once per opened form (manual:<uuid>), so a double submit comes back asduplicateinstead of a second row. Workout, dashboard and today queries are invalidated.DELETE /api/workouts/[id]: ownMANUALworkouts only (404 for others, 409workout.delete.synced_sourcefor synced ones, which the next sync would bring back); removes the row with its child rows and the personal records it set, then re-runs record detection; audit row; OpenAPI and error-code catalogue updated. A delete button with confirmation on the detail view for manual workouts in the own record.visibleCaptureKindsas the capture picker, so "Log mood" and "Log medication intake" also follow their modules; the workouts empty state mentions manual entry.Tests: payload, zones, km/mi, validation, form behaviour, delete route, menu/picker parity across module combinations, and an integration test (save, read back via
GET /api/workouts, duplicate, delete, 409 for a synced workout); each with a red proof on the old code. iOS: workouts are not in the sync delta and are re-read viaGET /api/workouts, so a deleted manual workout disappears on the next read.