GFS Platform

Process flows

Process flow charts

Process flows
12
Inline diagrams
9
Mermaid (clickable)
3
Archify diagrams
2
NS workflows
47
Suitelets
50

Reading these

Each flow has an inline SVG diagram (renders in any browser, no external dependencies) plus the Mermaid source if you want to render it elsewhere. Two flows have richer Archify diagrams linked inline.

Order-to-Cash (O2C)

Standard order lifecycle. Lead → quote → SO → production (WO + Assembly Build) → fulfillment → invoicing → payment. Credit memos branch from invoice.

LeadQSOWOABIFINVCPCredit Memo

Open interactive Archify diagram →

Mermaid source
flowchart LR L[Lead] --> Q[Quote] Q --> SO[Sales Order] SO --> WO[Work Order] WO --> AB[Assembly Build] AB --> IF[Fulfillment] IF --> INV[Invoice] INV --> CP[Payment] CP --> CM[Credit Memo]

Records / D1 tables: transactions, so_lines, invoice_lines, customers, items

Procure-to-Pay (P2P)

Procurement lifecycle. PR → PO → IR (3-way match input) → VB → VP / Check. 22,911 vendor bills in D1.

Purchase RequestPOIRVBVPCheck
Mermaid source
flowchart LR PR[Purchase Request] --> PO[Purchase Order] PO --> IR[Item Receipt] IR --> VB[Vendor Bill] VB --> VP[Vendor Payment] VP --> CHK[Check]

Records / D1 tables: transactions, vb_lines, vendors, items

Inventory & Work Orders

Production and warehouse. WO drives Assembly Build, which consumes raw items via IR and outputs finished goods.

Item ReceiptInv TransferWork OrderABInv WorksheetIADJUNBLD
Mermaid source
flowchart LR WO[Work Order] --> AB[Assembly Build] AB --> IADJ[Inv Adjustment] IT[Inv Transfer] --> WS[Inv Worksheet] IR[Item Receipt] --> AB AB --> UNBLD[Assembly Unbuild] UNBLD --> IADJ

Records / D1 tables: transactions, items, ref_location

Pricing Management

Customer-specific pricing flow. 1,264 customer_pricing rows in D1. Stale prices flagged via the 'Outdated Customer Pricing' saved search.

Prices Good Throu…Pricing RequestStale alertREVAPPCPSO pulls pricing
Mermaid source
flowchart LR REQ[Pricing Request] --> REV[Customer Pricing Review] REV --> APP[Approval] APP --> CP[customer_pricing update] CP --> SOP[SO pulls pricing] PGT[Prices Good Through] --> EXP[Stale alert]

Records / D1 tables: customer_pricing, customers, items

Collections & Dunning

Dual dunning: Customer-level + Invoice-level + Invoice Group-level. 18 workflows + 8 dunning email templates.

Group EvalOpen InvoiceAGEEVALPAEMClear after 7d
Mermaid source
flowchart LR INV[Open Invoice] --> AGE[Aging > threshold] AGE --> EVAL[Dunning Eval] EVAL --> PA[Procedure Assign] PA --> EM[Email Send] EM --> CLR[Clear after 7d] GRP[Group Eval] --> PA

Records / D1 tables: transactions (CustInvc), customers, dunningprocedure

Financial Close

Period close. All 154 periods (FY2018-FY2026) currently OPEN per audit — undermines comparative reporting. Tier 1 GAP.

Transactions all …POSTRECADJCLSFinancial Stateme…
Mermaid source
flowchart LR TX[Transactions all 20 types] --> POST[Post to Period] POST --> REC[Reconciliation] REC --> ADJ[Adjusting JEs] ADJ --> CLS[Close Period] CLS --> RPT[Financial Statements]

Records / D1 tables: transactions, gl_accounts, AccountingPeriod

NetSuite → D1 sync

Current sync path. Single-laptop dependency — #1 SPOF in the blueprint. Remediation: Worker scheduled() handler calling SuiteAPI directly.

NetSuite 4656898SAPICHRTSYNCWRGD1WKREST endpoints
Mermaid source
flowchart LR NS[NetSuite 4656898] --> SAPI[SuiteAPI 2948] SAPI --> CHRT[Chartstone Pro] CHRT --> SYNC[sync.sh every 15m] SYNC --> WRG[wrangler d1 execute] WRG --> D1[D1 transactions] D1 --> WK[Worker] WK --> API[REST endpoints]

Records / D1 tables: transactions, ref_*, sync_log

System architecture

Full architecture across NS, local sync layer, and Cloudflare. Interactive Archify version has dark/light toggle and PNG/SVG export.

KVNetSuitePagesR2SAPIUICHRTSYNCD1WKapi.ai-...

Open interactive Archify diagram →

Mermaid source
flowchart LR NS[NetSuite] --> SAPI[SuiteAPI] SAPI --> CHRT[Chartstone] CHRT --> SYNC[sync.sh] SYNC --> D1[D1] D1 --> WK[Worker] KV[KV] --> WK R2[R2] --> WK WK --> API[api.ai-...] PG[Pages] --> WEB[UI]

Records / D1 tables: all

Pricing pipeline (ADR-012)

Derive customer price lists from invoice history, review the three-bucket diff in the platform, approve, push back to NS. NS stays the system of record for live orders. AI flags anomalies and suggests smoothing — never auto-approves. Phase 1 done (derive + diff + audit endpoints). Phase 2-7 phased.

Workers AI reviewinvoice_lines 28KDERIVEPROPDIFFUIAPPRPUSHcustomer_pricing_…NS Item Pricing s…
Mermaid source
flowchart LR INV[invoice_lines 28K] --> DERIVE[derive job] DERIVE --> PROP[customer_pricing_proposed] PROP --> DIFF[3-bucket diff] DIFF --> UI[pricing.html review] UI --> APPR[approval] APPR --> PUSH[RESTlet push to NS] PUSH --> NSP[NS Item Pricing sublist] PUSH --> HIST[customer_pricing_history] AI[Workers AI review] --> UI

Records / D1 tables: invoice_lines, transactions, customer_pricing, customer_pricing_proposed, customer_pricing_history, pricing_anomalies

Intake Engine — email → review → resolve R45+ · live in code, awaits Email Routing activation

Inbound mail lands in one of 5 mailboxes, gets parsed by the Email Worker, archived to R2, converted to Markdown by the dual converter (unpdf + Workers AI vision), logged in inbound_email_log, then queued into review_queue for HITL approval. Council validation runs the proposed bid through Sonnet + Haiku + Llama with a chairman synthesis. On approval, bids + bid_lines + bid_pages auto-create and an outbound acknowledgement is queued through Email Sending. Every node below is clickable.

flowchart TD
  EMAIL["Customer Email"] --> MBX
  subgraph MBX["5 inbound mailboxes (CF Email Routing)"]
    BIDS["bids@"]
    PRICING["pricing@"]
    PRICEREQ["pricerequest@"]
    CUSTOMER["customer@"]
    VENDOR["vendor@"]
  end
  MBX --> WORKER["Email Worker · src/email.ts"]
  WORKER --> CONV["Dual Converter · unpdf + Workers AI vision"]
  CONV --> R2STORE["R2 attachment store · gfs-files/inbound-bids"]
  CONV --> LOG["inbound_email_log (D1)"]
  R2STORE --> LOG
  LOG --> REVIEW["review_queue"]
  REVIEW --> HITL["Council validation · Sonnet + Haiku + Llama → chairman"]
  HITL --> BID["bids + bid_lines + bid_pages"]
  BID --> OUTBOUND["outbound_email_log"]
  OUTBOUND --> TPL["6 email templates"]
  TPL --> SEND["CF Email Sending · ai-globalfoodsolutions.co"]

  click BIDS "/workflow/bid_intake" "Bid intake runbook"
  click PRICING "/workflow/bid_intake" "Pricing inbound runbook"
  click PRICEREQ "/workflow/bid_intake" "Price-request inbound runbook"
  click CUSTOMER "/workflow/bid_intake" "Customer inbound runbook"
  click VENDOR "/workflow/bid_intake" "Vendor inbound runbook"
  click WORKER "/workflow/bid_intake" "Email handler logic"
  click CONV "/api/intake/items" "Dual converter runs + drift"
  click R2STORE "/admin-dashboard.html" "R2 attachment storage (admin view)"
  click LOG "/admin-dashboard.html" "inbound_email_log (admin)"
  click REVIEW "/review.html" "HITL review queue UI"
  click HITL "/council.html" "Council audit dashboard"
  click BID "/bid/" "All bid pages"
  click OUTBOUND "/templates.html" "Outbound email log"
  click TPL "/templates.html" "Edit 6 email templates"
  click SEND "/admin-dashboard.html" "Email sending status"
  

Tables: inbound_email_log · review_queue · bids · bid_lines · bid_pages · outbound_email_log · email_templates · mailbox_routes

NetSuite ↔ D1 Sync Schedule R55–R58 live · 311,672 rows mirrored

14 NetSuite tables sync into D1 across 3 tiers via a custom RESTlet (customscript_gfs_platform_query, script 2950 deploy 1). OAuth1 TBA HMAC-SHA256 signing in the Worker. UPSERT on NS id (line items use delete_by_parent). Every node is clickable to the live data or runbook.

flowchart LR
  NS["NetSuite 4656898"] <--> RESTLET["Custom RESTlet · customscript_gfs_platform_query"]
  RESTLET <--> WORKER["Worker cron · OAuth1 TBA HMAC-SHA256"]
  WORKER --> HOT
  WORKER --> WARM
  WORKER --> COLD
  WORKER --> SYNCLOG["sync_log + /api/sync/health"]

  subgraph HOT["Hot · */5 min"]
    TXN["transactions · 102,433"]
    SOL["so_lines · 53,700"]
    INVL["invoice_lines · 52,445"]
    VBL["vb_lines · 58,321"]
    POL["po_lines · 33,733"]
    CPAY["customer_payments · 8,217"]
  end

  subgraph WARM["Warm · */15 min"]
    CUST["customers · 283"]
    VEND["vendors · 485"]
    ITEM["items · 1,265"]
    CONT["contacts · 490"]
  end

  subgraph COLD["Cold · */60 min"]
    GL["gl_accounts · 152"]
    EMP["employees · 117"]
    DEPT["departments · 14"]
    LOC["locations · 17"]
    SUB["subsidiaries · 1"]
  end

  click NS "/workflow/bid_intake" "NetSuite account 4656898"
  click RESTLET "/workflow/" "RESTlet runbook"
  click WORKER "https://gfs-platform.mikelevine.workers.dev" "Worker root"
  click SYNCLOG "/admin-dashboard.html" "Sync log + health (admin)"
  click TXN "/api/transactions?limit=5" "transactions data"
  click SOL "/api/transactions?type=SalesOrd&limit=5" "so_lines data"
  click INVL "/api/transactions?type=CustInvc&limit=5" "invoice_lines data"
  click VBL "/api/transactions?type=VendBill&limit=5" "vb_lines data"
  click POL "/api/transactions?type=PurchOrd&limit=5" "po_lines data"
  click CPAY "/api/transactions?type=CustPymt&limit=5" "customer_payments data"
  click CUST "/api/customers?limit=5" "customers data"
  click VEND "/api/vendors?limit=5" "vendors data"
  click ITEM "/api/items?limit=5" "items data"
  click CONT "/api/contacts?limit=5" "contacts data"
  click GL "/api/gl/accounts" "gl_accounts data"
  click EMP "/api/employees?limit=5" "employees data"
  click DEPT "/api/departments" "departments data"
  click LOC "/api/locations" "locations data"
  click SUB "/api/subsidiaries" "subsidiaries data"
  

14 tables · 311,672 rows · 5/15/60-min cadence · OAuth1 TBA signed · INSERT OR REPLACE on NS id

Platform Topology — NetSuite × Cloudflare live

Full topology across NetSuite (source of truth) and Cloudflare (intelligence layer). Worker has 14 bindings, 12 cron triggers, 175+ endpoints. Pages serves 17 static surfaces + 7 dynamic functions. Email Routing/Sending wired in code awaiting user dashboard activation. Every node clickable to live URL, data endpoint, or runbook.

flowchart LR
  subgraph NS_SIDE["NetSuite · account 4656898"]
    NSACC["NS Account 4656898"]
    INTEG["Integration · GFS Platform Cloudflare (OAuth1 TBA)"]
    ATOK["Access Token · ConnectAdmin v3 AI / Mike Bot"]
    RESTLET["RESTlet customscript_gfs_platform_query (script 2950)"]
    NSACC --> INTEG --> ATOK --> RESTLET
  end

  RESTLET <--> WORKER

  subgraph CF["Cloudflare · gfs-platform.mikelevine.workers.dev"]
    WORKER["Worker · 175+ endpoints · 12 crons"]
    EMAIL_IN["email() handler · inbound (5 mailboxes)"]
    EMAIL_OUT["EMAIL binding · send_email"]
    WORKER --- EMAIL_IN
    WORKER --- EMAIL_OUT
  end

  subgraph STORAGE["Cloudflare data plane"]
    D1["D1 gfs-netsuite · 95 tables · 13 views · 311K rows"]
    R2["R2 gfs-files · code backups · source docs · spec PDFs · quotes"]
    KV["KV CACHE · rate limiters · cron locks · top-50 cache"]
    VEC["Vectorize gfs-pricing-corpus · 4,357 vec · 8 ns"]
    QUEUE["NS_PUSH_QUEUE + DLQ"]
    DO["Durable Objects · CostCapDO · PushMutexDO"]
    WF["Workflows · AnnualRollWorkflow"]
    BROWSER["Browser Rendering"]
    AI["Workers AI · Llama 3.3 70B"]
  end

  WORKER --> D1
  WORKER --> R2
  WORKER --> KV
  WORKER --> VEC
  WORKER --> QUEUE
  WORKER --> DO
  WORKER --> WF
  WORKER --> BROWSER
  WORKER --> AI
  QUEUE --> RESTLET

  subgraph PAGES["Pages · gfs-netsuite.pages.dev"]
    STATIC["17 static HTML · chat · review · training · intake · admin · ..."]
    PFN["7 Pages Functions · /api proxy · /pricing · /vendor · /item · /bid · /workflow"]
  end

  STATIC --> PFN
  PFN --> WORKER

  subgraph EMAIL["Cloudflare Email"]
    ROUTING["Email Routing · 5 mailboxes (pending user activation)"]
    SENDING["Email Sending · ai-globalfoodsolutions.co (pending DNS verify)"]
  end

  ROUTING --> EMAIL_IN
  EMAIL_OUT --> SENDING

  click NSACC "/workflow/bid_intake" "NetSuite account 4656898"
  click INTEG "/workflow/" "Integration runbook"
  click ATOK "/workflow/" "Access Token runbook"
  click RESTLET "/workflow/" "RESTlet runbook"
  click WORKER "https://gfs-platform.mikelevine.workers.dev" "Worker root"
  click EMAIL_IN "/workflow/bid_intake" "Inbound email handler"
  click EMAIL_OUT "/templates.html" "Outbound email templates"
  click D1 "/api/customers?limit=5" "D1 sample (customers)"
  click R2 "/admin-dashboard.html" "R2 backups"
  click KV "/api/cache/stats" "KV cache stats"
  click VEC "/admin-dashboard.html" "Vectorize index"
  click QUEUE "/api/ns-push-queue/dlq" "Queue + DLQ"
  click DO "/admin-dashboard.html" "Durable Object state"
  click WF "/workflow/annual_roll" "Annual roll workflow"
  click BROWSER "/admin-dashboard.html" "Browser binding"
  click AI "/council.html" "AI / Council audit"
  click STATIC "/admin-dashboard.html" "Static pages"
  click PFN "/workflow/" "Workflow pages"
  click ROUTING "/intake.html" "Inbound mailbox dashboard"
  click SENDING "/templates.html" "Outbound templates"
  

Worker bindings: DB · STORAGE · CACHE · AI · BROWSER · VECTORIZE · NS_PUSH_QUEUE · NS_PUSH_DLQ · COST_CAP_DO · PUSH_MUTEX_DO · ANNUAL_ROLL_WORKFLOW · EMAIL · email() inbound

Related surfaces