NetSuite inventory reconciliation

Cycle count → variance → HITL → NS write → audit trail · 10 phases · cron-driven

Inventory truth drifts. Cycle counts catch the drift before it bleeds into pick errors and quote inaccuracies. This pipeline schedules a weekly count per zone, captures physical numbers, computes variance vs inventory_balance, auto-adjusts small deltas, stages larger deltas behind HITL, pushes the approved adjustment to NS, updates the D1 mirror, logs the reason, fires an events.inventory.adjusted signal, and surfaces a variance report on the admin dashboard.

cron-driven HITL on > 2% variance physical capture STUB

Pipeline — 10 phases, left to right

idle
NS inventory reconciliation — cycle count schedule → physical count → variance detection → threshold check → HITL stage → Mike approves → NS push → D1 mirror update → audit trail → variance report 01 / Schedule 02 / Count 03 / Variance 04 / Threshold 05 / HITL 06 / Approve 07 / NS push 08 / Mirror 09 / Audit 10 / Report CYCLE COUNT SCHEDULED — Weekly cron per warehouse zone selects a count list. Cron rotates zones so every SKU is counted within 30 days. CRON schedule: 0 6 * * MON (weekly Monday 06:00 UTC) rotation: zone_A · zone_B · zone_C · zone_D TABLES read: locations · cycle_count_schedule STATUS: REAL cycle count cron schedule weekly per zone MESSAGEBUS · CF Cron i PHYSICAL COUNT — Warehouse staff walks the zone and records counts. Currently captured on paper or via NS UI mobile; barcode scanner integration is STUB. ACTION capture: physical_qty per item × location SOURCE paper: walk-sheet typed in NS UI mobile: NS mobile inventory count form STATUS ns_native: REAL scanner_autoflow: STUB physical count warehouse staff walk and count EXTERNAL · STUB scanner i VARIANCE DETECTION — Diff physical_qty vs inventory_balance.quantityonhand per item × location. Compute variance_pct and variance_abs (absolute units and dollar value). ACTION variance = physical - on_hand variance_pct = variance / on_hand variance_value = variance × item.avg_cost TABLES read: inventory_balance · items (cost) write: cycle_count_variances (new) STATUS: REAL variance detect physical − on-hand pct + abs + value BACKEND · D1 compute i THRESHOLD BRANCH — If |variance_pct| ≤ 2% AND |variance_value| ≤ $100, auto-adjust. Otherwise route to HITL. Threshold configurable via guardrails table. THRESHOLD auto_adjust: |pct| ≤ 2% AND |$| ≤ $100 hitl_route: anything larger TABLES read: guardrails.inventory_auto_pct STATUS: REAL threshold ≤ 2% auto ≤ $100 auto else → HITL BACKEND · branch i HITL STAGE — proposed_action row with action_type='inventory_adjustment'. Payload contains item_code, location, on_hand, physical_qty, variance, suggested_reason. ACTION insert: proposed_actions (pending) HITL surface: /proposed-actions.html action_type: 'inventory_adjustment' risk: 3 TABLES write: proposed_actions STATUS: REAL HITL stage proposed_actions inventory_adjustment SECURITY · risk 3 i MIKE APPROVES — Admin reviews variance and reason at /proposed-actions.html. X-Edit-Token required. Approval flips proposed_action.status to 'approved'. ACTION status: pending → approved add: approved_by, approved_at, reason_note HEADER X-Edit-Token required TABLES write: proposed_actions (status flip) STATUS: REAL Mike approves X-Edit-Token /proposed-actions SECURITY · HITL i NS PUSH — Approval drops a row in ns_pending_pushes targeting inventoryadjustment record_type. PushMutexDO drains and writes via NS RESTlet OAuth1. ACTION enqueue: ns_pending_pushes drain: PushMutexDO → NS RESTlet ns_record: inventoryadjustment TABLES write: ns_pending_pushes ENDPOINT push: NS_PUSH_QUEUE drainer STATUS: REAL NS push ns_pending_pushes inventoryadjustment CLOUD · PushMutexDO i D1 MIRROR UPDATE — inventory_balance.quantityonhand reflects new value. Reservation rows recomputed. Sync engine confirms NS parity on next 5-min sync. ACTION set: inventory_balance.quantityonhand = physical_qty recompute: quantityavailable TABLES write: inventory_balance STATUS: REAL D1 mirror qty_on_hand updated available recomputed DATABASE · D1 i AUDIT TRAIL — reflexion_log row written with reason + delta + approved_by. events.inventory.adjusted fires onto the event ledger. ACTION insert: reflexion_log (tags=inventory_adjustment) fire: events.inventory.adjusted TABLES write: reflexion_log · events SUBSCRIBERS customer_health_predictor · ar_aging_view STATUS: REAL audit trail reflexion_log events.inventory.adjusted downstream listeners DATABASE · event ledger i VARIANCE REPORT — admin-dashboard tile surfaces last 30 days of variances by zone, item, value. Patterns inform next cron schedule. SURFACES admin-dashboard.html (inventory tile) /inventory/variances TABLES read: cycle_count_variances · reflexion_log STATUS: REAL variance report admin-dashboard 30-day rolling FRONTEND · tile i if ≤ 2% AND ≤ $100 → bypass HITL, auto-adjust D1 + NS LEGEND Cron External capture Backend HITL Push (NS) D1 / ledger Surface

Phase detail — 10 phases

01 Cycle count scheduled REAL

Weekly cron rotates through warehouse zones. Every SKU lands in a count list within 30 days.
Cron
0 6 * * MON
Tables read
locations · cycle_count_schedule

02 Physical count scanner STUB

Today the count is paper or NS mobile entry; barcode autoflow is not wired.
NS surface
NS Mobile inventory count form
STUB
no scanner integration → paper-to-keyboard step remains

03 Variance detection REAL

Diff physical vs on-hand. Compute variance_pct, variance_abs, variance_value.
Tables write
cycle_count_variances
Tables read
inventory_balance · items.avg_cost

04 Threshold branch REAL

|variance_pct| ≤ 2% AND |variance_value| ≤ $100 auto-adjusts. Larger routes to HITL.
Source
guardrails.inventory_auto_pct
Defaults
2% / $100 absolute value

05 HITL stage risk 3

proposed_action with action_type='inventory_adjustment'.
Surface
/proposed-actions.html
Table write
proposed_actions

06 Mike approves REAL

Admin approves with X-Edit-Token. status flips pending → approved.
Header
X-Edit-Token
Adds
approved_by · approved_at · reason_note

07 NS push REAL

Approved row enqueues into ns_pending_pushes; PushMutexDO drains it to a NetSuite inventoryadjustment record.
DO
PushMutexDO
NS record
inventoryadjustment
Code path
src/lib/ns.ts · src/durable_objects.ts

08 D1 mirror update REAL

inventory_balance.quantityonhand reflects the approved value; quantityavailable recomputed.
Verify
next NS sync confirms parity within 5 min

09 Audit trail REAL

Reason + delta + approved_by written to reflexion_log. events.inventory.adjusted fires on the event ledger.
Tables write
reflexion_log · events
Subscribers
customer_health_predictor · v_customer_ar_aging

10 Variance report REAL

admin-dashboard tile shows last 30 days of variances by zone, item, value. Drives next-cycle prioritization.
Surface
admin-dashboard.html · /inventory/variances

Tables, endpoints, code paths

kindnamepurpose
D1 tableinventory_balancequantityonhand, quantityavailable, reserved per item × location
D1 tablecycle_count_schedulezone rotation calendar
D1 tablecycle_count_variancesper-count variance row (pct, abs, value)
D1 tableproposed_actionsinventory_adjustment rows above threshold
D1 tablens_pending_pushesapproved → NS write queue
D1 tablereflexion_logaudit row with tag, reason, approved_by
D1 tableeventsinventory.adjusted event ledger row
NS recordinventoryadjustmentNS system-of-record adjustment entry
EndpointPOST /api/inventory/countingest physical count rows
EndpointPOST /api/inventory/adjustconfirm an approved adjustment
Code pathsrc/lib/workflow_runner.tsvariance workflow staging
Code pathsrc/durable_objects.tsPushMutexDO drainer
Cron0 6 * * MONweekly zone schedule trigger

Open gaps — honest punch list