Skip to content
prodworthy Get a production audit
SampleFictional app · real format This is what $390 gets you
§ Production audit · PW-A-SAMPLE

Coachbook:
production audit

App
Coachbook (fictional): bookings and payments for independent fitness coaches
Built with
Lovable, synced to GitHub
Stack
React + Vite · Supabase (Postgres, Auth, 4 Edge Functions) · Stripe
Users
~340 registered · 41 paying
Delivered
46 hours after payment
Target
AWS, in the client's own account
01 Summary

It works and people pay for it. It is not safe to grow.

Two critical issues expose every coach's client list and let anyone issue refunds from your Stripe account. Neither needs skill to exploit. There are no backups you can restore, and no one is told when something breaks.

The code itself is reasonable. This is a cleanup, not a rebuild. Everything below fits in a 14-day Launch Package.

Already fine
  • Supabase Auth with email verification
  • TypeScript strict, build passes
  • Clean schema, sensible foreign keys
  • Code already in GitHub
02 Severity

10 findings, ranked

Severity Count Findings When Effort
CRITICAL 2 F-01, F-02 Before anything else 7h
HIGH 3 F-03 – F-05 Before you market the app 10h
MEDIUM 4 F-06 – F-09 During the deployment 14h
LOW 1 F-10 When convenient 2h
Total engineering effort, included in the fixed quote 33h
03 Findings

What's wrong, what it costs you, how we fix it

F-01 CRITICAL Effort · 4h

Row Level Security is off on bookings, clients and payments

Supabase · public schema
Impact
The anon key ships in your frontend, as designed. With RLS off, that key can read and change every row in these tables. Anyone can download every coach's client list.
Fix
Day 1: enable RLS with owner-scoped policies (coach_id = auth.uid()), tested with two accounts in CI. After the move to RDS, the API enforces the same rule.
F-02 CRITICAL Effort · 3h

Stripe secret key is in the client bundle

src/lib/stripe.ts · VITE_STRIPE_SECRET_KEY
Impact
Anyone can read it in DevTools, then issue refunds, list your customers or create charges on your account.
Fix
Roll the key in Stripe today, before anything else. Move payment calls to the API. Keep the new key in AWS Secrets Manager.
F-03 HIGH Effort · 1h

Stripe webhook doesn't verify signatures

supabase/functions/stripe-webhook
Impact
Anyone can POST a fake checkout.session.completed event and unlock a paid plan for free.
Fix
Verify the Stripe-Signature header with the endpoint secret. Reject events older than five minutes.
F-04 HIGH Effort · 6h

No backups you control

Supabase Free plan
Impact
No point-in-time recovery and no backup you can restore yourself. One bad migration is permanent, with 41 paying customers on it.
Fix
Move app data to RDS Postgres with automated backups and 7-day point-in-time recovery. Supabase Auth stays, so users keep their logins. Run a restore drill before handoff.
F-05 HIGH Effort · 3h

No rate limiting on sign-up, sign-in or booking

Auth endpoints · supabase/functions/create-booking
Impact
A script can create thousands of fake accounts and bookings, burn your email quota and fill coaches' calendars with junk.
Fix
AWS WAF rate-based rules in front of the API, per-user limits in the booking handler, CAPTCHA on sign-up.
F-06 MEDIUM Effort · 2h

Stored XSS in coach bios

src/components/CoachProfile.tsx · dangerouslySetInnerHTML
Impact
A coach can save a script in their bio that runs in every client's browser and takes over their session.
Fix
Render bios as text, or sanitize with DOMPurify. Validate input on write.
F-07 MEDIUM Effort · 4h

No error tracking or alerting

Whole app
Impact
You find out about outages from customers. Failed payments and bookings leave no trace.
Fix
Sentry on the frontend and API. CloudWatch alarms on 5xx rate, p95 latency and database CPU, sent to email or Slack.
F-08 MEDIUM Effort · 2h

14 dependencies with known vulnerabilities

package-lock.json · 2 high, 12 moderate
Impact
Public exploits exist for the two high-severity packages.
Fix
Upgrade, remove three unused packages, turn on Dependabot with weekly PRs.
F-09 MEDIUM Effort · 6h

No staging. Every change goes straight to production

Lovable → production
Impact
Every edit in the builder is tested on paying customers.
Fix
Separate staging and production environments. CI deploys main to staging; a tagged release goes to production.
F-10 LOW Effort · 2h

N+1 queries on the coach dashboard

src/pages/Dashboard.tsx
Impact
One query per booking. For a coach with 200 bookings, the dashboard takes 2.8 s to load.
Fix
One joined query plus an index on (coach_id, starts_at).
04 Recommended AWS tier

Standard, about $80–107 a month

Paying users and payments mean you need backups you control and a staging environment. Serverless would mean reshaping the API, which isn't worth it at this size. Costs are on-demand prices in us-east-1, billed to you by AWS.

Component Per month
CloudFront + S3 · frontend $1–3
ECS Fargate · 1 task, 0.5 vCPU / 1 GB $18–22
Application Load Balancer $17–22
RDS Postgres · db.t4g.micro, 20 GB, 7-day PITR $14–17
Staging · smaller task + DB, shared ALB $15–22
AWS WAF · 1 web ACL, 3 rules $8–10
CloudWatch · logs, metrics, alarms $4–8
Secrets Manager · 4 secrets $2
Route53 · hosted zone $1
Total $80–107
architecture.txt
users
  └─▶ CloudFront ─▶ S3          frontend
        └─▶ WAF ─▶ ALB ─▶ Fargate API
                          ├─▶ RDS Postgres
                          ├─▶ Secrets Manager
                          └─▶ Stripe
Supabase Auth  logins stay put
CloudWatch + Sentry ─▶ alerts
New-account AWS credits ($100–200) cover roughly the first one to two months.
05 Quote

Launch Package · 14 days · fixed

Launch Package
$2,900
Audit credit
−$390
You pay
$2,510

$1,255 to start · $1,255 at handoff
AWS hosting billed to you separately

  1. Days 1–2 Critical fixes live in production: F-01, F-02, F-03
  2. Days 3–7 Edge Functions ported to an API on Fargate, data moved to RDS, staging environment
  3. Days 8–11 Remaining fixes, tests, monitoring, restore drill
  4. Day 12 Staging demo. You test it.
  5. Days 13–14 Production cutover, video walkthrough, runbook. Our access removed.
06 Verdict

Prodworthy: not yet → here's what it takes.

2 critical · 3 high14 days$2,510 after audit credit

Get yours

Same format, your app. $390, 48 hours, credited toward any package.

Get a production audit