# nikandr-surkov/ai-saas-starter architecture

> Architecture diagram of the GitHub repository nikandr-surkov/ai-saas-starter, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/nikandr-surkov/ai-saas-starter
- Repository: https://github.com/nikandr-surkov/ai-saas-starter

## Overview

This repository is a Next.js SaaS starter/demo whose main user journey is account access, credit-backed image generation, and subscription billing. The graph preserves the documented generation and billing stages plus the auth, ledger, and storage layers. The generation action and several billing modules are represented from the README and tree; their internal call wiring was not sampled, so only documented relationships are shown.

Main entry points: [`src/app/(app)/generate/actions.ts`](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/app/(app)/generate/actions.ts) (Generation action), [`src/lib/billing/webhook.ts`](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/billing/webhook.ts) (Webhook dispatch), [`src/db/index.ts`](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/db/index.ts) (PostgreSQL), [`src/lib/credits/index.ts`](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/credits/index.ts) (Credits ledger)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_experience["App experience"]
  node_app["App pages"]
  node_generate_ui["Generation form<br/>[generate-form.tsx]"]
  node_dashboard["Dashboard<br/>[page.tsx]"]
  node_billing_page["Billing page<br/>[page.tsx]"]
end

subgraph group_identity["Identity"]
  node_auth_route["Auth endpoint<br/>[route.ts]"]
  node_auth["Auth service<br/>[index.ts]"]
  node_session["Session helpers<br/>[session.ts]"]
end

subgraph group_generation["Image generation"]
  node_generation_action["Generation action<br/>[actions.ts]"]
  node_rate_limit["Rate limiting<br/>[rate-limit.ts]"]
  node_ai["AI image provider<br/>[provider.ts]"]
  node_image_storage["Image storage<br/>[storage.ts]"]
  node_image_route["Dev image route<br/>[route.ts]"]
end

subgraph group_billing["Billing and credits"]
  node_credits["Credits ledger<br/>[index.ts]"]
  node_billing_actions["Billing actions<br/>[actions.ts]"]
  node_stripe_webhook_route["Webhook endpoint<br/>[route.ts]"]
  node_billing_webhook["Webhook dispatch<br/>[webhook.ts]"]
  node_billing_sync["Subscription sync<br/>[sync.ts]"]
  node_plans["Plan configuration<br/>[plans.ts]"]
end

subgraph group_data["Persistence"]
  node_database[("PostgreSQL<br/>[index.ts]")]
end

node_user(("User"))
node_stripe["Stripe"]
node_ai_provider["Image model"]
node_blob[("Vercel Blob")]
node_email["Email service"]

node_user -->|"signs in"| node_auth_route
node_auth_route -->|"delegates auth"| node_auth
node_auth -->|"persists sessions"| node_database
node_user -->|"uses"| node_app
node_app -->|"checks session"| node_session
node_user -->|"submits prompt"| node_generate_ui
node_generate_ui -->|"submits generation"| node_generation_action
node_generation_action -->|"rate limits"| node_rate_limit
node_generation_action -->|"spends credit"| node_credits
node_generation_action -->|"requests image"| node_ai
node_ai -.->|"generates image"| node_ai_provider
node_generation_action -->|"stores result"| node_image_storage
node_image_storage -.->|"writes image"| node_blob
node_image_storage -->|"returns dev path"| node_image_route
node_image_route -->|"checks ownership"| node_database
node_image_route -->|"checks session"| node_session
node_dashboard -->|"reads balance and history"| node_credits
node_credits -->|"reads and writes ledger"| node_database
node_billing_page -->|"renders plans"| node_plans
node_user -->|"starts checkout"| node_billing_actions
node_billing_actions -->|"creates checkout or portal"| node_stripe
node_stripe -->|"sends events"| node_stripe_webhook_route
node_stripe_webhook_route -->|"dispatches verified event"| node_billing_webhook
node_billing_webhook -->|"syncs subscription"| node_billing_sync
node_billing_webhook -->|"grants top-up or plan credits"| node_credits
node_billing_webhook -->|"looks up customer and user"| node_database
node_billing_webhook -.->|"sends confirmation"| node_email
node_billing_sync -->|"reads subscription state"| node_stripe
node_billing_sync -->|"updates subscription state"| node_database

click node_app "https://github.com/nikandr-surkov/ai-saas-starter/tree/main/src/app/(app)"
click node_generate_ui "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/components/generate/generate-form.tsx"
click node_dashboard "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/app/(app)/dashboard/page.tsx"
click node_billing_page "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/app/(app)/billing/page.tsx"
click node_auth_route "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/app/api/auth/%5B...all%5D/route.ts"
click node_auth "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/auth/index.ts"
click node_session "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/auth/session.ts"
click node_generation_action "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/app/(app)/generate/actions.ts"
click node_rate_limit "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/rate-limit.ts"
click node_ai "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/ai/provider.ts"
click node_image_storage "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/ai/storage.ts"
click node_image_route "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/app/api/images/%5Bfile%5D/route.ts"
click node_credits "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/credits/index.ts"
click node_billing_actions "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/billing/actions.ts"
click node_stripe_webhook_route "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/app/api/stripe/webhook/route.ts"
click node_billing_webhook "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/billing/webhook.ts"
click node_billing_sync "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/billing/sync.ts"
click node_plans "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/config/plans.ts"
click node_database "https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/db/index.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_generate_ui,node_dashboard,node_billing_page,node_user toneBlue
class node_auth_route,node_auth,node_session,node_blob toneAmber
class node_generation_action,node_rate_limit,node_ai,node_image_storage,node_image_route toneMint
class node_credits,node_billing_actions,node_stripe_webhook_route,node_billing_webhook,node_billing_sync,node_plans toneRose
class node_database,node_stripe,node_ai_provider,node_email toneIndigo
```

## Components

### App experience

- [App pages](https://github.com/nikandr-surkov/ai-saas-starter/tree/main/src/app/(app)): `src/app/(app)`
- [Generation form](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/components/generate/generate-form.tsx): `src/components/generate/generate-form.tsx`
- [Dashboard](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/app/(app)/dashboard/page.tsx): `src/app/(app)/dashboard/page.tsx`
- [Billing page](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/app/(app)/billing/page.tsx): `src/app/(app)/billing/page.tsx`

### Identity

- [Auth endpoint](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/app/api/auth/%5B...all%5D/route.ts): `src/app/api/auth/[...all]/route.ts`
- [Auth service](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/auth/index.ts): `src/lib/auth/index.ts`
- [Session helpers](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/auth/session.ts): `src/lib/auth/session.ts`

### Image generation

- [Generation action](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/app/(app)/generate/actions.ts): `src/app/(app)/generate/actions.ts`
- [Rate limiting](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/rate-limit.ts): `src/lib/rate-limit.ts`
- [AI image provider](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/ai/provider.ts): `src/lib/ai/provider.ts`
- [Image storage](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/ai/storage.ts): `src/lib/ai/storage.ts`
- [Dev image route](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/app/api/images/%5Bfile%5D/route.ts): `src/app/api/images/[file]/route.ts`

### Billing and credits

- [Credits ledger](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/credits/index.ts): `src/lib/credits/index.ts`
- [Billing actions](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/billing/actions.ts): `src/lib/billing/actions.ts`
- [Webhook endpoint](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/app/api/stripe/webhook/route.ts): `src/app/api/stripe/webhook/route.ts`
- [Webhook dispatch](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/billing/webhook.ts): `src/lib/billing/webhook.ts`
- [Subscription sync](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/lib/billing/sync.ts): `src/lib/billing/sync.ts`
- [Plan configuration](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/config/plans.ts): `src/config/plans.ts`

### Persistence

- [PostgreSQL](https://github.com/nikandr-surkov/ai-saas-starter/blob/main/src/db/index.ts): `src/db/index.ts`

### Other components

- **User**
- **Stripe**
- **Image model**
- **Vercel Blob**
- **Email service**

## Connections

- User → Auth endpoint: signs in
- Auth endpoint → Auth service: delegates auth
- Auth service → PostgreSQL: persists sessions
- User → App pages: uses
- App pages → Session helpers: checks session
- User → Generation form: submits prompt
- Generation form → Generation action: submits generation
- Generation action → Rate limiting: rate limits
- Generation action → Credits ledger: spends credit
- Generation action → AI image provider: requests image
- AI image provider → Image model: generates image
- Generation action → Image storage: stores result
- Image storage → Vercel Blob: writes image
- Image storage → Dev image route: returns dev path
- Dev image route → PostgreSQL: checks ownership
- Dev image route → Session helpers: checks session
- Dashboard → Credits ledger: reads balance and history
- Credits ledger → PostgreSQL: reads and writes ledger
- Billing page → Plan configuration: renders plans
- User → Billing actions: starts checkout
- Billing actions → Stripe: creates checkout or portal
- Stripe → Webhook endpoint: sends events
- Webhook endpoint → Webhook dispatch: dispatches verified event
- Webhook dispatch → Subscription sync: syncs subscription
- Webhook dispatch → Credits ledger: grants top-up or plan credits
- Webhook dispatch → PostgreSQL: looks up customer and user
- Webhook dispatch → Email service: sends confirmation
- Subscription sync → Stripe: reads subscription state
- Subscription sync → PostgreSQL: updates subscription state
