# NearlExpress Console — Repository Flow Graph

> **⚠️ STALE — describes the retired jupiter.nearle.app backend.** The console now talks exclusively to `api.doormile.com` via `REACT_APP_DOORMILE_URL` (see `src/utils/doormileAxios.js`, `src/pages/api/doormileApi.js`, and `express-console-api.md` at the repo root for the current endpoint reference). The `REACT_APP_URL` / `REACT_APP_URL2` env vars and every jupiter endpoint below no longer exist in the codebase — this file is kept for historical/architectural context only, not as an accurate current reference.
>
> Human-readable navigation, action, and data-flow diagrams for `nearlexpress-xpressconsole-d0ee01adebe9`.
> Open this file in a Mermaid-aware viewer (GitHub, VS Code with the *Markdown Preview Mermaid* extension, or [mermaid.live](https://mermaid.live)).
>
> The same diagrams (plus the per-endpoint table) are also available to Claude via the project-level skill at `.claude/skills/nearlexpress-docs/SKILL.md`. **This file is the human-facing copy** — kept at the root for quick GitHub browsing.

---

## 1. End-to-end console flow

```mermaid
flowchart TD
    %% ============================ Styling ============================
    classDef entry   fill:#f9f6ff,stroke:#a78bfa,stroke-width:2px,color:#2e1065;
    classDef auth    fill:#fdf2f8,stroke:#ec4899,stroke-width:2px,color:#831843;
    classDef nav     fill:#eef2ff,stroke:#6366f1,stroke-width:2px,color:#312e81;
    classDef core    fill:#e0f2fe,stroke:#0ea5e9,stroke-width:2px,color:#0c4a6e;
    classDef sub     fill:#ecfeff,stroke:#06b6d4,stroke-width:1.5px,color:#155e75;
    classDef action  fill:#fef3c7,stroke:#f59e0b,stroke-width:2px,color:#78350f;
    classDef solver  fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#7c2d12;
    classDef api     fill:#f0fdf4,stroke:#10b981,stroke-width:1.5px,color:#064e3b;
    classDef state   fill:#fdf4ff,stroke:#8b5cf6,stroke-width:1.5px,color:#581c87;
    classDef ext     fill:#fef2f2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
    classDef report  fill:#f5f5f4,stroke:#78716c,stroke-width:1.5px,color:#292524;

    %% ============================ Entry & Auth ============================
    Boot([Browser load<br/>src/index.js]):::entry
    Providers["Providers wiring<br/>Redux store · QueryClient · Router · ThemeCustomization · Notistack"]:::entry
    App["src/App.js<br/>localStorage('authname') gate"]:::auth
    FCMInit["generateToken()<br/>initFirebaseNotificationListener()"]:::auth
    SW["public/firebase-messaging-sw.js<br/>FCM Service Worker"]:::auth
    Login[/"/login<br/>pages/nearle/login1.js"/]:::auth

    Boot --> Providers --> App
    App -- no authname --> Login
    Login -- POST /users/console/login<br/>(jupiter.nearle.app) --> AuthOK{Auth OK?}
    AuthOK -- yes, save authname/userid/roleid/userfcmtoken --> Layout
    AuthOK -- no --> Login
    App --> FCMInit --> SW

    %% ============================ Main Layout & Sidebar ============================
    Layout["layout/MainLayout<br/>Sidebar + Header + Outlet"]:::nav
    Sidebar["menu-items/nearle.js<br/>(sidebar definition)"]:::nav

    Layout --- Sidebar
    Sidebar --> Dispatch
    Sidebar --> Orders
    Sidebar --> Deliveries
    Sidebar --> Tenants
    Sidebar --> Pricing
    Sidebar --> Customers
    Sidebar --> Riders
    Sidebar --> Invoice
    Sidebar --> ReportsHub
    Sidebar --> ViewProfile

    %% ============================ Top-level pages ============================
    Dispatch[/"/doormile/dispatch<br/>Live Map · Riders · Batches"/]:::core
    Orders[/"/doormile/orders<br/>Orders Dashboard"/]:::core
    Deliveries[/"/doormile/deliveries<br/>Dispatched Deliveries"/]:::core
    Tenants[/"/doormile/tenants<br/>Client/Tenant Management"/]:::core
    Pricing[/"/doormile/pricing<br/>Pricing Matrix (master-detail)"/]:::core
    Customers[/"/doormile/customers<br/>Customer Directory"/]:::core
    Riders[/"/doormile/riders<br/>Rider Pool"/]:::core
    Invoice[/"/doormile/invoice<br/>Billing"/]:::core
    Requests[/"/doormile/requests<br/>Expense Approvals"/]:::core
    ReportsHub[/"/doormile/reports/*<br/>BI Suite"/]:::core
    ViewProfile[/"/viewprofile<br/>Profile Manager"/]:::sub

    %% ============================ Sub-routes ============================
    OrdersCreate[/"/orders/create<br/>Single Order Create"/]:::sub
    OrdersMulti[/"/orders/createorders<br/>Bulk Order Create"/]:::sub
    OrdersDetails[/"/orders/details<br/>Order Detail View"/]:::sub
    OrdersPreview[/"/orders/preview<br/>Optimised Preview"/]:::sub
    DispatchPreview[/"/dispatch/preview<br/>Dispatch Review &amp; Adjust"/]:::sub
    RidersCreate[/"/riders/create<br/>Onboard Rider"/]:::sub
    RidersEdit[/"/riders/edit<br/>Edit Rider"/]:::sub
    ClientsCreate[/"/clients/create<br/>Onboard Tenant"/]:::sub
    CustomerCreate[/"/customer/create<br/>Onboard Customer"/]:::sub
    InvoicePreview[/"/invoice/preview<br/>Invoice Preview"/]:::sub
    ReportsOS[/"/reports/orderssummary"/]:::report
    ReportsOD[/"/reports/ordersdetails"/]:::report
    ReportsRS[/"/reports/riderssummary"/]:::report
    ReportsRL[/"/reports/riderslogs"/]:::report

    Orders --> OrdersCreate
    Orders --> OrdersMulti
    Orders --> OrdersDetails
    Riders --> RidersCreate
    Riders --> RidersEdit
    Tenants --> ClientsCreate
    Customers --> CustomerCreate
    Invoice --> InvoicePreview
    ReportsHub --> ReportsOS
    ReportsHub --> ReportsOD
    ReportsHub --> ReportsRS
    ReportsHub --> ReportsRL

    %% ============================ Optimisation Pipeline ============================
    SelectOrders["Select N pending orders<br/>(checkbox column)"]:::action
    ChooseSolver{"Choose Dispatch Mode"}:::solver
    SolverBike["Mode 1 · Bike<br/>POST routes.workolik.com<br/>/optimization/riderassign"]:::ext
    SolverAuto["Mode 2 · Auto<br/>POST routemate.workolik.com<br/>/optimization/riderassign"]:::ext
    SolverManual["Mode 0 · Manual<br/>POST routes.workolik.com<br/>/optimization/createdeliveries"]:::ext
    Reconcile["POST routes.workolik.com<br/>/optimization/reconcile-steps"]:::ext
    FinalAssign["POST jupiter.nearle.app<br/>/deliveries/createdeliveries"]:::ext
    NotifyRider["POST /utils/notifyuser<br/>(FCM push to rider)"]:::ext

    Orders --> SelectOrders --> ChooseSolver
    ChooseSolver -- Bike --> SolverBike
    ChooseSolver -- Auto --> SolverAuto
    ChooseSolver -- Manual --> SolverManual
    SolverBike --> OrdersPreview
    SolverAuto --> OrdersPreview
    SolverManual --> OrdersPreview
    OrdersPreview --> DispatchPreview
    DispatchPreview -. drag-and-drop / change rider .-> Reconcile
    Reconcile --> DispatchPreview
    DispatchPreview -- Assign --> FinalAssign
    FinalAssign --> NotifyRider
    FinalAssign -- redirect --> Deliveries

    %% ============================ Deliveries actions ============================
    DChangeRider["Change Rider"]:::action
    DCancel["Cancel Delivery"]:::action
    DUpdate["Update Amount / Notes"]:::action

    Deliveries --> DChangeRider --> NotifyRider
    Deliveries --> DCancel --> NotifyRider
    Deliveries --> DUpdate
    Deliveries -. row expand .-> OrderItems["Order items detail<br/>GET /orders/getorderdetails"]:::api

    %% ============================ Dispatch (live) ============================
    DispatchMap["Live Leaflet map<br/>Riders · Routes · Batches"]:::action
    RiderLogs["GET /utils/getriderperiodiclogs<br/>(polled)"]:::api
    BatchEff["POST routes.workolik.com<br/>/batch/efficiency"]:::ext

    Dispatch --> DispatchMap
    Dispatch --> RiderLogs
    Dispatch --> BatchEff
    Dispatch -. drilldown .-> DispatchPreview

    %% ============================ Tenants / Pricing ============================
    TenantTabs["Tabs: Active · Pending · Inactive"]:::action
    TenantView["Row → View (collapse)"]:::action
    TenantEdit["Row → Edit (collapse)"]:::action
    TenantApprove["Approve Pending<br/>+ Set Pricing Dialog"]:::action

    Tenants --> TenantTabs
    Tenants --> TenantView
    Tenants --> TenantEdit
    Tenants --> TenantApprove

    PricingMaster["Master: Location List"]:::action
    PricingDetail["Detail: Slabs (StatChips)"]:::action
    Pricing --> PricingMaster --> PricingDetail

    %% ============================ Cross-cutting concerns ============================
    subgraph CROSS [Cross-cutting infrastructure]
      direction LR
      Store["Redux Toolkit store<br/>fcmSlice · loginUserSlice<br/>menu · snackbar · toastSlice · auth"]:::state
      QC["@tanstack/react-query<br/>QueryClient (cache + infinite scroll)"]:::state
      AxiosBase["axios (raw) +<br/>utils/axios.js (401 → /login)"]:::state
      Env["env vars: REACT_APP_URL ·<br/>REACT_APP_URL2"]:::state
      LS["localStorage:<br/>authname · userid · roleid ·<br/>userfcmtoken · applocations"]:::state
      Toasts["Notistack · OpenToast wrapper"]:::state
    end

    Layout -. reads .-> Store
    Layout -. reads .-> LS
    Layout -. uses .-> QC
    Orders & Deliveries & Dispatch & Tenants & Pricing & Customers & Riders & Invoice & ReportsHub -. fetches via .-> QC
    QC -. HTTP .-> AxiosBase
    AxiosBase -. base URLs from .-> Env
    DChangeRider & DCancel & DUpdate -. updates --> QC
    Toasts -. consumed by .-> Sidebar
```

---

## 2. Optimisation pipeline (sequence)

```mermaid
sequenceDiagram
    autonumber
    participant U as Operator
    participant O as /doormile/orders
    participant S as Solver (routes/routemate.workolik.com)
    participant P as /doormile/dispatch/preview
    participant R as reconcile-steps
    participant J as jupiter.nearle.app
    participant D as /doormile/deliveries
    participant F as FCM (rider device)

    U->>O: Select pending orders (checkbox)
    U->>O: Pick dispatch mode (Bike / Auto / Manual)
    O->>S: POST riderassign or createdeliveries
    S-->>O: Optimised route & assignments
    O->>P: Redirect to preview with payload
    U->>P: Drag steps / swap rider (optional)
    P->>R: POST reconcile-steps (after each manual edit)
    R-->>P: Updated, validated sequence
    U->>P: Confirm "Assign"
    P->>J: POST /deliveries/createdeliveries
    J-->>P: 200 OK, deliveries persisted
    P->>F: POST /utils/notifyuser (per rider)
    F-->>R: (out-of-band ack)
    P->>D: Redirect to deliveries dashboard
```

---

## 3. State & data flow (per page)

```mermaid
flowchart LR
    subgraph PAGE [Any operator page]
        UI[React component] --> QH["useQuery / useInfiniteQuery / useMutation"]
        UI --> US["useState (local UI state)"]
    end

    QH -- "queryKey = [name, appId, filters...]" --> Cache["TanStack Query cache"]
    QH -- queryFn --> ApiLayer["pages/api/api.js<br/>(named async fns)"]
    ApiLayer --> AxRaw["axios (raw)"]
    ApiLayer -. some calls .-> AxInt["utils/axios.js<br/>(401 interceptor)"]
    AxRaw --> EnvURL["process.env.REACT_APP_URL"]
    AxRaw --> EnvURL2["process.env.REACT_APP_URL2"]
    AxRaw --> ExtOpt["routes / routemate / jupiter (hardcoded)"]

    UI -. dispatches .-> RTK["Redux store (fcm · login · menu · snackbar · toast · auth)"]
    UI -. emits toast .-> Notistack
    UI -. reads .-> LS["localStorage"]

    Notistack -. renders .-> Header[Top-right toasts]
    RTK -. read by .-> Layout[MainLayout / Sidebar]
```

---

## 4. Reading the graph

- **Solid arrow** = direct call / navigation.
- **Dotted arrow** = read-only reference, polling, or async side-effect (FCM, cache, toast).
- **Cluster colours**:
  - Purple = entry/auth
  - Indigo = navigation frame
  - Cyan/Sky = top-level pages
  - Soft cyan = sub-routes
  - Amber = user-initiated actions
  - Red = external service (workolik, jupiter, Firebase)
  - Emerald = console-internal API/data
  - Violet = cross-cutting infra

For the full per-endpoint table with payloads and use cases (Authentication, Orders, Deliveries, Tenants, Pricing, Customers, Riders, Invoices, Dispatch, Reports, Requests), see `.claude/skills/nearlexpress-docs/SKILL.md`.
