Production-style REST API built with NestJS + PostgreSQL + Prisma.
- NestJS (TypeScript)
- PostgreSQL
- Prisma ORM
- JWT Authentication (Passport JWT)
- DTO validation (class-validator + class-transformer)
- Password hashing (bcrypt)
- Swagger API documentation (
/swagger)
npm install- Copy .env.example →
.env - Set a strong
JWT_SECRET
Option A (recommended): Docker
docker compose up -dOption B: Local PostgreSQL
- Install PostgreSQL
- Create a database (example:
prysm_crm) - Update
DATABASE_URLin.env
Development migration (creates/updates DB and generates Prisma client):
npm run prisma:migrateDeploy-style migration (uses checked-in migrations under prisma/migrations):
npm run prisma:deploynpm run start:devhttp://localhost:3000/swagger- Click Authorize and paste:
Bearer <accessToken>
Defined in .env.example:
PORT(default:3000)DATABASE_URL(PostgreSQL connection string)JWT_SECRET(required)
Optional seed variables (only if you run npm run db:seed):
SEED_ADMIN_EMAIL,SEED_ADMIN_PASSWORDSEED_EMPLOYEE_EMAIL,SEED_EMPLOYEE_PASSWORD
- Hashes password using bcrypt
- Enforces unique email
- Returns only:
id, name, email, role(never returns password)
- Returns:
accessTokenuser: { id, name, email, role }
JWT payload includes userId and role.
All protected routes require:
Authorization: Bearer <token>
ADMIN: full accessEMPLOYEE: read-only customers + only own tasks
GET /users→ list users (id, name, email, role, createdAt)GET /users/:id→ user by idPATCH /users/:id→ updates role only
POST /customers(ADMIN only)GET /customers(ADMIN + EMPLOYEE)- Query:
page(default 1),limit(default 10), optionalsearch - Response:
page,limit,totalRecords,totalPages,data
- Query:
GET /customers/:id(ADMIN + EMPLOYEE)PATCH /customers/:id(ADMIN only)DELETE /customers/:id(ADMIN only)
POST /tasks(ADMIN only)- Validates
assignedToexists and isEMPLOYEE - Validates
customerIdexists
- Validates
GET /tasks- ADMIN: all tasks
- EMPLOYEE: only tasks assigned to them
PATCH /tasks/:id/status- EMPLOYEE: can only update own tasks (403 otherwise)
- ADMIN: allowed
400validation failures (DTO validation)401missing/invalid token, invalid login credentials403role violations / employee trying to update someone else’s task404record not found409unique constraint conflicts (customer email/phone, user email)
- Import postman_collection.json into Postman
- Collection variables:
baseUrl(defaulthttp://localhost:3000)token(set by the “Login (ADMIN) -> sets token” request)
$API = "http://localhost:3000"
curl.exe -X POST "$API/auth/register" -H "Content-Type: application/json" -d "{\"name\":\"Admin\",\"email\":\"admin@example.com\",\"password\":\"password123\",\"role\":\"ADMIN\"}"
curl.exe -X POST "$API/auth/login" -H "Content-Type: application/json" -d "{\"email\":\"admin@example.com\",\"password\":\"password123\"}"Creates demo data (admin + employee + sample customer/task):
npm run db:seed