Query an item record, review its current state across all surfaces (NS field values, spec sheet, pricing, vendor costs, assembly memberships, recent transactions), propose targeted field updates, and after HITL approval push the changes back to NS plus invalidate every downstream cache + re-derive dependent aggregates. The data-cleanup workhorse for the items catalog.
—data_quality.item_flagged"manual_or_event"null"Manually invoked from /item/<code> review page OR fired by data-quality watchdog when an item field drift is detected."current_itemitems["item_code"]SELECT id, itemid, displayname, salesdescription, custitem_brand, custitem_pack_size, custitem_case_count, custitem_buyamerican, custitem_kosher, custitem_allergens, custitem_country_of_origin, custitem_storage_temp, reorderpoint, taxschedule, isinactive, lastmodifieddate FROM items WHERE UPPER(itemid) = UPPER(?1) LIMIT 1
current_specspec_items["item_code"]SELECT spec_id, brand, item_name, pack_size, claims_json, nutritionals_json, allergens_json, spec_status, spec_version, last_updated FROM spec_items WHERE UPPER(item_code) = UPPER(?1) ORDER BY spec_version DESC LIMIT 1
pricing_master_rowpricing_master["item_code"]SELECT customer_name, case_price, cost_basis, school_year, status, last_updated FROM pricing_master WHERE UPPER(item_code) = UPPER(?1) AND status='active'
vendor_costsvendor_costs · vendor_items["item_code"]SELECT vendor_name, vendor_item_code, unit_cost, effective_start, effective_end, status FROM vendor_costs vc JOIN vendor_items vi ON vi.vendor_item_id = vc.vendor_item_id WHERE UPPER(vi.item_code) = UPPER(?1) AND vc.status='active'
assembly_membershipsassemblies · assembly_bom["item_code"]SELECT a.id, a.item_code AS assembly_code, a.description FROM assemblies a JOIN assembly_bom bom ON bom.assembly_id = a.id WHERE UPPER(bom.line_key) = UPPER(?1) AND a.deleted_at IS NULL AND bom.deleted_at IS NULL
open_bid_linesbid_lines · bids["item_code"]SELECT
bid_id, customer_name, proposed_price
FROM bid_lines
WHERE UPPER(item_code) = UPPER(?1)
AND bid_id IN (SELECT id
FROM bids
WHERE status IN ('active','submitted'))recent_transactionsso_lines["item_code"]SELECT
COUNT(*) AS so_count_30d
FROM so_lines
WHERE UPPER(item)=UPPER(?1)
AND trandate >= date('now','-30 days')| check | rule | severity |
|---|---|---|
item_exists | current_item.id present | block |
item_active | current_item.isinactive = 0 | warn |
proposed_changes_non_empty | proposed_changes present | block |
rationale_present | rationale present | block |
not_in_active_bid | open_bid_lines is null | warn |
Risk level 3 ≥ 3 — runner stages a proposed_actions row before fan-out runs. Mike must approve in proposed-actions.html before any side-effect step executes (real or stub).
workflow_item_record_review (proposal envelope)workflow:item_record_review:run_<run_id>step_1 stage_proposed_action REALitem_field_updateitem{{item_code}}01_stage_ns_field_updateStage NS-bound field update for HITL review. Drainer flips status to applied only after confirmed NS write.step_2 kv_invalidate REALitem:{{item_code}}item_full:{{item_code}}ns:item:{{item_code}}02_invalidate_item_cacheBust the live item caches so /item/<code> page renders fresh on next request.step_3 kv_invalidate REALpricing:{{item_code}}:*03_invalidate_pricing_cacheBust pricing caches that key off item_code (pattern delete via list scan).step_4 chat_tool STUBregenerate_spec_sheet{"item_code":"{{item_code}}","reason":"{{rationale}}"}04_regenerate_spec_sheetIf proposed_changes touched any spec-relevant field (claims, pack_size, allergens), regenerate the PDF spec sheet via the existing generator. Conditional on field set.src/lib/workflow_runner.ts (kind chat_tool hits the placeholder branch at line ~340 and emits step status 'stub'). Documented intent only.step_5 d1_write STUBassembly_cost_rollup05_recompute_assembly_cost_rollupsrecomputefor each assembly in context.assembly_membershipsIf this item is in any assembly BOM, recompute the affected assembly cost rollups so margin math stays current.src/lib/workflow_runner.ts (kind d1_write hits the placeholder branch at line ~340 and emits step status 'stub'). Documented intent only.step_6 flag STUB06_flag_dependent_pricingmark_for_pricing_reviewpricing_master rows in context.pricing_master_rowIf item-level changes could affect customer pricing (e.g. pack_size change ripples to case_price), flag the impacted pricing_master rows for next pricing review cycle.src/lib/workflow_runner.ts (kind flag hits the placeholder branch at line ~340 and emits step status 'stub'). Documented intent only.step_7 hitl_email_draft STUBpropose_email_to_customer07_notify_sales_if_active_bidcontext.open_bid_lines not nullIf the item is in any open bid, draft a notification email to the bid owner so the customer can be looped in before NS push happens.src/lib/workflow_runner.ts (kind hitl_email_draft hits the placeholder branch at line ~340 and emits step status 'stub'). Documented intent only.| id | action | source |
|---|---|---|
runner_log_run | INSERT into workflow_run_log (run_id, workflow_type, status, started_at, completed_at, summary_json) | runner automatic |
runner_reflexion | INSERT into reflexion_log (tags=item_record_review, run_id, narrative) | runner automatic (reflexion_enabled=1) |
log_run | {"name":"log_run","kind":"d1_write","table":"workflow_run_log","always":true} | declared in contract |
reflexion | {"name":"reflexion","kind":"reflexion_log","entity_type":"item","entity_id":"{{item_code}}","tags":"item_review,data_cleanup","observation":"{{rationale}}","outcome_from_status":true,"description":"Records that this item was reviewed and what changed — future runs see the history."} | declared in contract |
fire_event | {"name":"fire_event","kind":"event","event_type":"item.review_completed","entity_type":"item","entity_id":"{{item_code}}","always":true} | declared in contract |
workflow_verify_results (pending — verify cron not yet wired)ns_field_actually_updatednon_nullSELECT lastmodifieddate FROM items WHERE UPPER(itemid)=UPPER(?1) AND lastmodifieddate > ?2
pricing_master_still_valid0SELECT COUNT(*) AS broken FROM pricing_master WHERE UPPER(item_code)=UPPER(?1) AND status='active' AND case_price IS NULL
spec_sheet_present_if_changednon_nullSELECT spec_id FROM spec_items WHERE UPPER(item_code)=UPPER(?1) ORDER BY spec_version DESC LIMIT 1
2[300,1800]["ns_push_transient","cache_invalidate_partial"]| system | table / resource | action | status | source |
|---|---|---|---|---|
| D1 | proposed_actions | INSERT (action_type=item_field_update, entity_type=item) | REAL | fan-out #1 () |
| KV (CACHE) | item:{{item_code}} | invalidate | REAL | fan-out #2 () |
| KV (CACHE) | item_full:{{item_code}} | invalidate | REAL | fan-out #2 () |
| KV (CACHE) | ns:item:{{item_code}} | invalidate | REAL | fan-out #2 () |
| KV (CACHE) | pricing:{{item_code}}:* | invalidate | REAL | fan-out #3 () |
| D1 | workflow_run_log | INSERT (run summary) | REAL | runner automatic |
| D1 | reflexion_log | INSERT (tags=item_record_review) | REAL | runner automatic |
| Event | workflow.completed (or workflow.failed) | fire | REAL | runner automatic |
| D1 | workflow_verify_results | INSERT pending × 3 | REAL | runner verify staging |
| D1 | proposed_actions | INSERT (HITL gate envelope) | REAL | runner HITL gate |
| Chat tool | regenerate_spec_sheet | invoke (side_effects=unknown) | STUB | fan-out #4 () |
| D1 | assembly_cost_rollup | write | STUB | fan-out #5 () |
| D1 | flags / status field | set = | STUB | fan-out #6 () |
| D1 | proposed_actions | INSERT (email draft via propose_email_to_customer) | STUB | fan-out #7 () |