Wiki · NS freight routing check R594

12-section R586 wiki · workflow contract: freight_routing_check · risk 2 · owner: logistics + sales/purchasing

The check that fires when a SO or PO has freight relevance, classifies the freight type, and routes the record into the logistics review queue. Without this gate, freight would silently fall through and the logistics team wouldn't know to plan it.

01 · Hero

Freight is the moment GFS hands physical goods to a carrier. When a SO is fulfilled by inventory or assembly, when a PO arrives at a dock, when a dropship vendor ships direct to the customer — freight has to be planned, carrier picked, BOL generated, tracking captured. This check is the dispatcher: it decides whether freight needs human routing (parcel-with-handling, LTL, FTL, dropship vendor freight, freight collect) or can be auto-handled (standard parcel, customer pickup, freight already arranged). When human routing is needed, the record lands on the logistics review queue.

02 · What this is

A v2 workflow contract that fires on:

It does NOT fire on: SOs marked customer pickup, POs where vendor pays freight, parcel orders < threshold, or records already past Item Fulfillment / Item Receipt.

03 · When it fires

TriggerSourceCondition
SO enteredNS SuiteFlow on SO saveshipmethod IS NOT NULL AND shipmethod != 'pickup' AND freight_status IS NULL
PO createdNS SuiteFlow on PO saveshipmethod IS NOT NULL AND PO is dropship OR vendor-freight-prepay-collect AND freight_status IS NULL
Manual triggerLogistics team button"Re-check freight" on any source record to re-run classification

04 · Step-by-step

  1. classify_freight_type — LTL / FTL / parcel / dropship_vendor_freight / customer_pickup / freight_collect. Based on weight, volume, dollar value, ship method on the record.
  2. assess_special_handling — refrigerated / frozen / hazmat / oversize / fragile. Based on item attributes.
  3. estimate_freight_cost — pull from carrier rate cards if integrated, else flag for manual quote. Lane history is consulted.
  4. flag_for_logistics_review — stages a proposed_actions row, HITL-gated per ADR-031.
  5. notify_logistics — email draft to logistics team with classification summary + estimated cost.
  6. update_so_or_po — D1 write: freight_status = 'pending_logistics_review'. NS push when approved.

05 · Outcomes

06 · Failure modes

ModeSymptomRecovery
Missing ship addressPrecondition fails, record HOLDS, owner gets emailOwner adds address, re-trigger
Classification ambiguousTwo classifications tie (e.g. could be LTL or FTL)Logistics team picks in stage 02 of logistics workflow
No rate card for laneestimate_freight_cost returns nullStage manual_quote HITL, logistics gets RFQ
Hazmat without permitItem flagged hazmat but no GFS hazmat carrier on fileHold + escalate to compliance

07 · Related

NextNS logistics review flow (what happens after this check) UpstreamNS sales order master (fires after SO entry) UpstreamNS purchase order master (fires on dropship PO) SystemSO+PO+WO integration view

08 · For developers

workflow_type: freight_routing_check
risk_level: 2
trigger: SuiteFlow on SO/PO save (conditional)
inputs_required:
  source_record_type: ['so', 'po']
  source_record_id: number
  ship_method: string | null
  ship_carrier: string | null
  shipping_cost: number | null
  total_weight: number | null
  total_volume: number | null
  ship_address: object
context_to_load:
  - customer_or_vendor_address
  - line_items (with shipping_cost)
  - special_handling_flags
preconditions:
  - source_record_exists
  - ship_address_valid
  - freight_relevance_check (block if no shipping_cost AND no ship_method)
fan_out_targets:
  - classify_freight_type (chat_tool)
  - assess_special_handling (chat_tool)
  - estimate_freight_cost (chat_tool)
  - flag_for_logistics_review (stage_proposed_action)
  - notify_logistics (hitl_email_draft)
  - update_so_or_po (d1_write)
post_actions:
  - log_run
  - reflexion
  - event(workflow.completed, 'freight_routing_check')
verify_checks:
  - logistics_review_completed (+24h)
  - freight_cost_finalized (+48h)

09 · Changelog

DateRoundChangeBy
2026-05-26R594Built freight-routing-check + logistics-review-flow workflows. NS custom field names (custbody_freight_status, custbody_freight_classification) flagged TBD pending Mike review.Mike + Claude

10 · Schema (PO# threading)

RecordCustomer PO# fieldCarries through to
SObodyFields.otherrefnumBOL.shipper_ref · logistics queue entry · Invoice.otherrefnum
PO (SO-connected)bodyFields.memo + lineFields.links[].tranidBOL when dropship · VendBill.memo
PO (inventory)internal req# in bodyFields.memo — does NOT carry customer PO#VendBill.memo (internal ref only)
Logistics queuesource_po_or_otherrefnum (mirrored from source record)BOL · tracking · POD
NS custom fields TBDcustbody_freight_status · custbody_freight_classificationPending Mike confirmation

11 · Runbook

Apply migration:

npx wrangler d1 execute gfs-netsuite --remote --file migrations/schema/134_freight_logistics_workflows.sql

Verify contracts:

npx wrangler d1 execute gfs-netsuite --remote --command "SELECT workflow_type, description, risk_level FROM workflow_definitions WHERE workflow_type LIKE 'freight%' OR workflow_type LIKE 'logistics%';"

Manual trigger (test):

POST /api/workflow/run
{ "workflow_type": "freight_routing_check", "inputs": { "source_record_type": "so", "source_record_id": 12345 } }

12 · Backlog