Stock Counts
What this is
Dentolize's inventory module has always tracked what a clinic owns — purchases, usage, transfers, returns, disposals. What it has never had is a way to check whether the system's number matches what is actually on the shelf. Stock Counts is that missing piece: a physical inventory / cycle count workflow that freezes what the system expects, lets staff (on web or on a phone) walk the shelves and record what they actually find, and — if the clinic chooses — books the difference as a stock adjustment.
This PR (mo/stock_counts, #414) adds the feature end‑to‑end:
- Two new database tables (
StockCount,StockCountItem) and a locking flag onInventoryStorage. - A full set of GraphQL queries/mutations to open, count, upload, confirm, cancel and delete a count.
- A web experience under Inventory → Stock Counts: a list, a detail/counting screen, a guided "one item at a time" counting modal, and an Excel upload for sheets counted on paper.
- A mobile experience for staff who count with a phone in hand: a list, a detail screen, a barcode-scan-to-line screen, and a single-line counting screen.
- A safety mechanism that blocks other inventory movements (purchases, transfers, usage, disposals, sales…) against any storage that is currently being counted, so nothing can move while someone is trying to count it.
Why it matters
Clinics accumulate drift between "what the system thinks is in stock" and "what is physically there" — breakage, theft, mis-recorded transactions, expired stock quietly removed without a transaction. Without a stock count, the only way to fix that drift is to manually edit item amounts, which is untracked and easy to get wrong. Stock Counts gives clinics a structured, auditable way to reconcile: freeze a snapshot, count against it, see the variance, and optionally have the system book a proper ADJUSTMENT inventory order for the difference — with full attribution (who counted what, when, and who confirmed).
Who touches this
- Inventory managers / owners open counts, review variances, and decide whether to update stock.
- Any staff member with count permissions (a new, narrower "counter" role is possible via
EDIT_STOCK_COUNT+VIEW_CREATED_STOCK_COUNT— see Permissions & Visibility) can be handed a phone and told "count storage X" without seeing every other count in the clinic. - Everyone else moving inventory is affected indirectly: if a storage is locked by an open count, their purchase/usage/transfer/etc. is refused with a message naming the count.
Where to look in the code
- Schema:
packages/prisma/schema.prisma:4421(StockCount),:4474(StockCountItem),:4524(StockCountStatus) - Server mutations:
packages/server/src/resolvers/mutations/actions/stockCounts/ - Server queries:
packages/server/src/resolvers/queries/actions/stockCounts/ - Web UI:
packages/clinic-web/src/components/dashboard/inventories/stockCounts/ - Mobile UI:
packages/clinic-mobile/src/components/dashboard/More/inventories/stockCounts/ - Excel upload parsing:
packages/server/src/queue/uploadFiles/handleParseStockCount.js - The locking guard shared by every other inventory mutation:
packages/server/src/resolvers/mutations/actions/inventory/inventoryUtils.js:29(assertStoragesAreNotBeingCounted)
Status
This feature is unreleased — it lives on branch mo/stock_counts and has not shipped to customers. Everything in this walkthrough was verified against the code and captured on the branch's sandbox deploy.