New ingredient / vendor onboard
New vendor onboarding is the lighter sibling of new_customer. The cascade covers vendor master data, baseline vendor_costs for initial items, NS vendor record, and a sourcing analysis pass that surfaces existing items the new vendor could supply (often the reason for the onboard in the first place).
Critical block: the no-duplicate precondition. Duplicate vendors are even worse than duplicate customers — they fragment cost history and break weighted-average computations.
Risk level 3 (medium).
Trigger conditions
- A vendor intake form is submitted from /intake.html.
- A first PO is drafted for a vendor not yet in the system.
- A vendor cost update arrives by email from an unknown vendor (chains via inbound_email_triage).
- A new commodity supplier is added (USDA program expansion).
Vendor duplicate check uses name OR email — same logic as new_customer. A common pattern: subsidiary of an existing parent vendor. Mike confirms with the buyer before overriding.
The 2 beats
-
01
Write vendor + vendor_items
INSERT into
vendorsfor the new entity. Batch INSERT intovendor_itemsfor the initial item mappings (vendor_item_code → internal item). -
02
NS vendor record
Enqueue NS vendor creation via
customscript_gfs_platform_queryRESTlet. NS internal id back-fills on drain.
What's different after the workflow runs
- A new vendors row with NS internal id back-fill.
- vendor_items rows for the initial product mapping.
- Baseline vendor_costs ready for the first PO.
- Sourcing analysis surfaces existing items that could use this vendor.
- AP setup with payment terms.
- reflexion_log carries a
new_vendortagged row.
What can go wrong and how to recover
Precondition blocks. Mike confirms: is this a subsidiary? If yes, override + tag. Often the right answer is to use the parent vendor record and add this as a new vendor_items mapping.
Vendor is created but vendor_items is empty. The first PO will need to link items manually. Often happens for service vendors.
Retry policy is 3 exponential attempts. Drainer recovers within 15 minutes.
Per the R115 brain dump, several entities are both (Bongards, Echo Lake Foods). The customer + vendor records exist separately; they don't conflict.
Adjacent workflows + diagrams
Code paths + invariants
| Concern | Where |
|---|---|
| Workflow contract | workflow_definitions WHERE workflow_type='new_ingredient_vendor_onboard' |
| Duplicate check | name (lower) OR email (lower) |
| Customer-vendor overlap | see feedback_customer_vendor_overlap memory |
| NS RESTlet | customscript_gfs_platform_query |
| Reflexion tag | new_vendor |
| Risk level | 3 |
| Expected duration | ~30 min |
| Trigger | manual · sources=vendor_intake_form |
Dated trail · spot stale claims
Dated trail of when this doc was last touched, what changed, and what to look at if it feels stale.
| Date | Round | Change | Touched by |
|---|---|---|---|
2026-05-26 | R586 | Added CHANGELOG · SCHEMA · RUNBOOK · BACKLOG sections — wiki became best-in-class operating documentation. | Mike + Claude |
2026-05-25 | R584/R585 | Wiki originally shipped — 8-section structure (hero / what / when / steps / outcomes / failure-modes / related / for-developers). | Mike + Claude |
workflow_definitions WHERE workflow_type='new_ingredient_vendor_onboard' before acting on these claims.The machine-readable spec
Canonical fields, table names, endpoint signatures. What code should match, what tests should assert. workflow_type · new_ingredient_vendor_onboard · risk_level · 3.
Inputs (required + optional)
| Field | Type | Description |
|---|---|---|
vendor_name | string | Legal name. Required. |
contact_email | string | Primary contact. |
category | string | 'protein' | 'grain' | 'produce' | 'dairy' | 'other' |
certifications | json? | Array of cert names + expiry. |
initial_items | json? | Items the vendor will supply. |
D1 tables written
| Table | Operation | Trigger |
|---|---|---|
proposed_actions | INSERT | Vendor creation proposal |
vendors | INSERT (post-HITL) | D1 mirror |
vendor_certifications | INSERT | Per-cert rows |
ns_pending_pushes | INSERT | NS vendor creation |
Endpoints called
| Method | Path | Purpose |
|---|---|---|
POST | /api/workflow/execute | Runner entrypoint |
POST | /api/proposed-actions/:id/decide | HITL approval |
Events fired
| event_type | When | Subscribers |
|---|---|---|
vendor.onboarded | Post-HITL + NS push | compliance + AP setup |
It broke at 2am — what now
Different from "how do I use this." This is the page Mike pulls up when something is wrong: logs to check, recovery steps, who to escalate to.
Scenario · Vendor onboarded but no certifications recorded
vendor_certifications writes are conditional on input.
- Add manually:
INSERT INTO vendor_certifications (vendor_id, cert_name, expires_at) VALUES (...) - Reminder: Set a calendar reminder for cert expiry.
Scenario · Vendor created in NS but not in D1
NS push went through but the post-NS d1_write didn't reflect.
- Force sync:
POST /api/sync/run?tier=hot&table=vendors - Verify ID linkage:
SELECT id, ns_internal_id FROM vendors WHERE name LIKE '%<name>%'
Scenario · Certification expiry not surfacing
No reminder workflow today.
- Manual check:
SELECT vendor_id, cert_name, expires_at FROM vendor_certifications WHERE expires_at < date('now','+60 days') - Reach out: Email vendor to refresh cert.
Logs to check
workflow_run_log· top-level run auditworkflow_step_log· per-step traceworkflow_verify_results· post-window verify outcomescron_locks· stuck cron lock detectionevents· workflow.completed / workflow.failed event trailreflexion_log· per-run narrative (if reflexion_enabled)npx wrangler tail· live Worker logs
Kill switch · emergency stop
If this workflow is misbehaving in a high-impact way (creating bad proposed_actions in volume, pushing wrong things to NS), flip a kill switch:
kill:ns_writes· stops every NS push platform-widekill:proposed_apply· stops HITL approvals from executing fan-outkill:high_risk_ops· stops risk_level >= 4 fan-out
See kill-switches-state-machine.html for the full state machine + recovery procedure.
Escalation
Primary: Mike Levine (single-admin) · mikelevine@globalfoodsolutions.co. For prolonged outage during business hours, notify warehouse lead + accounting lead so they can defer dependent work.
What's not done · what's uncertain
What's not done, what's uncertain, what we punted. Captured so it survives context switches and doesn't die in someone's head.
-
STUB
Auto-reminder 60 days before cert expiry
Today manual.
-
OPEN
Vendor risk scoring
Health-score equivalent for vendors. Today nothing.
-
DEFER
Vendor-portal self-service onboarding
Today Mike enters everything. Could be a form vendor fills.