Audits → Spot Check
Purpose
Run a focused, random-sample physical count against a subset of containers (typically a single substance, a single schedule, or a statistical random sample) to catch discrepancies between biennial inventories. Spot checks are the operational smoke alarm for a controlled-substance program: a 2-day-old discrepancy is investigable; a 6-month-old one usually isn't.
This is general product information about CS Logbook, not legal advice. Spot checks are an operational best practice, not a CS Logbook-defined requirement. Verify any required count cadence with the DEA Diversion Control Division and your state veterinary/pharmacy board.
Regulatory basis: spot checks are not directly mandated by the DEA, but ongoing physical accountability supports the security and recordkeeping principles in the DEA security rules and Part 1304. Some state boards may require periodic random counts; confirm your state's rules directly.
When to use it
- Monthly cadence: pick a day; run a 5-10% random sample of active containers. Catches drift before it compounds.
- Substance-focused: when a specific substance has been disproportionately involved in waste/disposal events, spot-check that substance's containers.
- Schedule II focus: many clinics run a weekly Schedule II spot check separate from the broader monthly check, given the regulatory sensitivity.
- Post-incident: administered the wrong dose, witness wasn't co-signed, container looks tampered → spot-check the immediate area.
- Pre-state-board visit: when state inspector is expected, spot-check the substances they're most likely to ask about.
The spot check is not a replacement for the biennial (the DEA still requires its periodic full count; see the DEA inventory rule). It's a complement. The relationship:
- Biennial = comprehensive snapshot, on the DEA's periodic cadence, signed by DEA registrant, regulator-facing
- Internal audit = process check, quarterly, owner-finalized, regulator + insurer-facing
- Spot check = random count, monthly (or more), staff-conducted, internal-facing
Walkthrough
The spot check is a multi-step wizard at /home/<your-clinic>/audits/spot-checks/new. The flow guides the staff member through scope selection, sampling, count entry, photo evidence, investigation (if discrepancies surface), and review.
Step 1: Open spot checks
Navigate to /home/<your-clinic>/audits/spot-checks. The history page shows previous spot checks with date, scope, the number of discrepancies, and status.

Click Start Spot Check in the top-right.
Step 2: Select scope
The wizard's first step asks: what is being audited?
- Full inventory: all active containers (rare for spot checks; this is essentially a mini-biennial)
- Schedule II only: most-regulated; reasonable weekly cadence
- Specific substance: pick one substance from your formulary; counts every active container of that substance
- Random sample: statistical sampling (next step configures sample size)
- Specific containers: manual selection of containers to count
- Specific location: when your clinic has multiple physical storage locations (controlled-substance safe, surgery suite, mobile vehicle), this audits one location
Add scope notes explaining the rationale (e.g., "Monthly Sched II routine", "Post-incident audit after 2026-04-12 near-miss").
Step 3: Configure random sampling (if applicable)
If you picked Random sample in the previous step, this step configures:
- Sample size: number of containers (typical: 10-20 for monthly check)
- Sampling method:
simple_random/stratified_by_schedule/stratified_by_substance - Confidence level: informational; surfaces in the audit summary for statistical interpretation
The wizard runs a deterministic random selection at this point (the seed is captured so the sample is reproducible if needed).
Step 4: Select containers
For non-random scopes, this step lets you confirm the auto-selected containers (and remove any that shouldn't be counted, e.g., containers known to be in transit). For random samples, the selected containers are pre-populated.
Step 5: Enter counts
First choose Counted by: the person who physically counted the containers on this screen. It starts as you, and anyone on the clinic's staff list can be chosen, including staff who do not sign in. If someone else continues the count later, they choose themselves for the containers they count, and the earlier counts keep the name they were saved with.
For each container, enter:
- Counted quantity: physical count
- Count notes: observations
- Photo: optional; recommended when the container appears to have been tampered, damaged, or recounts disagree
The system balance is shown alongside, with the difference (counted minus expected) and that difference as a percent of the expected quantity, worked out as you type.
Step 6: Investigation modal (per-discrepancy)
Any container whose counted quantity differs from the expected quantity, by any amount, is shown as a discrepancy, and you can open an investigation for it from the review step. CS Logbook does not grade the difference or apply a tolerance: it shows the numbers, and the clinic and its DEA registrant decide what they mean. The modal has four tabs:
- Overview: expected quantity, counted quantity, the difference, the percent, and any photos attached during counting.
- Access logs: who opened the container's records, and when.
- Transactions: the container's recent entries, so the difference can be traced against what was recorded. From here you record what the count found, in one of two ways:
- Correct an existing entry when the count shows that something was recorded wrongly, for example a dose entered as 1.0 mL that was really 0.1 mL.
- Record a loss or found stock when nothing was recorded wrongly but the stock is not what the log says. This opens a new ledger entry already linked to this count.
- Resolution: investigation notes, plus a Mark resolved checkbox.
Investigated and resolved are not the same thing, and the product keeps them apart. Saving notes records what you looked into. Ticking Mark resolved records that the discrepancy is closed. You can save notes and leave the item open, and the record will correctly show it as investigated but unresolved. Recording a loss or found stock from the Transactions tab resolves the item for you and notes the entry that resolved it.
Step 7: Review & complete
The review step shows all counts, differences and investigations as a summary. Add audit-level summary notes, then click Complete Spot Check.
A discrepancy does not stop you completing the spot check. You are not asked to investigate or resolve it first. The count is what dates the discovery, so the product records it and flags what is still open rather than holding the record back. An unresolved discrepancy stays unresolved on the completed record and is marked in amber on the detail view, so it can be found and followed up.
Completing still asks for supervisor verification: a one-time code is emailed to you and entered before the record is finalized. That step is unchanged.
Once verified, the spot check is stored with status completed, the per-container counts, and the scope and sampling settings it was created with.
A screenshot of the spot-check review summary will be added here.
Step 8: Finalize (owner-only)
Just like internal audits, completed spot checks can be finalized (owner-only) to lock the record. Navigate to /audits/spot-checks/<auditId> for the detail view; the Finalize Audit button is in the header. After finalization, the audit row is locked at the DB layer.
Correcting a spot check
Until a spot check is finalized, three things on it can be corrected on the detail view, each where it is displayed:
- Count date, at the top of the page. It cannot be set to a date after today.
- Counted, on each container's row, when a count was entered wrongly.
- Counted by, on each container's row, including filling in a row that reads Not recorded.
Click the value, change it, give a reason (recommended, not required), and save. Every correction is added to Correction history at the bottom of the page with the old value, the new value, the reason, and who made it. Nothing is overwritten without a trace, and the history cannot be edited.
A few things to know:
- Changing a count recalculates it. Its difference and the spot check's discrepancy total are worked out again, against the expected quantity recorded when the count was taken.
- Changing a count reopens its finding. A container you had marked resolved goes back to open, because the resolution was about the old number.
- If someone else changed the same count while you were editing, your change is not saved and you are asked to reload and check the new value first.
- A blank count is not saved. Enter 0 if you really counted none.
- A finalized spot check cannot be corrected. Finalizing is what locks the record.
Voiding a spot check that did not happen
If a spot check was started by mistake (the wrong clinic, a duplicate, a count that was never actually taken), void it instead of leaving it open. Click Void spot check on its detail page, give a reason if you can, and confirm.
- A reason is recommended, not required. If you leave it blank the void still goes through, and the record shows No reason recorded.
- The spot check stays on the list, marked Voided, with who voided it, when and why. It is kept for the record.
- A voided spot check cannot be changed again: no corrections, no new counts, no finalizing. A void cannot be undone.
- Ledger entries are left alone. If an adjustment or correction was recorded from this spot check, it still stands; the confirmation tells you how many there are, so you can correct them separately if they should not stand.
- Who can void: anyone who can conduct spot checks can void an open one. Voiding a finalized spot check needs the permission to approve audits (owner or admin).
What changes a container's balance
A spot check never changes a container's balance by itself. The count is a record of what you found. The balance moves only when an entry is made in the container's transaction log, and for a spot check that happens when you correct an existing entry, or record a loss or found stock, from the investigation.
That also means correcting a count does not undo anything you recorded from it. If you recorded a loss against a count and then find the count was mistyped:
- Correct the count. Its finding reopens.
- The row then shows an amber note: A reconciliation was recorded against the earlier count of X.
- The entry you recorded stays in the transaction log exactly as it was. If it moved the balance by the wrong amount, correct that entry from the container's transaction history, the same way as any other entry. CS Logbook does not change a log entry for you.
Field reference
Scope selection
| Field | Description |
|---|---|
scope_type |
full_inventory / schedule_specific / substance_specific / random_sample / specific_containers / location_specific |
scope_filter |
JSON: which schedule (II/III/IV/V), substance UUID, container UUIDs, or location label |
scope_notes |
free-text rationale |
Random sampling configuration
| Field | Description |
|---|---|
sample_size |
integer; how many containers to count |
sampling_method |
simple_random / stratified_by_schedule / stratified_by_substance |
confidence_level |
informational; e.g., 90 / 95 / 99% |
Per-container count entry
| Field | Description |
|---|---|
counted_quantity |
the physical count you entered |
item_notes |
your observations for that container |
photo_url |
optional photo evidence |
counted_by_clinic_staff_id |
who physically counted, chosen once per save. It can be corrected until the spot check is finalized, and each correction is kept in the correction history. Counts saved before this field existed show "Not recorded" |
Investigation modal (per discrepancy)
| Field | Description |
|---|---|
resolution_notes |
what was checked and what was found |
resolved |
whether the discrepancy is closed. An item may carry notes and still be unresolved |
Resulting database rows
| Table | Columns set |
|---|---|
audits |
audit_type='spot_check', account_id, audit_date, performed_by, status, total_discrepancies (how many counted containers have a difference other than zero), containers_sampled (how many containers were counted), and notes, which keeps the scope, sampling method, sampling seed and counted container ids from creation alongside the supervisor notes added at completion |
audit_items |
one row per counted container; counted_quantity, expected_quantity, discrepancy (generated: counted minus expected), resolution_notes, resolved, item_notes, photo_url, counted_by_clinic_staff_id |
audits_change_logs, audit_items_change_logs |
one row per corrected field: the old and new value, the reason, who changed it and when |
Edge cases
Empty random sample
If your account has fewer active containers than the requested sample size, the wizard surfaces a soft warning and adjusts the sample size to all available containers. The audit proceeds; the sample_size recorded in the audit row matches what was actually counted.
Discrepancy on a Schedule II container
A Schedule II container is treated like any other: any difference is shown as a discrepancy, with its numbers and no grade. If the investigation shows stock was lost, record a loss from the Transactions tab. Nothing is closed for you, and nothing prevents you completing the count.
Spot checks recorded before October 2026
Spot checks used to grade each container as acceptable, minor, major or critical. Those grades are still stored on the older records, but no screen shows them, so an older record reads the same way as a new one.
Container in transit during count
If a container's status is in_transit (mid-transfer between locations), the spot-check wizard excludes it by default. You can manually include it via specific_containers scope, but the system balance comparison will show the in-transit balance, not a final balance.
Audit submitted with zero containers counted
The wizard blocks completion if no containers have been counted. There's no useful audit with zero counted items: count at least one container, or void the spot check if it should not have been started.
Common mistakes
- Always running the same scope. If your monthly spot check is always "Schedule II only", a discrepancy in a Schedule III substance can hide for 2 years until the biennial. Rotate scopes month over month.
- Skipping the investigation modal on small differences. The investigation step is the value of the spot check: counts without investigation context are just numbers. Even a "0.5% difference, likely measurement" note is the record you'll want later.
- Treating spot checks as optional. Many clinics drop spot checks during busy periods. The discrepancies that compound during those periods are the ones the biennial then surfaces, often with no investigable trail.
- Not using photos when the container looks unusual. Photos are timestamped, location-stamped (if your device supports), and are the strongest evidence of physical-state-at-time-of-count. Use them generously.
- Leaving a discrepancy investigated but never resolved. Notes without a resolution is still an open finding, and it stays flagged on the completed record. Decide the follow-up and close it.
- Spot-checking only the substances you trust. The substances you trust are where you'll catch theft last. Spot-check randomly, not where you're confident.
Related
- Audits overview: the audit lifecycle and the Finalize step common to spot checks and internal audits
- Biennial inventory: the DEA's periodic mandated full count
- Inventory → Containers: the entities being counted
- Inventory → Transactions: the events between counts that move balances
- Sprint 18 spot check feature plan: internal architecture reference (random sampling, statistical confidence)