A RESTful API built with Node.js, Express and TypeScript for managing tasks.
This project demonstrates a production-ready backend architecture with authentication, request validation, centralized error handling, modular structure, pagination, filtering, automated tests and database persistence using PostgreSQL and Prisma.
- Node.js
- Express
- TypeScript
- Zod (validation)
- PostgreSQL
- Prisma ORM
- JWT (authentication)
- bcrypt (password hashing)
- Vitest + Supertest (testing)
src/
app.ts
server.ts
modules/
auth/
tasks/
users/
middlewares/
errors/
lib/
types/
- modules → domain-based organization (auth, tasks, users)
- controllers → handle HTTP layer
- services → business logic
- repositories → data access (Prisma)
- middlewares → validation, authentication and error handling
- schemas → request validation with Zod
- lib → shared modules (e.g. Prisma client)
This project follows a layered and modular architecture:
- Controller → Service → Repository → Prisma
- Controllers handle HTTP concerns
- Services encapsulate business logic
- Repositories abstract database access
- Middlewares handle cross-cutting concerns (validation, auth, errors)
This separation improves maintainability, scalability and testability.
The API uses JWT authentication.
- Register a user
- Login with credentials
- Receive a JWT token
- Use the token to access protected routes
POST /users
POST /auth/login
Response:
{
"token": "your_jwt_token"
}Authorization: Bearer your_jwt_token
All /tasks routes require authentication.
- PostgreSQL
- Prisma ORM for data access
User:
- id (UUID)
- email (unique)
- password (hashed)
- createdAt
Task:
- id (UUID)
- title
- description
- done
- createdAt
- userId (relation)
- A user can have multiple tasks
- Each task belongs to a single user
npm install
Create a .env file:
DATABASE_URL="postgresql://USER:PASSWORD@localhost:5432/task_manager"
JWT_SECRET="your_secret_key"
npx prisma migrate dev
npm run dev
Server will start at:
http://localhost:3000
npm run test
npm run test:coverage
- Integration tests using Supertest
- Authentication flow covered (register → login → token)
- Protected routes tested with JWT
- Pagination, filtering and sorting tested
- Validation errors tested (Zod)
- Test isolation using database cleanup (deleteMany)
- Multi-user isolation validation
POST /users
POST /auth/login
GET /tasks
GET /tasks/:id
POST /tasks
PUT /tasks/:id
DELETE /tasks/:id
GET /tasks?page=1&limit=10&done=true&search=task&sortBy=createdAt&order=desc
- page → page number (default: 1)
- limit → items per page (max: 100)
- done → filter by completion (true/false)
- search → search by title or description
- sortBy → createdAt | title
- order → asc | desc
{
"data": [],
"meta": {
"page": 1,
"limit": 10,
"total": 0,
"totalPages": 0,
"hasNextPage": false,
"hasPreviousPage": false
}
}All endpoints require:
Authorization: Bearer <token>
- Centralized error handler middleware
- Custom AppError for business errors
- Zod validation errors handled globally
- Consistent error responses
- 200 → success
- 201 → resource created
- 204 → resource deleted
- 400 → validation error
- 401 → unauthorized
- 404 → resource not found
- 500 → internal server error
- Add unit tests for services (mocking repositories)
- Implement refresh token flow
- Improve logging strategy
- Add role-based authorization
- Introduce CI pipeline
Paulo Martinelli