Product System Design
Product architecture, data model, services, and security model.
Status: Working architecture blueprint for the universal Starter Kit monorepo—a production-grade baseline for multi-tenant web, mobile, and API applications.
1. System Vision & Architecture Principles
Starter is built as a secure modular monolith first, with event-driven seams and clear module boundaries, designed to scale into independent services when load or compliance requires it.
The core operational loop is:
Action requested -> policy verification -> state transition in Postgres
-> outbox event -> background worker (notifications, audit, AI assist)
-> real-time sync to Web & Mobile clientsEngineering principles:
- Relational Source of Truth: PostgreSQL with Drizzle ORM holds all primary records.
- Tenant Isolation: Every multi-tenant operation is scoped by
organizationIdandworkspaceId. - Stateless Application Servers: API containers scale horizontally without local file or session state.
- Defense in Depth: Multi-factor authentication, passkeys (WebAuthn), CSRF protection, and strict Zod validation.
2. Product Boundaries & Personas
Primary personas:
| Persona | Primary Surface | Core Capabilities |
|---|---|---|
| Organization Owner | Web Dashboard | Workspace lifecycle, billing, plan management, audit trails |
| Workspace Admin | Web Dashboard, Mobile | Member invitations, role assignment, policy rules, integrations |
| Team Member | Web Console, Mobile | Day-to-day operations, task management, profile and security settings |
| Viewer / Auditor | Web Console (Read-only) | Compliance review, audit inspection, activity telemetry |
3. High-Level Architecture
+----------------------+
| apps/docs |
| Fumadocs site |
+----------------------+
+----------------+ +------------------+ +------------------+
| apps/web | | apps/nest-api | | apps/mobile |
| Next.js App |<--->| NestJS API Spine |<---->| Expo App |
+----------------+ +--------+---------+ +------------------+
|
+----------------+----------------+
| |
+-------v--------+ +-----v------------+
| Postgres | | apps/rust |
| Source of truth| | Axum Performance |
+-------+--------+ +------------------+
|
+-------v--------+
| Redis |
| Cache / Queue |
+----------------+4. Service Layout
Core Production Services
| Service | Path | Role | Technology |
|---|---|---|---|
| Web Console | apps/web | Public landing, admin dashboard, user settings, billing | Next.js, React, Tailwind CSS |
| Mobile App | apps/mobile | Cross-platform mobile client | Expo Router, Uniwind |
| API Spine | apps/nest-api | Auth, tenancy, users, billing, MFA, passkeys | NestJS, Drizzle ORM, Zod |
| Performance Service | apps/rust | High-throughput data processing & micro-benchmarks | Rust, Axum, Tokio |
| Documentation | apps/docs | Technical documentation and architecture guides | Fumadocs, MDX |
Shared Monorepo Packages
| Package | Workspace Name | Responsibility |
|---|---|---|
| UI Primitives | @starter/ui | Shadcn-style primitives, tokens, and motion components |
| Logger | @starter/logger | Injectable logger for TypeScript and Rust |
| TypeScript Config | @starter/typescript-config | Shared tsconfig.json bases across apps and packages |
5. Data Model & Tenancy
Tenancy and Access Control
| Table | Purpose | Key Attributes |
|---|---|---|
organizations | Top-level tenant account | id, name, slug unique, status, createdAt |
workspaces | Project / environment boundary | id, organization_id, name, slug, environment |
users | Global user identity | id, email unique, status, password_hash |
user_profiles | Personal details and avatar | id, user_id, display_name, avatar_url, locale |
memberships | User access to workspace | id, workspace_id, user_id, status |
roles | Role definitions | id, workspace_id nullable, code, name |
permissions | Granular permission catalog | id, code unique, module, description |
role_permissions | Permissions assigned to roles | role_id, permission_id |
sessions | Active user sessions | id, user_id, token_hash, expires_at, ip, userAgent |
subscriptions | Billing and plan state | id, user_id, provider, plan_id, status |
6. Security & Authentication Architecture
- Password Authentication:
- Hashed using Argon2id with per-user salt.
- Session & Token Model:
- Short-lived JWT access tokens (15 minutes).
- Long-lived secure, HTTP-only refresh cookies with rotation and revocation.
- Multi-Factor Authentication (MFA):
- RFC 6238 TOTP factors with encrypted secret storage.
- Encrypted backup codes generated on factor activation.
- Passkeys (WebAuthn):
- FIDO2 / WebAuthn standard support.
- Credential challenge verification stored with TTL.
- CSRF & Rate Limiting:
- Double-submit CSRF cookie guard on state-changing API endpoints.
- In-memory / Redis token-bucket rate limiting on authentication routes.
7. Event Streams & Outbox Pattern
All critical events follow the outbox pattern inside database transactions to ensure consistency:
| Topic | Partition Key | Purpose |
|---|---|---|
starter.workspace.events.v1 | workspaceId | Workspace creation, update, and quota telemetry |
starter.auth.events.v1 | userId | Login, password reset, MFA factor activation |
starter.billing.events.v1 | organizationId | Checkout, subscription renewal, invoice payment |
starter.notification.events.v1 | recipientId | Transactional emails, in-app alerts |
starter.audit.events.v1 | workspaceId | Immutable audit trail for compliance |
starter.ai.actions.v1 | workspaceId | Prompt telemetry, assist proposals, approval queue |
8. Deployment & Infrastructure
The starter supports multiple deployment targets out of the box:
- Local Development:
docker-compose.ymlorchestrates PostgreSQL, Nest API, Web, AI API, and optional Rust. - Production Web: Next.js deployed on Vercel with standalone output.
- Production API: NestJS container deployed on Render, Fly.io, or AWS ECS with pooled PostgreSQL (e.g. Neon).
- Object Storage: S3-compatible private buckets (Cloudflare R2, AWS S3) with pre-signed upload URLs.