Overview
Codapult follows a standard Next.js App Router layout with additional conventions for adapters, plugins, and infrastructure code.
src/
app/
(marketing)/ — Landing, pricing, blog, changelog, legal, help center
(auth)/ — Sign in, sign up
(dashboard)/ — Protected dashboard (settings, billing, teams, AI chat)
admin/ — Admin panel (users, subscriptions, feature flags)
api/ — API routes (auth, chat, upload, webhooks, trpc, graphql)
components/
ui/ — shadcn/ui base components
marketing/ — Landing page sections
dashboard/ — Dashboard components (sidebar, team switcher)
admin/ — Admin components (tables, managers)
auth/ — Auth components (AuthForm)
lib/
db/ — Drizzle client, schema, migrations, seed
auth/ — Auth adapter (Better-Auth / Kinde)
payments/ — Payment adapter (Stripe / LemonSqueezy)
storage/ — File storage adapter (local / S3 / R2)
actions/ — Server actions (mutations)
trpc/ — tRPC v11 routers
graphql/ — GraphQL schema + resolvers
plugins/ — Plugin system (types, registry, hooks)
jobs/ — Background job adapter (in-memory / BullMQ)
ai/ — AI chat, RAG pipeline, embeddings
validation.ts — Zod schemas (shared across all actions/routes)
rate-limit.ts — Sliding-window rate limiter
guards.ts — Auth + permission guards
config.ts — Typed env var access
config/
app.ts — Brand, features, auth settings
navigation.ts — Dashboard & admin sidebar items
marketing.ts — Landing page content (pricing, testimonials, FAQ)
content/
blog/ — MDX blog posts (i18n: slug.mdx, slug.ru.mdx)
docs/ — MDX documentation articles
messages/ — i18n translation files (en.json, ru.json)
cli/ — Interactive setup wizard (init.ts)
plugins/ — Community plugins directory
infra/
terraform/ — AWS infrastructure (HCL)
pulumi/ — AWS infrastructure (TypeScript)
helm/ — Kubernetes Helm chart
Key Directories
src/app/ — Routes
Next.js App Router uses route groups (parenthesized folders) to organize routes without affecting URL paths:
(marketing)/— public pages: landing, pricing, blog, changelog, legal pages, help center, feature requests. No auth required.(auth)/— sign in and sign up pages.(dashboard)/— all protected routes behind authentication. Includes settings, billing, team management, AI chat, onboarding, and plugin pages.admin/— admin panel with its own layout. Requiresrole: "admin". Manages users, subscriptions, feature flags, webhooks, SSO, performance metrics, and A/B tests.api/— REST and RPC endpoints. Every route follows the same pattern: auth check → rate limit → Zod validation → business logic → JSON response.
src/components/ — UI
Components are organized by domain. ui/ contains the shared shadcn/ui primitives (Button, Dialog, Table, etc.); other folders hold feature-specific components.
src/lib/ — Business Logic
Each adapter module (auth/, payments/, storage/, jobs/) contains a common interface and multiple implementations. The active implementation is selected at runtime by the corresponding env var — your application code only imports the interface.
Other modules:
actions/— server actions for form submissions and mutations. Each validates input with Zod and checks auth/permissions via guards.trpc/— type-safe API procedures organized into routers (user, billing, notifications). Client and server setup included.graphql/— optional GraphQL layer using graphql-yoga. SDL schema with resolvers.plugins/— plugin registry, types, lifecycle hooks, and marketplace catalog.ai/— AI chat with streaming, RAG pipeline, embedding generation, conversation history.jobs/— background job system with built-in jobs (send-email, webhook-retry, credit-reset, rag-index) and cron scheduling.
content/ — MDX Content
Blog posts and documentation articles are MDX files with frontmatter metadata. Blog posts support i18n via filename convention (post.mdx for default locale, post.ru.mdx for Russian). The help center documentation uses category-based organization.
infra/ — Infrastructure as Code
Three deployment options are included out of the box:
- Terraform — AWS infrastructure defined in HCL
- Pulumi — AWS infrastructure defined in TypeScript
- Helm — Kubernetes chart with Deployment, Service, Ingress, HPA, worker, and Redis
Configuration Architecture
Codapult uses a three-layer config system:
1. Environment Variables (.env.local)
Secrets and per-environment settings. All variables are documented in .env.example with inline comments. Access them type-safely via src/lib/config.ts:
import { config } from '@/lib/config';
config.turso.databaseUrl; // string — validated at startup
config.auth.provider; // "better-auth" | "kinde"
2. Application Config (src/config/app.ts)
Your main customization file. Controls brand identity, feature toggles, and auth settings:
export const appConfig = {
brand: {
name: 'My SaaS',
description: 'The best SaaS product',
logo: '/logo.svg',
url: 'https://my-saas.com',
supportEmail: '[email protected]',
},
features: {
aiChat: true,
teams: true,
blog: true,
// ... toggle any module on/off
},
};
3. Supporting Config Files
| File | Purpose |
| -------------------------- | ------------------------------------------------------- |
| src/config/navigation.ts | Dashboard and admin sidebar menu items |
| src/config/marketing.ts | Landing page content — pricing tiers, testimonials, FAQ |
| messages/en.json | English UI translations |
| messages/ru.json | Russian UI translations |
Database Schema
The database schema lives in a single file: src/lib/db/schema.ts. This is the source of truth for all tables. Conventions:
- Table names: singular
snake_case(user,organization_member) - Column names:
snake_case(created_at,user_id) - Primary keys:
text('id').primaryKey()with UUID/nanoid (not auto-increment) - Timestamps:
integer('created_at', { mode: 'timestamp' })with.$defaultFn(() => new Date()) - Foreign keys: always specify
onDeletebehavior
For development, run pnpm db:push to apply the schema directly. For production databases with existing data, use pnpm db:generate to create a migration, then pnpm db:migrate to apply it safely.
Next Steps
- Authentication — sign-in methods, 2FA, and SSO configuration
- Plans & Pricing — configure subscription tiers
- Customization — theming, branding, and white-label