Operating Manual

Internal training reference. Last reviewed 2026-04-26 (6 days ago).

What the system does, architecture, sources of truth.

What this ERP does

Manages a jewellery business end-to-end:

  • Buy raw / finished pieces from suppliers (often in foreign currency, with shipping & customs)
  • Track every batch's true landed cost and cost-per-gram
  • Recommend selling prices from live metal-spot snapshots
  • Take customer orders, reserve stock, fulfil with FIFO cost-of-goods
  • Issue invoices, record payments, generate receipts
  • Handle returns that reverse the original FIFO consumption
  • Run analytics (revenue, COGS, profit, FX gain/loss, cost-movement alerts)

High-level architecture

                  ┌──────────────────────────────────┐
                  │         BROWSER (Next.js UI)     │
                  │  /(dashboard)/* page components   │
                  └─────────────┬────────────────────┘
                                │ fetch JSON
                                ▼
                  ┌──────────────────────────────────┐
                  │   /src/app/api/*/route.ts        │
                  │   Business logic, validation,    │
                  │   transactions, audit logging    │
                  └─────────────┬────────────────────┘
                                │ Prisma
                                ▼
                  ┌──────────────────────────────────┐
                  │     SQLite database (Prisma)     │
                  │  ~30 tables, see schema.prisma   │
                  └──────────────────────────────────┘

External: metal-price API provider (simulated / MetalPriceAPI / GoldAPI)
Auth:     NextAuth (admin@fmt.com / STAFF or ADMIN role)

Source of truth — what owns each fact

ConceptSource of truthWhy
Inventory quantityPurchaseBatch.remainingQty (sum across batches), reflected in InventoryBalance.quantityFIFO is exact; balance is a cached rollup that can be replayed from movements
CostPurchaseBatch.unitCost (per batch, FIFO consumed in order)Each batch carries its true landed cost; weighted-average is informational only
PricingMetalPriceSnapshot.pricePerGram (latest by effectiveAt) + Product.weightPerUnit + Product.workmanshipCostMetal price moves daily; products don't store live prices
ProfitSalesOrder.grossProfit = totalAmount − totalCogs, where totalCogs is the sum of FIFO consumption snapshotsComputed at fulfilment, frozen on the SO
ReceivableInvoice.amountPaid + paymentStatus (rolled up from active payments)Payments + voids re-roll the invoice automatically

Data flow at a glance

Supplier ─► PO ─► Receive ─► PurchaseBatch ─► InventoryBalance
                                  │
                                  └─ FIFO queue (oldest receivedAt first)
                                              │
                                              ▼
Customer ─► SO ─► Confirm ─► Reserve ─► Fulfil ─► Consume FIFO ─► COGS
                                              │              │
                                              ▼              ▼
                                         Invoice ─► Payment ─► Receipt

Metal Price Snapshot ─► Pricing recommendation
Expenses ─► Net profit
Audit Log ◄─── every CREATE / UPDATE / DELETE / VOID / RECEIVE / FULFILL