CraftWeb
Loader image Loader image Loader image Loader image Loader image Loader image Loader image
0 %
Loading

GrowGPT

AI commerce platform helping merchants follow high-intent traffic into ChatGPT and Google AI

AI Commerce Nx Monorepo Next.js 15 React 19
Supabase MCP Server Gemini

/ Overview

The traffic that built e-commerce is migrating to AI platforms. GrowGPT helps merchants follow it — an Nx monorepo with seven apps shipping under one platform that lets shops reach customers on ChatGPT and Google AI.

See it live

/ Project Details

Category: AI commerce SaaS

Engagement: In-house product — CraftWeb Labs

Role: Architecture, full-stack, AI integration

Timeline: 2026 — active

/ Problem

Google Search delivers fewer clicks at higher cost. Meta Ads ROAS drifts. A generation of shoppers moved product discovery into ChatGPT, Gemini and Perplexity. ChatGPT-referred traffic converts 2× better than organic search — but every retailer with a Shopify or WooCommerce store is invisible at exactly the moment when discovery is happening. GrowGPT was started in early 2026 to be the missing layer.

/ TL;DR

7 apps

One Nx monorepo — dashboard, landing, widget, MCP server, MCP discovery, enrichment engine, Supabase.

37 edge fns

Supabase Deno Edge Functions powering real-time multi-tenant SaaS.

5 modules

FlowGuide, ShopScout, ProductGenie, DataFlow, ACP/UCP — all live behind one tenant config.

2× conversion

ChatGPT-referred traffic converts vs organic search (Similarweb 2025) — the data the platform bets on.

/ Vision

Five product modules behind a single tenant config, seven deployable apps in one Nx monorepo, multi-tenant SaaS enforced at the database. AI-native from day one — the MCP server lets agentic AI clients query the catalogue as first-class context.

/ Principles

One monorepo, many surfaces

Nx + pnpm holds dashboard, landing, widget, MCP server, discovery, enrichment and Supabase Edge Functions. Shared TS types, no version drift.

Multi-tenant at the DB

Supabase Row Level Security enforces tenant isolation at every query. Postgres rejects the read before it leaves the DB.

AI-native, not AI-bolted-on

Custom MCP server exposes catalogue + templates as MCP tools to ChatGPT/Gemini/Claude — no custom plugin per shop.

Five modules, one config

All modules live behind a single tenant config — one toggle reflects in dashboard, widget and Edge Functions.

/ Seven apps, one platform

Each app has one job and a clear contract. Nx dep graph keeps builds fast; shared packages keep types honest. No copy-paste between widget, dashboard and Edge Functions — one Supabase schema, one set of TS types, one source of truth.

/ Deployable units

web

Merchant dashboard — React 18 + Vite + Tailwind + shadcn/ui + JWT against Supabase.

landing

Marketing site SSG/ISR — Next.js 15 App Router + React 19.

widget

Embeddable IIFE bundle — React + esbuild + scoped CSS + XSS-sanitised.

mcp-server

Exposes catalogue + templates as MCP tools to ChatGPT/Gemini/Claude.

mcp-discovery

Routes AI-platform queries to the right merchant tenant.

enrichment-service

Node + Express + Drizzle. Pulls product feeds, enriches with Gemini, writes to Supabase.

supabase

Postgres + 37 Deno Edge Functions + Row Level Security + PLpgSQL migrations.

/ Engineering challenges

Shipping a multi-tenant SaaS in 90 days surfaces problems most monorepos never face: build-time env vars, XSS in customer-supplied CSS, dual-auth for cron and users. Every challenge below was solved with a single named commit. The fixes ship in production.

/ 01 — 04

01 — Landing into its own Next.js 15 app

Landing lived inside React/Vite dashboard, broke at 90 components. Fix: 513d2da — 108 files extracted into apps/landing with SSG/ISR, metadata API, hydration-safe theme toggle, Vercel rewrites so visitors still see one domain.

02 — Dual auth: API-key for cron, JWT for users

Scheduled imports need long-lived secrets; user-triggered imports need JWTs. Fix: 244df94 — Edge Function accepts either path; audit log records which was used per request.

03 — XSS-safe widget CSS injection

Merchants apply custom CSS to product carousel — naive <style> injection is a script-injection vector. Fix: ac050ed — sanitiser strips </style>, comment escapes, @import URLs, tag-like sequences; output wrapped in scoped shadow class.

04 — Scheduled imports + Gemini rate limits

First cron hit Gemini quota on a 10K-product feed. Fix: af92197 — Supabase scheduled Edge Functions (no external queue), per-tenant usage tracking, exponential backoff + full jitter on 429 (cap 60 s), batch size 10–20 rows.

/ More challenges

Build-time env-var crashes, dead third-party dependencies, three-tab UX that nobody could parse. The middle of a build is where the assumptions break — and where the case study earns its weight.

/ 05 — 08

05 — Build-time env vars vs runtime Supabase

Vercel build crashed: articles pages doing generateStaticParams + Supabase fetch with env vars missing during prerender. Fix: 31ef7a3 — articles forced to dynamic, Supabase client lazy-init (env checks on render not import).

06 — DataFlow: three tabs in, one flow out

Three tabs (Upload File / External Feed URL / Local XML) confused users; scheduling controls on only one tab. Fix: 6f29844 — single Scheduled Feed Imports flow with cron-builder UI; transport inferred from URL pattern.

07 — Removing GCS dependency nobody used

Early sketch included GCS; the actual flow ended on Supabase Storage. Fix: ea76397 — removed @google-cloud/storage, orphan UI field, dead enrichment paths. One storage layer, one bill, one set of credentials.

08 — Visual widget builder with live CSS preview

Merchants need to see widget before pasting embed snippet. Fix: 044cc65 — live preview renders the production widget bundle in an isolated iframe; same sanitiser as production. WYSIWYG that actually matches WYG.

/ Workflow

Merchant signs up, pastes a product feed URL into DataFlow, enrichment-service pulls the catalogue and Gemini fills missing fields. Data lands in Postgres scoped by tenant. Merchant enables modules, the dashboard generates a widget snippet, and the first shopper conversation streams within hours. In parallel: the MCP server makes the catalogue queryable by ChatGPT and Gemini agents natively.

/ 90-day build timeline

Phase 1 — Repo created

Early February 2026. Empty Nx + pnpm workspace, Supabase provisioned, Edge Functions skeleton, tenants table with RLS on day 1.

Phase 2 — First three modules live

FlowGuide + ShopScout + ProductGenie ship with backend Edge Functions, dashboard config and widget integration.

Phase 3 — DataFlow + enrichment

Self-hosted Node + Express + Drizzle. Gemini wired up, dual auth lands (244df94), DataFlow UX collapses from 3 tabs to 1 flow (6f29844).

Phase 4 — Landing extracted

Late February. Commit 513d2da (108 files), ThemeToggle hydration fix, build-time env-var crash fix (31ef7a3).

Phase 5 — Widget polish

Custom CSS sanitiser for XSS-safe injection (ac050ed); visual template builder with live CSS preview (044cc65).

Phase 6 — ACP/UCP + MCP layer

Early March. Commerce Pages + ChatGPT Apps integration; custom MCP server + discovery layer let AI platforms query catalogues natively; dead GCS dep removed (ea76397).

/ Stack

Two stacks: Vercel-deployed frontend (Next.js 15 + React 18/19 + Tailwind + shadcn) and Supabase-hosted backend (Postgres + Deno Edge Functions + Gemini + custom MCP). Nothing chosen for novelty. Each line has a reason.

/ Tech

Next.js 15 + React 19

Landing — SSG/ISR for SEO; dynamic article rendering avoids build-time Supabase fetches.

React 18 + Vite

Dashboard — interactive SPA with Vite HMR for fast dev, JWT auth against Supabase.

Nx + pnpm

Monorepo — 7 apps, 6 shared packages. Nx dep graph keeps builds fast.

Tailwind + shadcn/ui

Same primitives on landing + dashboard. shadcn = owned code in packages/ui.

Supabase (Postgres + RLS)

Multi-tenant enforced at DB. No app filters by tenant_id.

37 Supabase Edge Functions

Deno runtime — API surface for dashboard, widget and ChatGPT Apps. Zero cold starts.

Google Gemini API

~$0.075 per 1M input tokens. Structured-output mode for product fields. ~10× cheaper than OpenAI for this workload.

Custom MCP server

@modelcontextprotocol/sdk — domain-specific tools typed against the same Postgres schema as the dashboard.

/ Engineering decisions

Seven ADRs that shaped the platform. Each one has a why. If the why ever stops being true, the decision goes back on the table.

/ 7 ADRs

01 — Nx + pnpm monorepo over per-app repos

Shared types auto-generate from Supabase schema, no version skew between widget and dashboard.

02 — Separate landing (Next 15) from dashboard (React 18 + Vite)

Optimal tool for each surface; Vercel rewrites add ~5 ms latency, acceptable.

03 — Supabase over a custom Node API

Zero cold starts on Deno; RLS enforces tenant isolation at DB.

04 — Gemini over OpenAI for enrichment

~10× cheaper per-1M-tokens; quality good enough on structured product fields.

05 — Custom MCP server over off-the-shelf

Domain-specific tools typed against the same Postgres schema as the dashboard.

06 — Embeddable widget over iframe-only

Native-like interactivity, Shadow DOM scoping, XSS-sanitised CSS injection.

07 — Dual auth: JWT for users, X-Api-Key for cron

Cron-only secrets never leak through user sessions.

/ Results

Five modules in 90 days, an architecture a small team can actually ship and maintain. Live on staging; merchants onboard via a single product feed URL.

/ Numbers

7 apps, 6 shared packages

One Nx monorepo. An architecture that lets a small team ship 5 modules in 90 days.

37 Edge Functions

Multi-tenant API powering dashboard, widget and ChatGPT Apps.

2× conversion

ChatGPT-referred traffic converts vs organic search (Similarweb 2025) — the data the platform bets on.

800M+ weekly users

ChatGPT weekly active users in 2025 (OpenAI) — the discovery channel merchants are aiming at.

AI Commerce
Nx Monorepo
Next.js 15
Supabase
MCP Server
Gemini
Multi-tenant
RLS
Edge Functions
React 19
AI Commerce
Nx Monorepo