Prompt Details
Model
(claude-4-6-sonnet)
Token size
586
Example input
[APP_DESCRIPTION]: A multi-tenant SaaS invoicing platform with subscription billing, PDF export, and client portal
[TECH_STACK]: Next.js, Node.js, PostgreSQL, Stripe, Prisma, Tailwind CSS
[APP_TYPE]: Web SaaS
[LANGUAGE]: TypeScript
[SCALE]: 0β10,000 users, single region
Example output
Here is the complete production-ready blueprint for your multi-tenant SaaS invoicing platform.
Multi-Tenant SaaS Invoicing Platform β Architecture Blueprint
1. Project Overview
Purpose: A cloud-based invoicing platform that lets businesses (tenants) manage clients, create invoices, collect payments via Stripe, and give clients a self-service portal β all under subscription billing tiers.
Core Features:
Multi-tenant workspace isolation (org-scoped data, subdomain routing)
Invoice lifecycle management (draft β sent β paid β overdue)
Stripe Subscription billing with plan enforcement (Free / Pro / Business)
PDF invoice generation with branded templates
Client portal (view invoices, pay online, download PDFs)
Recurring invoice scheduling
Revenue dashboard (MRR, outstanding, aging report)
Webhook-driven payment status sync from Stripe
Target Users: Freelancers, small agencies, and SMBs needing structured invoicing without accounting software complexity.
Architectural Pattern: Modular Monolith with service-oriented feature modules
At 0β10k users in a single region, a full microservices split introduces operational overhead with no tangible benefit. A modular monolith β strict module boundaries enforced at the code level, single deployment unit β delivers clean separation of concerns (Auth, Billing, Invoicing, Portal, PDF) while remaining easy to reason about, deploy, and debug. Feature modules communicate through well-typed internal APIs, not network calls. If a specific module (e.g. PDF generation) needs extraction later, the boundary already exists.
2. Full Folder Structure
invoicely/
βββ .github/
β βββ workflows/
β βββ ci.yml # lint, type-check, test on PR
β βββ deploy.yml # deploy to production on main merge
β
βββ apps/
β βββ web/ # Next.js application (App Router)
β βββ app/
β β βββ (auth)/ # unauthenticated routes group
β β β βββ login/
β β β β βββ page.tsx # login page
β β β βββ register/
β β β β βββ page.tsx # org signup page
β β β βββ layout.tsx # auth shell layout
β β β
β β βββ (dashboard)/ # authenticated tenant routes group
β β β βββ layout.tsx # sidebar + top-nav shell
β β β βββ page.tsx # revenue dashboard
β β β βββ invoices/
β β β β βββ page.tsx # invoice list
β β β β βββ new/
β β β β β βββ page.tsx # invoice builder
β β β β βββ [id]/
β β β β βββ page.tsx # invoice detail / edit
β β β βββ clients/
β β β β βββ page.tsx # client list
β β β β βββ [id]/
β β β β βββ page.tsx # client detail + invoice history
β β β βββ settings/
β β β β βββ page.tsx # org branding, email settings
β β β β βββ billing/
β β β β βββ page.tsx # subscription plan management
β β β βββ reports/
β β β βββ page.tsx # aging report, MRR chart
β β β
β β βββ portal/ # client-facing portal (public)
β β β βββ [token]/
β β β βββ page.tsx # invoice view + pay button
β β β βββ success/
β β β βββ page.tsx # payment confirmation
β β β
β β βββ api/ # Next.js Route Handlers
β β βββ auth/
β β β βββ [...nextauth]/
β β β βββ route.ts # NextAuth.js handler
β β βββ webhooks/
β β β βββ stripe/
β β β βββ route.ts # Stripe event ingestion
β β βββ invoices/
β β β βββ route.ts # GET list, POST create
β β β βββ [id]/
β β β βββ route.ts # GET, PATCH, DELETE
β β β βββ send/
β β β β βββ route.ts # POST: email invoice to client
β β β βββ pdf/
β β β βββ route.ts # GET: generate + stream PDF
β β βββ clients/
β β β βββ route.ts # GET list, POST create
β β β βββ [id]/
β β β βββ route.ts # GET, PATCH, DELETE
β β βββ portal/
β β β βββ [token]/
β β β βββ route.ts # GET invoice by public token
β β β βββ pay/
β β β βββ route.ts # POST: create Stripe Payment Intent
β β βββ billing/
β β βββ checkout/
β β β βββ route.ts # POST: create Stripe Checkout Session
β β βββ portal/
β β βββ route.ts # POST: create Stripe Billing Portal session
β β
β βββ components/ # React UI components
β β βββ ui/ # shadcn/ui primitives
β β β βββ button.tsx
β β β βββ dialog.tsx
β β β βββ table.tsx
β β β βββ ...
β β βββ invoices/
β β β βββ InvoiceForm.tsx # line-item builder form
β β β βββ InvoiceTable.tsx # sortable invoice list
β β β βββ StatusBadge.tsx # visual status indicator
β β βββ clients/
β β β βββ ClientCard.tsx
β β βββ dashboard/
β β β βββ RevenueChart.tsx # recharts MRR chart
β β β βββ StatCard.tsx # KPI summary card
β β βββ layout/
β β βββ Sidebar.tsx
β β βββ TopNav.tsx
β β
β βββ lib/ # app-level utilities
β β βββ auth.ts # NextAuth config + session helpers
β β βββ prisma.ts # singleton Prisma client
β β βββ stripe.ts # Stripe SDK singleton
β β βββ pdf.ts # puppeteer/Playwright PDF wrapper
β β βββ email.ts # Resend email client
β β βββ tenant.ts # tenant resolution from session/header
β β
β βββ middleware.ts # org auth guard + route protection
β
βββ packages/
β βββ db/ # Prisma schema + migrations (shared)
β β βββ prisma/
β β β βββ schema.prisma # all data models
β β β βββ migrations/ # migration history
β β βββ seed.ts # dev seed data
β β βββ index.ts # re-exports Prisma client type
β β
β βββ pdf-templates/ # invoice HTML templates for PDF rendering
β β βββ default/
β β β βββ template.tsx # React component β HTML string
β β βββ minimal/
β β βββ template.tsx
β β
β βββ types/ # shared TypeScript domain types
β βββ invoice.ts
β βββ tenant.ts
β βββ billing.ts
β
βββ scripts/
β βββ seed-dev.ts # populate local DB with fixtures
β βββ migrate-prod.sh # safe production migration wrapper
β
βββ tests/
β βββ unit/ # Jest unit tests (pure functions)
β β βββ invoice-calculations.test.ts
β β βββ tenant-resolver.test.ts
β βββ integration/ # API route tests (test DB)
β β βββ invoices.test.ts
β β βββ webhooks-stripe.test.ts
β βββ e2e/ # Playwright browser tests
β βββ invoice-flow.spec.ts
β βββ client-portal.spec.ts
β
βββ .env.example # documented env var template
βββ .env.local # local secrets (gitignored)
βββ docker-compose.yml # local PostgreSQL + Redis
βββ turbo.json # Turborepo pipeline config
βββ package.json # root workspace config
βββ tsconfig.base.json # shared TS config
βββ prettier.config.js # formatting config
3. Layer-by-Layer Breakdown
Routing & Middleware Layer (apps/web/middleware.ts, route groups)
Next.js App Router route groups enforce authentication boundaries without prop drilling. The middleware intercepts every request, resolves the tenant from the session JWT, and attaches it to request headers. Public routes (/portal/[token], /login, /register, /api/webhooks/stripe) bypass auth. All (dashboard) routes receive a guaranteed orgId context.
API Route Handlers (apps/web/app/api/)
Thin orchestration layer. Each handler: validates the incoming request with Zod, calls the appropriate service function from the module layer, and returns a typed JSON response. No business logic lives here. The Stripe webhook handler (/api/webhooks/stripe) validates the raw body signature before parsing β raw body buffering is critical and handled explicitly.
Service / Module Layer (apps/web/lib/)
Domain logic lives here, organised by concern:
auth.ts β session management, org membership checks
tenant.ts β resolves orgId from session, enforces plan limits (e.g. invoice count ceiling on Free tier)
pdf.ts β calls Puppeteer with the HTML from packages/pdf-templates, streams the buffer back
email.ts β wraps Resend SDK, renders portal link into email body
stripe.ts β exposes typed wrappers for Checkout, PaymentIntent, and BillingPortal creation
Data Layer (packages/db/)
Prisma is the single source of truth. Schema changes always go through migration files (never db push in production). The Prisma client is instantiated as a singleton in apps/web/lib/prisma.ts to avoid connection pool exhaustion under Next.js hot-reload. Row-level data isolation is enforced by always scoping queries with where: { orgId }.
PDF Template Layer (packages/pdf-templates/)
React components rendered to static HTML strings via renderToStaticMarkup, then hydrated into Puppeteer. Keeping templates in a separate package means they can be independently tested and swapped without touching route logic.
Client Portal Layer (app/portal/[token]/)
Entirely stateless from an auth perspective. Access is governed by a cryptographically random UUID token stored on the Invoice record (portalToken). No session or JWT is required β the token IS the credential. Expiry and revocation live on the Invoice model.
4. Data Models & Relationships
Organization (tenant)
βββ id, name, slug, logoUrl
βββ stripeCustomerId, stripeSubscriptionId
βββ plan: ENUM(FREE, PRO, BUSINESS)
βββ planStatus: ENUM(ACTIVE, PAST_DUE, CANCELED)
βββ createdAt
User
βββ id, email, name, passwordHash
βββ orgId β Organization (many users per org)
βββ role: ENUM(OWNER, ADMIN, MEMBER)
βββ createdAt
Client
βββ id, name, email, phone
βββ address, city, country, taxId
βββ orgId β Organization
βββ createdAt
Invoice
βββ id, invoiceNumber (org-scoped sequence)
βββ orgId β Organization
βββ clientId β Client
βββ status: ENUM(DRAFT, SENT, PAID, VOID, OVERDUE)
βββ issueDate, dueDate
βββ currency, subtotal, taxRate, taxAmount, total
βββ notes, terms
βββ portalToken (UUID, unique) β public access credential
βββ stripePaymentIntentId (nullable)
βββ paidAt (nullable)
InvoiceLineItem
βββ id, invoiceId β Invoice
βββ description, quantity, unitPrice, amount
βββ sortOrder
RecurringSchedule
βββ id, orgId β Organization
βββ clientId β Client
βββ frequency: ENUM(WEEKLY, MONTHLY, QUARTERLY, ANNUALLY)
βββ nextRunAt, lastRunAt
βββ templateSnapshot: JSON β frozen line-item snapshot
βββ isActive
Payment
βββ id, invoiceId β Invoice
βββ stripePaymentIntentId, amount, currency
βββ status: ENUM(PENDING, SUCCEEDED, FAILED, REFUNDED)
βββ paidAt
AuditLog
βββ id, orgId, userId, action
βββ resourceType, resourceId
βββ metadata: JSON
βββ createdAt
Key relationships:
Organization 1:N Users, Clients, Invoices, RecurringSchedules
Invoice 1:N InvoiceLineItems, Payments
Client 1:N Invoices
RecurringSchedule generates Invoices on cron trigger
5. API / Interface Contracts
MethodPathInputOutputAuthPOST/api/auth/[...nextauth]{email, password}Session cookiePublicGET/api/invoices?status&clientId&page{invoices[], total}Session + orgIdPOST/api/invoices{clientId, lineItems[], dueDate, currency, notes}InvoiceSession + orgIdGET/api/invoices/[id]βInvoice + lineItems[]Session + orgIdPATCH/api/invoices/[id]Partial Invoice fieldsInvoiceSession + orgIdDELETE/api/invoices/[id]β204Session + orgId (OWNER/ADMIN)POST/api/invoices/[id]/send{message?}{sent: true}Session + orgIdGET/api/invoices/[id]/pdfβPDF stream (application/pdf)Session + orgIdGET/api/clients?search&page{clients[], total}Session + orgIdPOST/api/clients{name, email, address, ...}ClientSession + orgIdPATCH/api/clients/[id]Partial Client fieldsClientSession + orgIdDELETE/api/clients/[id]β204Session + orgIdGET/api/portal/[token]β{invoice, client, org}Token (public)POST/api/portal/[token]/pay{amount, currency}{clientSecret}Token (public)POST/api/billing/checkout{planId}{checkoutUrl}Session + orgIdPOST/api/billing/portalβ{portalUrl}Session + orgIdPOST/api/webhooks/stripeRaw Stripe event body200 OKStripe-Signature header
Webhook events handled:
checkout.session.completed, customer.subscription.updated, customer.subscription.deleted, invoice.payment_succeeded, invoice.payment_failed, payment_intent.succeeded
6. Key Dependencies & Rationale
PackageVersion CategoryRationalenext14.x (App Router)Full-stack framework with RSC, route handlers, and middleware β eliminates separate Express servertypescript5.xEnd-to-end type safety from DB schema to UI components@prisma/client5.xType-safe ORM with migration tooling; schema-first approach keeps DB and types in syncprisma5.xCLI for migrations, introspection, and studio dev toolstripe14.xOfficial SDK for Checkout, PaymentIntent, webhooks, and Billing Portalnext-auth4.xSession management with JWT, credential provider, and database adaptertailwindcss3.xUtility-first CSS; zero runtime overhead, consistent design tokens@radix-ui/react-*latestAccessible, unstyled headless primitives β composed with Tailwind for shadcn/uizod3.xRuntime validation for all API inputs; shares types with react-hook-formreact-hook-form7.xPerformant form state management for invoice builder without re-render overhead@react-pdf/renderer3.xReact-based PDF generation without headless browser dependency (alternative to Puppeteer)resend2.xTransactional email with React email templates; deliverability-focusedrecharts2.xDeclarative React charts for revenue dashboardsdate-fns3.xTree-shakeable date utilities for due-date calculations and aging reports@tanstack/react-query5.xServer-state caching for client-side data fetching in dashboard componentsjose5.xPortal token signing and verification (lightweight JWT/JWE)turbolatestMonorepo task runner with caching for build/lint/test pipelines
7. Environment & Config Strategy
bash# .env.example
# βββ Database βββββββββββββββββββββββββββββββββββ
DATABASE_URL="postgresql://invoicely:password@localhost:5432/invoicely_dev"
# βββ NextAuth βββββββββββββββββββββββββββββββββββ
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="generate-with-openssl-rand-base64-32"
# βββ Stripe βββββββββββββββββββββββββββββββββββββ
STRIPE_SECRET_KEY="sk_test_..."
STRIPE_PUBLISHABLE_KEY="pk_test_..."
STRIPE_WEBHOOK_SECRET="whsec_..."
# Stripe Price IDs (from your Stripe dashboard)
STRIPE_PRICE_PRO_MONTHLY="price_..."
STRIPE_PRICE_PRO_YEARLY="price_..."
STRIPE_PRICE_BUSINESS_MONTHLY="price_..."
STRIPE_PRICE_BUSINESS_YEARLY="price_..."
# βββ Email (Resend) ββββββββββββββββββββββββββββββ
RESEND_API_KEY="re_..."
EMAIL_FROM="billing@yourdomain.com"
# βββ App βββββββββββββββββββββββββββββββββββββββββ
NEXT_PUBLIC_APP_URL="http://localhost:3000"
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_test_..."
# βββ Portal Token Signing ββββββββββββββββββββββββ
PORTAL_TOKEN_SECRET="generate-with-openssl-rand-base64-32"
# βββ Optional: Redis (for rate limiting / job queue) ββ
REDIS_URL="redis://localhost:6379"
Config loading strategy:
Next.js loads .env.local automatically in development. Variables prefixed NEXT_PUBLIC_ are inlined at build time and exposed to the browser β keep only non-sensitive Stripe publishable key and app URL there. All other secrets remain server-only.
In production (Vercel or Railway), environment variables are injected at the platform level. A src/lib/env.ts file uses zod to validate and parse all required env vars at startup, throwing a descriptive error if any are missing β this catches misconfigured deployments before they reach users:
typescript// lib/env.ts
import { z } from 'zod'
const envSchema = z.object({
DATABASE_URL: z.string().url(),
NEXTAUTH_SECRET: z.string().min(32),
STRIPE_SECRET_KEY: z.string().startsWith('sk_'),
STRIPE_WEBHOOK_SECRET: z.string().startsWith('whsec_'),
RESEND_API_KEY: z.string(),
PORTAL_TOKEN_SECRET: z.string().min(32),
})
export const env = envSchema.parse(process.env)
```
---
## 8. Testing Strategy
**Testing Pyramid:**
```
ββββββββββββ
β E2E β β Playwright (5β10 critical flows)
ββββββββββββ
ββββββββββββββββ
β Integration β β Vitest + test DB (API routes, webhooks)
ββββββββββββββββ
ββββββββββββββββββββββββ
β Unit (pure logic) β β Vitest (calculations, resolvers, validators)
ββββββββββββββββββββββββ
Test tools:
LayerToolWhyUnitVitestFaster than Jest, native ESM, compatible with Next.jsIntegrationVitest + @prisma/client test DBReal DB queries against a test_ schema, seeded per suiteAPI mockingmsw (Mock Service Worker)Intercept Stripe/Resend calls without hitting live APIsE2EPlaywrightChromium-based, excellent Next.js support, network interceptionCoverage@vitest/coverage-v8V8-native, fast, accurate
Concrete test examples:
Unit β invoice total calculation:
typescript// tests/unit/invoice-calculations.test.ts
import { calculateInvoiceTotals } from '@/lib/invoice-utils'
test('applies tax rate to subtotal correctly', () => {
const result = calculateInvoiceTotals([
{ quantity: 2, unitPrice: 150_00 }, // cents
{ quantity: 1, unitPrice: 80_00 },
], { taxRate: 0.20 })
expect(result.subtotal).toBe(380_00)
expect(result.taxAmount).toBe(76_00)
expect(result.total).toBe(456_00)
})
Integration β invoice creation API:
typescript// tests/integration/invoices.test.ts
import { createTestOrg, createTestSession } from '../helpers'
test('POST /api/invoices creates invoice scoped to org', async () => {
const { org, client } = await createTestOrg()
const session = await createTestSession(org)
const res = await fetch('/api/invoices', {
method: 'POST',
headers: { Cookie: session.cookie, 'Content-Type': 'application/json' },
body: JSON.stringify({
clientId: client.id,
dueDate: '2025-12-31',
currency: 'USD',
lineItems: [{ description: 'Design work', quantity: 1, unitPrice: 500_00 }],
}),
})
const invoice = await res.json()
expect(res.status).toBe(201)
expect(invoice.orgId).toBe(org.id)
expect(invoice.status).toBe('DRAFT')
})
E2E β invoice send and portal access:
typescript// tests/e2e/invoice-flow.spec.ts
test('client can view and pay invoice via portal link', async ({ page }) => {
await page.goto('/login')
await page.fill('[name=email]', 'owner@acme.com')
await page.fill('[name=password]', 'testpass')
await page.click('[type=submit]')
await page.goto('/invoices/new')
// ... fill form, click Send
// Intercept sent email, extract portal URL
const portalUrl = await getLastEmailPortalLink()
await page.goto(portalUrl)
await expect(page.getByText('Invoice #0001')).toBeVisible()
await expect(page.getByRole('button', { name: 'Pay now' })).toBeVisible()
})
9. CI/CD & Deployment Blueprint
Deployment target: Vercel (app) + Neon or Supabase (PostgreSQL) β both offer connection pooling (PgBouncer) critical for serverless Next.js.
Pipeline stages:
yaml# .github/workflows/ci.yml
name: CI
on:
pull_request:
branches: [main]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20', cache: 'npm' }
- run: npm ci
- run: npm run type-check # tsc --noEmit
- run: npm run lint # eslint
- run: npm run format:check # prettier
test-unit:
needs: quality
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run test:unit # vitest run tests/unit
test-integration:
needs: quality
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_DB: invoicely_test
POSTGRES_PASSWORD: test
ports: ['5432:5432']
env:
DATABASE_URL: postgresql://postgres:test@localhost:5432/invoicely_test
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx prisma migrate deploy
- run: npm run test:integration
test-e2e:
needs: [test-unit, test-integration]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npm run build
- run: npm run test:e2e
# .github/workflows/deploy.yml
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: bash scripts/migrate-prod.sh # prisma migrate deploy on prod DB
- uses: vercel/action@v1
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'
Environment promotion:
feature/* branches β Vercel Preview deployments (auto, own preview URL)
main β Production (gated by passing CI)
Migration safety: scripts/migrate-prod.sh runs prisma migrate deploy (never migrate dev) and exits non-zero on any failure before the Vercel deploy step proceeds, preventing schema/code mismatch deploys.
10. Architect's Notes
Non-obvious decisions worth flagging:
1. Stripe webhook idempotency is your most critical edge case. Stripe retries events on non-2xx responses for up to 72 hours. Without an idempotency check, a payment can be marked PAID multiple times. Store processed stripeEventId values in a deduplicated StripeEvent table and return 200 immediately for already-processed events before doing any work.
2. Multi-tenancy via orgId scoping is correct at this scale β but audit every Prisma query. There is no database-level row isolation (unlike PostgreSQL Row Level Security). Any forgotten where: { orgId } clause leaks cross-tenant data. Enforce this by wrapping Prisma in a factory function that injects orgId into every query: withTenant(prisma, orgId).invoice.findMany(...).
3. PDF generation is the main performance risk. @react-pdf/renderer runs synchronously in the Node.js thread. For invoices with many line items it can block for 200β400ms. Move PDF generation to a background job (BullMQ + Redis) and respond with a pre-signed S3 URL rather than streaming synchronously. At low scale this is optional; plan the interface so swapping is non-breaking.
4. Portal token security. A UUID v4 token (portalToken) is statistically secure but has no built-in expiry. Add portalTokenExpiresAt to the Invoice model and check it in the /api/portal/[token] handler. Rotating the token on each send action prevents stale forwarded links from remaining valid indefinitely.
5. Plan enforcement must be centralised. Free-tier limits (e.g. max 10 invoices/month) are trivially bypassed if checked inside individual route handlers. Extract a checkPlanLimit(orgId, feature) function called from a single middleware point, and back it with a cached count query (Redis TTL 60s) to avoid hitting the DB on every request.
Concrete next steps:
Bootstrap the Prisma schema and run prisma migrate dev β get the DB contract locked in before writing any route handlers. The data model is the foundation everything else builds on.
Wire Stripe webhooks first β set up the webhook handler, Stripe CLI local forwarding (stripe listen --forward-to localhost:3000/api/webhooks/stripe), and the idempotency table before building any payment UI. Getting the async payment loop right early prevents painful retrofitting.
Build the client portal before the dashboard β it has zero auth complexity and gives you a complete invoice β PDF β payment flow to validate your data model end-to-end in a day.
Add zod validation to every API route before shipping β unenforced inputs are a security and stability risk; bake validation in from the first route, not as a cleanup pass.
Set up Vercel Preview deployments and a seed script immediately β previews with realistic seed data let you share working features before production exists, and the seed script pays compounding dividends every time a developer clones the repo.
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
animation-duration: 0.25s;
animation-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
}
VvisualizeVvisualize show_widgetThe diagram above shows the full architecture at a glance β external actors at the top, Next.js app layer routing into four domain modules, Prisma as the unified data layer over PostgreSQL, and external services (Stripe, Resend, PDF renderer, Redis) wired to the modules that own them.
A few things worth calling out that don't fit neatly into any single section: the portalToken on the Invoice model is doing real security work and should be treated with as much care as an API key. The orgId-scoped Prisma wrapper pattern in note #2 is probably the most important structural decision you can make before writing your first route β retrofitting it later is painful. And if you're targeting Vercel, plan for the serverless cold-start reality early: keep Prisma connection pooling (PgBouncer via Neon/Supabase) configured from day one, not after you see connection exhaustion in production logs.
By purchasing this prompt, you agree to our terms of service
CLAUDE-4-6-SONNET
Blank file. Blank architecture. Hours lost planning. This prompt generates a full app blueprint β tailored folder structure, data models, API contracts, dependencies, and CI/CD plan β matched to your stack and scale.
ποΈ Dynamic folder tree β fits your stack, not a generic template
π§± Layer-by-layer breakdown with real domain names
π API contracts + data models ready to implement
βοΈ Env config, testing strategy & deployment plan included
ποΈ Works for web, mobile, CLI, desktop & microservices
...more
Added 3 weeks ago
