Findings
Specific issues, severity, evidence, and recommended fixes from the sample review.
High: Supabase service access pattern
Evidence: Public JavaScript referenced Supabase project config and performed direct table reads from the browser.
Fix: Confirm no service-role key is present, rotate all keys, enforce RLS on every table, and add tenant-isolation tests for anonymous, authenticated, and cross-account users.
High: Admin route rendered publicly
Evidence: /admin returned a 200 response and loaded dashboard chrome before redirecting on some client states.
Fix: Move auth and role checks into server middleware or route loaders. Never rely on hidden links or client-side redirects for admin protection.
High: Stripe workflow trusted client state
Evidence: Checkout state was assembled in browser code and did not show a server-side price or tenant verification step.
Fix: Create checkout sessions server-side, verify tenant ownership before session creation, and validate webhook events before changing account state.
Medium: Missing security headers
Evidence: The production domain did not return Content-Security-Policy, HSTS, or Referrer-Policy headers.
Fix: Add hosting-level headers, start with report-only CSP if needed, and verify third-party scripts before enforcement.
Medium: No rollback plan
Evidence: Schema changes were applied manually in Supabase with no migration history in the repo.
Fix: Move schema changes into migrations, require review before production changes, and document rollback for destructive operations.
Low: Observability gap
Evidence: Failed API calls appeared in the browser console, but no error tracking or alerting target was configured.
Fix: Add error monitoring, uptime checks, and a lightweight incident checklist before launching paid users.