System architecture — post-R524 file split

Cloudflare Workers + D1 + R2 + KV + Vectorize + Queues + Workflows + Durable Objects + Email + Browser Rendering · 4 layers

This replaces the stale pre-R524 monolithic system-architecture.html. R524 split src/index.ts from a ~41K-line monolith into a 12-module structure while keeping the entrypoint single-file. tsc baseline is 0 errors as of R526. The platform runs entirely on Cloudflare — no AWS/GCP — with NetSuite as the system of record reached via TBA OAuth1 + a custom RESTlet.

post-R524 162 D1 tables tsc 0 errors Single tenant

Architecture — 4 layers

System architecture post-R524 — Edge → Worker (12 modules) → CF Bindings → Data tier + External (NetSuite, Dropbox, Council LLMs) Layer 1 / Edge Layer 2 / Worker module structure (src/) Layer 3 / Cloudflare bindings Layer 4 / Data tier + External CF Pages admin HTML (20+ pages) chat · admin-dashboard · cost-ingestion FRONTEND · gfs-netsuite.pages.dev CF Workers api.ai-globalfoodsolutions.co fetch · scheduled · queue · email CLOUD · 175+ endpoints Pages Functions live entity render (no cache) /pricing/ · /vendor/ · /item/ · /bid/ FRONTEND · functions/ Custom domains chat.ai-globalfoodsolutions.co gfs-system-guide · gfs-nycdoe-hub CLOUD · CF Access JWT src/index.ts ~33K lines · entrypoint fetch · scheduled · queue HTTP routes · sync engine workflow tool impls BACKEND · syncTable() · syncLineTable() · handleSyncTier() src/chat_tools/impls.ts ~6.7K · executeChatTool branches 175+ tools src/chat_tools/prompt.ts ~230 · CHAT_TOOLS_FOR_PROMPT src/sync_table_map.ts ~790 · SYNC_TABLE_MAP · 3 tiers src/lib/auto_context.ts ~715 · entity extraction customer/vendor/item context src/lib/ns.ts (~100) TBA OAuth1 · ns_suiteql src/lib/recall.ts (~140) prior-context recall lib/guardrail · escape · role_context src/email.ts 5 mailboxes · inbound triage src/document_converter.ts PDF/DOCX/XLSX → Markdown src/annual_roll_workflow.ts CF Workflow class · pillar 4 src/durable_objects.ts CostCapDO + PushMutexDO R524 import-cycle fix: chat_tools/impls.ts imports value from '../lib' & '../sync_table_map' only `import type {Env}` remains from '../index' (compile-only, runtime-safe) src/lib/{workflow_runner, events, customer_health, sql_helpers} — substrate (R549–R562) DB (D1) 162 tables DATABASE STORAGE (R2) PDFs · specs · backups DATABASE CACHE (KV) caches · locks · kill-switches DATABASE VECTORIZE 3360 + corpora chunks DATABASE · 4 indexes AI Workers AI · Llama 3.3 CLOUD NS_PUSH_QUEUE + NS_PUSH_DLQ MESSAGEBUS · CF Queue BROWSER Browser Rendering API CLOUD · PDF render EMAIL routing 5 inbound mailboxes CLOUD · CF Email COST_CAP_DO CostCapDO · daily AI spend cap BACKEND · Durable Object PUSH_MUTEX_DO PushMutexDO · single-drain BACKEND · Durable Object ANNUAL_ROLL_WORKFLOW CF Workflow · 11 steps · waitForEvent CLOUD · pillar 4 July 1 31 cron triggers · 11 cadence bands · R121 hot/warm/cold tiered sync */2 hot · */5 warm · */15 verify · 0 * cold · weekly + monthly maintenance MESSAGEBUS · see cron-schedule.html D1 162 tables · 311K+ rows 14+ NS mirror tables (live) customer · vendor · transactions item · so_lines · po_lines · CustInvc + derived: pricing_master · spec_items + substrate: proposed_actions · events + telemetry: tool_invocations · audit_log DATABASE · 60+ migrations tiered sync: hot/warm/cold R2 STORAGE spec sheets (PDF) attachments + intake docs bid packets D1 backups (weekly) analytics CSV exports DATABASE · BUCKET=STORAGE KV CACHE query cache drift detection state kill switches session locks rate-limit counters DATABASE · CACHE binding VECTORIZE ns_knowledge · 3360 chunks decision_corpus bid corpus (B5875) entity_notes few-shot retrieval DATABASE · 4 indexes NetSuite (SoR) TBA OAuth1 customscript_gfs_platform_query EXTERNAL · system of record Dropbox · source docs EXTERNAL Council v2 LLMs EXTERNAL · Claude + Kimi + Llama

Worker module structure — post-R524

fileLOC (approx)responsibility
src/index.ts~33,000fetch/scheduled/queue/email entrypoints, HTTP routes, sync engine (syncTable, syncLineTable, handleSyncTier), workflow tool impls
src/chat_tools/impls.ts~6,700all executeChatTool branches — 175+ tools
src/chat_tools/prompt.ts~230CHAT_TOOLS_FOR_PROMPT catalog + filterToolsForRole + GFS_OPERATIONAL_CONTEXT
src/chat_tools/index.tsbarrelmodule re-exports
src/sync_table_map.ts~790SYNC_TIERS, SyncTableSpec, SYNC_TABLE_MAP — canonical mirror config
src/lib/auto_context.ts~715customer/vendor/item auto-context generators, entity extraction
src/lib/ns.ts~100NS RESTlet OAuth1 + ns_suiteql
src/lib/recall.ts~140prior-context recall
src/lib/guardrail.ts~50guardrail logging
src/lib/escape.ts~10SQL escape helpers
src/lib/role_context.ts~20role types
src/lib/workflow_runner.ts~400 (substrate)executeWorkflowContract — the runner for 22 workflow contracts (R549)
src/lib/events.ts~280 (substrate)event ledger + CDC subscriptions (R553/R560)
src/lib/customer_health.ts~360 (substrate)6 leading-indicator signals + composite (R557/R558/R561)
src/lib/sql_helpers.ts~120shared SQL helpers (date normalize, existence guards)
src/lib/index.tsbarrelmodule re-exports
src/email.ts~600inbound email pipeline (5 mailboxes)
src/document_converter.ts~500PDF/DOCX/XLSX → Markdown
src/annual_roll_workflow.ts~400Pillar 4 annual price roll — CF Workflow class with step.do + step.sleep + step.waitForEvent
src/durable_objects.ts~200CostCapDO + PushMutexDO

tsc baseline: 0 errors (R526) · was 125 pre-R525. Import cycle: closed in R524 — chat_tools/impls.ts only imports type Env from ../index; all value imports go through ../lib + ../sync_table_map.

Cloudflare bindings — canonical names from wrangler.jsonc

bindingkindpurpose
DBD1canonical data store · 162 tables
STORAGER2 bucketPDFs, attachments, backups
CACHEKV namespacequery cache, locks, kill switches
VECTORIZEVectorize4 indexes: ns_knowledge, decision_corpus, bid_corpus, entity_notes
AIWorkers AILlama 3.3 inference + embeddings
NS_PUSH_QUEUECF QueueNetSuite write queue
NS_PUSH_DLQCF Queuedead-letter queue (3rd retry)
COST_CAP_DODurable Objectdaily AI spend cap enforcement
PUSH_MUTEX_DODurable Objectsingle-drainer mutex for ns_pending_pushes
ANNUAL_ROLL_WORKFLOWCF Workflowpillar 4 annual price roll · July 1 SY cutover
EMAILEmail Routing5 inbound mailboxes
BROWSERBrowser RenderingPDF render for spec sheets + quotes

External integrations

externalprotocolpurpose
NetSuiteTBA OAuth1system of record · customscript_gfs_platform_query RESTlet for writes; SuiteQL for reads
DropboxHTTPSsource documents (specs, price quotes, bid PDFs) · manual + scheduled pull
CF Email RoutingSMTP5 inbound mailboxes: pricerequest@ · spec@ · bid@ · ar@ · ops@ (per src/email.ts)
Council v2 LLMsHTTPS APIClaude (Anthropic) + Kimi (Moonshot) + Workers AI Llama 3.3 · 3-model parallel + anonymized peer review

Key invariants — from CLAUDE.md

  1. Council v2 default chat mode — 3 models parallel + anonymized peer review + chairman synthesis (~$0.007/query).
  2. All write endpoints take ?preview=true|confirm=true — preview shows dependency cone; confirm requires X-Edit-Token.
  3. D1 is canonical store; NetSuite is system of record — D1 mirrors NS for read; push back through NS_PUSH_QUEUE.
  4. Pages Functions render entity pages live — no caching for /pricing/<slug>, /vendor/<slug>, /item/<code>, /bid/<id>.
  5. Cloudflare-only stack — no AWS, no GCP. Single vendor by design.
  6. HITL gates — every AI-proposed action lands in proposed_actions for admin approval before NS push (ADR-031).