Skip to content

v1.0.0 — Production failure modes for Next.js + Supabase (+ Stripe), made runnable

Latest

Choose a tag to compare

@mahdibrr mahdibrr released this 21 Jul 00:26
62b1aeb

v1.0.0 — Production failure modes for Next.js + Supabase (+ Stripe), made runnable

The first tagged release. An awesome-list of production-focused Next.js + Supabase resources, now paired with a runnable examples/ workspace that reproduces real bugs and proves the fixes.

The thesis across the whole repo: nothing throws, nothing crashes, the build is green — and yet the app is quietly wrong. Every incident is written symptom-first (what you see in prod) → root cause → fix → a reusable asset you can copy.

What's in this release

Production Incident Index — 21 incidents

A symptom-first triage table (reference/incident-index/README.md) mapping each incident to its root cause, fix, and a reusable reference asset. Built for debugging under pressure, not reading top to bottom. Covers RLS, SSR sessions, Stripe webhooks, Next.js 15 async params, caching/revalidation, connection pooling, ORM role bypass, Realtime tab suspension, Storage RLS, migrations, pgvector, and middleware.

Runnable examples/ workspace (Tier 1) — 3 examples, broken vs fixed

Each example ships a broken implementation and a corrected one so the diff is the lesson, plus automated verification:

Example Runner Incidents covered Verification
examples/rls-pgtap Supabase CLI + pgTAP INC-002, 003, 015, 018, 021 5 pgTAP files
examples/stripe-webhook-idempotency Vitest (pg-mem, zero services) INC-006, 007, 012, 016 integration tests
examples/nextjs15-cache-and-params Vitest INC-008, 011, 020 unit tests

13 of 21 incidents are covered by a runnable example. examples-ci.yml runs Vitest + pgTAP on every PR touching examples/**.

INC-016 deep dive — Stripe webhook returns 200 OK but business state is wrong

The flagship postmortem. The failure is two-sided: marking the event processed before its side effects commit produces duplicates on retry, while a first attempt that fails after recording the event ID makes retries skip it as already seen — silently dropping the event. The fix is a processing state machine (receivedprocessingprocessed / failed) with per-side-effect idempotency keys, a lease + attempts cap on processing, and reconciliation from the Stripe API for expired/missed events. Backed by a 7-scenario test plan (reference/playbooks/stripe-webhook-test-plan.md) including a reconciliation-backfill scenario, and a copy-ready SQL state machine (reference/templates/stripe-webhook-idempotency-template.sql).

Thanks to @leo-liu-522 for sharpening the INC-016 root-cause wording and contributing the retry-semantics + reconciliation-backfill scenarios.

Postmortems & diagrams

  • Phase 1: RLS empty-array (INC-002), revalidatePath stale-data (INC-008), plus a Stripe webhook state-machine diagram.
  • Phase 2: connection-pool exhaustion (INC-017), ORM bypassing RLS via service_role (INC-018), Realtime tab-suspension (INC-019), Next.js 15 async params/searchParams (INC-020), Storage RLS upload leak/403 (INC-021).

AI-tool guardrails

AGENTS.md + .cursor/rules you drop into your own project, mapping each rule to a real production failure so Cursor / Copilot / Claude Code stop reintroducing RLS-gaps, SSR-session-loss, and webhook-double-processing bugs.

Contributor UX

Issue/PR templates, CODEOWNERS, and a good-first-issues badge so external contributors can land fixes safely.

Reference tree

reference/playbooks/, diagrams/, sql/, templates/, checklists/, and incident-index/.

CI

  • awesome-lint (required): the awesome-list lint rules.
  • Link Check (required): lychee over README, CONTRIBUTING, AGENTS, CLAUDE, content/, reference/, .github/.
  • examples-ci: Vitest (no services) + pgTAP (Postgres service container) on examples/** PRs.

Stats (July 2026)

~176 third-party resources, 12 blog write-ups, ~188 total unique links, 21 incidents, 3 runnable examples. Third-party to blog ratio ~15:1 globally (~11:1 in the core list) — the postmortems cite official docs heavily as evidence.

What's next (not in this release)

Tier 2 examples (local-only): Realtime tab-suspension Playwright e2e (INC-019), connection-pooling k6 + SQL introspection scripts (INC-017).


Full diff: git log since the initial commit. This is the first tagged release, so there is no v0.x...v1.0.0 compare range yet — future releases will link one.

Not affiliated with Vercel, Next.js, Supabase, or Stripe. Issues and PRs welcome — especially scrutiny on the RLS and Stripe sections from people running these at higher scale.