System Flow & Architecture

The complete developer guide to this Factory ERP: layers, modules, data model, business flows, state machines, algorithms and rules — everything a developer needs to understand, run and extend the system.

1 · System Overview & Design Principles

Factory ERP runs a complete small-factory operation — procurement, lot-based inventory, daily production, quality control, sales with invoicing, HR with payroll, analytics and an AI analyst — around one shared dataset. Six principles shape every part of the implementation:

One central store

All business data lives in a single in-memory store. Screens never keep their own copies of records — they read from the store and ask it to perform actions. There is exactly one source of truth, so every screen always agrees with every other screen.

Lots are the stock truth

Physical stock is stored as lots (batches). A product’s stock number is only a cached sum of its lots and is recomputed after every change: product.stock = Σ lot.qty. Costs, expiries and sources live on the lot, never averaged away.

Losses are first-class records

Nothing disappears silently. Supplier shortages, production shortfalls, quality rejections and write-offs are stored as money-valued loss records with date, product, quantity, unit cost, reference and note — so "profit after losses" is always computable.

Every stock change is a ledger entry

Receipts, deliveries, production output, manual adjustments and write-offs all append a signed movement (IN / OUT / ADJUST) with the running balance after it. The ledger can replay the full history of any product.

Derive, don’t store

Totals, payment statuses, alerts, statistics and KPIs are computed at read time by pure helper functions. The only stored snapshots are deliberate historical facts: receivedQty per order line, the COGS frozen on a sales order at delivery, and the cached stock sum.

Guarded transitions

Documents move through explicit status machines. Transitions validate preconditions (enough stock, correct current status, no double posting) and either succeed completely — including all side records — or change nothing.

2 · Architecture at a Glance

The system is a layered, single-page application. Data flows down as user intents and back up as derived view-data. The only server component is the AI gateway; everything else runs around the central store.

Screens Layer (Presentation)

Sixteen screens (tables, forms, popups, dashboards, print views). Screens are stateless views: they render derived data from the store and translate clicks into store actions. They never mutate records directly.

DashboardProductsStock ManagementDaily ProductionQuality ControlSuppliersPurchase OrdersSales & InvoicesCustomersHRInsights & ReportsAI AssistantHistory & AuditLabelsInvoice PrintSystem Flow
↓user intents (actions) down · derived view-data up

Central Store (Application State)

Owns the entire dataset in memory. Every change is one guarded, immutable state transition that also writes its side records (movements, losses, audit entries) and persists the result. On load it normalizes older saved data into the current shape.

upsert / remove / setStatusreceivePOdeliverSOadjustStockaddProductionrecordInspectiondeleteProductionupdateLot / writeOffLotrecordLossaudit writernotificationsresetData
↓pure calculations, called by both screens and store

Domain Logic (Pure Helpers)

Stateless functions: data in, value out, no side effects. This is where every business formula lives exactly once, so screens, reports and the AI snapshot can never disagree on a number.

FEFO orderingvaluation & average costorder totals & VATpayment statussupplier / customer statisticspayrollrestock plannerquality statisticsexpiry classificationcategory tree operationsEAN-13 generatorAI snapshot builderformatters
↓reads and writes whole collections of records

Data Layer (Dataset & Persistence)

The dataset is one structured object of record collections (products, lots, orders, …). A first visit starts from a deep copy of the built-in demo factory dataset; afterwards the visitor’s own workspace is saved automatically after every change and restored on return.

demo seed datasetper-visitor persistent workspaceload-time normalization & defaults
↓AI questions leave the device only through this gateway

Server AI Gateway (the only server component)

A small server endpoint that keeps the AI access key on the server. It receives a question plus a grounded snapshot of the data, automatically routes to the fastest responding AI engine (with silent failover), and streams the answer back token by token. Engine details never reach the screens.

key stays server-sidefastest-engine auto-routingsilent failovertoken streaminggeneric error messages

What happens on every user action

1 · User acts

Clicks a button / submits a form

→

2 · Screen validates

Required fields, ranges, confirmations

→

3 · Store action

One guarded state transition

→

4 · Side records

Movements · losses · audit written together

→

5 · Persist

Workspace saved automatically

→

6 · Re-derive

All screens recompute & re-render

Because side records are written inside the same transition as the change itself, the system can never end up half-updated — e.g. stock can never increase without its ledger movement, and a shortage can never be booked without its loss record.

3 · Module Map — Every Feature

Sixteen functional modules share the central store. Each card lists what the module does and the features it owns.

Dashboard

The operational home screen.

  • Headline KPI cards: revenue, gross profit, profit after losses, inventory value, receivables vs payables, payroll
  • Alert banners for low stock, out-of-stock and expiry risks
  • Business summaries and shortcuts into every module

Products & Category Tree

The product master catalogue.

  • Rich product record: SKU, barcode, type (Raw Material / Finished Product), unit, cost & sale price, reorder level, max stock, main supplier, status and descriptive fields
  • Unlimited-depth category tree with a visual manager; every product hangs on one tree node and filters match whole subtrees
  • Search by name / SKU / barcode, tree + type + status filters, spreadsheet export
  • Details popup: edit, print barcode labels, jump to stock & lots, delete (guarded)

Stock Management (Lots)

Where physical inventory lives.

  • Per-product popup listing every lot: batch code, quantity, initial quantity, unit cost, expiry, received date, source and supplier
  • Stock In creates a new lot; Stock Out consumes lots in FEFO order or from a chosen lot; write-off removes quantity and books a loss
  • Lot editing with quantity clamped between 0 and its initial quantity; every change writes a ledger movement
  • Live valuation (Σ qty × lot cost), weighted average cost, expiry classification: Expired / Expiring soon (≤ 30 days) / OK

Daily Production

Target vs actual output per day.

  • Record per product & day: target quantity, produced quantity, unit cost, supervisor, reason for any gap
  • Produced quantity becomes a production lot in stock automatically
  • Shortfall (target − produced) is booked as a Production Shortage loss valued at unit cost
  • Deleting a record reverses its lot, movement and loss; efficiency per product / supervisor feeds Reports

Quality Control

Lot-level inspection and defect management.

  • Inspection queue: every new lot (supplier receipt, production batch, manual stock-in) starts as Pending until inspected
  • Sampling inspections with a structured defect breakdown; failed units are written off the lot as a Quality Rejection loss at lot cost
  • The 90% rule: below a 90% pass rate the lot is quarantined and FEFO delivery skips it until a re-inspection releases it
  • Pass rates by supplier and product, defect Pareto, monthly inspection counts, and a fully reversible inspection register

Suppliers

Vendor master data and performance.

  • Contact, address, payment terms, status and rating
  • Computed statistics: order count, received value, fulfilment % (received ÷ ordered), shortage losses caused, outstanding payables
  • Account statement popup with orders and payments; deletion blocked while referenced

Purchase Orders

Procure-to-stock documents.

  • Lifecycle: Draft → Pending → Approved → Partially Received / Received (or Cancelled)
  • Multi-line items (product, quantity, unit cost) with per-line receivedQty tracking
  • Partial receiving: each receipt creates one lot per line; short-closing converts the missing quantity into a Supplier Shortage loss
  • Payments against the received value; outstanding payable is always derived

Sales & Invoices

Order-to-cash documents.

  • Lifecycle: Draft → Confirmed → Delivered (or Cancelled); salesperson assignment
  • Delivery is stock-checked and atomic: lots are consumed FEFO and the real COGS is frozen on the order
  • Printable invoice with 14% VAT; payments against the grand total; outstanding receivable is derived

Customers

Customer master data and balances.

  • Contact details and customer type (Corporate / Retail / Government)
  • Computed statistics: order count, delivered revenue, outstanding receivables, last order date
  • Account statement popup; deletion blocked while referenced

Barcode Labels

Product identification labels.

  • Every product carries a 12-digit code; the 13th EAN-13 check digit is computed with the standard algorithm
  • Label sheet designer (copies, fields); one preview is rendered and the chosen number of copies is sent to print

Human Resources

People, attendance and payroll.

  • Employee master: code (EMP-…), department, job title, salary, allowances, hire date, status
  • Monthly attendance per employee: absent days, late count, overtime hours
  • Payroll computed from attendance (see formulas); leave requests with Pending → Approved / Rejected decisions

Insights & Reports

Organized analytics.

  • Five tabs — Overview, Sales, Procurement, Inventory, Losses & Production — each with its own KPI row, chart and detail table
  • Key ratios: gross margin, margin after losses, losses as % of revenue, inventory turnover, net receivables position, payroll as % of revenue
  • Period switch (this month / quarter / year / all) re-derives every figure; AI report generator with print / save / download

AI Assistant

A grounded analyst over live data.

  • Chat answered only from a structured snapshot of the current dataset — figures are never invented
  • Suggested questions, seven report templates (executive, inventory, sales, procurement, losses, HR, restocking), saved report library
  • Replies stream in; the server gateway automatically uses the fastest responding engine and switches silently if one is slow to start

History & Audit

Full traceability.

  • Stock movement ledger with type, reference and running balance per product
  • Product & category audit trail: who-changed-what field diffs for creates, updates and deletes (kept to the most recent 800 entries)

System Flow (this page)

Living documentation.

  • Architecture, data model, flows, state machines and formulas — generated from the same concepts the code implements, with live record counts below

Visitor Analytics

Who visited the system, from where, on what device, and what they did.

  • A page-view beacon fires on every route change; the browser sends only the path and basic client hints (screen, language, timezone) plus the time spent on each page
  • A server endpoint enriches each event with the IP address, country/region/city and parsed device, OS and browser — values the page script cannot fake — and ignores crawlers
  • Every audited store action (create, update, delete, status change, goods receipt, delivery, production, inspection, data reset) is mirrored as an analytics action; AI chat and report usage are logged server-side
  • Events persist in an external key-value store when configured (in-memory fallback otherwise); there is deliberately NO analytics screen inside the app — a private message alerts the owner the first time a new visitor arrives, and an hourly digest (sent only when there was activity) is delivered privately to the site owner messaging app, and the hosting dashboard provides owner-only traffic analytics

4 · Core Business Flows

The seven flows below are the heart of the system. Every arrow is a real implemented transition in the central store.

4.1 Procure-to-Stock (Suppliers → Purchase Orders → Lots)

Supplier

Master data, terms, rating

→

Purchase Order

Draft → Pending → Approved

→

Receive Goods

Full or partial, per line

→

Stock Lots

One lot per received line

→

Payable

Received value − paid

  1. An approved order can be received any number of times. For each line the receiver enters how many units arrived now (between 0 and the remaining quantity) and optionally an expiry date.
  2. Each received line creates a stock lot (batch code from the PO number, cost = line unit cost, source = Purchase Order) and an IN movement with the new running balance.
  3. Line receivedQty accumulates; the order becomes Received when every line is complete, otherwise Partially Received.
  4. If the buyer closes the order short, every missing unit is booked as a Supplier Shortage loss (missing qty × unit cost) — the loss that later reduces profit and scores the supplier.
  5. Payments are recorded against the received value (not the ordered value), so payables always match goods actually in the warehouse.

4.2 Order-to-Cash (Customers → Sales Orders → Invoice)

Customer

Master data & balance

→

Sales Order

Draft → Confirmed

→

Deliver

FEFO consumption, real COGS

→

Invoice

Subtotal + 14% VAT, printable

→

Receivable

Grand total − paid

  1. Delivery first checks every line against the product’s total lot quantity. If anything is short, the delivery is refused with the short lines listed — nothing is posted.
  2. Otherwise lots are consumed in FEFO order (earliest expiry first, then oldest receipt), decrementing lot quantities and writing OUT movements.
  3. The exact cost of the consumed units is summed and frozen on the order as its COGS — later purchase-price changes never rewrite history.
  4. The order becomes Delivered with a delivery date; its printable invoice shows lines, subtotal, 14% VAT and grand total; payments reduce the receivable (grand total − paid).

4.3 Daily Production (Target → Output Lot → Shortfall Loss)

Daily Target

Planned units per product

→

Actual Output

Produced units + supervisor

→

Production Lot

Output enters stock

→

Shortfall Loss

(target − produced) × unit cost

  1. A record captures date, product, target quantity (optional), produced quantity, unit cost, supervisor and — when there is a gap — the reason.
  2. Produced units become a production lot with an IN movement, immediately sellable.
  3. Any missing units against the target are booked as a Production Shortage loss carrying the reason, so Reports can rank loss causes and supervisor efficiency.
  4. Deleting the record reverses its lot quantity, its movement and its loss in one step.

4.4 Manual Stock Operations

  1. Stock In — creates a new lot (batch, cost, expiry, source such as a direct supplier receipt). When an expected quantity is given and less arrives, the difference is booked as a Supplier Shortage loss.
  2. Stock Out — consumes lots FEFO (or one specific lot chosen in the popup) and writes an OUT movement with a reason note.
  3. Write-off — removes damaged/expired quantity from a chosen lot and books a loss valued at that lot’s cost.
  4. Lot edit — corrects batch, cost, expiry or quantity (clamped to the lot’s initial quantity); quantity deltas post ADJUST movements.
  5. Every path ends with the same step: recompute the product’s cached stock from its lots.

4.5 HR: Attendance → Payroll, and Leave Decisions

Employees

Salary, allowances, department

→

Monthly Attendance

Absent days · lates · overtime

→

Payroll

Net = base + allowances + overtime − deductions

→

Leave Requests

Pending → Approved / Rejected

  1. Attendance is one record per employee per month; payroll for any month is derived on demand by the payroll formula (section 7) — no month-end “closing” step exists.
  2. Leave requests start as Pending (and badge the HR tab), then are approved or rejected; the decision is stored on the request.
  3. Headcount, department totals and payroll-as-%-of-revenue all derive from the same records in Reports.

4.6 AI Analyst: Snapshot → Gateway → Streamed Answer

Question / Report Type

From chat or report studio

→

Data Snapshot

Compact aggregates of live data

→

Server Gateway

Key server-side; picks fastest engine

→

Streamed Answer

Rendered live; print / save / download

  1. The screen builds a bounded snapshot: headline figures, per-module aggregates and capped top-N lists (top products, risks, restock needs) — enough to answer precisely without shipping the whole database.
  2. The snapshot is embedded in the instructions with strict grounding rules: use only these numbers, format money as EGP, admit when detail is missing, never discuss the technology behind the assistant.
  3. The gateway tries its engines in speed order: an engine that does not start answering within a short deadline (~10 seconds) is abandoned for the next one, silently; a final patient attempt guarantees an answer whenever any engine is alive.
  4. Tokens stream back and render progressively. Reports can be printed (PDF via the browser), downloaded as text, or saved into the report library.

4.7 Quality Gate: Inspect → Accept / Reject → Quarantine

New Lot

Receipt / production / stock-in → Pending

→

Inspection

Sample checked, defects broken down by type

→

Failed Units

Written off as Quality Rejection loss

→

Decision

Passed / Partially Passed released · Failed quarantined

  1. An inspector samples units from one lot and records how many were checked, how many failed, and a defect breakdown (type × quantity) that must add up to the failed count.
  2. Failed units are removed from the lot in the same transition: an OUT movement and a Quality Rejection loss valued at the lot's cost — so QC waste reduces profit-after-losses like every other loss.
  3. The lot's quality status follows the result: Passed (no defects), Partially Passed (pass rate at least 90%), or Quarantine (below 90%). Delivery and manual stock-out consume only non-quarantined lots, and the delivery guard reports how much is held.
  4. Re-inspecting a quarantined lot can release it; deleting an inspection reverses it completely (units back to the lot, loss and movement removed, previous status restored). Supplier and product pass rates across all inspections feed Suppliers, Reports and the AI analyst.

5 · Data Model (Entities & Relationships)

Eighteen record types. Order lines are embedded arrays inside their orders; everything else is a top-level collection keyed by string ids (prefixed, e.g. product, PO, SO, employee codes are human-readable). Money is stored as plain EGP numbers; dates as yyyy-mm-dd strings.

Supplier

→1 : many

PurchaseOrder

→lines →

Product

→1 : many

StockLot

→consumed by

SalesOrder

→many : 1

Customer

EntityPurposeKey FieldsRelationships
CategoryNode of the product classification treeid, name, parentId (null = root)Parent → children (unlimited depth); 1 → many Products
ProductCatalogue item (raw material or finished product)id, name, sku, barcode (12-digit base), type, categoryId, unit, costPrice, salePrice, stock (cached), reorderLevel, maxStock, supplierId (main), statusBelongs to Category & main Supplier; has many Lots, Movements, order lines
StockLotOne physical batch of a productid, productId, batchCode, qty, initialQty, costPrice, expiryDate?, receivedDate, source, sourceRef, supplierId?, qualityStatusBelongs to Product; created by PO receipt, production or manual stock-in
StockMovementLedger entry for every stock changeid, date, productId, type (IN / OUT / ADJUST), qty (signed), ref, note, balanceAfterBelongs to Product; ref points to PO / SO / batch / adjustment
SupplierVendor master recordid, name, contactPerson, email, phone, address, paymentTerms, status, ratingHas many Purchase Orders; main supplier of many Products
PurchaseOrderBuying document with linesid, number (PO-…), supplierId, status, orderDate, expectedDate, receivedDate?, createdBy, notes, closedShort, paidAmount, items[]Belongs to Supplier; items reference Products
PurchaseOrderItemEmbedded PO lineproductId, qty, receivedQty, unitCostReceived quantity drives partial-receipt status and lot creation
CustomerCustomer master recordid, name, contactPerson, email, phone, address, typeHas many Sales Orders
SalesOrderSelling document with linesid, number (SO-…), customerId, status, orderDate, deliveryDate?, salesperson, paidAmount, cogs (frozen at delivery), items[]Belongs to Customer; items reference Products
SalesOrderItemEmbedded SO lineproductId, qty, unitPriceDelivery consumes the product’s lots FEFO
ProductionRecordOne day’s output of one productid, date, productId, batchCode, targetQty, producedQty, unitCost, expiryDate?, supervisor, reason, notesCreates one StockLot (+ a Loss when produced < target)
LossRecordMoney-valued loss of any kindid, date, type, productId, qty, unitCost, value, ref, noteBelongs to Product; ref points to the PO / batch / lot that caused it
QualityInspectionSample check of one stock lot with defect breakdownid, number (QC-…), date, productId, lotId, batchCode, supplierId?, type, inspector, inspectedQty, passedQty, failedQty, passRate, result, prevQualityStatus, defects[], notesBelongs to a StockLot; failed units create a LossRecord + OUT movement
EmployeeStaff master recordid, code (EMP-…), name, department, jobTitle, email, phone, salary, allowances, hireDate, statusHas many AttendanceRecords and LeaveRequests; salespeople & supervisors are referenced by name
AttendanceRecordOne employee-month of attendanceemployeeId, month (yyyy-mm), absentDays, lateCount, overtimeHoursCombined with salary by the payroll formula
LeaveRequestLeave application to approveemployeeId, leave type, from, to, days, reason, status (Pending / Approved / Rejected)Belongs to Employee; pending count badges the HR tab
AuditEntryField-level change logtimestamp, entity label, action (Created / Updated / Deleted), record id, details (human-readable diff)Written automatically by create / update / delete on products & categories
AIReportSaved generated reportid, title, type, content (formatted text), createdAtProduced by the AI Assistant / Reports generator on demand
Deliberate denormalizations (each maintained by exactly one code path): product.stock mirrors Σ lots; receivedQty mirrors lot-creation progress per PO line; salesOrder.cogs freezes delivery-time cost. Everything else is derived at read time.

6 · State Machines

Statuses are stored as plain strings on the records. Only the transitions drawn below are possible; each is guarded in the store (or by button availability plus a store-level check).

Purchase Order

Draft

Editable

→

Pending

Awaiting approval

→

Approved

Can be received

→

Partially Received

Some lines still open

→

Received

All lines complete / closed

Cancelled

No postings allowed

Sales Order

Draft

Editable

→

Confirmed

Ready to deliver

→

Delivered

Stock consumed, COGS frozen

Cancelled

No postings allowed

Leave Request

Pending

Awaiting decision

→

Approved

Rejected

Stock Lot Lifecycle (implicit — no status field)

Created

qty = initialQty

→

Active

0 < qty ≤ initialQty — available to FEFO

→

Depleted

qty = 0 — kept for traceability

Lot Quality Status

Pending

New lot — not inspected yet

→

Passed

Released for delivery

Partially Passed

Released; defects written off

Quarantine

Failed — delivery skips this lot

A quarantined lot returns to Passed / Partially Passed only through a new inspection. Deleting an inspection restores the status the lot had before it.

Payment status is never stored either: it is derived from paidAmount vs the amount due (SO: grand total incl. VAT; PO: received value) as Unpaid / Partial / Paid.

7 · Key Algorithms & Formulas

Every number in the system comes from one of these definitions, implemented once in the domain-logic layer.

ConceptDefinition
Product stockΣ over its lots of lot.qty — cached on the product and recomputed after every mutation.
Inventory valuation (per product)Σ lot.qty × lot.costPrice. Weighted average cost = valuation ÷ stock quantity.
FEFO consumption orderSort lots by expiryDate ascending (lots without expiry last), then by receivedDate ascending; consume from the front.
Expiry classificationExpired when expiryDate is before today; Expiring Soon when within 30 days; OK afterwards; No Expiry when empty.
Order totalsLine value = qty × unit price/cost; sales grand total = subtotal × 1.14 (14% VAT) as printed on the invoice.
Received value (PO)Σ receivedQty × unitCost — the payable basis; outstanding payable = received value − paidAmount.
Real COGS (per delivery)Σ consumed lot quantity × that lot’s costPrice, computed during FEFO consumption and frozen on the sales order.
Profit chainGross profit = delivered revenue − real COGS. Profit after losses = gross profit − Σ loss.value. Margins are the same figures ÷ revenue.
Payment status (derived)paidAmount = 0 → Unpaid; 0 < paidAmount < due → Partial; paidAmount ≥ due → Paid. (SO due = grand total incl. VAT; PO due = received value.)
Payroll (per employee-month)daily = salary ÷ 30; hourly = daily ÷ 8; overtime pay = overtimeHours × hourly × 1.5; deductions = absentDays × daily + lateCount × hourly; net = salary + allowances + overtime pay − deductions.
Restock suggestionFor active products with stock ≤ reorderLevel: target = max(maxStock, 3 × reorderLevel); suggested order = target − stock; estimated cost uses weighted average lot cost; list sorted by urgency (stock ÷ reorderLevel).
Supplier fulfilment %Σ receivedQty ÷ Σ ordered qty across the supplier’s non-cancelled orders; shortage losses are summed from the loss register by reference.
EAN-13 check digitFrom the stored 12-digit base: multiply digits alternately by 1 and 3 from the right, sum, check = (10 − (sum mod 10)) mod 10.
Quality pass rate & quarantine rule(inspectedQty − failedQty) ÷ inspectedQty. Result: 0 failed → Passed; at least 90% → Passed with Defects; below 90% → Failed and the lot is quarantined. Failed units are valued at lot cost as a Quality Rejection loss; supplier/product pass rates aggregate all inspections.

8 · Business Rules & Invariants

Rules the store enforces regardless of which screen triggers the change — a developer adding a feature must preserve all of them.

Stock can never be oversold

Delivery validates every line against available lot quantity first; if any line is short, nothing is posted and the shortages are listed. The check-and-consume step is one atomic transition.

No double posting

A purchase order only receives against its remaining quantities and a delivered sales order cannot be delivered again; status guards make re-posting impossible.

Referential integrity

Products, suppliers and customers referenced by orders, lots or movements cannot be deleted. Deleting a production record reverses its lot, movement and loss instead of orphaning them.

Stock equals the sum of lots

The cached product stock is recomputed from lots after every single mutation — receipts, deliveries, adjustments, write-offs, lot edits and production reversals all pass through the same recomputation.

Lot quantity bounds

Manual lot editing clamps quantity to [0, initialQty], so history can be corrected but never inflated beyond what physically arrived; the delta is written as an ADJUST movement.

Quality gate on delivery

FEFO consumption skips quarantined lots everywhere (sales delivery and manual stock-out), so failed stock can never reach a customer unnoticed — and the delivery guard reports exactly how much is held in quarantine.

Losses are always valued & referenced

Every loss record carries quantity × unit cost = value and a reference to its cause (order, batch or lot), making loss analysis by type, product and cause exact.

Sequential document numbers

Purchase orders (PO-1001…), sales orders (SO-2001…), employee codes (EMP-001…) and product barcodes are generated from the current maximum, so numbers are unique and human-readable.

Automatic alerting thresholds

stock ≤ reorderLevel flags Low Stock; stock = 0 flags Out of Stock; lots expiring within 30 days or already expired raise expiry alerts on the dashboard, sidebar badge and reports.

Payments never overstate balances

Outstanding amounts are derived (due − paidAmount) at read time, so recording or editing a payment instantly corrects every balance, statement and KPI.

Auditability by construction

Stock changes flow into the movement ledger with running balances; product and category edits flow into the audit log as field-level diffs. No change path bypasses either log.

9 · Screens Inventory

Each screen, its address, its job, and the store actions it is allowed to call. Read-only screens only derive and display.

ScreenPathPurposeStore Actions
Dashboard/KPIs, alerts, summaries— (read-only)
Products/productsProduct master + category tree managerupsert, remove
Stock Management/inventoryLots per product, stock in/out, write-offsadjustStock, updateLot, writeOffLot
Daily Production/productionTarget vs actual productionaddProduction, deleteProduction
Quality Control/qualityLot inspections, quarantine, defect analyticsrecordInspection, deleteInspection
History & Audit/historyMovement ledger + audit diffs— (read-only)
Suppliers/suppliersVendor master, stats, statementsupsert, remove
Purchase Orders/purchase-ordersPO lifecycle, receiving, paymentsupsert, setStatus, receivePO
Sales & Invoices/salesSO lifecycle, delivery, paymentsupsert, setStatus, deliverSO
Customers/customersCustomer master, stats, statementsupsert, remove
Invoice / PO Print/invoices/…Printable invoice (VAT) & PO document— (read-only)
Barcode Labels/labels/…EAN-13 label sheets— (read-only)
Human Resources/hrEmployees, attendance, payroll, leavesupsert, remove, setStatus
Insights & Reports/reportsTabular analytics + AI reportsupsert (saved reports)
AI Assistant/aiChat + report studio + libraryupsert (saved reports)
System Flow/flowThis documentation— (read-only)

10 · How a Developer Extends This System

Three recipes cover almost any change. The golden rule: new behaviour goes in the store (transition) or the domain helpers (calculation) — screens only display and dispatch.

Add a new record type

  1. Define its shape and add sample records to the seed dataset.
  2. Give the load-time normalizer a default (collection: saved.collection || []) so older saved workspaces upgrade safely.
  3. Reuse upsert / remove / setStatus for plain CRUD, or add one dedicated guarded transition for anything with side effects.
  4. Build the screen (table + form + details popup), then register it in the sidebar navigation.

Add a new KPI or statistic

  1. Write it as a pure helper next to the existing formulas (input: dataset or records; output: number/object).
  2. Display it with the standard KPI card (big coloured title, value, sub-note) — pick the tone by meaning: green money-in, red losses/danger, amber waiting/risk, and so on.
  3. If the AI should know it, add it to the bounded snapshot builder so chat and reports share the same figure.

Add an order-like workflow

  1. Give the document a status field and draw its state machine first (section 6 style).
  2. Implement each transition as one store action that validates the current status, applies the change, and writes all side records (movements/losses/audit) in the same transition.
  3. Expose only the buttons valid for the current status; colour them distinctly, keep the rest inside the details popup.

Conventions used everywhere

  • Immutable updates: actions build the next dataset instead of mutating records in place.
  • One user intent = one transition = one persistence write + one notification.
  • Ids come from a single generator with readable prefixes; document numbers from “next after current maximum”.
  • Money is formatted through one formatter (EGP 12,500); dates are yyyy-mm-dd strings end to end.
  • Buttons are colour-coded by meaning and adjacent buttons never share a colour; destructive actions live in details popups, not table rows.
  • No decorative icons in the interface — colour and typography carry the meaning.

11 · Assumptions, Limitations & the Production Path

Current assumptions (demo mode)

  • Single workspace per visitor/browser: data persists on the device and is not shared between users or devices.
  • No login or roles — every visitor can do everything in their own workspace; “Reset demo data” restores the seed dataset.
  • Single currency (EGP) and a fixed 14% VAT on sales invoices.
  • The AI assistant needs its server-side access key configured; without it the assistant reports itself offline and the rest of the ERP is unaffected.
  • Visitor Analytics events live outside the workspace dataset (a separate key-value store when configured; server memory otherwise), so analytics observe every visitor rather than a single browser.

Path to a production deployment

  • Keep the screens and domain helpers exactly as they are — the store boundary is the seam.
  • Re-implement the store actions behind authenticated server endpoints backed by a shared database (same transitions, same side records, same guards).
  • Add users & roles at the endpoint layer (e.g. warehouse vs finance), plus server-side validation mirroring the store guards.
  • Move document-number generation into database sequences to stay unique under concurrency.

Live Dataset Right Now

Record counts in your current workspace — proof that this page documents the very dataset you are looking at:

Products: 12Stock lots: 14Categories: 47Suppliers: 5Customers: 5Purchase orders: 5Sales orders: 4Stock movements: 9Production records: 3Loss records: 5Employees: 10Attendance records: 0Leave requests: 0Quality inspections: 3Audit entries: 0Saved AI reports: 0