# Creating a test booking and assigning it to a miler How to create a pickup booking through the real customer API and put it on a specific miler, against `https://api.doormile.com`. Every call below is the production API — nothing here is a test harness or a shortcut. Base URL: `https://api.doormile.com/api/v1` --- ## 1. Log in as a customer (two steps) Customer auth is phone lookup, then PIN. The first call only confirms the account exists; it returns no token. ```bash curl -X POST https://api.doormile.com/api/v1/customer/login \ -H 'Content-Type: application/json' \ -d '{"phone":"9876543222"}' ``` ```json { "success": true, "message": "PIN verification required", "phone": "9876543222" } ``` ```bash curl -X POST https://api.doormile.com/api/v1/customer/verify-pin \ -H 'Content-Type: application/json' \ -d '{"phone":"9876543222","pin":"1234"}' ``` The token is at the top level as `token` — **not** under `data`. ```json { "success": true, "token": "eyJhbGciOi...", "user": { "appcustomerid": 1, "firstname": "Rahul", ... } } ``` Save it: `TOKEN=eyJhbGciOi...` ### Customer test logins (all PIN `1234`) | City | Name | Phone | appcustomerid | |---|---|---|---| | Coimbatore | Rahul Sharma | 9876543222 | 1 | | Hyderabad | Test Customer HYD | 9999900001 | 7 | | Bangalore | Test Customer BLR | 9999999999 | 6 | --- ## 2. Create the booking ```bash curl -X POST https://api.doormile.com/api/v1/customer/bookings \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -d '{ "pickupaddress": "123 Gandhipuram Main Rd, Coimbatore", "pickuppincode": "641012", "pickuplatitude": 11.0168, "pickuplongitude": 76.9558, "deliveryaddress": "45 Saravanampatti, Coimbatore", "deliverypincode": "641035", "deliverylatitude": 11.0780, "deliverylongitude": 77.0010, "serviceoption": "Normal", "parcels": [{ "itemcategory": "Documents", "itemdescription": "Test parcel", "declaredvalue": 500, "weight": 1.5, "length": 20, "width": 15, "height": 10 }] }' ``` Returns the created booking under `data`, with `bookingid` and status `Pending_Pickup`. Note the `bookingid` — step 3 needs it. ### Required vs optional Only **`pickupaddress`**, **`pickuppincode`** and a non-empty **`parcels`** array are enforced. Delivery fields are optional; if you give a `deliverypincode` but no delivery lat/lon, the server geocodes the pincode for you. Parcel weight and dimensions are optional too — the miler weighs at pickup — but supplying them makes the volumetric-weight and pricing path realistic. `serviceoption` is one of `Normal`, `Fast`, `Superfast`. ### The pickup pincode must be in an operating city `CityGateMiddleware` rejects anything else with `{"code":"CITY_NOT_SUPPORTED"}`. Allowed 3-digit prefixes: | Prefix | City | |---|---| | `641` | Coimbatore | | `600` | Chennai | | `560` | Bengaluru | | `500` | Hyderabad | ### Same-prefix pickup and delivery goes hyperlocal If pickup and delivery share the first 3 digits, `BookingPickupComplete` sends the consignment straight to `Out_for_Delivery` and the same miler does the final mile. Different prefixes park it at `Inwarded_at_Hub`, which currently has no automated path onward. Keep both pincodes in the same prefix unless you are specifically testing the cross-hub gap. --- ## 3. Assign it to a specific miler **The AI routing layer usually gets there first.** `CreateCustomerBooking` kicks off `AssignCustomerMiler` in a background goroutine, so a booking is often auto-assigned within seconds of creation. Check before assigning manually — you may already have what you want, on a miler you didn't pick. ### Admin console — works for any miler ```bash curl -X POST https://api.doormile.com/api/v1/admin/bookings/26/assign-miler \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"mileruserid": 4}' ``` Admin token comes from `POST /admin/login` (roles 1, 3, 4). This path has **no hub check and no city check** — it will put any miler on any booking. That is what makes it the reliable option. ### Hub console — miler must belong to the calling hub ```bash curl -X POST https://api.doormile.com/api/v1/hub/bookings/26/assign-miler \ -H "Authorization: Bearer $HUB_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"mileruserid": 4}' ``` Two extra constraints, both common sources of confusion: - The booking must be in an assignable state, else `400 booking is not in an assignable state`. - The miler's `milerprofiles.hubid` must equal the hub the token belongs to, else `403 miler does not belong to this hub`. **Most milers in production have `hubid = NULL` and therefore cannot be assigned here at all** — they are also invisible in the hub console's miler list. Use the admin endpoint, or set a `hubid` first. Both endpoints take the same body and funnel into the same `AssignMilerToBooking` function, so the resulting DB state is identical: booking → `Miler_Assigned`, a new `bookingassignments` row with status `Assigned`, and the miler's `availabilitystatus` → `Assigned`. --- ## 4. Accept it as the miler — within about a minute A watchdog on the AI routing layer reverts assignments that are not accepted promptly: the assignment row is deleted and the booking goes back to `Created`. Observed turnaround is under a minute. In practice it often re-assigns rather than leaving the booking idle, so the booking still looks assigned to the same miler — but under a **new `bookingassignmentid`**. Observed on booking 26: assignment 42 was swept and replaced by 43 within ~2 minutes, same miler, same booking. So never hardcode an assignment ID you noted earlier; always re-read `GET /miler/assignments` immediately before accepting, or the accept will 404. ```bash # Miler login mirrors the customer flow curl -X POST https://api.doormile.com/api/v1/miler/login \ -H 'Content-Type: application/json' -d '{"phone":"9876543255"}' curl -X POST https://api.doormile.com/api/v1/miler/verify-pin \ -H 'Content-Type: application/json' \ -d '{"phone":"9876543255","pin":"1234"}' # List what is actually actionable, then accept curl -H "Authorization: Bearer $MILER_TOKEN" \ https://api.doormile.com/api/v1/miler/assignments curl -X POST https://api.doormile.com/api/v1/miler/assignments/42/accept \ -H "Authorization: Bearer $MILER_TOKEN" ``` `GET /miler/assignments` only returns assignments in `Assigned` or `Accepted`, and accept only succeeds on one currently `Assigned` — a completed or rejected job can no longer be revived. To reject instead, the reason goes in the **body**, not the query string: ```bash curl -X POST https://api.doormile.com/api/v1/miler/assignments/42/reject \ -H "Authorization: Bearer $MILER_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"reason":"too far"}' ``` --- ## 5. Rest of the delivery flow In order, all as the miler, all `Authorization: Bearer $MILER_TOKEN`: | Step | Call | |---|---| | Arrived at customer | `POST /miler/bookings/:bookingid/reached` | | Confirm parcels | `POST /miler/bookings/:bookingid/parcel-confirm` | | Pickup complete | `POST /miler/bookings/:bookingid/pickup-complete` | | Deliver | `POST /miler/consignments/:consignmentid/deliver` | `pickup-complete` is what converts the booking into a consignment, sets the origin hub from the miler's own `hubid`, and applies the hyperlocal rule from step 2. --- ## Miler reference Milers with `hubid = NULL` work fine via the admin endpoint but not the hub console. Verify the current roster before relying on this table — production has ~24 milers and the seed data has been reshaped more than once. | userid | Name | Phone | Hub | City | |---|---|---|---|---| | 4 | Ramesh Kumar | 9876543255 | 1 — Jupiter | Coimbatore | | 23 | Karthikeyan Vel | 9876500003 | 1 — Jupiter | Coimbatore | | 6 | Rajesh Sekhar | 9876543256 | 2 — Neptune | Coimbatore | | 7 | Karthi Keyan | 9876543257 | 7 — RS Puram | Coimbatore | | 21 | Murugan Palani | 9876500001 | 8 — Saravanampatti | Coimbatore | | 22 | Selvam Raja | 9876500002 | 17 — Test Hub | Coimbatore | | 8 | Suresh Goud | 9876543261 | **NULL** | Hyderabad | | 28 | Suresh Naik | 9876500008 | **NULL** | Bangalore | Coimbatore hubs: 1 Jupiter (641012, sorting centre), 2 Neptune (641004), 7 RS Puram (641002), 8 Saravanampatti (641035), 17 Test Hub (641099). All miler PINs above are `1234`.