updates on the address while creasating the orders and security updates as well

This commit is contained in:
2026-09-11 11:39:34 +05:30
parent 8936669f94
commit c85f57324a
24 changed files with 4409 additions and 170 deletions

165
CLAUDE.md Normal file
View File

@@ -0,0 +1,165 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
npm run start:staging # dev server (loads .env.staging via env-cmd)
npm run build:staging # production build — USE THIS, see "Environment" below
npm test # CRA/Jest, watch mode
CI=true npx react-scripts test --watchAll=false # single run
CI=true npx react-scripts test --watchAll=false -t "step ordering" # one test by name
CI=true npx react-scripts test --watchAll=false --testPathPattern=api # one file
```
Lint is not wired to a script. ESLint is deliberately disabled in the webpack pipeline
(`config-overrides.js` filters out `ESLintWebpackPlugin`; `.env` sets `DISABLE_ESLINT_PLUGIN`),
so **lint errors never fail a build** — run ESLint explicitly if you need it.
## Environment — read this before building
`REACT_APP_URL` (v1) and `REACT_APP_URL2` (v2) are the Jupiter API bases. They live in
`.env`, `.env.development`, and `.env.staging`. **All three files are gitignored**, so a
fresh clone or a CI/build host has none of them.
`npm run build` does *not* load the env-cmd files — only `build:dev` / `build:staging` do.
CRA auto-loads `.env` alone. A build missing `REACT_APP_URL` does not fail; it inlines
`undefined`, every request becomes the *relative* path `"undefined/orders/..."`, and those
silently resolve against whatever origin the console is served from. This shipped to
production once and looked like "the API base URL changed to the front-end's own host".
`config-overrides.js` now hard-fails a production build when `REACT_APP_URL`/`REACT_APP_URL2`
are missing. Add any new required var to `REQUIRED_PROD_ENV` there.
**`REACT_APP_URL3` is referenced but defined nowhere** (`Dispatch.js`, the
`getdeliverylogs` fetch). Actual-GPS trails and all Compare deltas silently render nothing
as a result. Whether that endpoint is v1 or v2 is unconfirmed.
## Architecture
CRA + `react-app-rewired` on the **Mantis** MUI template. The template's own pages/theme are
mostly inert scaffolding — all real work lives in `src/pages/nearle/`. Data fetching is
TanStack Query v5; maps are Leaflet + OSRM. Redux is vestigial — `store/reducers/index.js`
combines only `menu` and `snackbar` (the `auth.js` reducer file is not registered), so no
domain data flows through it. Server state belongs in TanStack Query.
### Auth is localStorage, and it is not enforced
`login.js` writes `tenantid`, `applocationid`, `locationid`, `userid`, `authname` etc. to
localStorage; everything else reads them from there. `AuthGuard`/`GuestGuard` exist but are
**commented out in both route files**, so every route is publicly reachable. `App.js` does a
soft redirect to `/login` when `authname` is absent and clears localStorage after a 1-hour
session window.
### The API layer has a module-load trap
`pages/nearle/api/api.js` reads `const tenid = localStorage.getItem('tenantid')` **at module
scope**. It is captured once on first import, so a login that happens afterwards leaves every
`tenid`-using query pinned to the stale value until a full reload. Prefer reading
localStorage inside the query function for anything new.
Several endpoints bypass the env vars and hardcode absolute hosts — the solver calls
(`routes.workolik.com`, `routemate.workolik.com`), `finalCreatedeliveries`, and
`fetchRidersLogs`. `finalCreatedeliveries` hardcodes the **live** Jupiter host, so a staging
build still commits deliveries to production.
### Dispatch.js has two personalities
`pages/nearle/dispatch/Dispatch.js` (~6k lines, plus a ~10k-line CSS file) is one component
serving two modes, switched by whether a `data` prop is passed:
| | standalone `/nearle/dispatch` | embedded (`data` passed) |
|---|---|---|
| source | live API polling | a solver response |
| `shouldFetchLive` | `true` | `false` |
| default `viewMode` | `riders` | `zones` |
| header / batch / date bar | shown | hidden |
Both paths converge on the same shape: `{ zones: [{ zone_name, riders: [{ rider_id,
rider_name, orders[] }] }], zone_summary[], details[] }`. The live path builds it in the
`liveData` memo by re-bucketing flat delivery rows by `deliverysuburb`; the embedded path
receives it already shaped. **Anything that produces data for Dispatch must match that
shape** — that is what `normaliseAssignResponse` in `api.js` exists to guarantee.
View modes: By Location / By Zone / By Rider / Active / Rider Info. "Active" is the live-ops
view — only riders whose latest GPS log is `active`/`pending`, collapsed to their single
in-progress delivery, polling deliveries every 15s.
Orders bucket into three fixed **batches** (Morning <08:00, Afternoon 09:00–12:30, Evening
16:00–19:00) on `assigntime`. Gaps between them are intentional. Layout persists under
`dispatch.slots.v8`; bump the key and add the old one to `LEGACY_SLOTS_STORAGE_KEYS` when the
shape changes. The operator-editable slot editor and the status-wise time-field dropdown are
both commented out in the JSX, not deleted.
Shared constants and pure helpers live in `dispatchShared.js` specifically to avoid a circular
import between `Dispatch.js` and its children (`CompareDataPanel`, `ActiveSection`).
### Assign flow: two clicks, two endpoints
```
/nearle/orders "Assign Orders (N)"
→ POST https://routes.workolik.com/api/v1/optimization/nagercoil/riderassign
(fixed-rider Nagercoil solver; body {deliveries:[...]}, or {} to let the server
pull created orders itself. Empty result → info snackbar, no navigation.)
→ navigate('/nearle/dispatch/preview', { state: { dispatchPreviewData, ... } })
/nearle/dispatch/preview "Assign Orders" ← this is the commit
→ POST https://jupiter.nearle.app/live/api/v1/deliveries/createdeliveries
→ navigate('/nearle/deliveries')
```
The first click writes nothing — it only produces a preview. `Preview.js` deliberately wipes
`history.state.usr` after consuming the response so a reload cannot resurrect a stale plan
(it bounces to `/nearle/orders` instead).
Two de-duplication rules matter here and were both written to fix real duplicate-delivery
bugs: `extractRiders` de-dupes by `orderid` across zones (one rider legitimately appears once
per delivery suburb), and `applyReconcileResponse` wipes a rider's orders from *every* zone
before re-placing them.
`normaliseAssignResponse` assigns `step` **per rider across the whole response**, before zone
bucketing. Numbering within each zone instead would restart the sequence at every suburb and
misrepresent the solver's ordering on map pins and route lines.
## Dead code that looks live
Several features are fully implemented but unreachable. Do not assume a feature works because
the code exists:
- **Compare mode** (`CompareDataPanel`, compare map, delta engine, Kalman/OSRM track
snapping) — `compareOpen` only becomes `true` via `pendingCompareRef.current`, which nothing
ever sets. There is no Compare button in the JSX.
- **Analysis view** (`#dispatch-analysis`, batch efficiency) — `setTopView` is never called,
so `topView` is permanently `'live'`. Its tenant is also hardcoded (`ANALYSIS_TENANT_ID = 916`).
- **Preview.js reconcile / re-optimise / CSV export / tuning** — `handleReconcile`,
`handleCreateDelivery`, `tabValue`, `csvExportData`, `tuningTypes` and their imports each
appear exactly once (their own declaration). The render is now just a header plus an
embedded `<Dispatch>`. `reconcileSteps` and `createOptimisationDeliveries` remain wired in
`api.js` but nothing invokes them.
- **`/nearle/orders/preview`** (`OrdersPreview.js`, ~770 lines) — routed, but nothing
navigates to it. Superseded by the dispatch Preview.
- **Rider push notification** — `Preview.js` only calls `notifyRider` when
`stateData.rider?.userfcmtoken` exists, and `orders.js` never passes a `rider` key. The
assigned rider is never notified.
## Tests
Two suites, 67 tests:
- `src/pages/nearle/api/api.test.js` — `normaliseAssignResponse` across every response shape,
`createNagercoilDeliveries` request wiring, and the `!data?.details?.length` contract that
`orders.js` branches on. `axios` is mocked with a module factory (CRA automock breaks on
`response.data`).
- `src/utils/route-guard/authState.test.js` — session validity, which gates every protected
route. Covers the 1-hour boundary, a missing start time (accepts, rather than logging the
user out) and storage throwing (fails closed).
Component tests do not exist. The large page components have heavy provider requirements
(react-query, notistack, router, theme), so prefer testing extracted pure logic in `api.js` /
`dispatchShared.js` over mounting them.
## Conventions
Prettier: single quotes, no trailing comma, 140 print width, 2-space indent. Files use CRLF —
multi-line string matching in scripts needs `\r?\n`.