Mike drafts a customer quote via chat. Cascade: NS quote record, proposed_pricing → pricing_master, customer email draft (HITL), AR/credit forecast update, quote PDF generation + R2 store.
hitl_approval"proposed_actions approved with action_type=quote_draft"| name | required | type / hint |
|---|---|---|
customer_id | required | — |
item_codes[] | required | — |
school_year | required | — |
quote_id | optional | — |
catalog | optional | — |
include_pdf | optional | — |
customercustomersSELECT * FROM customers WHERE id=?
customer_programscustomer_programsSELECT * FROM customer_programs WHERE customer_id=? AND status='active' AND deleted_at IS NULL
current_pricingpricing_masterSELECT item_code, case_price, cost_basis, margin_pct FROM pricing_master WHERE customer_id=? AND item_code IN (?) AND school_year=?
open_quotesquotesSELECT
id, generated_at
FROM quotes
WHERE customer_id=?
AND lifecycle_status IN ('draft','proposed','sent')
ORDER BY generated_at DESC
LIMIT 3| check | rule | severity |
|---|---|---|
customer_exists | customer.id IS NOT NULL | block |
items_resolved | all item_codes match spec_items.item_code | warn |
customer_not_on_hold | customer.entitystatus != 'hold' | block |
margin_floor | all line.margin_pct >= 15 | 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_customer_quote (proposal envelope)workflow:customer_quote:run_<run_id>write_quote d1_write STUB["INSERT quotes","INSERT quote_lines (batch)"]src/lib/workflow_runner.ts (kind d1_write hits the placeholder branch at line ~340 and emits step status 'stub'). Documented intent only.render_pdf http_call STUB/api/quote/pdf["R2 artifact at quotes/{id}.pdf"]include_pdfsrc/lib/workflow_runner.ts (kind http_call hits the placeholder branch at line ~340 and emits step status 'stub'). Documented intent only.send_email hitl_email_draft STUBsend_quote_to_customersrc/lib/workflow_runner.ts (kind hitl_email_draft hits the placeholder branch at line ~340 and emits step status 'stub'). Documented intent only.ns_push ns_push STUBestimateNS_PUSH_QUEUEquote_with_linesretry_3_then_alertsrc/lib/workflow_runner.ts (kind ns_push hits the placeholder branch at line ~340 and emits step status 'stub'). Documented intent only.ar_forecast_touch d1_write STUB["UPDATE customer_profiles SET last_quote_event=now WHERE customer_id=?"]src/lib/workflow_runner.ts (kind d1_write 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=customer_quote, run_id, narrative) | runner automatic (reflexion_enabled=1) |
log_run | INSERT workflow_runs | declared in contract |
reflexion | INSERT reflexion_log with tags=quote,customer:?,school_year:? | declared in contract |
workflow_verify_results (pending — verify cron not yet wired)quote_persistedSELECT id, lifecycle_status FROM quotes WHERE id=?
pdf_storedemail_sentSELECT id FROM outbound_email_log WHERE related_quote_id=? ORDER BY sent_at DESC LIMIT 1
3exponential150030000true| system | table / resource | action | status | source |
|---|---|---|---|---|
| D1 | workflow_run_log | INSERT (run summary) | REAL | runner automatic |
| D1 | reflexion_log | INSERT (tags=customer_quote) | 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 |
| D1 | unknown | write | STUB | fan-out #1 (write_quote) |
| Worker HTTP | POST /api/quote/pdf | invoke | STUB | fan-out #2 (render_pdf) |
| D1 | proposed_actions | INSERT (email draft via send_quote_to_customer) | STUB | fan-out #3 (send_email) |
| NetSuite (via NS_PUSH_QUEUE) | estimate | push | STUB | fan-out #4 (ns_push) |
| D1 | unknown | write | STUB | fan-out #5 (ar_forecast_touch) |