Serverless orchestration backend for the AI Shopping Assistant chat feature described in ai-shopping-assistant-plan.md.
This service runs on Cloudflare Workers using Hono and exposes a single unified /chat endpoint. It leverages Google Gemini API (with an automatic failover to Groq if Gemini quotas are exceeded) and retrieves product candidates directly from your Shopify Storefront API.
The backend orchestrates the entire user request lifecycle to ensure safe, grounded, and high-performance product recommendations. Unlike simple wrappers, this system ensures the LLM never invents products or hallucinates prices.
graph TD
A[Shopper Request: Text/Image] --> B[1. Guardrails & Moderation]
B -->|Passed| C[2. Budget & Brand Constraint Extraction]
B -->|Failed/Safety| Z[Polite Decline Response]
C --> D[3. Keyword Extraction & Catalog Retrieval]
D -->|If Non-English/Latin| E[Translate Terms to English]
E --> F[Fuzzy Catalog Search via Shopify]
D -->|English/Latin| F
F --> G[4. Multi-stage Price Filter]
G --> H[5. Structured LLM Decision]
H -->|Gemini Flash-Lite| I[Live Catalog Hydration]
H -->|Fallback to Gemini Flash / Groq| I
H -->|Degraded/All Failed| J[Keyword Search / Busy Safe State]
I --> K[6. Response Construction & Price Formatting]
K --> L[Shopper UI: Chat Bubble + Product Cards]
- 🛡️ Pre-LLM Guardrails: Deterministic protection against empty, abusive, or oversized payloads before invoking any AI endpoint.
- 💰 Smart Budget & Brand Parsing: Natural language price filter (e.g. "under $50", "around 9000") is extracted in code. The catalog is pre-filtered, guaranteeing that the LLM only recommends products in the user's budget.
- 🌐 Multilingual & Cross-Language Retrieval: Users can chat in any language (e.g., Arabic). The backend translates search terms on-the-fly to query the English Shopify catalog, then returns the final reasoning and product annotations back in the user's language.
- 📸 Multimodal Image Search: Vision support allows shoppers to upload images (e.g., "find me something like this").
- 🔄 Multi-Provider Quota Resilience: Silently falls back through Google Gemini Flash-Lite ➔ Gemini Flash ➔ Groq (
llama-3.3-70b-versatile) when free quotas/rate limits are hit. - ⚡ Zero-Signup Mock Mode: Ready to run locally with synthetic product catalogs and mock AI responses out of the box—no API keys required.
- ⏱️ Rate Limiting: Per-device fixed-window rate limiter powered by Cloudflare KV or fallback in-memory state.
Here is the directory structure for the backend codebase:
- src/index.ts: Entry point. Configures Hono, CORS, routes, global error handling, and hooks in rate limiting.
- src/orchestrator.ts: The orchestrator coordinating guardrails, keyword translation, Shopify retrieval, price filters, LLM decisions, and live price/image hydration.
- src/config.ts: Typed configuration loading, schema validation, and mock-mode detection.
- src/types.ts: Shared Zod request schemas and type models.
- src/guardrails.ts: Pre-LLM protection checking inputs and image MIME validations.
- src/rateLimit.ts: Fixed-window rate limiter utilizing Cloudflare KV (or in-memory cache).
- src/keywords.ts: Basic Latin keyword extraction for initial candidate retrieval.
- src/shopify.ts: Interacts with Shopify Storefront API for searching, catalog queries, and live product hydration.
- src/gemini.ts: Communicates with Google Gemini API & Groq API, and handles structured output parsing.
- src/constraints.ts: Budget & price constraint parsers.
- src/sanitize.ts: Utility functions to sanitize user and API input.
- src/mock.ts: Synthetic LLM decisions and mock product catalog for offline testing.
- src/logger.ts: Structured JSON logging helper.
- src/logic.test.ts: Suite of Vitest unit tests verifying budget parsing, guardrails, and orchestration behavior.
To start testing the backend locally immediately without setting up Gemini or Shopify accounts, run the service in Mock Mode:
-
Install dependencies:
npm install
-
Run the local development server:
npm run dev
The server starts locally at
http://127.0.0.1:8787. -
Verify the server is running:
curl -s http://127.0.0.1:8787/ # Returns: {"service":"ai-shopping-assistant","status":"ok","mockMode":true,...} -
Send a mock chat query:
curl -s -X POST http://127.0.0.1:8787/chat \ -H 'Content-Type: application/json' \ -d '{"deviceId":"test_device","message":"breathable summer shirts"}' | jq
The project uses Vitest for unit testing.
npm run test # Run tests once
npm run test:watch # Run tests in watch modeYou can run automated E2E tests using Newman against the local or live environment:
npx newman run postman/ai-shopping-assistant.postman_collection.json \
-e postman/ai-shopping-assistant.postman_environment.jsonThe suite runs 34 assertions testing happy path queries, rate-limiting (429), validation failures (400), off-topic/abusive messages, and image handling.
Configuration is managed via non-secret environment variables in wrangler.toml and secrets in .dev.vars (local) or injected via wrangler secret (production).
| Variable | Default Value | Description |
|---|---|---|
MOCK_MODE |
true |
When true, returns synthetic mock data and does not call external APIs. Set to false to enable live Gemini and Shopify connections. |
BRAND_NAME |
our store |
The brand/store name injected into system prompts. |
GEMINI_MODEL |
gemini-2.5-flash-lite |
Primary AI model (has highest free RPM tier). |
GEMINI_FALLBACK_MODEL |
gemini-2.5-flash |
Secondary model used if primary fails or is throttled. |
GROQ_MODEL |
llama-3.3-70b-versatile |
Groq model fallback when Gemini quotas are depleted. |
SHOPIFY_STORE_DOMAIN |
— | Domain of your store (e.g. your-store.myshopify.com). |
SHOPIFY_API_VERSION |
2024-10 |
Storefront API version. |
MAX_CANDIDATES |
15 |
Number of candidate products queried from Shopify per request. |
MAX_HISTORY_MESSAGES |
6 |
Number of prior conversational history messages sent to the LLM. |
RATE_LIMIT_MAX |
20 |
Maximum allowed API requests per device in the configured window. |
RATE_LIMIT_WINDOW_SECONDS |
3600 |
Rate limit window in seconds (1 hour). |
GEMINI_API_KEY (Secret) |
— | API Key from Google AI Studio. |
SHOPIFY_STOREFRONT_TOKEN (Secret) |
— | Storefront Access API Token from Shopify Admin dashboard. |
GROQ_API_KEY (Secret) |
— | Optional API key from Groq console to handle rate-limiting failovers. |
To take the backend live with real Gemini and Shopify integration:
- API Keys Checklist:
- Google AI Studio: Get a free API Key at ai.google.dev.
- Groq API Key (Recommended): Get one from console.groq.com.
- Shopify Storefront API Token: Enable the
unauthenticated_read_product_listingsscope on Shopify Admin -> Develop Apps.
- Local Environment Secrets: Copy
.dev.vars.exampleto.dev.varsand add your keys. Updatewrangler.tomlwith your shop domain and setMOCK_MODE = "false". - Deploy to Cloudflare: Follow the instructions in the docs/DEPLOYMENT.md guide.
For detailed API payload specifications, refer to docs/API.md. For building the mobile frontend client, check out docs/CMP_IMPLEMENTATION_PLAN.md.