Cloudflare
Workers, D1, KV, R2, Pages, DNS, Access — inventory, limits, AI query roadmap
Why this page exists
Cloudflare is the load-bearing layer of the platform — Worker (API), D1 (data), KV (cache), R2 (files), Pages (UI), DNS (routing), and soon Workers AI + Vectorize for the natural-language query layer. This page consolidates every product, its current state, where it's referenced in source, common operations, and what's planned next. Decisions about Cloudflare are tracked in ADRs; live health is on admin-dashboard.
Inventory 11 products
Per-product card with status, instance, binding, source/config, common ops, and limits.
Workers
Activegfs-platform
Single public API for the platform. 20+ GET endpoints over the D1 mirror. CORS allowlist, Bearer auth, security headers.
Detail
Binding: —
Source: src/index.ts
Config: wrangler.jsonc
Limits: 100,000 requests/day on free tier; CPU 50ms/request; sub-requests 50/request (Paid: 1000)
Common ops:
- wrangler deploy
- wrangler tail
- wrangler dev
D1
Active — 185K rowsgfs-netsuite
SQLite read-mirror of NetSuite. 18 tables, 152 GL accounts, 102K transactions across 20 types, full entity backfill.
Detail
Binding: DB
Source: schema.sql, sql/*.sql (45 loaders)
Config: wrangler.jsonc d1_databases
Limits: 10 GB max per DB (currently ~150 MB), 100K reads/day free, point-in-time recovery on Paid
Common ops:
- wrangler d1 execute gfs-netsuite --remote --command "SELECT…"
- wrangler d1 backup create gfs-netsuite
- wrangler d1 export gfs-netsuite
KV
Provisioned, not usedCACHE (e880e40b…)
Short-TTL cache layer. Bound but no endpoints read/write yet. Planned uses: cache /api/ar/aging, /api/kpis responses; rate-limit counters for AI query layer; AI response cache.
Detail
Binding: CACHE
Source: src/index.ts (env.CACHE)
Config: wrangler.jsonc kv_namespaces
Limits: 100K reads/day free, 1K writes/day, 25 MB value max
Common ops:
- wrangler kv:key put --binding=CACHE "k" "v"
- wrangler kv:key list --binding=CACHE
R2
Active (light use)gfs-files
Binary file storage. File Upload RESTlet (NS script 2512) writes here via SuiteAttach. Planned uses: scheduled D1 → SQL export for DR, archived PDF templates, AI audit log cold storage.
Detail
Binding: STORAGE
Source: src/index.ts (env.STORAGE)
Config: wrangler.jsonc r2_buckets
Limits: 10 GB free storage, 1M Class A ops/month, 10M Class B/month (egress is free)
Common ops:
- wrangler r2 object put gfs-files/path file.bin
- wrangler r2 object list gfs-files
Pages
Active — this platformgfs-netsuite.pages.dev
Static hosting for this admin guide. All 10 surfaces + JSON data + reference docs deploy here.
Detail
Binding: —
Source: Whole repo minus src/, sql/, archive/, configs
Config: —
Limits: 500 builds/month free, 100 concurrent builds, unlimited bandwidth
Common ops:
- wrangler pages deploy . --project-name gfs-netsuite
- wrangler pages deployment list --project-name gfs-netsuite
- wrangler pages deployment tail --project-name gfs-netsuite
Pages (legacy)
Deprecated — pre-consolidationgfs-system-guide.pages.dev
Original platform site. Kept available until migration is fully validated. Will be deleted after greenlight.
Detail
Binding: —
Source: Frozen at pre-consolidation state
Config: —
Limits: Same as Pages (above)
Common ops:
- dash.cloudflare.com → Workers & Pages → gfs-system-guide → Delete
DNS / Zone
Activeai-globalfoodsolutions.co
Authoritative DNS for ai-globalfoodsolutions.co (owned). Corporate domain globalfoodsolutions.co also owned. 6 records: CNAME (api, www), MX, TXT (SPF + DMARC), NS.
Detail
Binding: —
Source: wrangler.jsonc routes
Config: dash.cloudflare.com → ai-globalfoodsolutions.co → DNS
Limits: DNS records: 3,500/zone soft limit
Common ops:
- dash.cloudflare.com → DNS → add/edit records
Access (Zero Trust)
Tier 1 GAP — required before sharing URL(not configured)
Auth in front of gfs-netsuite.pages.dev. Currently anyone with the URL can read GAPS, NS reference, runbook. Tier 1 in GAPS_TO_CLOSE.
Detail
Binding: —
Source: —
Config: dash.cloudflare.com → Zero Trust → Access → Applications
Limits: 50 free seats on the Free Zero Trust plan
Common ops:
- Create Application → Self-hosted → gfs-netsuite.pages.dev → Email OTP policy → Save
AI Gateway
Planned — AI query layer(planned)
Proxy + cache + logging layer in front of all LLM calls. Lets us swap models (native Llama ↔ Claude/GPT) without changing app code.
Detail
Binding: —
Source: —
Config: dash.cloudflare.com → AI → AI Gateway → Create
Limits: Free tier covers caching, observability, and most use; per-request pricing for advanced routing
Common ops:
- Create gateway
- Point Worker LLM calls at gateway URL
Vectorize
Planned — AI query layer(planned — gfs-corpus)
Vector store for the embedded corpus (D1 entities + manifest + research docs + SuiteQL library + schema). 768-dim (BGE-base). Source of retrieval for AI query.
Detail
Binding: VECTORIZE (planned)
Source: —
Config: wrangler.jsonc vectorize (planned)
Limits: Free tier: 30M queried dimensions/month, 5M stored vector-dimensions
Common ops:
- wrangler vectorize create gfs-corpus --dimensions=768 --metric=cosine
- wrangler vectorize insert gfs-corpus --file=embeddings.ndjson
Workers AI
Planned — AI query layer(planned)
Native inference at the edge. Embeddings: @cf/baai/bge-base-en-v1.5. LLM: @cf/meta/llama-3.3-70b-instruct (fallback @cf/meta/llama-3.1-8b-instruct).
Detail
Binding: AI (planned)
Source: —
Config: wrangler.jsonc ai (planned)
Limits: Pay-per-neuron; ~$0.59/M in + $0.79/M out for Llama 3.3 70B (verify before launch)
Common ops:
- env.AI.run('@cf/meta/llama-3.3-70b-instruct', {messages})
- env.AI.run('@cf/baai/bge-base-en-v1.5', {text})
AI query layer — phased build
Natural-language query over D1 + the manifest + research docs. Decision recorded in ADR-011 (native Cloudflare stack: Workers AI + Vectorize + AI Gateway). Phased so each step ships independently.
| Phase | Deliverable | Status | Detail |
|---|---|---|---|
| Phase 0 | Cloudflare surface + ADR | Done | This page + ADR-011 in decisions log. |
| Phase 1 | Vectorize index seeded | Planned | Create gfs-corpus, embed manifest (3,486 items) + 8 research docs + 29 SuiteQL queries via Workers AI bge-base. Stored vectors ~10K, well under free tier. |
| Phase 2 | Schema + entity chunks | Planned | Add 18 table descriptions + FK notes + ~2,500 entity rows (customers/vendors/items/employees/gl) as additional chunks. Aggregate-only on transactions (monthly summaries, not row-level). |
| Phase 3 | Query endpoint v1 | Planned | POST /api/ai/query — retrieve+answer mode only (no SQL gen). Cite source row/doc. Bearer auth. Per-token rate limit via KV. |
| Phase 4 | SQL generation mode | Planned | LLM emits parameterized SELECT → validator (allowlist tables, no DDL/DML) → D1 execute → LLM summarizes. Test corpus: 20 known admin questions with expected SQL. |
| Phase 5 | /ai-query.html UI | Planned | Chat surface. Citations as links. 'See generated SQL' expandable. Per-role: admin sees SQL by default, reader sees answer only. |
| Phase 6 | Audit + status endpoints | Planned | /api/ai/audit, /api/ai/status, /api/ai/sources. KV 30d hot, R2 cold. |
| Phase 7 | Reindex automation | Planned | Worker scheduled() cron — incremental reindex of D1 rows modified since last run. |
Default decisions (you can override before any phase starts)
- LLM: Llama 3.3 70B Instruct (native Workers AI) for v1. AI Gateway lets us proxy to Claude/GPT later without app changes.
- Embedding model: BGE-base-en-v1.5 (768d, native). Swap to text-embedding-3-small via AI Gateway if recall is poor.
- Transactions in corpus: aggregate-only (monthly summaries per customer/item/account). Row-level is too big and answers little.
- Show generated SQL: yes for admin role, no for reader. Builds trust without overwhelming non-technical users.
- Reindex cadence: nightly Worker cron for v1. Live updates (on sync) in v2.
- Audit retention: KV 30 days hot, R2 cold indefinitely.
Endpoints (planned)
| Endpoint | Auth | Purpose |
|---|---|---|
| POST /api/ai/query | Bearer | Single-turn natural-language query → answer + citations + optional SQL |
| POST /api/ai/index | Bearer (admin) | Force reindex (one source or all) |
| GET /api/ai/status | Bearer | Last index date, query count 24h, cache hit rate |
| GET /api/ai/sources | Bearer | List indexed sources with chunk counts |
| GET /api/ai/audit | Bearer | Recent queries (last N), redacted |
Other Cloudflare roadmap
Non-AI items that depend on Cloudflare products. Sequencing per the GAPS tracker tiers.
| Item | Tier | Detail |
|---|---|---|
| Worker scheduled() handler for sync | Tier 2 GAP | Move sync.sh into the Worker so it calls SuiteAPI directly. Eliminates the single-Mac dependency. ~4 hr. |
| R2 archival of D1 | Tier 2 | Daily Worker cron: wrangler d1 export + put to R2. Rolling retention 30/90/365. ~2 hr. |
| KV caching wrapper | Tier 3 | Wrap /api/kpis, /api/ar/aging, /api/items/performance with KV (TTL 5 min). ~3 hr. |
| Email Routing / Email Workers | Optional | If dunning notices move out of NS or admin alerts (sync failed, gap created) need to go to email. ~2 hr. |
| Browser Rendering API | Optional | If Advanced PDF/HTML limits get hit, render templates via Browser Rendering. ~half a day to wire. |
| Durable Objects | Defer | Only if real-time multi-user state shows up (live dashboard collaboration, in-app chat). Not currently needed. |
Usage & limits
Approximate current usage vs ceiling. Refresh from the Cloudflare dashboard for live values.
| Product | Metric | Current | Ceiling | Headroom |
|---|---|---|---|---|
| Workers | Requests/day | low (manual) | unlimited (Paid) | ∞ |
| D1 | Storage | ~150 MB | 10 GB / DB | 98.5% |
| D1 | Reads/day | low (sync only) | 5M (Paid) | ~100% |
| D1 | Writes/day | low (sync only) | 100K (Paid) | ~100% |
| KV | Reads/day | 0 | 10M (Paid) | 100% |
| R2 | Storage | light | 10 GB free, then $0.015/GB-mo | large |
| Pages | Builds/month | ~5 | 500 free | 99% |
| Pages | Concurrent builds | 1 | 5 free | large |
Cost model
Current monthly burn (Workers Paid plan $5 base). All other usage is within free tiers.
| Line item | Unit cost | Current usage | Monthly $ |
|---|---|---|---|
| Workers Paid plan | $5/mo base | — | $5.00 |
| D1 reads / writes / storage | free up to limits | well under | $0.00 |
| KV ops | free up to limits | 0 | $0.00 |
| R2 storage | $0.015/GB-mo after 10 GB | under 10 GB | $0.00 |
| Pages builds + bandwidth | free | under limits | $0.00 |
| Workers AI (when AI query ships) | per-neuron, ~$0.001–$0.005/query | 0 today | ~$5–30 est at 100 queries/day |
| Vectorize | $0.04/M queried dims; storage tiny | 0 today | ~$1–5 est |
| AI Gateway | free tier covers cache + observability | 0 today | $0.00 |
| Access (Zero Trust) | free up to 50 seats | 0 (not configured) | $0.00 |
Wrangler quick-ref
Cross-links
- Data model — D1 schema, ER diagram, example queries, SuiteQL admin library
- Infrastructure — Worker endpoints (per-endpoint detail), DNS records, bindings, secrets
- Admin dashboard — live health of every Cloudflare service
- ADR-011 — AI stack decision
- GAPS — Tier 1 (Access on Pages), Tier 2 (Worker-side sync, D1 backups)
- Runbook → incident response — sync stopped, D1 quota, Pages down