Developer GuideCommon Tasks

Common Tasks

Quick recipes for the tasks you will do most often. Each one is a brief, self-contained procedure.

Add a New API Endpoint

  1. Open the appropriate domain controller in apps/backend/src/domains/<domain>/.
  2. Add a new method with route decorator (@Get(), @Post(), etc.).
  3. Add @Roles() to restrict access.
  4. Add @ApiOperation() and @ApiResponse() for Swagger docs.
  5. Create a service method in the corresponding service file.
  6. Create a DTO in the dto/ directory if the endpoint accepts a request body.
  7. Export the DTO from dto/index.ts.
// In the controller
@Get(':id/summary')
@Roles(UserRole.DISPATCHER, UserRole.ADMIN, UserRole.OWNER)
@ApiOperation({ summary: 'Get resource summary' })
async getSummary(@Param('id') id: string, @CurrentUser() user: any) {
  const tenantDbId = await this.getTenantDbId(user);
  return this.service.getSummary(id, tenantDbId);
}

Full tutorial: Adding an Endpoint


Add a New Page

  1. Create a directory under apps/web/src/app/ matching the desired URL path.
  2. Create a page.tsx file inside it.
  3. Import and render a feature component.
apps/web/src/app/dispatcher/reports/page.tsx
import { ReportsDashboard } from '@/features/operations/reports/components/ReportsDashboard';
 
export default function ReportsPage() {
  return <ReportsDashboard />;
}

The route is automatically registered. No router configuration needed.

Full guide: App Router Guide


Add a New Database Table

  1. Open apps/backend/prisma/schema.prisma.
  2. Add the new model:
model MaintenanceLog {
  id          Int      @id @default(autoincrement())
  logId       String   @unique @map("log_id") @db.VarChar(50)
  description String
  performedAt DateTime @map("performed_at") @db.Timestamptz
 
  tenantId    Int      @map("tenant_id")
  tenant      Tenant   @relation(fields: [tenantId], references: [id])
 
  createdAt   DateTime @default(now()) @map("created_at") @db.Timestamptz
  updatedAt   DateTime @updatedAt @map("updated_at") @db.Timestamptz
 
  @@index([tenantId])
  @@map("maintenance_logs")
}
  1. Add the relation to the Tenant model (if tenant-scoped).
  2. Run the migration:
cd apps/backend
pnpm run prisma:migrate
  1. Regenerate the Prisma client:
pnpm run prisma:generate

Full guide: Database & Prisma


Install a New Shadcn Component

cd apps/web
pnpm dlx shadcn@latest add [component-name]

For example:

pnpm dlx shadcn@latest add calendar
pnpm dlx shadcn@latest add checkbox
pnpm dlx shadcn@latest add radio-group

The component is installed to src/shared/components/ui/. Import it in your code:

import { Calendar } from '@/shared/components/ui/calendar';

Full reference: UI Standards


Add a New Feature Module

  1. Create the directory structure:
mkdir -p apps/web/src/features/<domain>/<feature>/{components,hooks,__tests__}
  1. Create api.ts with fetch functions.
  2. Create types.ts with TypeScript interfaces.
  3. Create hooks in hooks/ using React Query.
  4. Create components in components/.
  5. Create index.ts barrel export.
index.ts
export * from './types';
export { useMyFeature } from './hooks/use-my-feature';

Full guide: Feature Modules


Run Database Migrations

Create a new migration (after editing schema.prisma):

cd apps/backend
pnpm run prisma:migrate

Deploy existing migrations (production):

cd apps/backend
pnpm run prisma:migrate:deploy

Check migration status:

cd apps/backend
pnpm run prisma:migrate:status

Seed the Database

Base data (essential records):

cd apps/backend
pnpm run setup:base

Demo data (sample records for development):

cd apps/backend
pnpm run setup:demo

Reset and reseed (drops all data):

cd apps/backend
pnpm run setup:reset

Check seed status:

cd apps/backend
pnpm run setup:status

Run Tests

Backend unit tests:

cd apps/backend
pnpm run test              # Run once
pnpm run test:watch        # Watch mode
pnpm run test:cov          # With coverage report

Backend E2E tests:

cd apps/backend
pnpm run test:e2e

Frontend tests:

cd apps/web
pnpm run test              # Run once
pnpm run test:watch        # Watch mode

All tests via Turborepo:

pnpm run test              # From project root

Access Prisma Studio

Prisma Studio is a visual database browser. Run it from the project root:

pnpm run backend:prisma:studio

Or from the backend directory:

cd apps/backend
pnpm run prisma:studio

This opens a web interface (typically at http://localhost:5555) where you can browse tables, view and edit records, and explore relationships.


Check API Docs (Swagger)

  1. Make sure the backend is running (pnpm run backend:dev or pnpm run dev).
  2. Open http://localhost:8000/api in your browser.
  3. Click “Authorize” to enter a JWT token for authenticated endpoints.
  4. Browse endpoints grouped by tags (Drivers, Vehicles, Route Planning, etc.).

The OpenAPI spec is also available as JSON at http://localhost:8000/api/openapi.json.


Start and Stop Infrastructure

Start PostgreSQL and Redis:

pnpm run docker:up

Stop containers:

pnpm run docker:down

View container logs:

pnpm run docker:logs

Restart containers:

pnpm run docker:restart

Generate the Prisma Client

Run this after any schema change or fresh install:

pnpm run backend:prisma:generate

Or from the backend directory:

cd apps/backend
pnpm run prisma:generate

Quick Reference Table

TaskCommandRun From
Start all appspnpm run devRoot
Start backend onlypnpm run backend:devRoot
Start frontend onlypnpm run frontend:devRoot
Start docs onlypnpm run docs:devRoot
Start Docker (DB + Redis)pnpm run docker:upRoot
Stop Dockerpnpm run docker:downRoot
Install dependenciespnpm installRoot
Run migrationspnpm run prisma:migrateapps/backend/
Generate Prisma clientpnpm run backend:prisma:generateRoot
Open Prisma Studiopnpm run backend:prisma:studioRoot
Seed base datapnpm run setup:baseapps/backend/
Seed demo datapnpm run setup:demoapps/backend/
Reset databasepnpm run setup:resetapps/backend/
Run backend testspnpm run testapps/backend/
Run frontend testspnpm run testapps/web/
Build allpnpm run buildRoot
Add Shadcn componentpnpm dlx shadcn@latest add [name]apps/web/
View Swagger docsOpen http://localhost:8000/apiBrowser