Files
doormile_backend/docs/miler-auth-and-review-fixes-2026-09-16.md
Suriyakumarvijayanayagam e714e1de73 docs: handover for Dharaneesh — miler self-set-PIN flow, review fixes, seed data
docs/miler-auth-and-review-fixes-2026-09-16.md: what changed on main today and
the current flow — the new /miler/login pin_set + /miler/set-pin first-login
contract (app work needed), the seven fixes to the merged cx/handover commits,
and the live-DB test data (no-PIN riders, sample multi-destination booking).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WRaFH5hMRqmUQvVPQsyjZD
2026-09-16 12:43:10 +05:30

6.3 KiB

Backend changes & current flow — for Dharaneesh (2026-09-16)

Covers three things landed on main today: the miler self-set-PIN login flow (needs app work), the fixes made to the merged customer-app / base-handover commits, and the test data seeded on the live DB. git pull before you start.

Commits: ba2cd22 (review fixes), dd0fa75 (miler PIN flow), 5e5230e (seed).


1. Miler login — self-set PIN on first login (app change needed)

Riders now create their own PIN the first time they log in, instead of the console assigning a shared 1234. The login endpoint tells the app which screen to show.

Flow

flowchart TD
    A["Rider enters phone number"] --> B["POST /miler/login"]
    B --> C{"account found & active?"}
    C -- "not found" --> D["404 — no miler account"]
    C -- "inactive / not a miler" --> E["403"]
    C -- "yes" --> F{"pin_set ?"}
    F -- "pin_set: false" --> G["Show SET-PIN screen"]
    F -- "pin_set: true" --> H["Show ENTER-PIN screen"]
    G --> I["POST /miler/set-pin {phone, new_pin}"]
    I --> J["200 — logged in (token + user)"]
    H --> K["POST /miler/verify-pin {phone, pin}"]
    K --> L["200 — logged in (token + user)"]

Endpoints

POST /miler/login — unchanged request, new pin_set field in the response.

Request:

{ "phone": "8000000001", "configid": 1001 }

Response (200):

{
  "success": true,
  "message": "PIN verification required",
  "phone": "8000000001",
  "pin_set": false
}
  • pin_set: false → route to the Set-PIN screen.
  • pin_set: true → route to the Enter-PIN screen (existing behaviour).
  • 404 = phone not registered; 403 = account inactive / not a miler.

POST /miler/set-pin — NEW. First-time PIN creation, self-service.

Request:

{ "phone": "8000000001", "new_pin": "1234", "configid": 1001, "device_token": "<fcm>" }

Response (200) — the rider is logged in immediately, same shape as verify-pin:

{
  "success": true,
  "token": "<jwt>",
  "tenantid": 1,
  "tenantname": "Doormile Coimbatore Logistics",
  "user": { "userid": 46, "authname": "...", "contactno": "...", "profile": { ... } }
}
  • 409 if the account already has a PIN — send the rider to Enter-PIN instead.
  • 404 phone not registered; 403 inactive / not a miler.

POST /miler/verify-pin — unchanged. Used when pin_set: true.

Notes for the app

  • Branch on the pin_set boolean, not on the message string.
  • set-pin returns a full session (token + user) — no need to call verify-pin afterwards.
  • The console no longer sends a PIN when creating a rider (the backend ignores any password field on CreateMiler). New riders always start with no PIN and set it on first login.
  • The 6 existing riders keep their current 1234 PIN (deliberate) — they report pin_set: true and go straight to Enter-PIN. Only newly created riders use the set-PIN screen.

Security note (for later)

set-pin is self-service and can't overwrite an existing PIN, so it can't take over an active account. The only residual gap is a brand-new, never-logged-in account being claimed by whoever knows the phone first. Close it by OTP-gating set-pin once the SMS gateway is live.


2. Fixes to the merged customer-app / base-handover work

Reviewed the 10 merged commits — the OTP/auth, IDOR/tenant scoping, CHECK constraints and pagination were solid. These defects were fixed (ba2cd22):

Severity What was wrong Fix
HIGH (money) CreateCxBooking let the request body's estimate set the billed price with no server check; it flows into Estimatedprice → ridercharges (miler pay + tenant bill). estimate:{min:1,max:1} settled a delivery at ₹1. Client estimate is honoured only when within 15% of the server quote; otherwise the server quote stands.
MED Multi-destination handover freed the rider and closed the booking assignment after the first parcel, dropping the remaining stops and crediting one leg. Assignment closes / rider frees only when no parcel of the booking is still in their hands.
MED inwardedat / completedat written with time.Now() (UTC) instead of DBNow() (IST) → ~5h30 off, skewing earnings/reconcile windows. Switched to DBNow() in the handover, inbound-scan, reconcile and pickup-complete paths.
MED Customers got two "miler assigned" pushes on auto-assign (two token stores) and none on manual assign. One cxstage.Notify on both paths.
LOW ReconcileHubInbound could return 200 with a silently-missing audit row. Wrapped in a transaction; audit inserts checked.
LOW CxLogout returned signedOut:true even when the token revoke failed. Returns 500 on a failed revoke.
LOW A rider-named handover base far from their location silently rerouted the parcel to another city. Rejected when the named base is >50 km from the rider's reported position.

One thing to confirm your side

The CX_STAGING_OTP fixed-code OTP bypass is gated only on ENV == "production". Confirm the live k8s manifest sets ENV=production exactly, or the bypass is reachable in prod.


3. Test data seeded on the live DB

scratch/seed_test_data.go (committed, idempotent, safe to re-run) has been run against live. Available now:

  • Test riders — NO PIN (for the set-PIN flow): phones 8000000001, 8000000002, 8000000003 (Coimbatore).
  • Test customer: phone 9000000001.
  • Sample multi-destination booking DM-SEED-CX-001 — one Coimbatore pickup → two destinations (Chennai, Bengaluru), two consignments in the rider's hands, assigned to 8000000001. Use it to test the base-handover fix: inwarding the first parcel must not free the rider while the second is still carried.
  • Reference serviceable states / districts (TN, KA, KL; CBE, CHN, BLR, EKM), the base/hub network, a tenant location, and pricing.

Quick test path

  1. Miler app → enter 8000000001 → expect pin_set: false → Set-PIN screen → set a PIN → land logged in.
  2. That rider sees booking DM-SEED-CX-001 with two destinations.
  3. Hand over parcel #1 at a base → rider stays on the job (assignment open).
  4. Hand over parcel #2 → assignment closes, rider freed, both legs credited.