Skip to content

TMS v2 at a glance ​

TMS v2 takes BigC customer orders from the store to the customer's door. BigC's order system sends the orders, ops plan them into vehicle routes, drivers deliver them and collect cash, and the store takes the cash back. This page covers an order's day from start to finish, the records involved, which area owns each record, and the build status.

Scope: the backend (core-v2) and the admin (store-v2). The driver app v2 is designed but not started.

How to read it: read this page before writing a spec for any phase. Foundations explains the rules every feature follows, and v1 vs v2 covers what changed from v1 and what it cost. For detail, use the numbered reference pages 01 to 07 in the sidebar (feature list, system overview, schema, states and flows, business rules, master data, integrations).

Every item on this page is marked Built (in code on main-v2-prototype, 9 Nov 2026), Prototype (code exists but does not yet follow the design), or Designed (written down, no code yet).

Who takes part ​

whowhat they do in TMShow they reach it
OMS (BigC's order system)sends new orders, changes and cancellations; hears back every order status changeKafka
BigC staff apphears every order status change, for the store teamKafka
Ops adminplans each store's day, fixes exceptions, follows held orders, open cash and overdue tasksstore-v2 admin in a browser
Driver (works for a partner company)clocks in, loads, delivers stop by stop, collects cash on delivery (COD), reports failed attempts, returns to the storedriver app v2 (not started)
Store staffat the driver's return, confirm the unload with a PIN and decide each failed order: deliver again later or fail itstore PIN at close-out
Store cashiertakes the driver's cash for one task and confirms it with their PINcashier PIN at the hand-over
Partnerthe company that supplies drivers and vehicles; sees only its own rowsadmin, partner scope

One order's day ​

An order goes through seven stages. The order's status changes at each stage. Every change is sent to OMS and the staff app and written to the history.

stagewhat happensownerorder status afterstate
1 IntakeAn OMS message becomes a delivery order (DO) for its store within 5 seconds. Each message is applied once. An order for an unknown store is parked so it can be replayed, not lostintakeUNASSIGNEDBuilt; parking is Designed (today the message is dead-lettered)
2 PlanOps open the plan for one store and one date from the store's template, run Google route optimisation and adjust routes by hand. A plan can have variants, and orders are not claimed yetplanningUNASSIGNEDPrototype: optimise runs inside the request, no variants
3 GenerateThe chosen plan turns each route into one driver task in a single all-or-nothing step. The orders are claimed at this momentplanningASSIGNEDDesigned; the endpoint is a stub
4 DispatchThe driver loads the goods and departs (store check-in, staff PIN and photo). Execution writes DISPATCHED; workforce only supplies the driver's duty state, which must be on dutyexecutionDISPATCHEDDesigned
5 DeliverThe driver opens the first stop, then delivers each order with proof of delivery (POD), collecting COD in the same step. A failed attempt puts the order on HOLD and counts the attemptexecution, cod-paymentOUT_FOR_DELIVERY → DELIVERED or HOLDDesigned
6 Close-outBack at the store, store staff confirm the unload with a PIN and decide each held order. Redeliver sends it back to the pool for another day; fail ends itexecutionUNASSIGNED or FAILED_DELIVERYDesigned
7 Cash handoverThe cashier of the task's store takes the cash for the whole task with their PIN. A shortage needs a reasoncod-payment(order unchanged)Designed

Sending each change to OMS and the staff app is Built: it is written as a durable row in the same step as the change and sent by a worker that retries. 04 States and flows has a sequence diagram for every stage.

The records and how they connect ​

The order is the centre. Planning and execution hold only references to it, never a copy, so its status and its cash amount live in one place.

recordin plain wordsrule to remember
delivery_order (DO)one customer order to deliverthe only place its status and COD amount live
delivery_order_itemthe order lines as OMS sent themthe DO keeps the totals (weight, volume, amount), so lists never read the lines
planthe planning workspace for one store and one datecan have variants; only one chosen variant generates tasks
routeone vehicle's ordered stops inside a planbecomes at most one task
taskone driver's trip from the store and backreplaces v1's load + task pair
stop / stop DOone address in the task / one order at that addressrefer to the DO by id, never copy it
attemptone failed delivery try, with its reasonthe DO counts attempts in attempt_count
duty recordone driver on one date: work windows, clock-in and out, statetwo windows of one driver never overlap
cash handoverthe cash of one task handed to the storeCOD money itself stays on the DO

The full field list is in 03 Schema.

Words every spec uses ​

Order status. Every module uses these eight names. A redelivered order goes back to UNASSIGNED with its attempt count kept, so there is no separate "rescheduled" status.

statusmeaningfinal
UNASSIGNEDin the pool, on no route yetno
ASSIGNEDon a route that has not left the storeno
DISPATCHEDloaded and on a task that has left the storeno
OUT_FOR_DELIVERYthe driver has opened the first stopno
HOLDthe driver recorded a failed attempt; the store decides at returnno
DELIVEREDdelivered with proof; COD collected in the same stepyes
FAILED_DELIVERYwill not be delivered on this DO; OMS may send a new oneyes
CANCELLEDcancelled by OMS or ops. The design accepts an OMS cancel only before the order is in a task and before any failed attempt, and puts a refused cancel on the ops list (rule waiting on BigC)yes

The code today still uses the v1-style names (PENDING, PLANNED, IN_TRANSIT and so on). The mapping is in 04 States and flows.

Task status. A task goes PENDING (generated) → ACCEPTED (driver accepts) → DISPATCHED (left the store) → IN_TRANSIT (first stop opened) → COMPLETED (closed out at return). Close-out completes the task only when every stop is final and every undelivered order has been decided. Ops can cancel a task only before it leaves the store. Stop, plan, duty record and job each have their own statuses, listed in 04 States and flows.

"Hold" means three different things. v1 used one word for all three. v2 gives each its own name, and a spec must say which one it means.

namewhat it iswho sets it
ops hold (suspend)ops pause an order so planning skips it; a record on the DO, not a statusops admin, only while the order is UNASSIGNED or ASSIGNED and its task has not left the store
HOLDthe order status after a failed attemptdriver
HELDthe driver's duty state: the driver gets no new workops admin, or automatically when an on-demand driver does not accept a job in time

Two more terms: a booking is a work window a driver books (for example 13:00–17:00), which adds that window to the driver's duty record; day close is the end-of-day run that ends every duty record of the day, including drivers who never clocked out.

Who owns what ​

v2 is split into seven business areas. Each area owns its records and is the only one that writes them. Another area that needs a change calls the owner's command, for example "assign these orders to a route" or "set the COD amount". It never edits the record directly.

The DO is the one record several areas touch, so its rules are fixed: intake creates it, each status move is made by the area that runs that stage (for example planning moves it to ASSIGNED, execution moves it from DISPATCHED onward) through the DO's single transition table, and only cod-payment writes the COD fields.

areaownsphase
platformlogin, jobs and schedules, Kafka in and out, history, settings, files, notifications1
intakeDO, DO items, parked messages, channels, stores2
workforcedrivers, partners, vehicles, bookings, leave, duty record3
planningplan, routes, plan templates, plan history4
executiontask, stops, POD, attempts, GPS trail, close-out5
cod-paymentCOD fields on the DO, cash handover5 (collection), 6 (handover)
admin-reportingreports, imports, exports, roles and permissions7

Where the build stands ​

The platform base is mostly built. Intake and planning have a working prototype that does not yet follow the designed states and rules. Execution, COD and workforce are designed only. Per-feature status is in 01 Feature list, and the phases are in 02 System overview.

phasewhat works at the endstate
1 Platformsafe login, every event, email and job saved and retried, one history, files to S3in progress: jobs, outbox, history, settings, files done; auth fixes open
2 Intake + mastersorders become DOs once each, unknown stores parked, cancel and redelivery rules, admin create and importstarted: Kafka intake and DO updates out work
3 Workforcedrivers, partners, bookings, duty record, day closenot started
4 Planningone chosen plan per store and date, optimise as a job, generate tasksa prototype was built before its phase came up
5 Execution + COD collectionthe driver's run end to endnot started
6 COD handovercashier PIN, one handover per tasknot started
7 Admin and reportingreports on live data, imports, exports, rolesfoundations only

Before you write a spec ​

A phase spec is ready when it answers these questions. Each one comes from a foundation rule.

questionwhy it matterswhere to look
Which status moves does the feature make, and from which starting status?every write is guarded by the status it expects04 States and flows
Which area owns each record it changes, and which command does it call?only the owner writesthis page, "Who owns what"
What does it write in one all-or-nothing step?no half-done statesFoundations
What makes a repeat the same request (double tap, resent message)?repeats must change data onceFoundations
Which side effects may never be lost, and which may?decides durable row or best effort07 Integrations and jobs
How does each record it opens get closed, and who is told when it does not?nothing stays open foreverFoundations
Which business rules apply, and are any still waiting on BigC?17 rules still wait on BigC05 Business rules