Customer entity lifecycle — Driscoll's journey end-to-end Customer lifecycleend-to-end

6 phases · 16 nodes · tables written highlighted per phase

A customer's full journey through the system, end-to-end. Phase 1 onboard creates the NS record + program. Phase 2 order intake handles both email and NS-native flows. Phase 3 fulfillment + invoice. Phase 4 payment + AR aging buckets. Phase 5 health-score computation + reactive workflows (ar_aging_action_plan on red tier, customer_invoice_dispute on credit memo). Phase 6 reflexion captures every workflow's observations into a status-curated log keyed by customer.

0 · Visual flow 6 lanes · 16 nodes

System flow
01 / Onboard 02 / Order intake 03 / Fulfillment + invoice 04 / Payment + AR aging 05 / Health + reactive workflows 06 / Reflexion (every interaction) Customer record created in NetSuite via UI or via /api/proposed-actions chat tool (propose_create_customer). On NS-side creation, SystemNote CDC fires the /api/ns-webhook and syncs the row into D1 customers. ONBOARD: customer record primary_source: NetSuite UI D1_mirror: customers trigger: SystemNote CDC + /api/ns-webhook AI_assist: propose_create_customer chat tool i NS customer record created in NS tables written: customers · name_synonyms · customer_program Maps partial names ('Driscoll', 'Driscoll Foods') to canonical NS customer_id. Mike maintains synonyms; brand-prefix groups (Melt Mates, Right Start) also live here (R115). ONBOARD: name_synonyms table: name_synonyms source: data/name_synonyms.json (Mike-curated) used_by: auto_context entity extraction i name_synonyms map partial→full aliases tables written: customers · name_synonyms · customer_program Each customer gets one customer_program row defining pricing rules (markup, freight terms, payment terms, USDA eligibility). New customers default to 'standard' until Mike configures. ONBOARD: customer_program table: customer_program default: 'standard' program config: markup_pct, freight_terms, payment_terms_days, usda_eligible i customer_program seeded pricing program tables written: customers · name_synonyms · customer_program Customer emails a PO/order to bids@ or customer@. Email landed in R2, parsed via PDF vision, extracted lines proposed in inbound_email_log + review_items. Mike approves → SO created in NS. ORDER: email intake surface: email flow: R2 raw → parse → review_items → HITL → SO table: inbound_email_log i Inbound email order orders@ → inbound_email_log PDF vision parse → SO proposal Customer rep creates SO directly in NS. SystemNote CDC fires webhook, D1 transactions + transaction_lines mirrored. ORDER: NS-native surface: NetSuite UI D1_mirror: transactions, transaction_lines trigger: SystemNote CDC i NS-native order SO created directly in NS CDC → D1 transactions/transaction_lines On SO create, workflow contracts fire: customer_quote_review checks pricing vs customer_program; new_assembly_item runs if any line uses an assembly we haven't priced before. ORDER: workflows contracts: customer_quote_review, new_assembly_item inputs: pricing_master, spec_items, customer_program i price_check + spec_check workflows fire on SO create pricing_master + spec_items consulted Item fulfillment created in NS when warehouse ships. D1 mirror item_fulfillment + item_fulfillment_lines. FULFILL: IF D1: item_fulfillment trigger: NS-native or NS_PUSH_QUEUE i item fulfillment IF created Shipment record links the IF to a tracking number + carrier. shipping_events captures status updates. FULFILL: shipment D1: shipments, shipping_events i shipment tracking + carrier Invoice (CustInvc) issued on shipment. D1 customer_invoice + customer_invoice_lines. FULFILL: invoice D1: customer_invoice, customer_invoice_lines amount_due: tracked in v_customer_ar_aging i customer invoice CustInvc Customer payment received. D1 customer_payment + payment_application linking the payment to one or more invoices. PAYMENT: customer_payment D1: customer_payment, payment_application i customer_payment CustPymt row Computed view: outstanding invoices bucketed by aging (current, 1-30, 31-60, 61-90, 90+). Refreshed each cron tick. AR: aging view view: v_customer_ar_aging refresh: cron (warm tier 15m) drives: customer_health_scores i v_customer_ar_aging bucket view When an invoice transitions from current → 1-30 → 31-60, an event is fired and reactive workflows pick it up. AR: bucket transitions events: ar.bucket_changed consumed_by: ar_aging_action_plan workflow i bucket transitions aging row movement R558 leading-indicator score 0-100 + tier band (green/yellow/orange/red). Recomputed nightly via 6 signals (AR aging, dispute count, payment lateness trend, order frequency drop, credit memo count, contact churn). HEALTH: health_scores table: customer_health_scores signals: 6 cron: nightly tiers: green (80+), yellow (60-79), orange (40-59), red (<40) i customer_health_scores leading-indicator scoring Triggered when customer crosses to 61-90 or red tier. Drafts collection email, stages call task, optional service hold. Risk 3 — HITL gated. REACTIVE: ar_aging_action_plan trigger: tier=red OR bucket>=61 risk: 3 (HITL) fan_out: 3 i ar_aging_action_plan workflow on red tier Triggered when a credit memo posts against an invoice. Logs dispute reason, links to invoice, drafts customer email confirming resolution. REACTIVE: invoice_dispute trigger: CreditMemo posted risk: 3 fan_out: 2 i customer_invoice_dispute on credit memo Every workflow execution that touches this customer writes a row to reflexion_log with entity_type='customer', entity_id=<NS customer id>, tags=[workflow_name], status='needs_review'. Mike triages; approved rows feed future retrieval (decision_corpus + few-shot). REFLEXION: customer table: reflexion_log filter: entity_type='customer' written_by: all workflows with reflexion_enabled=1 curation: needs_review → approved_for_reuse | rejected | expired i reflexion_log (entity_type='customer') every workflow run touching this customer appends an observation row

1 · What this is

goal
A customer's full journey through the platform end-to-end. Walk through 'a day in the life' of Driscoll Foods.
layout
horizontal swimlanes left→right per phase
phases
6 phases · 16 nodes
example_entity
Driscoll Foods (36.4% of cumulative revenue per reference_gfs_business_data.md)

2 · Tables written per phase

PhaseD1 tablesNS records
Onboardcustomers, name_synonyms, customer_programcustomer
Order intakeinbound_email_log, review_items, transactions, transaction_linessalesorder
Fulfillmentitem_fulfillment, item_fulfillment_lines, shipments, shipping_eventsitemfulfillment
Invoicecustomer_invoice, customer_invoice_linescustinvc
Paymentcustomer_payment, payment_applicationcustpymt
AR agingv_customer_ar_aging (view)(computed)
Healthcustomer_health_scores(D1-only)
Reactiveworkflow_run_log, proposed_actions(N/A — staged for HITL)
Reflexionreflexion_log (entity_type='customer')(D1-only)

3 · How to read it

ColorMeaning
frontendUser-facing surface (chat UI, admin HTML pages)
backendWorker logic / agent code / business rules
databaseD1 table / R2 object / KV key / Vectorize index
cloudExternal system (NetSuite, Anthropic, etc.)
securityGate / policy / HITL approval / kill switch
messagebusEvent ledger, Queues, async fan-out
externalInbound source (email, webhook, cron tick, user input)
→ solidSynchronous call (request → response)
→ greenApproved / happy-path
→ red dashedPolicy or security check
→ grey dashedOptional / conditional / async