Platform Overview
8
Pillars
33
D1 Tables
95+
Chat Tools
22
Dashboard Pages
13
Build Phases (0-12)
5
Email Channels
22
CF Services
~$30
/mo + $250 AI cap
Eight Pillars
PILLAR 1
NetSuite (ERP)
253 customers, 474 vendors, 1,121 items. System of record. Bidirectional sync — portal is the data quality layer.
PILLAR 2
Vendor Pricing
35 vendors, input costs, price tiers, expiration tracking. Email intake for price sheets.
PILLAR 3
Assembly Costing
146 finished goods, 7 programs, BOMs, labor, overhead. FOB dock cost per case.
PILLAR 4
Product Data & Compliance
136 items, 55 fields, FDA compliance, allergens, nutrition, CN labels, spec sheet generation.
PILLAR 5
Customer Pricing
69 customers, 127+ items, case prices, regional prices, version history. Live HTML quote pages.
PILLAR 6
Bid Management
33 bids, 23 reviews. AI email intake, auto-review, pipeline tracking, deadline alerts.
PILLAR 7
Margin Intelligence
Cost vs sell price. Customer profitability. Vendor impact analysis. Low-margin alerts.
PILLAR 8 — FROM PROVENDER
Product Identity & Regulatory
CODEX regulatory engine (9 authorities, restricted ingredients). WARDEN field-level validation + provenance scoring (0-100). CLEARING approval queue. Dual-converter document pipeline. GS1 barcodes (bwip-js). Phases 10-12.
The Cost Chain
Vendor Input
35 Vendors
Price sheets
Tiers / brackets
Effective dates
↓
Assembly Cost
BOM × vendor price
+ Labor ($0.09/u)
+ Overhead ($1.00/cs)
+ Packaging
+ Freight
= FOB dock cost
↓
Customer Sell Price
69 customers
127+ items
4 regions
Version history
↓
Margin
Sell price − FOB cost = Margin
Low-margin alerts
Vendor impact simulation
Customer profitability
System Architecture
Two-Project Architecture
gfs-portal (Pages) — UI + API (Hono)
gfs-worker (Worker) — Agent DO + Cron + Queues + Email
↓
Layer 1 — Ingest / Edit
Admin UI (Chat + Dashboard)
bids@ (Email Worker)
vendors@ (Email Worker)
costs@ (Email Worker)
quotes@ (Reply handler)
NetSuite (MCP sync)
↓
Layer 2 — AI Processing (via AI Gateway, $250/mo cap)
Dual Markdown Converter (Docling + MarkItDown)
Haiku (extract + bid review)
Sonnet (chat queries)
Opus (complex analysis)
Vectorize (semantic search)
4 Queues (NS sync, email, notifications, cost recalc)
↓
Layer 3 — Canonical Store (dev / staging / prod)
D1 — 33 tables + 27 indexes
R2 — forever retention (no auto-delete)
KV — sessions + cache
Secrets Store — 6 secrets (Anthropic + NS TBA)
↓
Layer 4 — Serve / Distribute
Chat Interface (/)
Dashboard (18 pages)
Quote Pages (/quotes/*)
Email Notifications
NetSuite Writeback
Analytics Engine
Logpush → R2
↓
Layer 5 — Background
Cron: Nightly backup
Cron: NS entity sync
Cron: Drift detection
Cron: Bid expiration
Cron: Vendor price alerts
Cron: Cost recalc sweep
Cron: Margin erosion scan
Cron: AI spend report
Security Perimeter
Access Control
Cloudflare Access (email OTP)
WAF (rate limiting)
Turnstile (signed URLs)
Admin | Editor | Broker | Viewer
Data Flow Map
NetSuite ↔ Portal
Pull (NS → Portal) — Daily Cron
253 Customers
478 Vendors
1,137 Items
AR Aging (weekly)
↓
Reconcile — Nightly Drift Detection
Compare D1 vs NS entities
Compare prices: portal vs NS
Compare costs: FOB vs NS item cost
Flag drifts → Drift Report page
↓
Push (Portal → NS) — On Approval Only
Admin approves via chat
Sell prices → NS item pricing
FOB costs → NS item cost
Vendor prices → NS vendor bills
Vendor Price Change → Impact Chain
1. Vendor sends price update
vendors@ receives email
↓
2. AI extracts & stages
Workers AI classifies
Haiku extracts prices
D1: stage vendor_prices update
↓
3. Calculate impact
BOM lookup: which items use this vendor?
Recalculate FOB costs
Recalculate margins across all customers
↓
4. Notify & approve
Email Mike: "Bongards +5% — 12 items affected, avg margin -1.8%"
[Review & Approve] → costs update → done
Bid Intake Flow
1. Broker emails bid PDF
bids@ receives
↓
2. AI processes
Workers AI: classify as bid
Haiku: read PDF (vision), extract line items
Haiku: match against 146 items in D1
↓
3. Store & review
R2: store original PDF
D1: create bid + bid_review
Email Mike: "15 matches, 6 commodity — [Review]"
↓
4. Human approves
Mike reviews, adjusts matches, approves
Status: Intake → Submitted
D1 Schema — 33 Tables + 27 Indexes
Items & Costing
itemsUnified item catalog (127 commercial + 14 commodity + 146 costing)
assembly_programs7 programs: VFF, MealKit, Sandwich, etc.
bom_linesBill of materials per finished good
assembly_costsCalculated FOB dock cost per item
cost_historyCost change audit trail
Vendors
vendors35 vendors with NS IDs
vendor_pricesInput prices, tiers, effective dates
vendor_documentsQuotes, COAs, contracts in R2
Customer Pricing
customers69 active customers with NS IDs + customer_type
pricesCustomer × item sell prices + school_year
regional_prices4 regions × items + school_year
price_historyPrice change audit trail
version_logQuote version history
customer_notesPer-customer notes
nycdoe_itemsNYCDOE-specific item links
Bids
bids33 bids + email intake pipeline
bid_reviews23 reviews + AI-generated matches
Platform
usersAuth + roles + status (instant revocation)
user_customersJunction: broker/viewer → assigned customers
customer_programsCustomer-specific programs (allowances, rebates)
email_eventsInbound email audit trail
notificationsIn-app notification queue
chat_logEvery message, tool call, token
activity_logAll non-chat actions
email_eventsInbound email audit trail
filesR2 file references
configSystem configuration
Chat Tools — 95+
NetSuite (15)
ns_get_customer(name)
ns_get_vendor(name)
ns_get_item(code)
ns_customer_orders(customer, days)
ns_vendor_purchases(vendor, days)
ns_item_transactions(code, days)
ns_inventory(code)
ns_customer_ar(customer)
ns_vendor_ap(vendor)
compare_ns_prices(customer)
compare_ns_costs(item)
sync_prices_to_ns(customer)
sync_cost_to_ns(item)
ns_drift_report()
ns_link_entity(portal_id, ns_id)
Cost & Vendor (9)
get_item_cost(code)
get_bom(code)
recalculate_cost(code)
recalculate_program(program)
get_vendor(name)
update_vendor_price(vendor, item, price)
vendor_price_impact(vendor, pct)
expiring_vendor_prices(days)
cost_history(code, range)
Margin (5)
get_margin(code, customer)
margin_report(customer)
low_margin_alert(threshold)
cost_vs_price_matrix()
customer_profitability(customer)
Customer Pricing (13)
get_customer(name)
search_customers(query)
get_customer_price(customer, code)
update_price(customer, code, price)
batch_update_prices(customer, prices[])
create_customer(data)
get_regional_prices(region)
get_version_history(customer)
compare_prices(customer, v1, v2)
get_quote_url(customer)
share_quote(customer, email, expiry)
send_quote_notification(customer, msg)
search_items(query)
Bids (7)
get_bid_pipeline(filters)
add_bid(customer, data)
update_bid_status(id, status)
log_external_bid(data)
review_bid(pdf_r2_key)
search_bid_reviews(query)
get_bid_review(id)
Admin (10+)
add_item(data)
update_item(code, fields)
archive_customer(name)
run_health_check()
trigger_backup()
manage_users(action, data)
view_activity_log(filters)
view_chat_log(filters)
get_dashboard_stats()
export_pivot()
AI Email System
Every inbound email is AI-processed before a human sees it. Workers AI classifies, Haiku extracts, D1 stages, human approves.
Inbound Channels
bids@
Workers AI classifies as bid
Haiku reads PDF, extracts line items
Match against 146 items in D1
Store PDF in R2, create bid + review in D1
Email Mike with match summary
Mike reviews & approves
vendors@
Workers AI classifies (price update / COA / contract)
Haiku extracts prices, items, dates
Calculate cost + margin impact
Stage vendor_prices update in D1
Email Mike with impact analysis
Mike approves → costs recalculate
costs@
Workers AI classifies as cost update
Haiku extracts: what changed, which items
Calculate downstream impact
Stage update in D1
Email Mike with one-click approve
Mike applies or ignores
quotes@
Catches customer replies to notifications
Haiku extracts intent: question / negotiation / approval
Log in activity_log with customer context
Route to Mike with context + margin data
support@
AI summary prepended
Forward to Zoho inbox
Outbound Triggers (17)
| Category | Trigger | From |
|---|---|---|
| Quotes | Price updated | notifications@ |
| Quotes | Quote page viewed | notifications@ |
| Quotes | Quote shared | notifications@ |
| Bids | Bid intake reviewed | notifications@ |
| Bids | Deadline 3 days | notifications@ |
| Bids | Bid expired | notifications@ |
| Vendors | Price sheet processed | notifications@ |
| Vendors | Price expiring 30d | notifications@ |
| Vendors | Price expiring 7d | notifications@ |
| Vendors | Document received | notifications@ |
| Costs | FOB change > 5% | notifications@ |
| Costs | Margin below threshold | notifications@ |
| Costs | Cost update staged | notifications@ |
| System | Backup success | system@ |
| System | Backup failure | system@ |
| System | NS drift detected | system@ |
| System | New user login | system@ |
NetSuite Integration
253
NS Customers
474
NS Vendors
1,121
NS Items
151
Items Mapped
15
NS Chat Tools
Data Ownership
| NetSuite Owns (Portal Reads) | Portal Owns (NetSuite Reads Back) |
|---|---|
| Customer identity (name, address, terms) | Customer sell prices |
| Vendor identity (name, contact, terms) | Assembly FOB costs |
| Item identity (code, description, brand) | Vendor input prices + tiers |
| Transactions (POs, SOs, invoices) | BOMs + cost rollups |
| Inventory (on-hand, committed) | Bids + reviews |
| AR/AP aging | Margins + analysis |
Sync Modes
| Mode | Direction | Frequency | Method |
|---|---|---|---|
| PULL | NS → Portal | Daily cron | SuiteQL via MCP |
| PUSH | Portal → NS | On approval | MCP record update |
| RECONCILE | Both | Nightly cron | SuiteQL compare → drift report |
| ON-DEMAND | NS → Portal | Chat query | SuiteQL via MCP (live) |
Build Phases
0
Foundation
Security, domain, repo, CI/CD, 3 environments, CF Pro
Lock dashboards, DNS transfer, email routing, AI Gateway ($250 cap), GitHub Actions, pre-build docs
1
Database + Migration
D1 + R2 + KV + Vectorize + Queues, all data migrated, NS entity resolution
33 tables + 27 indexes (incl. Provender tables created empty), dual-system migration, create 26 NS customers + 33 items + 9 vendors, embeddings
2
API Layer
Hono + Drizzle + Zod, 20 endpoint groups, cost recalc engine, NS push logic
All endpoints, role middleware, cost engine, NS push, Zod validation, rate limits, testing
3
Unified Dashboard
Astro + React, 14 data pages (admin deferred to Phase 4)
Costing + pricing + analysis pages, KV cache, TanStack, Analytics Engine, mobile responsive
4
Access Control + Admin
BEFORE quotes go live — auth, roles, admin panel, signed URLs
CF Access, admin pages (8), role-based UI, Turnstile, custom domain, session revocation
5
Quote Pages
HTML quotes (auth is already live), interactive, printable, multi-year
Quote renderer, print CSS, versioning, sharing (18-mo URLs), margin column, view tracking
6
Chat Agent
Agents SDK in gfs-worker, 75 tools (grows to 95+ after Phases 10-12), role-enforced, hybrid AI
Agent DO, tool auth (programmatic), Sonnet+Opus routing, WebSocket, chat_log, scope limits
7
AI Email System
Dual converter, 5 inbound, 17 outbound, Workflows approval queue
Email Worker, dual-convert pipeline, AI handlers, Workflows, notifications, R2 migration
8
Backup + Cron
6-hour backups (3 destinations), NS sync, AI background jobs
R2+Dropbox+GDrive backups, NS sync via Queues, 10 cron jobs, monthly D1 archival
9
Polish + Launch
Performance, security review, 15 docs, onboarding, go-live
Web-perf, security audit, docs suite, E2E tests, cutover, archive (not delete) originals
10
CODEX — Regulatory Intelligence (from Provender)
Compliance authorities, restricted ingredients, ingredient scanning, portfolio compliance
9 authorities + 20 restricted ingredients seeded, 14 validation rules, ingredient scanner, 7 new chat tools, compliance dashboard page, weekly cron scan
11
WARDEN + CLEARING (from Provender)
Field-level provenance, validation scoring (0-100), human-in-the-loop approval queue
field_provenance table, weighted scoring algorithm, provenance on every write, CLEARING approval workflow, dual-converter diff review, 11 new chat tools, 2 dashboard pages
12
Document Pipeline + GS1 Barcodes (from Provender)
Dual-converter document ingestion, polymorphic linking, GS1-128 + QR barcodes, case labels
documents + document_subjects tables, Docling + MarkItDown Docker containers via CF Tunnel, bwip-js, /labels/[item-code] route, 4 new chat tools, documents dashboard page
Cloudflare Services Used
| Service | Purpose | Phase |
|---|---|---|
| Pages | UI hosting (dashboard, chat, quotes, admin) | 0 |
| Pages Functions | API layer (Hono) | 2 |
| D1 | Primary database (33 tables + 27 indexes, 3 environments) | 1 |
| R2 | File storage (bids, vendors, backups, logs) — forever retention | 1 |
| KV | Sessions + dashboard cache | 1 |
| Vectorize | Semantic search (items, bids, vendors) | 1 |
| AI Gateway | Claude API proxy ($250/mo cap, caching, logs) | 0 |
| Agents SDK | Chat agent DO in gfs-worker (95+ tools, role-enforced) | 6 |
| Workers AI | Email classification, embeddings | 7 |
| Email Service | Outbound transactional email | 7 |
| Email Routing | Inbound (5 addresses) | 0 |
| Email Workers | AI processing of inbound email | 7 |
| Queues | 4 queues: NS sync, email, notifications, cost recalc | 1 |
| Workflows | Durable approval flows | 7 |
| Cron Triggers | Backup, NS sync, drift, bid/vendor alerts | 8 |
| Analytics Engine | Quote views, chat usage, API metrics | 3 |
| Secrets Store | 6 secrets (Anthropic + NS TBA 4 values + Zoho) | 0 |
| Access | Email OTP auth, 4 roles (CF Pro plan) | 0/4 |
| WAF | Rate limiting on ALL /api/* endpoints (CF Pro) | 2 |
| Turnstile | CAPTCHA on signed quote URLs | 6 |
| Logpush | Worker logs → R2 for audit trail | 2 |
| DNS + SSL | Domain management, universal TLS | 0 |
Infrastructure Inventory
Development Machine — Apple M3 Max
128
GB RAM
2.4T
Free Disk
arm64
Architecture
macOS 26
OS Version
Local Tools
| Tool | Status | Action |
|---|---|---|
| Node.js v25.9.0 | Ready | — |
| npm/npx v11.12.1 | Ready | — |
| Git 2.39.2 | Ready | — |
| Homebrew 5.1.11 | Ready | — |
| Python 3.11.3 | Ready | — |
| Tailscale 1.96.5 | Ready | — |
| pnpm | NOT INSTALLED | npm install -g pnpm |
| Wrangler 4.90.1 | OUTDATED (4.92+) | npm install -g wrangler@latest |
| GitHub CLI (gh) | NOT INSTALLED | brew install gh && gh auth login |
| Docker Desktop | NOT INSTALLED | Install Docker Desktop for Mac |
| cloudflared | NOT INSTALLED | brew install cloudflare/cloudflare/cloudflared |
External Service Accounts
| Service | Account | Status | Monthly Cost |
|---|---|---|---|
| Cloudflare | mikelevine@globalfoodsolutions.co | Active (upgrading to Pro) | $20 |
| Anthropic | Existing key (from assembly costing) | Active | $50-250 (cap $250) |
| GoDaddy | ai-globalfoodsolutions.co | Active (transfer DNS to CF) | ~$1 |
| Zoho Mail | mikelevine@globalfoodsolutions.co | Active | Existing |
| Dropbox | GlobalFoodSolutions Dropbox | Active (desktop sync) | Existing |
| Google Drive | /Users/MichaelLevine/Google Drive/ | Active (desktop sync) | Existing |
| NetSuite | MCP connector (dev) + TBA REST API (prod) | MCP active, TBA credentials need verification | Existing |
| GitHub | Not set up | NEEDED | $0 (Free plan) |
| UptimeRobot | Not set up | NEEDED | $0 (Free plan) |
Existing Cloudflare Resources
| Resource | Name | Fate |
|---|---|---|
| Pages | gfs-pricing | Replaced by portal — retire after cutover |
| Pages | gfs-assembly-costing | Replaced by portal — migrate KV data, then retire |
| Pages | gfs-hub, gfs-nycdoe-hub, gfs-docs | Keep — separate purpose |
| Pages | gfs-broker-roster / broker-roster | Evaluate — fold into portal or keep |
| Pages | evidence-dashboard, echo-lake-* | Keep — separate projects |
| KV | gfs_assembly_state | Migrate data to D1 → deprecate |
| KV | ANALYTICS, BROKER_CHANGES, ECHO_LAKE_ANALYTICS | Keep — used by other projects |
| D1 | (none) | Create gfs-portal-db (dev/staging/prod) |
| R2 | (none) | Create gfs-portal-files |
| Workers | (none) | Create gfs-worker |
NetSuite Access — Dev vs Production
| Context | Method | Status |
|---|---|---|
| Claude Code (development) | MCP connector (mcp__claude_ai_NetSuite__) | Active — 50+ suite skills, SuiteQL |
| Cloudflare Workers (production) | SuiteQL REST API with TBA credentials | TBA credentials need verification |
MCP connector runs through Anthropic infra — cannot be called from Workers. Production uses direct NS REST API with TBA (Token-Based Authentication). Same SuiteQL syntax, different transport.
Domain Architecture
| Domain | Purpose | DNS | |
|---|---|---|---|
| globalfoodsolutions.co | Main business domain | Current registrar | Zoho Mail |
| ai-globalfoodsolutions.co | AI platform (this portal) | Cloudflare (transfer from GoDaddy) | CF Email Routing + Service |
| agents.globalfoodsolutions.co | Cloudflare Tunnel (dual-converter for Phase 12) | Cloudflare | — |
Monthly Cost Summary
$20
CF Pro
$5
Workers Paid
$50-250
Anthropic AI
$0
D1/R2/KV/Email
$80-280
Total Range
Decisions — 53 Total (28 Resolved + 25 New Recommendations)
Original 28 resolved by Mike. Items 29-53 are recommended defaults from infrastructure audit — review and confirm.
| # | Question | Decision |
|---|---|---|
| 1 | Chat model | Hybrid — Sonnet for quick queries, Opus for complex analysis |
| 2 | Bid intake AI | Hybrid + dual markdown converter — two converters diff for validation, then AI extracts |
| 3 | Signed URL expiration | 18 months |
| 4 | Chat panel layout | Sidebar page — chat takes full main area (like Claude’s UI) |
| 5 | Domain | ai-globalfoodsolutions.co (root) — purchased on GoDaddy, transfer DNS to CF |
| 6 | COOPS / School Districts | Merge into customers with customer_type field |
| 7 | Commodity regional prices | Migrate as $0.00, populate later |
| 8 | Programs | D1 table + customer-specific programs section for logging per-customer program details |
| 9 | Multi-school-year | Yes — add school_year column. Support rolling cycles (7/1/26-6/30/27, 7/1/27-6/30/28) |
| 10 | First users | Internal team |
| 11 | Customer emails | Collect over time — admin-only notifications at launch |
| 12 | Cloudflare plan | Pro — pay for all additional services needed |
| 13 | NetSuite sync | Bidirectional with cleanup — portal is the data quality layer. Pull, clean, push back. |
| 14 | Bid intake email | bids@ai-globalfoodsolutions.co confirmed |
| 15 | Bid notifications | Configurable per bid |
| 16 | Quote view tracking | Full backend tracking — every view logged with timestamp, IP, user-agent |
| 17 | .docx requirement | No — HTML + Print + PDF from print. Drop .docx entirely (2,912 lines removed) |
| 18 | Anthropic budget | $250/mo hard cap |
| 19 | Backup retention | Forever — small business, keep everything |
| 20 | Backup alerts | Mike only |
| 21 | NYCDOE | Yes — biggest single customer, fully migrate |
| 22 | Dashboard pages | All tabs — full suite. Landing = chat interface like Claude. |
| 23 | Cost placeholder rates | Use as placeholders — update ongoing as system builds out |
| 24 | Vendor pricing tiers | Track ALL — case, pound, FOB, delivered, bracket tiers |
| 25 | Dual-vendor items | Show both side by side — flag dual-vendor items, support 2+ vendors per FG |
| 26 | Cost recalculation | Automatic — vendor price change triggers instant FOB recalc |
| 27 | Vendor docs | Full R2 migration — CF hosts everything. Backup to Dropbox + Google Drive. |
| 28 | Existing KV data | Migrate everything — audit, enrich, keep building |
Infrastructure & Technical Decisions (29-53) — Recommended Defaults
| # | Decision | Recommendation |
|---|---|---|
| 29 | Package manager | pnpm — strict lockfile, faster |
| 30 | GitHub plan | Free — private repos + basic Actions. Upgrade if team grows. |
| 31 | Dual-converter hosting | This Mac via Docker + Tunnel. 128GB is overkill for 2 containers. Start single, add dual in Phase 7. |
| 32 | Google Drive backup folder | /Google Drive/GFS Portal Backups/ |
| 33 | DNS transfer method | Nameserver delegation (keep GoDaddy registration, point NS to CF) |
| 34 | Wrangler version | Update to 4.92+ before starting |
| 35 | Anthropic billing | Reuse existing key from assembly costing. Move to Secrets Store. |
| 36 | AI Gateway billing model | Direct Anthropic + manual tracking in D1 chat_log. Soft alerts via cron. |
| 37 | Vectorize embedding model | @cf/baai/bge-base-en-v1.5 (768 dim, free via Workers AI) |
| 38 | Test data strategy | Real data with prices randomized ±10% for dev/staging |
| 39 | Historical SY2526 | Start with SY2627, import SY2526 later if needed |
| 40 | File size limits | 25MB (matches CF Email Routing limit) |
| 41 | Concurrent users | Design for 20, test with 5 |
| 42 | Performance targets | Dashboard <2s, API <500ms, chat first-token <2s |
| 43 | NS production access | SuiteQL REST API (direct) for Workers + MCP for Claude Code dev |
| 44 | Signed URL max views | Optional max_views field. Default: unlimited. Admin configurable. |
| 45 | AI-generated email review | All AI-drafted outbound emails stage for admin approval. No auto-send. |
| 46 | Backup encryption | R2 encrypted at rest (CF). Dropbox/GDrive encrypted by provider. Sufficient. |
| 47 | Admin 2FA | Email OTP via CF Access. Add TOTP for admin role if needed later. |
| 48 | School year rollover | Chat tool: prepare_school_year(SY2728). Copies prices, creates new records. |
| 49 | Vendor onboarding | Chat tool: onboard_vendor(). Creates vendor, links items, populates prices. |
| 50 | Customer onboarding | Chat tool: onboard_customer(). Creates customer, assigns broker, sets prices. |
| 51 | Privacy policy | Simple notice in quote page footer. "GFS tracks views for business purposes." |
| 52 | Data retention (legal) | Business data: forever. IP/user-agent: 90 days in D1, then archived to R2. |
| 53 | Support channel | support@ai-globalfoodsolutions.co → Zoho. Link in portal footer. |
Status
28
Resolved by Mike
25
Recommended defaults
0
Blockers