256 lines
11 KiB
Markdown
256 lines
11 KiB
Markdown
# NearlExpress Console — Repository Flow Graph
|
|
|
|
> 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[/"/nearle/dispatch<br/>Live Map · Riders · Batches"/]:::core
|
|
Orders[/"/nearle/orders<br/>Orders Dashboard"/]:::core
|
|
Deliveries[/"/nearle/deliveries<br/>Dispatched Deliveries"/]:::core
|
|
Tenants[/"/nearle/tenants<br/>Client/Tenant Management"/]:::core
|
|
Pricing[/"/nearle/pricing<br/>Pricing Matrix (master-detail)"/]:::core
|
|
Customers[/"/nearle/customers<br/>Customer Directory"/]:::core
|
|
Riders[/"/nearle/riders<br/>Rider Pool"/]:::core
|
|
Invoice[/"/nearle/invoice<br/>Billing"/]:::core
|
|
Requests[/"/nearle/requests<br/>Expense Approvals"/]:::core
|
|
ReportsHub[/"/nearle/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 & 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 · REACT_APP_GOOGLE_MAPS_API_KEY"]:::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 /nearle/orders
|
|
participant S as Solver (routes/routemate.workolik.com)
|
|
participant P as /nearle/dispatch/preview
|
|
participant R as reconcile-steps
|
|
participant J as jupiter.nearle.app
|
|
participant D as /nearle/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`.
|