Skip to content

Phase 42: cancellation gap-fill — freed slots propose nearby due recalls (D-2)#252

Merged
RJK134 merged 4 commits into
mainfrom
feature/42-cancellation-gap-fill
Jun 12, 2026
Merged

Phase 42: cancellation gap-fill — freed slots propose nearby due recalls (D-2)#252
RJK134 merged 4 commits into
mainfrom
feature/42-cancellation-gap-fill

Conversation

@RJK134

@RJK134 RJK134 commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Phase 42 — Cancellation gap-fill (June-10 deferral D-2)

Overnight multi-agent build authorised by Freddie (2026-06-12). When a CONFIRMED appointment within the next 21 days (env-overridable GAP_FILL_WINDOW_DAYS) is cancelled, the freed slot no longer evaporates: a task-centre task proposes the top-5 nearby due-recall candidates. The vet stays the decision-maker — nothing is auto-booked, no customer is contacted.

Design

  • Hook lives in rescheduleService.cancelAppointment (verified as the only CANCELLED writer, so reschedules inherit it — intended: the old slot is genuinely freed; idempotency prevents task stacking). Runs post-commit and try-wrapped: a gap-fill failure can never mask a committed cancellation.
  • Ranking is a pure function in lib/ (haversine on stored coordinates — zero Google API calls): urgency bucket → competition flag → effective distance (with a multi-horse-yard credit of 3 km per extra distinct due horse, capped at 3 — the credit can't beat urgency/competition tiers) → soonest due.
  • Each candidate deep-links into the existing /appointments/new prefill contract with the freed date; "Gap-fill suggestions created" notice in the cancel flow links to /tasks.
  • No schema change — reuses the Phase 38 Task model (sourceType='AppointmentGapFill' is both UI discriminator and dedup key; renaming it later would be a data migration — pinned by a test).

Verification

Gates all green in the build worktree: lint ✓ typecheck ✓ prisma validate ✓ build ✓, tests 2,621 → 2,655 (+34) (ranking weights, hook fires/doesn't-fire matrix, idempotency, deep-link params, task-centre mapping). EN/FR gapFill namespace parity 10=10.

Notes for reviewers

  • Booking deep-link date uses the existing UTC toISOString().slice(0,10) convention (same as follow-up presets) — a 00:00–01:00 CH-time slot prefills the prior UTC date; pre-existing convention, not introduced here.
  • Shares docs/JUN10_OVERNIGHT_BUILD.md edits with the Phase 43 PR (adjacent deferral rows) — I'll rebase whichever merges second.

Suggested merge order tonight: #PR44 → #PR43 → Phase 41 → this. Final merge with Richard / Freddie as always.

https://claude.ai/code/session_01VzJJTUcvzZgS9jN8aap9iv


Generated by Claude Code

claude added 2 commits June 12, 2026 22:11
…k (Phase 42, D-2)

- cancelAppointment (single CANCELLED chokepoint) now gates on prior
  CONFIRMED status + slot within GAP_FILL_WINDOW_DAYS (default 21,
  env-overridable) and raises an internal task-centre proposal —
  post-commit, try-wrapped, never blocks the cancellation, no outbound
  messaging, nothing auto-booked
- new pure lib/gap-fill/gap-fill.ts: window gate, priority, deep-link
  builder (Phase 33/40 /appointments/new param contract incl. the
  yard-must-belong-to-customer rule), task title/notes builders
- cancellation-fill ranking gains the multi-horse-yard preference:
  each extra due horse at a yard credits 3 km off effective distance
  (capped at 3 mates); distinct-horse counting; candidates without
  yard data rank exactly as before. Cancelling customer's own horses
  excluded from the pool; yardCustomerId surfaced for safe deep links
- task centre: TaskCentreItem carries sourceType/sourceId; gap-fill
  tasks deep-link to the cancelled appointment and render a live
  candidate shortlist (top 5: name, yard, distance, recall type,
  overdue badge, competition badge, Book link) via new
  GapFillSuggestionList; TaskCard gains a children slot
- FillSuggestions panel rows gain the same Book-this-slot deep link
- appointment detail cancel flow shows a small dismissible notice
  linking to the task centre when a proposal was created
- EN/FR keys under new gapFill namespace (10 + 10)

https://claude.ai/code/session_01VzJJTUcvzZgS9jN8aap9iv
…elivered

- docs/BUILD_PLAN.md — Phase 42 entry: detection hook, ranking design
  (multi-horse-yard credit: 3 km per extra distinct due horse, capped at
  3 mates), task-centre proposal surface, deep-link contract, gate
  results (2,621 → 2,655 tests), unchanged scope-out deferrals
- docs/JUN10_OVERNIGHT_BUILD.md — §6 row and deferred note D-2 flipped
  to delivered (WP-B pull surface + Phase 42 push half), pointing at the
  build-plan entry

https://claude.ai/code/session_01VzJJTUcvzZgS9jN8aap9iv

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b3c6c4a. Configure here.

Comment thread app/[locale]/appointments/[id]/page.tsx
…e pass-through

Bugbot finding on #252: rescheduleAppointment runs the same post-cancel
gap-fill hook and its API response carries gapFill, but only the cancel
handler read it — rescheduling a near CONFIRMED slot raised the task
with no in-flow pointer. RescheduleResult now declares the field, the
page surfaces the same notice from both handlers, and a service test
pins the pass-through. Also appends tonight's git-proxy + gate-plumbing
lessons to .claude/memory.md.

https://claude.ai/code/session_01VzJJTUcvzZgS9jN8aap9iv

@RJK134 RJK134 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed

@RJK134 RJK134 merged commit e2a0d77 into main Jun 12, 2026
6 checks passed
@RJK134 RJK134 deleted the feature/42-cancellation-gap-fill branch June 12, 2026 23:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants