v0.9.0 Latest Since v0.9.0

Consumables

Supply inventory with append-only ledger — toner, drums, batteries, anything that's interchangeable.

Consumables track stock of items Inventory shouldn’t store per-serial — toner cartridges, spare drum kits, UPS batteries, replacement keyboards. Distinct from assets so the durable-stuff schema doesn’t accumulate fungible-stuff rows.

Schema

  • consumablespart_no (unique), vendor_company_id, name, current_stock, low_stock_threshold, notes, archive flag.
  • consumable_movements — append-only ledger. consumable_id, delta (signed int), reason, ticket_id (nullable), by_user_id, at, note.

Every stock change runs UPDATE consumables SET current_stock = current_stock + $delta + INSERT consumable_movements … in the same transaction. Direct PATCH /current_stock is rejected with 400 "use /:id/move" so the audit trail can’t be bypassed.

Endpoints

EndpointPurpose
GET /api/consumablesList (search, archive filter).
POST /api/consumablesCreate.
GET / PATCH / DELETE /api/consumables/:idRead / update metadata / soft-archive.
POST /api/consumables/:id/moveAtomic stock adjust + ledger insert.
GET /api/consumables/:id/movementsNewest-first ledger.
POST /api/consumables/:id/print-labelSend a label to the printer.

POST /:id/move body shape:

{
  "delta": -2,
  "reason": "issued",
  "ticket_id": 4521,
  "note": "Toner for ACME-0042"
}

UI

  • Consumables top-nav entry, parallel to Inventory. Handler-only.
  • List page: search box, low-stock chip, archive toggle, count by vendor.
  • Detail page: stock card (current + threshold), inline edit, +/- stock controls, full ledger table, Print label button.

Low-stock is purely informational right now — surfaces a red badge but doesn’t fire a notification. Reorder alerts via the existing notification matrix is a roadmap follow-up.

Common operations

  • Receive shipment — Detail → + N with reason received, optional vendor PO note.
  • Issue to ticket — Detail → - 1 with reason issued, link to ticket. Or from the ticket itself (future — currently you start from the consumable).
  • Disposal / recall- N with reason disposed. Reason values are free-text but the seeded list is received | issued | returned | disposed | count_correction | loss.
  • Count correction — when a manual recount disagrees with the on-screen number, log a count_correction movement with the delta. Keeps the discrepancy on the audit trail rather than hiding it inside an edit.