feat/templates #4

Merged
rssnyder merged 8 commits from feat/templates into main 2026-06-10 21:57:13 -05:00
Owner
No description provided.
Templates are user-created ordered milestone lists (e.g. Airport Travel)
that can be marked public for others to use. Events started from a
template get a one-tap "Next: <milestone>" button in strict sequence,
and completed events sharing a template compare milestone-by-milestone
across own + public events, filterable by location and tags.

Backend: migration 003 (event_templates, template_milestones,
events.template_id), TemplateRepo, /api/v1/templates CRUD + public
browse + compare endpoints. Milestone lists lock once a template is
used (409) to keep sequence-based comparison valid; deletes are soft
so existing events keep rendering and comparing.

App: local template tables + repository, create/update/delete_template
sync ops with client-ID resolution (offline-created templates resolve
to server UUIDs before dependent events sync), template picker in
NewEventSheet, template-driven next-milestone button in
ActiveEventSheet, Templates list/editor screens, CompareScreen
(per-milestone grid, best-per-row highlight, scope + location/tag
filters), compare entry from EventDetail, Profile menu entry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ActiveTimerCard had its own milestone handler that ignored templates:
it always named "Milestone N" and raised an Ok/Rename alert. For
template events it now marks the next predefined milestone with its
canonical name and shows only a passive toast — no rename, no
confirmation. Freeform events keep the rename alert.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Marking the final template milestone is the finish line, so the event
now stops automatically — no manual Stop press. Applies in both the
single event view (navigates back) and the timer-list card (card clears
via removeTimer, toast shows "⚑ <name> — complete"). The list card no
longer falls through to the freeform Milestone N prompt after the
template is exhausted, since the event completes on the last step.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Timeline sync rewrites local_events.template_id to the server UUID, so
the editor's local lock check (matching only the client UUID) missed
in-use templates and sent the milestone list with metadata edits. The
server correctly 409'd the locked milestones — silently discarding the
is_public/name change with it, since the sync queue drops 4xx ops.

Backend: PATCH now treats an unchanged milestone list as a no-op and
applies metadata; 409 only fires when the submitted milestones actually
differ on a used template.

App: getMilestones and isUsedLocally resolve templates by local id OR
server UUID. This also fixes the active-event "Next" button losing its
template milestones after a timeline sync.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- EventDetailScreen: milestones at template sequences are no longer
  renamable — canonical names are what make cross-event comparison work.
- Compare scope defaults to where you came from: your own event or
  template → "My events"; another user's event or a public template →
  "Everyone".
- Compare grid transposed for phones: events run vertically (they grow
  without bound), milestones + Total run horizontally (small and fixed).
  Fastest event per milestone still highlighted green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Extra milestones would misalign the (template_id, sequence) mapping
that milestone comparison relies on.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
minHeight let the pinned event-label column and the scrollable milestone
grid grow row heights independently, drifting out of alignment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
add vite to ignore
All checks were successful
Backend CI / test (pull_request) Successful in 34s
Backend CI / build-push-api (pull_request) Successful in 2m21s
Backend CI / build-push-web (pull_request) Successful in 17s
8cbbbad5c1
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rssnyder/span!4
No description provided.