Structured SEO audit findings, from record to deliverable.
Every finding is the same 40 fields, grouped as identity, scope, evidence, impact, remedy, risk, priority and lifecycle. Because the record is fixed, one finding can be sorted by score, filtered to an owner, grouped by template, counted by band, and exported to four formats without being retyped.
The document is a view of the register, not the other way round.
- Supabase for Postgres, OAuth, row level security and evidence storage
- React + Vite + TypeScript, no server of its own
- Cloudflare Pages at
auditbuilder.jakelabate.com
| Format | How it works |
|---|---|
| JSON | The full nested record, grouped exactly like the schema |
| CSV | The flat register projection, stable column order |
The browser's own print engine against src/export/print.css.ts, which uses @page and mm units. No rendering service and no cost |
|
| Google Sheets | Creates a new sheet in the user's Drive using the drive.file scope only, which Google classifies as non-sensitive: the app can only touch files it created |
npm install
cp .env.example .env # fill in VITE_GOOGLE_CLIENT_ID if you want Sheets
npm run dev- Supabase Auth providers. Dashboard → Authentication → Providers. Enable
Google and GitHub, paste each client id and secret, and add the callback
https://vvekkbboqqkxnlpmxazh.supabase.co/auth/v1/callbackto both. - Redirect URLs. Dashboard → Authentication → URL Configuration. Add
https://auditbuilder.jakelabate.comandhttp://localhost:5173. - Cloudflare Pages. Connect this repo, build command
npm run build, output directorydist. AddVITE_SUPABASE_URL,VITE_SUPABASE_PUBLISHABLE_KEYandVITE_GOOGLE_CLIENT_IDas environment variables, then attach the custom domain. - Google Cloud, for Sheets only. Create an OAuth client of type Web,
authorized origin
https://auditbuilder.jakelabate.com, scopehttps://www.googleapis.com/auth/drive.file. Sheets export is hidden untilVITE_GOOGLE_CLIENT_IDis set, so the app works without it.
src/
lib/ supabase client, types mirroring the schema, the score formula, data access
pages/ Login, Brands, BrandView, AuditView
components/ Chrome, FindingEditor
export/ serialize (JSON + CSV), pdf, print.css, sheets
supabase/ schema notes and how to pull the migrations
impact_basis is required whenever a quantity is asserted. The editor
refuses to call a finding complete without it. Every number the document
prints has to say where it came from.
verification_method is written before the fix, not after. It is what
makes the register still useful six months later.