TLDR: Shipping a Next.js SaaS to real, paying, hostile users takes more than a green build. This checklist enumerates 27 concrete things — across security and data, payments and billing, and observability and testing — that stand between a demo and production. Vibe44 ships most of the 27 by default, backed by RLS across 32 tables, 900 Vitest unit tests, and 9 Playwright E2E suites. Doing all 27 yourself from scratch is roughly 480 hours of foundation work, about $36,000 in engineering time.
"It works on my machine" is not a launch plan. Here are the 27 things standing between your demo and a SaaS that survives real, paying, hostile users — the ones who fuzz your API, double-click your checkout button, and live in a timezone where your error monitoring is asleep.
Most launch checklists you find are vibes. "Add error handling." "Make sure billing works." "Test it." Useless. A real production checklist is specific enough that you can tick each item with a yes or no and know you are not lying to yourself. That is what this is. Three sections, 27 numbered items, no padding. Tick them honestly before you point a domain at your app.
What does security and data hardening actually require?
Security is where the silent failures live. Your app returns 200 OK while leaking another tenant's data. Your CSRF token validates against nothing. Your server fetches a URL an attacker controls. None of these throw a stack trace. You find out when a customer does, or when someone on the internet does it for you.
The foundation is defense-in-depth: each layer enforces the constraint independently, and no layer trusts another to do its job. App-layer auth checks the session; the database layer enforces isolation in policy. If one is wrong, the other still holds. For the full mapping of which web vulnerabilities matter most here, The OWASP Top 10 (2025) Checklist for Next.js SaaS — and How to Actually Cover It walks the categories one by one. This section is the launch-blocking subset.
Here is the security and data checklist. Tick each one.
- Enable Row-Level Security on every tenant-scoped table. RLS executes inside PostgreSQL on every SELECT, INSERT, UPDATE, and DELETE before a row reaches the caller. App-layer filters get forgotten when someone adds a new endpoint; database policies do not. Partial coverage is false confidence — an attacker needs one unguarded table, not all of them.
- Write matching policies for reads and writes. A tenant restricted to SELECTing their own rows but free to INSERT rows with an arbitrary
tenant_idcan poison another tenant's dataset. Every operation needs a corresponding policy, not just reads. - Audit every use of the database service-role key. Supabase's service-role key bypasses RLS entirely — that is its purpose. Any user-facing handler that initializes the client with it operates outside all your policies. Reserve it for deliberate elevated operations, keep the boundary explicit, and grep for it in code review.
- Bind CSRF tokens to the session, not a static secret. A CSRF token that validates against a fixed value or nothing is theater. HMAC-bind the token to the session so a token issued to one user cannot be replayed by another. Validate on every state-changing request.
- Guard against SSRF on every outbound fetch. Any feature that fetches a user-supplied URL — webhooks, image proxies, link previews — can be tricked into hitting internal services or cloud metadata endpoints. Validate and allowlist destinations, block private IP ranges, and refuse redirects to them.
- Set hardened security headers on every response. Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, and Referrer-Policy are cheap and load-bearing. Missing CSP turns a single XSS into total account takeover. Set them at the framework edge so they apply everywhere.
- Keep secrets out of the repo and the client bundle. API keys, database URLs, and signing secrets belong in environment variables loaded server-side, never in
NEXT_PUBLIC_vars and never committed. Audit your client bundle for leaked keys before launch — anything prefixed for the browser is public forever. - Rotate and scope every credential. Use least-privilege keys: a read-scoped key where you do nothing but read, a restricted key per integration. Have a rotation path that does not require a redeploy panic. A leaked all-powerful key is a breach; a leaked scoped key is an incident.
- Enforce server-side input validation on every endpoint. Client-side validation is UX, not security. Validate and parse every request body, query param, and header on the server with a schema. Reject malformed input before it touches your database or business logic.
- Hash passwords and protect the auth core. Sessions, multi-factor authentication, and PKCE for OAuth flows are table stakes. Store password hashes with a modern algorithm, expire sessions sensibly, and make MFA available before launch, not after the first account-takeover support ticket.
- Rate-limit authentication and expensive endpoints. Login, password reset, signup, and any AI- or compute-heavy route need rate limits keyed by IP and account. Without them, credential-stuffing and cost-bombing attacks are trivial and free for the attacker.
- Lock down database and storage access at the network edge. Your PostgreSQL instance and object storage should not be open to the public internet beyond what your app needs. Use connection pooling, restrict origins, and treat your storage buckets as private by default with signed URLs for access.
Twelve items, and not one of them is optional for a multi-tenant app. The hard truth: hand-rolling all twelve from scratch — schema policies, HMAC CSRF, SSRF guards, header config, secrets discipline, the auth core — is where most of that 480-hour foundation estimate comes from. Security is not a feature you bolt on at the end. It is the floor you build on.
How do you make payments and billing production-safe?
Payments are the one part of your app where bugs cost money directly — yours or your customers'. The failure modes are nastier than they look. A webhook that fires twice grants a subscription twice. A failed charge that goes unhandled silently downgrades a paying customer to nothing. A plan check that lives just in the UI lets anyone with the dev tools open hit your premium endpoints for free.
The core discipline is that your billing state must be driven by provider events, verified and idempotent, and your access control must be enforced server-side against that state. The UI is a hint. The server is the truth. If you are choosing or abstracting a provider, Next.js SaaS Boilerplate: Build vs. Buy — The Real 2026 Cost Math breaks down where the hidden time goes; payments integration is consistently underestimated.
Here is the payments and billing checklist, continuing the count.
- Verify every incoming webhook signature. Webhook endpoints are public URLs. Anyone can POST to them. Verify the provider's signature on every event before you trust a single field. An unverified webhook handler is an open door to forge subscription grants.
- Make webhook processing idempotent. Providers retry events, and networks duplicate them. Store each event's unique ID and skip events you have already processed. Without idempotency, one delivery retry can double-grant a subscription, double-count usage, or double-fulfill an order.
- Reconcile billing state from events, not from the checkout redirect. Never grant access because the user landed on your success page. They can navigate there directly. Grant access just once the verified
checkout.completedor equivalent event arrives and updates your database. The redirect is UX; the event is truth. - Handle failed and recovered payments with dunning. A card declines on renewal. What happens? If the answer is "nothing," you just lost a paying customer silently. Implement dunning: retry on a schedule, notify the customer, and downgrade gracefully once the recovery window closes — not on the first decline.
- Gate every paid feature on the server. Plan entitlement checks must run in your API routes and server actions, reading from your billing state. A feature flag checked just in React is bypassable in seconds. The server decides what a given subscription can access.
- Handle the full subscription lifecycle. Upgrades, downgrades, cancellations, pauses, and trial expirations each change what a customer can do. Map every state transition to an entitlement change and test the proration and timing edges. Mid-cycle upgrades are the classic place this breaks.
- Persist an immutable record of every billing event. Keep an append-style log (never updated in place) of what the provider told you and how you responded. When a customer disputes a charge or your numbers do not reconcile, this log is the difference between a five-minute answer and a forensic nightmare.
- Test webhooks against real provider payloads. Provider sandbox events have edge cases your hand-written fixtures will not — nullable fields, currency rounding, partial refunds. Replay real sandbox payloads through your handler in CI so a schema change from the provider does not silently break renewals.
Eight items here, items 13 through 20. The pattern across all of them is the same: trust verified events, dedupe everything, enforce on the server. A normalized webhook layer that handles signature verification, idempotency, and lifecycle events the same way across providers is exactly the kind of plumbing that takes weeks to get right and is invisible when it works.
What does observability and testing look like before you launch?
You cannot fix what you cannot see, and you cannot ship with confidence what you have not tested. This section is the difference between learning about an outage from your dashboard and learning about it from an angry tweet. Observability tells you what is breaking in production; tests stop you from shipping the break in the first place.
The mindset shift: in production, errors are data, not surprises. Every unhandled exception, every slow query, every failed background job should land somewhere you can search, alert on, and trace back to a release. And your test suite is not there to hit a coverage number — it is there so that the next change, including changes you did not write yourself, cannot silently regress a guarantee you already shipped.
Here is the observability and testing checklist, finishing the count.
- Wire up error monitoring before launch, not after the first outage. Capture unhandled exceptions on both server and client with full stack traces, request context, and the affected user. Your Sentry config should be in place and verified with a test error before you go live. Flying blind in production is a choice.
- Set up alerting with sane thresholds. Monitoring you do not get paged for is a diary, not an alarm. Define what an incident looks like — error rate spike, latency regression, failed-payment surge — and route those alerts somewhere a human will actually see them off-hours.
- Add structured logging with request correlation. Logs without a correlation ID are noise. Tag every log line with a request ID so you can reconstruct a single user's failing request end to end. When something breaks at 2 a.m., grep-able structured logs are how you find it fast.
- Run a CI pipeline that gates merges on green. Your
.github/workflows/should run lint, type-checks, and the full test suite on every pull request, and block the merge if anything fails. CI that does not block is decoration. The point is that broken code cannot reach main. - Maintain a real unit test suite over critical logic. Billing math, entitlement checks, auth flows, and data-access helpers are where bugs cost the most — cover them with fast unit tests in
tests/. A meaningful suite (Vibe44 ships 900 Vitest unit tests) is what lets you refactor without holding your breath. - Cover critical paths with end-to-end tests. Signup, login, checkout, and the core product loop need browser-level E2E tests that exercise the real stack. Unit tests prove functions work; E2E tests prove the user can actually pay you. Vibe44 ships 9 Playwright E2E suites over exactly these flows.
- Test your security guarantees explicitly. RLS policies, CSRF binding, and authz checks are code — they can be wrong when written and regress when changed. Write tests that assert tenant A cannot read tenant B's rows and that an unauthorized request is rejected. A guarantee with no test is a hope.
That is item 27. Twenty-seven concrete things, numbered continuously, distributed across security and data (1-12), payments and billing (13-20), and observability and testing (21-27). Print it, paste it into your launch ticket, and refuse to ship until each line is a yes.
How does Vibe44 tick most of this list by default?
Here is the part that changes the math. Most of the 27 items above ship in Vibe44 out of the box. You are not starting from a blank repo and a 480-hour foundation. You are starting from a hardened baseline and adding your product on top.
The mapping is direct. On security and data: RLS is enabled across 32 Supabase tables with tenant-scoping policies already written, covering items 1 and 2 — schema definitions live in lib/db/ and the policies ship in the migration history. CSRF is HMAC-bound to the session (item 4), SSRF guards protect outbound fetches (item 5), and hardened security headers are set at the edge (item 6). The security primitives live in lib/security/, and the whole posture is aligned to the OWASP Top 10 (2025), which covers the spirit of items 7 through 12. The auth core — sessions, MFA, and PKCE — is built in, ticking item 10.
On payments: the Universal Payment Adapter abstracts Stripe, Lemon Squeezy, Polar, Dodo, and Creem behind one interface, with normalized webhooks that handle signature verification and idempotency the same way across providers — items 13, 14, and 15, the easiest plumbing on the list. The lifecycle and entitlement scaffolding (items 17 and 18) comes wired to that adapter, so plan gating runs server-side rather than in the UI.
On observability and testing: Sentry error monitoring is configured (item 21), GitHub Actions CI/CD runs on every change in .github/workflows/ and gates merges (item 24), and the test suite is substantial — 900 Vitest unit tests over critical logic (item 25) and 9 Playwright E2E suites over signup, login, and checkout (item 26). The RLS and security tests assert the guarantees from item 27 actually hold.
| Checklist area | Items | Vibe44 ships by default |
|---|---|---|
| Security & data | 1-12 | RLS across 32 tables, HMAC-bound CSRF, SSRF guards, hardened headers, OWASP Top 10 (2025)-aligned, auth core (sessions, MFA, PKCE) |
| Payments & billing | 13-20 | Universal Payment Adapter (Stripe/Lemon Squeezy/Polar/Dodo/Creem), normalized webhooks (verification + idempotency), lifecycle + server-side gating |
| Observability & testing | 21-27 | Sentry error monitoring, GitHub Actions CI/CD, 900 Vitest unit tests, 9 Playwright E2E suites, explicit security tests |
The honest tradeoff: Vibe44 hands you the foundation, not your product. Your specific dunning copy, your alerting thresholds, your domain-specific E2E paths — those are yours to write. But the structural items, the ones that take weeks and are invisible when they work, are already done. That DIY foundation is roughly 480 hours. In 2026, with senior full-stack engineer rates averaging $80–$180+/hr in the US and Canada, a mid-complexity SaaS MVP routinely costs between $40,000 and $150,000 to build. That foundational boilerplate alone accounts for about $36,000 of engineering time. The license is $197 one-time. The detailed build-vs-buy breakdown lives in Next.js SaaS Boilerplate: Build vs. Buy — The Real 2026 Cost Math, and numerous solo founders have run that math already.
How does the agent-native design keep you production-ready after launch?
Passing all 27 at launch is one thing. Staying green when you — or an AI coding agent — change the code next week is another. This is where most boilerplates quietly fall apart: the foundation is solid on day one and full of holes by day thirty, because every change risks regressing a guarantee nobody re-tests.
Vibe44 is built so that agent changes stay safe. Two mechanisms do the work.
First, Graphify. It builds AST-level knowledge graphs of the codebase so an AI agent understands structure — which function calls which, where a policy is enforced, what a change touches — instead of grepping blindly through files. That structural awareness delivers up to 71.5x token cost reduction, but the production-readiness benefit is bigger than cost: an agent that understands the dependency graph is far less likely to "fix" one thing and silently break the RLS policy or the webhook handler three files away. The deep dive on this is How to Cut AI Coding Token Costs Up to 71.5x With a Codebase Knowledge Graph, but the headline is that context is what keeps agents from introducing regressions.
Second, the test suite is the safety net under every change. Those 900 Vitest unit tests and 9 Playwright E2E suites are not just a launch checkbox — they are the gate that catches a regression before it ships. When an agent modifies billing logic, the entitlement tests run. When it touches data access, the RLS tests run. CI in .github/workflows/ blocks the merge if any guarantee breaks. The combination means item 27 — test your security guarantees — keeps paying off long after launch, on every change, whether a human or an agent wrote it.
That is the agent-native advantage in production terms: not just faster development, but a codebase where the 27 things stay true. Graphify gives the agent the map; the tests give it the guardrails. You can move fast without the foundation rotting underneath you.
Want to see it running? demo.vibe44.com is the full stack live, and you can read the actual structure rather than take the claims on faith.
Get the checklist, then see how many you already cover
Copy the 27 items above straight into your launch ticket. Use them as a hard gate — no item ships as a "we'll do it later." That is the entire value of a checklist: it makes the lie of "we're basically ready" impossible.
Then do the build-vs-buy math on the time to actually satisfy all 27. Hand-rolling the foundation — RLS across every table, HMAC CSRF, SSRF guards, hardened headers, a normalized payment layer, error monitoring, CI, and a real test suite — is roughly 480 hours and about $36,000 of engineering time before you write a single line of your actual product. Vibe44 ships most of the 27 by default for a $197 one-time license, which is why top founders started there instead of from a blank repo.
Get the checklist — then see how many Vibe44 already covers at demo.vibe44.com.
Frequently asked questions
1. How many of the 27 items does Vibe44 ship by default?
Most of them. Across security and data (items 1-12), Vibe44 ships RLS on 32 tables, HMAC-bound CSRF, SSRF guards, hardened headers, an OWASP Top 10 (2025)-aligned posture, and the auth core. Across payments (13-20), it ships the Universal Payment Adapter with normalized, verified, idempotent webhooks and server-side gating. Across observability and testing (21-27), it ships Sentry, GitHub Actions CI/CD, 900 Vitest unit tests, and 9 Playwright E2E suites. What you still own is your product-specific logic — dunning copy, alert thresholds, and domain E2E paths.
2. How long does it take to satisfy all 27 from scratch?
Building the foundation yourself — schema policies, security primitives, a normalized payment layer, error monitoring, CI, and a meaningful test suite — is roughly 480 hours, about $36,000 in engineering time, before any product work. That figure is why the build-vs-buy decision matters: a $197 one-time license covers most of the 27 on day one.
3. Which of the 27 items are the most commonly skipped before launch?
Idempotent webhook processing (item 14), reconciling billing from events rather than the redirect (item 15), dunning for failed payments (item 16), and testing security guarantees explicitly (item 27). They are skipped because they are invisible until they fail — and when they fail, they fail as silent revenue loss or a silent data leak rather than a loud crash.
4. Is app-layer authorization enough, or do I really need RLS?
You need both. App-layer authz is the first line, but it gets forgotten the moment someone adds a new endpoint without the right filter. RLS (items 1-3) enforces tenant isolation inside PostgreSQL on every query, regardless of which code path issued it. That is defense-in-depth: if one layer is wrong, the other still holds.
5. How does Vibe44 keep these 27 things true after I start changing the code?
Through Graphify and the test suite working together. Graphify builds AST knowledge graphs so an AI agent understands the codebase structure — up to 71.5x token cost reduction — and is far less likely to break a distant guarantee while editing. The 900 unit tests and 9 E2E suites then run in CI on every change and block the merge if any guarantee regresses. The result is a foundation that stays green instead of rotting after launch.






