# Order Service
An **order management REST API** with authentication, role-based access control, and MongoDB persistence. It exposes endpoints for:
- **Auth** – register/login, issue JWTs
- **Products** – admin-only create/update, public list
- **Orders** – customers create/list/pay/cancel orders
- **Users** – admin-only user listing
Built with **Node.js**, **Express 5**, **TypeScript**, and **Mongoose**.
Swagger doc for test in the browser:
---
## 1. Setup & Installation
- **Prerequisites**
- **Node.js**: v20+ recommended
- **Package manager**: `pnpm` (project uses `pnpm-lock.yaml`)
- **MongoDB**: running locally or accessible via connection string
- **Clone and install**
```bash
git clone order-service
cd order-service
pnpm install
```
- **Build the project**
```bash
pnpm run build
```
- **Start the server**
By default the compiled server entrypoint is `dist/server.js`:
```bash
node dist/server.js
```
The API will listen on `http://localhost:` (defaults to `3000`).
---
## 2. Environment Variables
Environment variables are loaded via `dotenv` in `src/config/env.ts`. The following variables are **required/recommended**:
- **Required**
- **`MONGO_URI`**: MongoDB connection string
Example: `mongodb://localhost:27017/order_service`
- **`JWT_SECRET`**: Secret key used to sign JWT access tokens
- **Optional**
- **`PORT`**: HTTP port to run the server on
Default: `3000`
- **`NODE_ENV`**: `development` | `production`
Default: `development`
- **`API_URL`**: External base URL for the API
Default: `http://localhost:3000`
- **`JWT_EXPIRES_IN`**: Token lifetime, e.g. `1h`, `7d`
Default: `1h`
- **Example `.env`**
```bash
NODE_ENV=development
PORT=3000
API_URL=http://localhost:3000
MONGO_URI=mongodb://localhost:27017/order_service
JWT_SECRET=super-secret-change-me
JWT_EXPIRES_IN=1h
```
Create a `.env` file at the project root before running the server or scripts.
---
## 3. Database, Migrations & Seeding
This project uses **MongoDB + Mongoose**. There is no formal migration tool configured; schemas are defined via Mongoose models under `src/models`.
- **Database connection**
- Configured in `src/config/db.ts` using `MONGO_URI`.
- **Seeding products**
There is a seed script at `src/scripts/seed.ts` which:
- Connects to MongoDB
- Clears the `products` collection
- Inserts a fixed list of sample products (mice, keyboards, etc.)
**Run the seed script:**
```bash
pnpm run seed
```
Under the hood this will:
1. Compile TypeScript (`tsc`)
2. Run `node dist/scripts/seed.js`
Make sure:
- The project is built without errors.
- `MONGO_URI` is correctly set in your `.env`.
---
## 4. Running the Service
- **Build once:**
```bash
pnpm run build
```
- **Start server:**
```bash
node dist/server.js
```
The service will:
- Connect to MongoDB.
- Expose health check at `GET /health`.
- Expose REST endpoints under `/auth`, `/products`, `/orders`, `/users`.
- Expose Swagger docs under `/docs`.
> Note: For local development you can also use `ts-node` / `nodemon` if you wire custom scripts, but for this task the build‑then‑run flow above is sufficient.
---
## 5. API Reference & Example `curl` Requests
## 5.1 Health Check
- **GET `/health`**
```bash
curl -i https://order-service-t77z.onrender.com/health
```
---
## 5.2 Auth
### Register
- **POST `/auth/register`**
- Body:
```bash
curl -i -X POST https://order-service-t77z.onrender.com/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "customer@example.com",
"password": "Password123",
"role": "customer"
}'
```
For an admin user, set `"role": "admin"`.
### Login
- **POST `/auth/login`**
```bash
curl -i -X POST https://order-service-t77z.onrender.com/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "customer@example.com",
"password": "Password123"
}'
```
The response includes a `token` field (JWT). Use this token in subsequent requests:
```text
Authorization: Bearer
```
---
## 5.3 Products
### List products (public)
- **GET `/products`**
```bash
curl -i https://order-service-t77z.onrender.com/products
```
### Create product (admin only)
- **POST `/products`**
```bash
curl -i -X POST https://order-service-t77z.onrender.com/products \
-H "Content-Type: application/json" \
-H "Authorization: Bearer " \
-d '{
"name": "New Gadget",
"price": 1999,
"stock": 25
}'
```
### Update product (admin only)
- **PATCH `/products/:id`**
```bash
curl -i -X PATCH https://order-service-t77z.onrender.com/products/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer " \
-d '{
"price": 2499,
"stock": 40
}'
```
---
## 5.4 Orders
### Create order (customer or admin)
- **POST `/orders`**
```bash
curl -i -X POST https://order-service-t77z.onrender.com/orders \
-H "Content-Type: application/json" \
-H "Authorization: Bearer " \
-d '{
"items": [
{ "productId": "", "quantity": 2 },
{ "productId": "", "quantity": 1 }
]
}'
```
### List my orders
- **GET `/orders`**
```bash
curl -i https://order-service-t77z.onrender.com/orders \
-H "Authorization: Bearer "
```
### Pay for an order
- **POST `/orders/:id/pay`**
```bash
curl -i -X POST https://order-service-t77z.onrender.com/orders//pay \
-H "Authorization: Bearer "
```
### Cancel an order
- **POST `/orders/:id/cancel`**
```bash
curl -i -X POST https://order-service-t77z.onrender.com/orders//cancel \
-H "Authorization: Bearer "
```
---
## 5.5 Users (Admin only)
### List users
- **GET `/users`**
```bash
curl -i https://order-service-t77z.onrender.com/users \
-H "Authorization: Bearer "
```
---
## 6. Swagger / API Docs
The service is wired with `swagger-jsdoc` and `swagger-ui-express`. OpenAPI annotations live in the route files (e.g. `src/routes/auth.routes.ts`, `src/routes/order.routes.ts`, etc) and are aggregated in the Swagger configuration.
- **View documentation UI:**
```bash
open https://order-service-t77z.onrender.com/docs
```
This provides an interactive UI for exploring and testing all endpoints.
---
## 7. Design Notes
- **Architecture**
- **Layered structure**:
- `controllers/`: Express route handlers (request/response orchestration).
- `services/`: Business logic (auth, orders, products, users).
- `repositories/`: Data access layer over Mongoose models.
- `models/`: Mongoose schemas and models.
- `middleware/`: Cross-cutting concerns (auth, validation, error handling, rate limiting, role checks).
- **Separation of concerns** keeps controllers thin and business logic testable.
- **Authentication & Authorization**
- JWT-based auth (see `auth.middleware.ts` and `utils/jwt.ts`).
- Role-based access control via `requireRole` middleware:
- Customers can create/list/pay/cancel their own orders.
- Admins can manage products and list all users.
- **Validation & Error Handling**
- **Zod** schemas validate payloads (`validation/*.schema.ts`).
- Central `error.middleware.ts` normalizes API error responses.
- `rateLimit.middleware.ts` limits sensitive endpoints (e.g. auth) to mitigate brute-force.
- **Persistence**
- MongoDB via Mongoose models (`user.model.ts`, `product.model.ts`, `order.model.ts`).
- Order items reference products and store quantities and pricing data for consistency.
- **Observability & DX**
- `morgan` + custom `logger` provide structured request logs.
- TypeScript configuration (`tsconfig.json`) and linting (`eslint.config.mts`) encourage a consistent, safe codebase.