Data architecture · Free tool
SaaS Database Schema Generator
Generate a modular PostgreSQL and Prisma schema for auth, workspaces, billing, credits, API keys, webhooks, and audit logs.
Everything runs in this browser. Results, code, copy, and downloads are fully ungated.
Inputs
01 / configureChoose your SaaS modules
The core User model is always included. Add only the capabilities you need.
Tokens and API keys are hashed; signing secrets are encrypted. Generation is local and account-free.
Live output
02 / inspectPostgreSQL + Prisma · 5 modules
Complete relations, indexes, uniqueness constraints, cascade behavior, and implementation notes.
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
email String @unique
emailVerifiedAt DateTime?
name String?
imageUrl String?
stripeCustomerId String? @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
sessions Session[]
ownedWorkspaces Workspace[] @relation("WorkspaceOwner")
memberships WorkspaceMember[]
subscriptions Subscription[]
apiKeys ApiKey[]
}
model Session {
id String @id @default(cuid())
tokenHash String @unique
userId String
expiresAt DateTime
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([expiresAt])
}
enum WorkspaceRole {
OWNER
ADMIN
MEMBER
}
model Workspace {
id String @id @default(cuid())
name String
slug String @unique
ownerId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
owner User @relation("WorkspaceOwner", fields: [ownerId], references: [id])
members WorkspaceMember[]
invitations WorkspaceInvitation[]
@@index([ownerId])
}
model WorkspaceMember {
id String @id @default(cuid())
workspaceId String
userId String
role WorkspaceRole @default(MEMBER)
createdAt DateTime @default(now())
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([workspaceId, userId])
@@index([userId])
}
model WorkspaceInvitation {
id String @id @default(cuid())
workspaceId String
email String
tokenHash String @unique
role WorkspaceRole @default(MEMBER)
expiresAt DateTime
acceptedAt DateTime?
createdAt DateTime @default(now())
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
@@index([workspaceId, email])
@@index([expiresAt])
}
enum SubscriptionStatus {
TRIALING
ACTIVE
PAST_DUE
CANCELED
UNPAID
}
model Plan {
id String @id @default(cuid())
key String @unique
name String
priceCents Int
currency String @default("usd")
interval String
stripePriceId String? @unique
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
subscriptions Subscription[]
}
model Subscription {
id String @id @default(cuid())
userId String
planId String
stripeSubscriptionId String? @unique
status SubscriptionStatus
currentPeriodEnd DateTime?
cancelAtPeriodEnd Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
plan Plan @relation(fields: [planId], references: [id])
@@index([userId, status])
@@index([planId])
}
model ApiKey {
id String @id @default(cuid())
userId String
name String
prefix String @unique
secretHash String
lastUsedAt DateTime?
expiresAt DateTime?
revokedAt DateTime?
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId, revokedAt])
}
Method and assumptions
Modules are composed around one User model, so every selected relation has a matching back-reference. The generated PostgreSQL schema includes practical uniqueness constraints and indexes for common lookup and worker paths.
Sensitive credentials are represented by hash fields rather than plaintext. Ledger records include idempotency keys, API keys use safe prefixes for lookup, and delivery tables separate durable work from request handling.
From estimate to implementation
FastStaq already ships the production layer.
Use the free output now, then skip the weeks of wiring auth, billing, webhooks, support, and operations yourself.
Common questions
Can I use the schema without an account?
Yes. Select modules, copy the complete Prisma schema, or download it without signing in or submitting an email.
Does this replace application authorization?
No. The schema defines data relationships and constraints. Your service layer must still enforce tenant membership, roles, ownership, and field-level access.
Can I run this schema directly?
It is designed for PostgreSQL and Prisma. Review names and ownership for your product, then run prisma format and prisma validate before creating a migration.
Keep the production checklist
Get the 32 checks FastStaq uses before real users pay—billing, webhooks, security, recovery, and more.