Reorderly · Derwent production

How live MYOB data becomes a buying decision

Reorderly is not guessing from the numbers on the screen. It fetches three MYOB data sets, normalises them by SKU, checks for missing or unsafe values, calculates demand and stock coverage, and then produces a row-by-row recommendation.

Live connection verified Snapshot observed 17 Aug 2026, 03:01 UTC Policy: 26 weeks demand · 6 weeks delivery · 2 weeks safety

What Reorderly v2 is receiving today

These are the three read-only requests made server-side to the Derwent MYOB data center by the v2 service. Credentials never go to the browser.

Item catalogue

2,506
Products returned from /v1/items

Stock records

25,421
Rows returned from stock on hand

Sales products

247
Products with sales transaction arrays

Sales transactions

451
Transactions in the current response

Where the data goes

This is the current production architecture. The original Streamlit dashboard remains at the root URL; Reorderly v2 is the separate browser application under /v2.

Derwent and Reorderly production architecture MYOB and manual exports feed the data center and legacy Streamlit app. The data center feeds the Reorderly Node application, which stores source snapshots and decisions in SQLite and serves the v2 browser interface. MYOB web / desktop Live web data plus exports Manual files Item list, stock summary, sales history, supplier/DDT Used by legacy Streamlit only MYOB data center FastAPI + Playwright items · stock · item sales admin API, protected server-side Legacy Streamlit Root URL · upload overrides in-memory files + tracker/cache Reorderly v2 Next.js / Node service normalise · validate · decide no demo fallback SQLite source artifacts · products sales history · proposals Tim’s browser Cloudflare Access dashboard /v2 To order first
Live v2 pathManual upload pathLegacy or storage component

Important boundary

Manual files are accepted by the original Streamlit app as session-only overrides or fallback inputs. Reorderly v2 currently does not read those uploads. Its current production calculation is built from the three live data-center endpoints and its SQLite ingestion history.

Streamlit versus Reorderly v2

Both are intended to solve the same replenishment problem, but they are at different stages. Streamlit contains the older integration path; v2 is the newer live-data application currently being exercised.

Tim’s Streamlit dashboard

Code supports API Production currently upload-only

manual files → Python parsers → merged table → Python calculations → Streamlit

The Python code was updated with data_center_client.py, data_center_feed.py, and data_center_adapters.py. When configured, it fetches items, stock, and sales from the MYOB data center, converts the API response into CSV-like in-memory payloads, and sends those through the original upload compiler.

Production check: the running Streamlit service currently has its persistent dashboard data directory but no MYOB data-center environment variables. Therefore Tim’s current root application should be treated as upload-only until its service configuration is updated.

Reorderly v2

Live API configured SQLite ingestion history

MYOB API JSON → TypeScript parser → validation → proposal → SQLite → Next.js

V2 reads the raw item, stock, and item-sales endpoints directly. It does not use the Streamlit Python adapters or manual upload widgets. It stores source artifacts, products, sales transactions, inventory snapshots, policies, and proposal lines in SQLite.

Production check: the v2 API currently returns live source status and a live proposal. It has no demo-data fallback.

CapabilityStreamlit todayReorderly v2 today
MYOB APIImplemented in code, but not configured in the current production service.Configured and verified live.
Manual uploadsSupported for item, stock, sales, and supplier files. Uploads override API data for that session.Not supported yet.
Sales handlingAPI sales are flattened into CSV-like rows, cached locally, then processed by the existing sales parser.Nested sales JSON is parsed directly; transactions are persisted into SQLite for durable history.
Stock handlingAPI stock is converted into an Analyse Inventory Summary-shaped table, then merged with other inputs.Stock records are parsed directly, duplicate stock rows are reduced, and required values are validated.
Supplier/DDT filesSupported and used for incoming-stock and reconciliation logic.Not wired yet; incoming fields can be read from the API when present, but supplier-file ingestion is not built.
Separator rowsLegacy item-file parsing ignores non-inventory/header/divider rows.The source exposes rowKind, but v2 does not yet filter all non-item kinds. This is why dirty rows reach Review.
Decision enginePython order_logic.py plus the Streamlit compiler.TypeScript proposal engine with row-level issues and trace text.
Current UIBroad upload-and-analysis workspace with many controls and diagnostic sections.Focused To order page under /v2; other pages are placeholders.

Bottom line

Streamlit is not a fake prototype: its API integration exists in the codebase. But it is not currently receiving live API data in production because the service is not configured for it. Reorderly v2 is currently the only deployed path verified to fetch and calculate from the live MYOB data center.

The pipeline

Every refresh follows the same sequence. A failure produces an explicit unavailable or stale state; it no longer substitutes test rows.

1

Fetch

Reorderly calls the item, stock, and sales endpoints from the server. The server adds the admin API key and, where required, Cloudflare Access service headers.

2

Match

Products are matched primarily by SKU. The sales adapter can also use the supplier item number when that is the identifier in the sales payload.

3

Validate

Missing stock, invalid numbers, duplicate products, missing demand, negative quantities, and incomplete history become visible issues. Unsafe rows are blocked from a buy recommendation.

4

Calculate

Sales are converted into weekly demand. On-hand, committed, and incoming quantities become the stock counted toward the target.

5

Decide

The system calculates a target, measures the gap, applies the item reorder quantity where present, and returns Buy, Covered, or Review.

6

Explain

Each row carries a trace showing the demand window, incoming views, coverage equation, target equation, and any issue that prevented a safe recommendation.

What each input means

InputSourceUsed forImportant behaviour
SKU, name, supplier, reorder quantityItem catalogueIdentity, display, supplier context, minimum/order multiple floorInactive items are ignored. Duplicate SKUs are flagged.
On handStock on handPhysical stock currently available before commitmentsMissing or invalid values block a safe calculation.
CommittedStock on handStock already promised or allocatedSubtracted from on hand to avoid counting committed units twice.
MYOB on orderStock on handSupplier stock already recorded as on orderOne of the incoming-stock views.
Supplier pipelineStock on handSupplier-ordered, in-transit, waiting-to-ship, or backordered stockDerived from the best available source fields.
Sales transactionsItem salesDemand over the 26-week windowOnly sale/invoice transaction types in the valid date window are counted.
Source timestampsResponse metadataFreshness and traceabilityMore than 24 hours old becomes stale rather than silently appearing live.

The calculations

The current Derwent policy is deliberately simple and visible. It is a starting policy, not a claim that every client should use the same values.

1. Weekly demand

Total qualifying sales in the demand window divided by the number of weeks.

weekly demand = units sold in 26 weeks ÷ 26

2. Incoming stock

Reorderly compares the available incoming views and uses the highest supported value so the same shipment is not added together multiple times.

incoming = max(MYOB on order, supplier pipeline, dashboard open order)

3. Stock counted

This is the usable quantity considered against the target.

coverage units = on hand − committed + incoming

4. Target stock

The target covers the expected delivery period plus the safety period.

target units = weekly demand × (6 delivery weeks + 2 safety weeks)

5. Gap

The gap is rounded up because a partial unit cannot satisfy a stock requirement.

gap = max(ceil(target units − coverage units), 0)

6. Suggested order

If an item has a reorder quantity, the recommendation cannot be lower than that quantity.

suggested order = max(gap, reorder quantity) when gap > 0; otherwise 0

The replenishment policy in plain language

A policy is the set of operating assumptions Reorderly uses to decide how much stock should be available. These settings are not facts discovered by the software; they are choices that the business can review and change.

Demand window

26 weeks
How much recent sales history is used to estimate normal demand.

Delivery time

6 weeks
Expected time between placing an order and stock becoming available.

Safety stock

2 weeks
Extra demand coverage kept as protection against uncertainty.

History requirement

26 weeks
Minimum complete history required before making a safe recommendation.

What the policy is trying to achieve

When Tim orders today, the next shipment is expected to take about six weeks. Reorderly therefore tries to keep enough stock to cover demand during those six weeks, plus another two weeks in case sales are higher than usual or the shipment is delayed.

target stock = expected demand during delivery time + expected demand during safety period

With the current settings, the target is eight weeks of expected demand. If the business sells 10 units per week, the target is 80 units. Stock already on hand, less stock committed to customers, plus stock already coming is compared with that 80-unit target.

Why use 26 weeks of sales?

A longer window reduces the effect of one unusually busy or quiet month. It gives the estimate a broader view of normal demand across roughly half a year. It is a practical starting point for a distributor with many products and uneven sales.

Trade-off: it can be slow to react when demand has recently changed. A future policy may compare 4-, 13-, 26-, and 52-week demand rather than relying on one window.

Why use six weeks of delivery time?

This represents the current planning assumption for supplier lead time: the time from placing an order until the stock is usable. It makes the recommendation forward-looking instead of waiting until shelves are empty.

Trade-off: one global value is not accurate for every supplier, product, container, or route. Supplier- and item-specific lead times should replace this default when reliable data is available.

Why add two weeks of safety stock?

Sales and deliveries are not perfectly predictable. Two weeks creates a small buffer so an ordinary delay or demand fluctuation does not immediately create a stockout.

Trade-off: safety stock ties up cash and warehouse space. It should eventually vary by demand volatility, service importance, and supplier reliability.

Why require complete history?

Without enough valid sales history, a zero could mean “no sales” or “sales data missing.” Reorderly treats that ambiguity as Review instead of assuming demand is zero and recommending too little stock.

Trade-off: newer or slow-moving products will need a deliberate fallback policy, such as a manual demand estimate or a comparable product.

What is fixed policy versus business judgement?

The arithmetic is fixed and repeatable. The settings are business judgement. Tim should confirm whether six weeks is the right default, whether two weeks of protection is enough, and whether different suppliers or product groups need their own values. Reorderly should make those assumptions visible rather than hide them inside a formula.

Language used in the dashboard

These definitions describe what the current system means by each term. They are intentionally more precise than everyday shorthand.

TermDefinitionWhy it matters
DemandThe number of units sold in the selected sales period, converted into an average number of units per week.It estimates how quickly stock is being used.
Weekly demandQualifying units sold during the 26-week window divided by 26.It is the rate used to convert weeks of cover into units.
On handUnits recorded as physically in stock now.It is the starting stock quantity before commitments.
CommittedUnits already allocated or promised to customers.Those units should not be treated as freely available for a new order.
Available stockOn hand plus MYOB on order minus committed. This is the ordinary accounting view shown by the source system.It is useful context, but Reorderly separately calculates coverage to avoid counting different incoming views twice.
IncomingUnits expected to arrive from an existing order. Reorderly uses the strongest available incoming view rather than adding overlapping views together.It prevents an order already placed from triggering another recommendation.
CoverageOn hand minus committed plus incoming.It is the quantity Reorderly compares with the target.
Target stockThe number of units needed to cover expected demand during delivery time plus the safety period.It is the desired position after considering the current policy.
GapThe target stock minus coverage, never below zero.It is the amount of stock apparently missing from the planned position.
Reorder quantityA quantity stored on the item record that acts as a minimum recommendation when an order is needed.It can reflect supplier pack sizes, normal order sizes, or a business rule. Its exact meaning should be confirmed with Tim.
Suggested orderThe quantity Reorderly proposes to buy after comparing the gap with the item’s reorder quantity.It is a recommendation, not an order sent to a supplier.
BuyA positive suggested quantity passed the current input checks.It is ready for human review; it does not mean an order has been placed.
CoveredCoverage meets or exceeds the target, so the current calculation does not suggest buying.It does not guarantee that stock will never run out.
ReviewThe system cannot make a safe recommendation because an input is missing, invalid, incomplete, stale, or conflicting.Review means “resolve the data or use judgement,” not “buy now.”
StaleThe source data is older than the allowed freshness period, currently 24 hours.A stale result may still be useful, but it must not look like a current live position.
Source artifactA captured copy of a source response or uploaded file used for traceability.It allows the system to explain which inputs produced a decision.
Separator / category headerA non-product row used by Tim to organise the MYOB item list visually.It is not an orderable product and should be excluded before recommendation logic runs.

Worked example

Illustrative numbers show the mechanics. They are not a customer product record.

InputExample
Units sold over 26 weeks260 units
Weekly demand260 ÷ 26 = 10 units/week
On hand, committed, incoming42, 12, 20 units
Coverage units42 − 12 + 20 = 50 units
Target units10 × (6 + 2) = 80 units
Gap80 − 50 = 30 units
Suggested order30 units, or the item reorder quantity if that is higher

What the current live run produced

This is a system-level snapshot only. The HTML does not contain customer product data.

Buy

223
Rows with a positive safe recommendation

Covered

503
Rows where counted stock meets target

Review

1,491
Rows blocked by missing or conflicting information

Why so many reviews?

The current policy requires complete stock inputs and a complete 26-week sales history before making a safe recommendation. Review is not a buy decision. It is the system refusing to invent demand or stock facts. The current run has 1,489 invalid-source-value issue instances, 1,484 missing-demand instances, and 202 missing-stock instances. These are issue instances, so one row can appear in more than one category. Separator and category-header rows should be filtered earlier so they do not appear in this queue at all.

Manual files and static inputs

These are the actual Derwent export types visible in Dahlia’s Downloads and the roles defined in the original dashboard. The files are not embedded in this document and are not being treated as live v2 data.

File or inputWhat it containsOriginal Streamlit roleReorderly v2
Derwent Distributors - ItemListReport.xlsx
manual export
MYOB item master, SKU, name, supplier item number/CAI, reorder quantity, minimum level, prices and price tiers.Required in upload-only mode; optional session override when the data center is available.Not read — v2 uses /v1/items?all=1&columns=myob.
ITEM-16-06-26.TXT
manual export
Same MYOB item export shape as the item list. The export visibly contains separator and non-item rows.Alternative item-master upload. The legacy parser ignores non-inventory/header/divider rows.Not read — row-kind filtering is not yet applied in v2.
Analyse_Inventory_Summary.txt
manual export
Current on-hand, committed, on-order and related stock position.Optional stock override. The app explicitly rejects Inventory Journal files for this purpose.Not read — v2 uses /v1/raw/stock-on-hand.
sales-16-06-26.TXT and ItemSalesReport workbooks
manual export
Invoice/sale lines with item number, date and quantity; sales history for burn rate.One or more sales files can be uploaded. Overlapping rows are deduplicated; uploads override the cache/API for that session.Not read — v2 uses /v1/raw/item-sales and persists ingested transactions in SQLite.
Derwent_Summary_08-07-2026.csv
supplier file
CAI/CAD, Total Order, goods in transit, waiting to ship and back order.Supplier pipeline and reconciliation input. CAI/CAD is normalised to match MYOB SKU.Not read — supplier/DDT ingestion is a future v2 input.
Dashboard order tracker
saved state
Orders placed through the legacy dashboard that remain open or received.Persisted separately from raw uploads and counted as incoming until received.Not read — v2 has the field in its contract but no user workflow yet.

What this explains about the separator rows

The live item endpoint exposes rowKind values. In the current snapshot there are 2,275 item rows, 101 separators, 94 category headers, and 36 blank-supplier rows. v2 currently accepts any non-inactive row with an SKU, so those 231 non-item rows can flow into Review. The correct next fix is to exclude non-item row kinds at ingestion and report the excluded count, not ask Tim to review them.

Information architecture: what exists today

There are five intended v2 destinations. Only To order is currently a live, data-backed workflow; the other destinations are navigation shells so the product can grow without redesigning the frame.

Reorderly v2 information architecture The v2 workspace has five pages. To order is built and live. Overview, inventory, open orders, and settings are placeholders or not yet built. /v2/to-order Built · live MYOB data /v2/overview Placeholder · not built /v2/inventory Placeholder · not built /v2/open-orders Placeholder · not built /v2/settings Placeholder · not built Shared frame Sidebar Connection state User context
Built and wired to live dataRoute exists as a placeholder
PageCurrent statusIntended jobWhat is still required
To orderBuilt · liveTurn validated stock and demand into a focused buy/review queue.Filter/reason grouping, non-item filtering, supplier order workflow.
OverviewPlaceholderSee the health of inventory and the work queue at a glance.Define KPIs first; then wire real aggregates and trends.
InventoryPlaceholderSearch the catalogue and inspect one product’s stock, demand and history.Product detail model, snapshots, history and exception states.
Open ordersPlaceholderTrack supplier acknowledgements, incoming stock and receipts.Supplier-file ingestion or manual order entry, status changes and reconciliation.
SettingsPlaceholderManage connection status and planning policy.Policy editing, source freshness, import controls and audit history.

What the screen does not mean

Screen labelMeaningNot a claim that
IncomingThe highest supported incoming quantity view from the current source payloads.Every source field can be added together safely.
Weeks coveredCoverage units divided by weekly demand.The exact run-out date, if demand is intermittent or history is incomplete.
Ready to orderA positive recommendation passed the current validation checks.An order has been sent to MYOB. The current screen is read-only.
ReviewA human needs to resolve missing, invalid, stale, or conflicting input.The product should be ordered immediately.

Live-data behaviour now

Before the connection responds

The page shows “Connecting to live data” with an empty table. There are no sample rows and no demo numbers.

If the connection fails

The page shows “Live data unavailable” or a stale-state message. It does not silently replace the result with test data.

When the connection succeeds

The page shows live data from the MYOB data center and the source timestamp. The server-side response is currently verified as LIVE.

What still needs improvement

The formula is intentionally conservative. We still need to filter non-item row kinds, validate lead times, seasonality, intermittent demand, purchase multiples, and the meaning of each incoming-stock field with Tim.