2.5 KiB
11 — Route & Sales Visit Management
Status: Not Started Depends On: 00 — Existing Gap Fixes
Goal
Route CRUD already exists (Features/Route). This step covers the sales-visit half of
mainPlan.md §3 — the part that is
about a SalesRep's daily visit schedule, not the ride/dispatch route from
03_ride_lifecycle.md's planDeliveryRoute.
Background / Context
Today a Store has a single FK_RouteId (bulk-assign not yet supported via API — see gap #2 in
00_existing_gaps.md), and route access is only granted via UserRouteScope
(a many-to-many grant), not single ownership. There is no visit check-in/out data anywhere.
Data Model Changes
Route Ownership
RouteId, OwnerUserId — single-owner assignment, distinct from the broader UserRouteScope
access grant which may cover multiple users (e.g. a Supervisor overseeing several reps' routes).
Route Visit Log
RouteId, StoreId, UserId, CheckInAt, CheckInGps, CheckOutAt — one row per planned visit.
API Endpoints
| Function reference | Endpoint intent |
|---|---|
assignOutletsToRoute(routeId, outletIds[]) |
POST /api/routes/{id}/stores — bulk version of the existing single Store.RouteId field |
assignRouteToSalesRep(routeId, salesRepId) |
PUT /api/routes/{id}/owner |
optimizeRouteSequence(routeId) |
POST /api/routes/{id}/optimize |
recordRouteCheckIn(routeId, outletId, gpsCoords, timestamp) |
POST /api/routes/{id}/visits/check-in |
recordRouteCheckOut(routeId, outletId, timestamp) |
POST /api/routes/{id}/visits/check-out |
getRouteAdherence(routeId, date) |
GET /api/routes/{id}/adherence?date=... |
reassignRoute(routeId, newSalesRepId) |
PUT /api/routes/{id}/owner (same as assign, different actor) |
getRoutePerformance(routeId, period) |
GET /api/routes/{id}/performance?period=... |
Business Rules
- Check-in
gpsCoordsfeedssendRouteDeviationAlertin 09_fraud_controls.md — a check-in materially outside the store's registered location should flag, not silently accept. getStoreVisitHistory(§4) reads directly fromRoute Visit Log— no separate storage.
Open Questions
- Is route sequence optimization (
optimizeRouteSequence) a manual reorder endpoint, or does it need actual distance/priority-based computation (external mapping API)?
Implementation Notes
Fill this section in during planning discussion before writing any code.