# CLAUDE.md — `src/pages/nearle/orders/`

Rules for editing `orders.js`, `OrdersPreview.js`, `createorder1.js`, `newcreateOrder.js`, `multipleOrders.js`, `details.js`, and the optimised preview.

This is the **revenue-critical area** of the console — the path from "order received" to "rider assigned" runs through here. The optimiser hand-off and the assign-and-notify sequence are the two flows you must not break.

---

## 1. The three dispatch modes (Mode 0 / 1 / 2)

The orders page tracks the chosen mode in `aiModeRef` (a `useRef`, not state — it's set just before the mutation fires).

| Mode | Solver | Endpoint | When operator picks it |
|---|---|---|---|
| **0 · Manual** | `routes.workolik.com` | `POST /optimization/createdeliveries` | "Optimise selected orders" — gives a tentative route, operator can rearrange in preview |
| **1 · Bike** | `routes.workolik.com` | `POST /optimization/riderassign?hypertuning_params={...}` | Bike fleet with hyper-tuning (Balanced / Fuel Saver / Aggressive / Strict Zone) |
| **2 · Auto** | `routemate.workolik.com` | `POST /optimization/riderassign?strategy=multi_trip` | Auto-rickshaw fleet, hourly multi-trip |

The mutation function gets picked by mode:

```js
useMutation({
  mutationFn: aiModeRef.current == 0 ? createOptimisationDeliveries : createAutomationDeliveries,
  ...
});
```

**`createAutomationDeliveries` covers both Mode 1 and Mode 2** — the difference is the URL it constructs and the `hypertuning_params` query string. Don't split them into separate functions.

---

## 2. The hand-off to `/orders/preview` (and then `/dispatch/preview`)

After the solver returns:
1. Solver response → stored in the orders page state.
2. Operator navigates to `OrdersPreview.js` (`/nearle/orders/preview`) for a first look.
3. From there → `/nearle/dispatch/preview` (`Preview.js` in the dispatch folder) for drag-and-drop adjustment.
4. `Preview.js` is the one that calls `finalCreatedeliveries` to commit.

Don't try to commit from `orders.js` or `OrdersPreview.js` — they are read-only / staging steps. The reconcile-then-commit dance only happens on the dispatch preview page (see `src/pages/nearle/dispatch/CLAUDE.md`).

---

## 3. Selection state

Multi-order optimisation uses a checkbox column. The selection lives in component state as an array of order objects (not just IDs) because the solver payload needs full order data (`pickup_lat`, `pickup_lng`, `drop_lat`, `drop_lng`, `weight`, `expecteddeliverytime`, etc.).

- "Select all" is implemented per visible page — not across all loaded infinite pages — to avoid accidental multi-thousand-order solver runs.
- Selection clears when `currentStatus`, `appId`, or date range changes. This is intentional — solver runs are scoped to a single tab.
- Don't add a "select across pages" affordance without confirming the optimiser's payload limits.

---

## 4. Cancellation paths

| Function | Use |
|---|---|
| `cancelOrder` (`PUT /orders/updateorder`) | Single-order cancel (per-row icon) |
| `cancelMultipleOrder` (`PUT /orders/updatemultipleorders`) | Bulk cancel of selected orders (toolbar button) |

Both record a cancel timestamp on the order. Neither triggers a rider FCM notification because the order was never assigned. **Do not call `notifyRider` after these.**

---

## 5. Filters & data

The orders list is a `useInfiniteQuery` keyed by `['fetchorders', appId, currentStatus, debouncedSearch, startdate, enddate, rowsPerPage, tenantid, locationid]`. The corresponding `api.js` function (`fetchOrders`) destructures in this same order — see `src/pages/api/CLAUDE.md` §1.

The summary endpoint (`fetchorderscount`) uses a slightly different key — `currentStatus` comes after the date range. Match the call site, don't normalise.

---

## 6. Don'ts specific to this folder

- **Don't introduce a 4th dispatch mode** without coordinating with the workolik backend team. The solver URL and `?hypertuning_params=` query are versioned.
- **Don't move solver URLs into env vars.** They are deliberately hardcoded because the optimiser is a separate, versioned service — pinning the URL is the version pin.
- **Don't fold `createorder1.js`, `newcreateOrder.js`, and `multipleOrders.js` into one component.** They serve different operator flows (existing customer vs new customer vs CSV bulk import).
- **Don't reorder `OrdersTableSkeleton`'s column count** without checking every page that imports it. It's used as a shared skeleton across orders, deliveries, tenants, and customers.
