Developer Guide
Build on top of CMS One
Set up your local environment, understand the architecture, and extend the platform with new routes, models, and integrations.
Tech Stack
CMS One is a TypeScript-first, full-stack Next.js application.
Next.js 15
App Router, Server Components, API routes
React 19
UI layer with hooks
MongoDB
Document database, multi-tenant scoped queries
TypeScript
Strict typing throughout the codebase
Tailwind CSS 4
Utility-first styling with shadcn/ui
NextAuth.js
Session management & OAuth providers
Zod
Runtime validation and schema parsing
Core Topics
Local Setup
- Clone the repo and run npm install.
- Copy .env.example to .env.local and fill in the required values (MONGODB_URI, NEXTAUTH_SECRET, etc.).
- Start MongoDB locally or point MONGODB_URI at Atlas.
- Run npm run db:init to create indexes.
- Start the dev server: npm run dev.
- Optionally create a super-admin: npm run create-superadmin.
Project Structure
- app/ — Next.js App Router pages grouped by (auth), (dashboard), (business), (pages), and api/.
- components/ — Shared UI: blocks, forms, layout, post-editor, and shadcn/ui primitives in ui/.
- db/ — MongoDB connection (config.ts), Mongoose models (models/), and shared operations (operations.ts).
- lib/ — Auth config (auth.ts), RBAC helpers (rbac.ts), auth guards (auth-guards.ts), and utilities.
- services/ — Client-side API wrappers consumed by components.
- scripts/ — CLI tools for DB init and super-admin creation.
Database & Multi-Tenancy
- Every document (except users/tenants) carries a tenantId field.
- Always scope queries: db.posts.find({ tenantId }) — never fetch across tenants.
- Core collections: users, tenants, tenant_users, posts, media, api_keys, webhooks.
- Run npm run db:init to apply all recommended indexes before first use.
- See db/structure.dbml for the full schema reference.
Authentication & RBAC
- NextAuth.js handles sessions; config lives in lib/auth.ts.
- Three platform roles: superadmin (CLI only), admin (default on signup), user (legacy).
- Granular permissions are defined in lib/rbac.ts (canCreatePosts, canManageUsers, etc.).
- Protect API routes with helpers from lib/auth-guards.ts: requireAuth(), requireRole(), requirePermission().
- Middleware in proxy.ts guards route groups automatically — add new protected paths there.
REST API
- All v1 endpoints live under /api/v1/tenants/:tenantId/…
- Authentication via Bearer token (API key) or active NextAuth session cookie.
- Standard response envelope: { success, data, message, meta }.
- Error envelope: { success: false, error: { code, message, details } }.
- Full OpenAPI spec available at docs/api-v1.yaml and the interactive UI at /docs/api/v1.
Webhooks
- Register webhook URLs in Dashboard → Webhooks.
- Events: post.published, post.updated, post.deleted, media.uploaded.
- Each request includes an X-CMS-Signature header (HMAC-SHA256) for verification.
- Retry logic: up to 3 attempts with exponential back-off on non-2xx responses.
Adding New API Routes
- Create a file under app/api/ following Next.js route conventions.
- Call requireAuth() (or requirePermission()) at the top of each handler.
- Validate request bodies with Zod before touching the database.
- Return responses using the standard envelope to maintain consistency.
- Add corresponding service methods in services/api.ts for client consumption.
Code Style & Conventions
- TypeScript for all new files; avoid any unless absolutely necessary.
- PascalCase for components and types; camelCase for functions and variables.
- Imports: external deps → internal components → utils/hooks → types.
- Use the ListTable component from @/components/list-table for all tabular data.
- Run npm run lint and npm run format before committing.
Useful Commands
| Command | Description |
|---|---|
npm run dev | Start the Next.js development server |
npm run build | Compile the production build |
npm run start | Serve the production build |
npm run lint | Run ESLint across all files |
npm run format | Format code with Prettier |
npm run db:init | Create MongoDB indexes |
npm run create-superadmin | Interactive CLI to create a super admin |