feat(GRO-2156): travel buffer + reorder endpoint (Phase 2.2) #180

Merged
Flea Flicker merged 1 commits from flea/gro-2156-travel-buffer-reorder into dev 2026-06-08 18:07:55 +00:00
Member

GRO-2156 — Route Optimization: Travel buffer + reorder endpoint (Phase 2.2)

Builds on GRO-2155 (route CRUD + optimization). Repo: groombook/api.

What changed

  • Travel buffer between consecutive stops — persisted bufferMins per stop = businessSettings.defaultTravelBufferMins (default 15). The first stop has no predecessor, so it carries bufferMins: 0.
  • Tight-schedule conflict detection (detectScheduleConflicts) — for each consecutive pair, compares the real schedule gap (next.startTime − prev.endTime) against travelMinsFromPrev + bufferMins. Flags hasConflict when the gap is too tight. Appointments are never auto-moved — only flagged for the frontend.
  • PATCH /api/routes/:routeId/reorder — accepts { stopOrder: string[] } (every current routeStops.id, exactly once, first-to-last). Validates the permutation, persists the new stopOrder (two-pass update through a negative temp range so the unique(routeId, stopOrder) constraint never trips), re-estimates each leg offline for the new adjacency, re-applies buffers, and recomputes route totals.
  • Conflict flags in responsesGET /daily, POST /optimize, and PATCH /reorder now return per-stop conflict objects plus top-level hasConflicts / conflictCount. Derived at read time from live appointment times, so they stay accurate.
  • Auth unchanged: /routes/* is manager-or-groomer; reorder reuses the groomer-own / manager rule against the route owner.

Tests

  • 7 new unit tests (detectScheduleConflicts, recomputeLegsForOrder): tight/roomy/overlapping schedules, null-travel handling, fixed-order leg estimation. Full suite: 637 passed, typecheck + lint clean.

UAT Playbook

  • Updated UAT_PLAYBOOK.md §4.17 (new — Travel Buffer + Reorder, TC-API-17.1–17.8) and amended §4.16 / TC-API-16.2 for the first-stop bufferMins: 0 and new conflict fields.

cc @cpfarhood

## GRO-2156 — Route Optimization: Travel buffer + reorder endpoint (Phase 2.2) Builds on GRO-2155 (route CRUD + optimization). Repo: `groombook/api`. ### What changed - **Travel buffer between consecutive stops** — persisted `bufferMins` per stop = `businessSettings.defaultTravelBufferMins` (default 15). The first stop has no predecessor, so it carries `bufferMins: 0`. - **Tight-schedule conflict detection** (`detectScheduleConflicts`) — for each consecutive pair, compares the real schedule gap (`next.startTime − prev.endTime`) against `travelMinsFromPrev + bufferMins`. Flags `hasConflict` when the gap is too tight. **Appointments are never auto-moved** — only flagged for the frontend. - **`PATCH /api/routes/:routeId/reorder`** — accepts `{ stopOrder: string[] }` (every current `routeStops.id`, exactly once, first-to-last). Validates the permutation, persists the new `stopOrder` (two-pass update through a negative temp range so the `unique(routeId, stopOrder)` constraint never trips), re-estimates each leg offline for the new adjacency, re-applies buffers, and recomputes route totals. - **Conflict flags in responses** — `GET /daily`, `POST /optimize`, and `PATCH /reorder` now return per-stop `conflict` objects plus top-level `hasConflicts` / `conflictCount`. Derived at read time from live appointment times, so they stay accurate. - Auth unchanged: `/routes/*` is manager-or-groomer; reorder reuses the groomer-own / manager rule against the route owner. ### Tests - 7 new unit tests (`detectScheduleConflicts`, `recomputeLegsForOrder`): tight/roomy/overlapping schedules, null-travel handling, fixed-order leg estimation. Full suite: **637 passed**, typecheck + lint clean. ### UAT Playbook - Updated `UAT_PLAYBOOK.md` **§4.17** (new — Travel Buffer + Reorder, TC-API-17.1–17.8) and amended **§4.16 / TC-API-16.2** for the first-stop `bufferMins: 0` and new conflict fields. cc @cpfarhood
Flea Flicker added 1 commit 2026-06-08 18:06:10 +00:00
feat(GRO-2156): travel buffer + reorder endpoint (Phase 2.2)
CI / Lint & Typecheck (pull_request) Successful in 28s
CI / Test (pull_request) Successful in 28s
CI / Build & Push Docker Images (pull_request) Successful in 1m2s
3e22cc4243
- Apply travel buffer between consecutive stops (default 15 / businessSettings.defaultTravelBufferMins); first stop carries bufferMins 0
- detectScheduleConflicts: flag tight schedule when appointment gap < travelMins + bufferMins; never auto-move appointments
- PATCH /api/routes/:routeId/reorder — validate permutation of current stops, persist new stopOrder (two-pass to avoid unique collision), re-estimate legs, re-apply buffers, recompute totals
- Return route + per-stop conflict flags + hasConflicts/conflictCount on /daily, /optimize, /reorder
- Unit tests for detectScheduleConflicts + recomputeLegsForOrder; UAT_PLAYBOOK §4.17

Co-Authored-By: Paperclip <noreply@paperclip.ing>
Flea Flicker merged commit ca62fb8ef6 into dev 2026-06-08 18:07:55 +00:00
Sign in to join this conversation.