This repository implements the requested NestJS e-commerce backend scenario and includes the optional authentication and order flows:
- Core Technologies: Built with NestJS, TypeScript, and PostgreSQL using TypeORM.
- Product Management: Implemented product listing and detailed view features. (Includes an automatic mock data seeding feature when the application first starts up.)
- Cart Management: Added operations to add, remove, list, and update quantities of cart items for authenticated users.
- Authentication (Bonus): Includes a JWT-based authentication flow (Register, Login, Me).
- Order Management (Bonus): Includes converting a cart into an order, calculating totals, validating stock, and cancelling orders.
- API Documentation & Validation: Request DTOs are validated with
class-validator, UUID inputs are checked at the controller boundary where needed, and the API is documented with Swagger and Scalar UI.
- NestJS
- TypeScript
- PostgreSQL
- TypeORM
- @nestjs/config
- class-validator
- class-transformer
- PostgreSQL with TypeORM was chosen to model clear relationships between users, products, carts, and orders.
- The codebase is split into NestJS modules so each domain stays isolated, readable, and easy to extend.
- Controllers are kept thin; business rules live in services, while database access is organized behind repositories.
- DTO validation, global exception handling, and OpenAPI docs were added to keep the API consistent and aligned with the task expectations.
- Copy the example file.
- Enter your local values.
cp .env.example .envMain variables:
NODE_ENVPORTDB_HOSTDB_PORTDB_USERNAMEDB_PASSWORDDB_NAMEDB_SYNCHRONIZEPASSWORD_PEPPERJWT_SECRETJWT_EXPIRES_INSWAGGER_ENABLED
PASSWORD_PEPPER is used as a server-side secret during password hashing and should be different from JWT_SECRET.
The easiest way to run the project (including the PostgreSQL database) is using Docker Compose.
# 1. Make sure you have your .env file
cp .env.example .env
# 2. Build and start the containers
docker compose up --build -dThe API will be accessible at http://localhost:3000 (along with Swagger UI) and the database will be running on localhost:5432.
If you prefer to run the application manually without Docker:
npm install -g bun # If you don't have bun installed
bun install
bun run start:dev- The config structure is organized under
src/common/config. - The database configuration for TypeORM is built from the host, port, username, password, and database fields.
- The current automated e2e test boots a minimal Nest test application for the health endpoint; it does not start the full
AppModuleor require a live database connection. - Order creation and cancellation use pessimistic row locks inside the transaction to prevent overselling and double cancellation during concurrent requests.
A basic JWT-based authentication flow has been added.
POST /auth/register: Creates a new user and returns an access token.POST /auth/login: Logs in the user and returns an access token.GET /auth/me: Returns the profile of the authenticated user with a Bearer token.
Example Authorization header:
Authorization: Bearer <access_token>- Using crypto is not a good idea for password hashing, but for simplicity, we are using it here with a pepper. In production, consider using bcrypt or argon2.
The product management requirement currently includes public read endpoints.
GET /products: Returns the full product list.GET /products/:id: Returns the details of a single product.
When the products table is empty, the application seeds a few mock products automatically on startup.
Cart operations are scoped to the authenticated user and require a Bearer token.
GET /cart: Returns the current cart.POST /cart/items: Adds a product to the cart.PUT /cart/items/:itemId: Updates the quantity of a cart item.DELETE /cart/items/:itemId: Removes a cart item from the cart.
The order flow converts the current cart into an order for the authenticated user.
POST /orders: Creates an order from the current cart, validates stock, decreases product stock, and clears cart items.GET /orders: Returns the authenticated user's order history.DELETE /orders/:orderId: Cancels an existing order and restores product stock.
Swagger / OpenAPI documentation is enabled for the request and response DTOs used by the modules and is sufficient for the requirements of this task. As an additional alternative, Scalar API Reference is also integrated. After starting the server, you can inspect the API schemas from both documentation UIs:
GET /docs: Swagger UIGET /docs/scalar: Scalar API Reference