Holdfast

This page is the short version of a rescue audit.

The full deal review adds a deal card for brokers, a risk map, costs in pounds, open source and IP, AI features, cost and scalability, privacy, questions for the seller and the evidence behind every finding.

Download the 11-page sample deal review (PDF)

Rescue audit, buyer-side, delivered in 7 working days

Sample Co. booking platform

B2B appointment-booking SaaS for small clinics. About 140 paying customers, listed at £9,400 monthly recurring revenue. Under offer to a non-technical buyer.

Stack

Next.js, Supabase, Stripe, Vercel. Partly built with Cursor

Access used

Read-only: repo, Vercel, Supabase, Stripe, test account

Verdict

Fix, don't rebuild. About 18 hours before completion.

The data model is sound and the product works. The serious problems are a handful of configuration and access mistakes, not a rotten codebase. Two of them expose every customer's data today and must be fixed before money changes hands. The rest can follow in the first month of ownership.

What this means for the deal

Before completion

Ask the seller to fix findings 1 to 3 and move the accounts in finding 5 into the business's name. About 14 hours of work. If they won't, agree who pays for it.

Revenue check

Stripe shows £9,050 a month, not the listed £9,400. Two annual plans were counted as monthly. Worth raising with the seller.

After close

Findings 4, 6, 7 and 8 fit into the first 30 days. None blocks the sale, but finding 6 is quietly leaking revenue.

Scorecard

1. Secrets and accessCRITICAL
2. Authentication and authorisationHIGH
3. Data protectionCRITICAL
4. PaymentsHIGH
5. DependenciesMEDIUM
6. Backups and recoveryHIGH
7. Hosting and deploymentHIGH
8. Monitoring and errorsMEDIUM
9. Code healthMEDIUM
10. Data modelSOUND

Top findings

CRITICAL

1. Admin database key shipped to every browser

What
The Supabase service key, which bypasses all security rules, is included in the front-end code. Anyone who opens the site's developer tools can copy it.
Business risk
Anyone can read, change or delete every customer's data. A breach here is a reportable data incident.
Fix
Rotate the key today, move the two calls that use it to the server. About 3 hours.
CRITICAL

2. Customers can see other customers' bookings

What
Row-level security is switched off on 4 of 11 tables, including bookings and invoices. Changing one number in a request returned another clinic's records.
Business risk
Patient appointment data from one clinic is visible to others. Serious for trust and for UK GDPR.
Fix
Turn on and test rules for all 11 tables. About 6 hours.
HIGH

3. Payment webhook can be faked

What
The endpoint Stripe calls after a payment doesn't check the signature, so anyone can send a fake "paid" message.
Business risk
Accounts can be upgraded without paying. No sign it has been abused yet.
Fix
Verify signatures and ignore repeats. About 3 hours.
HIGH

4. Backups exist, restore never tested

What
Daily database backups are on, but nobody has ever restored one. Uploaded files (clinic logos, PDFs) aren't backed up at all.
Business risk
A bad migration or deletion could mean days of downtime, or permanent loss of uploaded files.
Fix
Test a restore on a copy, add storage backups, write a one-page recovery note. About 4 hours.
HIGH

5. Key accounts belong to the founder personally

What
The domain, Vercel and Stripe accounts sit under the founder's personal email and card.
Business risk
If these don't transfer cleanly, the buyer doesn't fully own the business they paid for.
Fix
Move each into the company's name before completion. About 2 hours, plus the seller's time.

All findings

#FindingAreaSeverityHours
1Service key in front-end bundleSecretsCRITICAL3
2Row-level security off on 4 tablesData protectionCRITICAL6
3Webhook signature not verifiedPaymentsHIGH3
4Restore untested, files not backed upBackupsHIGH4
5Accounts in founder's personal nameHostingHIGH2
6Cancelled plans keep access for 30 days on 2 of 3 code pathsCode healthMEDIUM10
7Framework two major versions behind; 3 high-severity package advisoriesDependenciesMEDIUM4
8No tests on billing; error alerts go to an inbox nobody readsMonitoringMEDIUM6
9README doesn't run; 14 unused routesCode healthLOW3
Critical and high total18
All findings total41

Transfer checklist

Every account the business depends on, and whether it moves cleanly to the buyer.

AccountHeld byTransfer routeStatus
DomainFounder, personalRegistrar account transferACTION
Vercel hostingFounder, personalMove project to a company teamACTION
StripeFounder, personalStripe account ownership changeACTION
SupabaseCompany organisationChange organisation ownerREADY
GitHub repoCompany organisationChange organisation ownerREADY
Email sending serviceCompanyChange account ownerREADY
AnalyticsFormer contractorRecreate under companyACTION
Error trackingCompanyChange account ownerREADY
SMS reminders APICompanyCheck terms allow a change of ownerCHECK

30-day fix plan

  1. Before completion: rotate the leaked key and move it server-side (1), switch on row-level security (2), verify webhooks (3), move accounts into the company's name (5).
  2. Week 1 of ownership: test a restore and add file backups (4). Recreate analytics under the company.
  3. Weeks 2 to 3: put cancellation logic in one place and close the 30-day access gap (6). Add tests around billing (8).
  4. Week 4: upgrade the framework and patch flagged packages (7). Route error alerts to someone who acts on them.

Keeping it safe after the fixes

Monthly: patch dependencies, check that backups ran and a restore still works, review error alerts and uptime, and remove access for anyone who has left. About 2 to 4 hours a month for an app this size.

Want this for a real deal?

Fixed fee from £950 (£2,500 to £3,500 for deals over £250K), seven to ten working days, read-only access. Book 15 minutes to see if it fits.

Book a call