BrandGuard AI reviews human-written marketing drafts against a saved Brand Profile. It flags voice, terminology, reading-level, and banned-claim drift, assigns a brand-fit score, and produces a corrected version before publication.
The current repository implements the complete Phase 1–5 MVP described in SPEC.md: authentication, one Brand Profile per owner, Gemini-powered reviews, review history, a three-review trial, Stripe billing, and production-readiness coverage.
- Next.js 14 App Router with strict TypeScript
- Supabase Postgres and Auth with Row-Level Security
- Tailwind CSS and shadcn/ui primitives
- Google Gemini REST API
- Stripe Checkout, Customer Portal, and verified webhooks
- Vitest and Playwright
- Vercel deployment target
- Node.js 20 or newer
- npm
- A Supabase project
- A Google AI Studio Gemini API key
- A Stripe account with one recurring monthly Price
- Supabase CLI and Stripe CLI for the recommended local workflow
Copy .env.example to .env.local and replace every placeholder.
| Variable | Exposure | Purpose |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Browser-safe | Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Browser-safe | Supabase anonymous key; RLS enforces access |
NEXT_PUBLIC_SITE_URL |
Browser-safe | Canonical site and OAuth/billing return URL |
GEMINI_API_KEY |
Server-only | Gemini API authentication |
GEMINI_MODEL |
Server-only | Gemini model used for reviews; defaults to gemini-3.5-flash-lite |
STRIPE_SECRET_KEY |
Server-only | Stripe server API authentication |
STRIPE_WEBHOOK_SECRET |
Server-only | Stripe webhook signature verification |
STRIPE_PRICE_ID |
Server-only | Single recurring BrandGuard Pro Price |
SUPABASE_SERVICE_ROLE_KEY |
Server-only | Verified webhook database updates only |
Never prefix a server-only variable with NEXT_PUBLIC_.
npm install
npm run devOpen http://localhost:3000.
Apply migrations in filename order from supabase/migrations using a linked Supabase CLI project:
supabase link --project-ref YOUR_PROJECT_REF
supabase db pushThe initial migration creates brand_profiles, reviews, and subscriptions, their enums, constraints, and owner-scoped RLS. The review-access migration makes trial claiming and rate limiting atomic, revokes direct review mutation privileges, and exposes narrowly scoped authenticated functions.
In Supabase Authentication:
- Enable Email authentication.
- Enable Google and add its OAuth client credentials.
- Add
http://localhost:3000/auth/callbackto local redirect URLs. - Add
https://YOUR_DOMAIN/auth/callbackbefore production deployment.
The Playwright signup test is simplest against local Supabase or a dedicated test project where email delivery cannot affect production users.
Create a Gemini API key in Google AI Studio and set GEMINI_API_KEY. GEMINI_MODEL is optional and defaults to gemini-3.5-flash-lite. Gemini is called only from the server-side adapter in src/lib/ai/brand-review.ts; the key is absent from browser bundles.
- Create one Product and recurring monthly Price; set its ID as
STRIPE_PRICE_ID. - Configure Customer Portal so customers can update payment methods and cancel subscriptions.
- Register
/api/stripe/webhookfor:checkout.session.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_failed
- Save the endpoint signing secret as
STRIPE_WEBHOOK_SECRET.
For local webhook forwarding:
stripe listen --forward-to localhost:3000/api/stripe/webhookUse the whsec_... value printed by that command only for the local listener. Dashboard-managed endpoints have a different signing secret.
npm test
npm run typecheck
npm run lint
npm run build
npm run audit:secretsThe secret audit must run after npm run build. It scans generated client assets for server-only environment names, configured secret values, and common secret prefixes.
The Playwright test covers signup → Brand Profile creation → review result → upgrade. It uses real Supabase Auth and persistence, seeds a deterministic completed review with the test service role, and intercepts only the browser requests that would otherwise call Gemini and Stripe.
Set these variables in the shell that runs Playwright:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEY- Optional:
E2E_TEST_PASSWORD - Optional:
E2E_BASE_URLwhen testing an already-running deployment
Then install Chromium once and run the test:
npx playwright install chromium
npm run test:e2eThe test creates a unique user and deletes it afterward. If the required Supabase test variables are missing, it reports an explicit skip rather than silently passing the workflow.
- Import the repository into Vercel.
- Add every environment variable from
.env.examplefor the appropriate environments. - Set
NEXT_PUBLIC_SITE_URLto the production origin. - Add the production Supabase OAuth callback URL.
- Register
https://YOUR_DOMAIN/api/stripe/webhookin Stripe and use that endpoint's signing secret. - Deploy, then test email login, Google login, one review, Checkout, Portal, and a test webhook event.
- All application tables have Row-Level Security.
- Brand Profiles and reviews are scoped to
auth.uid(). - Direct review writes are revoked; database functions enforce trial and rate limits.
- Stripe webhook bodies are signature-verified before parsing or database access.
- Service-role, Stripe, and Gemini secrets are server-only.
- Every mutating application route validates input with Zod.
- The specification currently fixes Next.js 14. The dependency audit reports advisories whose automated remediation requires a breaking Next.js major upgrade; changing majors requires an explicit specification decision.
Multi-workspace accounts, file parsing, team roles, CMS integrations, browser extensions, third-party API access, usage analytics, and multiple billing tiers are outside the MVP.