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
This commit is contained in:
141
docs/miler-auth-and-review-fixes-2026-09-16.md
Normal file
141
docs/miler-auth-and-review-fixes-2026-09-16.md
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
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:
|
||||||
|
```json
|
||||||
|
{ "phone": "8000000001", "configid": 1001 }
|
||||||
|
```
|
||||||
|
Response (200):
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:
|
||||||
|
```json
|
||||||
|
{ "phone": "8000000001", "new_pin": "1234", "configid": 1001, "device_token": "<fcm>" }
|
||||||
|
```
|
||||||
|
Response (200) — **the rider is logged in immediately**, same shape as verify-pin:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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.
|
||||||
Reference in New Issue
Block a user