Skip to content

Case study · DryDock Kit

DryDock Kit: a multi-tenant SaaS foundation, proven by tests.

DryDock Kit is a product I build and sell: a self-hosted Next.js starter kit for multi-tenant B2B SaaS. Organizations, roles, billing and an admin console come already wired together, for developers and small agencies who would rather build their product than its plumbing.

01 — At a glance

The short version.

Role
Creator: architecture, implementation, test suites and security reviews
Status
On sale as a one-time purchase
Stack
  • Next.js 16
  • React 19
  • TypeScript
  • Prisma
  • PostgreSQL
  • Stripe
  • Razorpay
  • Paddle
  • Polar
  • Docker
  • Tailwind CSS

02 — The problem

What it had to solve.

Every B2B SaaS rebuilds the same foundation: sign-in, organizations, invitations, roles, plans, billing webhooks and an admin console. The pages are quick to build. The bugs live in the rules between them.

Those bugs are the expensive kind: one customer reading another's data, an admin granting themselves ownership, a retried payment webhook changing billing twice. A starter kit is only worth buying if it proves those rules hold.

03 — What I built

The product, feature by feature.

  • Authentication with email verification, magic links, passkeys and two-factor, plus Google, GitHub, X and Discord sign-in.
  • Organizations as tenants, with members, invitations and role-based access control.
  • Plans, usage limits and feature flags, with billing through Stripe, Razorpay, Paddle and Polar.
  • A platform-admin console with impersonation, API keys and notifications.
  • A Docker and CI deploy path with a readiness checker.

04 — Architecture

The decisions that shaped it.

Tests against a real database

The integration and security suites run against a real PostgreSQL database, in CI on every push and locally with one command. Payment providers and email are stubbed; the database never is.

Every lookup is scoped to the organization

Organization-scoped records are always fetched by organization and ID together, so a valid ID from another tenant simply isn't found.

Webhooks are idempotent

A redelivered payment event is recognised and acknowledged without changing billing again, with unique keys in the database for the case where two copies arrive at once.

Purchases resolve from the app's own records

A purchase is granted only for a checkout the app itself recorded, for the right product and amount, never from data the buyer can set.

05 — Challenges

What was hard, and how I solved it.

An admin could invite an address they control as owner.

The owner-only rule lived in role changes but not in invitations. Invitations now enforce it too, and a test fails if it regresses.

A 10-seat plan could end up with 29 members.

Pending invitations now reserve seats, and accepting one re-checks the limit under a lock, tested with a concurrent race for the last seat.

A late webhook could move a paid invoice back to open.

Impossible billing status changes are refused, and all 50 transitions are tested.

06 — Results

Results, as published.

  • 1,258 passing tests in 104 files.
  • 244 security tests in 24 files, covering tenant isolation, authorization, billing limits, payments, webhooks, impersonation, admin 2FA and open redirects.
  • 35 findings published from two security reviews, each with its fix and its test.
  • Zero database mocks.

Figures from the test run published on drydockkit.com on 2 October 2026. Both reviews were done in-house, not by an independent penetration tester.

Building something similar?

An MVP or a full SaaS product, built on a foundation that survives its first customers.

07 — Contact

Let's Build Something.

I take on a small number of projects at a time, from full product builds to deployment, performance and automation work: scoped, shipped, and handed over clean.

Bengaluru, India → Open to RelocationReplies under 24h

Send a message

What happens next: I read every message myself. Typical reply time: under 24h.