New customer onboard
New customer onboarding is the simpler sibling of new_assembly_item. The cascade is narrower but the duplicate check is critical — a duplicate customer creates two AR records, two pricing trees, and a downstream mess that takes hours to unwind.
The 10-step cascade culminates in a "first-quote-context bundle" — a pre-built reference dossier so when the customer's first quote drafts, the AI has the full context (terms, MDF tier, sales rep, expected SKU mix) already loaded.
Risk level 3 (medium). The block-severity duplicate check is the main guard.
Trigger conditions
- A sales intake form is submitted via /intake.html.
- A bid award arrives for a previously-unknown customer (bid_award_notification chains here).
- A K-12 district or NYC DOE feeder customer is added during bid prep.
- A wholesale account is added during M&A integration.
Duplicate check runs by name AND email — both lowercase-matched. Common false positives are franchise locations of the same parent (e.g. "Driscoll Foods" vs "Driscoll Foods - Bronx"); Mike confirms with the sales rep before overriding.
The 4 beats
-
01
Write customer record
INSERT into
customerswith company name, contact, billing/shipping addresses, terms, credit limit, and sales rep. -
02
NS customer record
Enqueue NS customer creation. The NS internal id back-fills into D1 when the push drains.
-
03
Assign default customer_programs
INSERT default
customer_programsrows: payment_terms=Net 30, default MDF tier, default rebate tier. These can be edited later via program-specific workflows. -
04
Welcome email draft
AI drafts a welcome email introducing GFS, listing the sales rep, and providing the first-quote-context. Mike approves before send.
What's different after the workflow runs
- A new customers row + NS internal id back-filled.
- Default customer_programs assigned.
- AR setup with credit limit + terms.
- Welcome email draft waiting for Mike.
- First-quote-context bundle pre-built so first quote drafts faster.
- reflexion_log carries a
new_customertagged row.
What can go wrong and how to recover
Precondition blocks. Mike confirms with sales: is this truly a new location? If yes, override with a tagged note. If no, redirect to customer_record_review for the existing record.
Precondition warns. Often a typo; sales fixes and re-stages.
Retry policy is 3 exponential attempts. D1 holds the proposed state; drainer recovers within 15 minutes.
When chained from bid_award_notification, the bid context auto-populates the first-quote-context bundle — saves Mike a few minutes.
Adjacent workflows + diagrams
Code paths + invariants
| Concern | Where |
|---|---|
| Workflow contract | workflow_definitions WHERE workflow_type='new_customer' |
| Duplicate check | name (lower) OR email (lower) |
| Default terms | Net 30 |
| NS RESTlet | customscript_gfs_platform_query |
| First-quote-context | pre-built dossier for first quote |
| Reflexion tag | new_customer |
| Risk level | 3 |
| Expected duration | ~20 min |
| Trigger | manual · sources=sales_intake_form |