Order Service (order-app)
Relevant source files
The following files were used as context for generating this wiki page:
The Order Service (order-app) is a microservice within the e-commerce platform responsible for managing the entire lifecycle of customer orders. Its scope includes order creation, retrieval, status updates, and management of individual order items. It operates independently with its own PostgreSQL database, defined by a Prisma schema.
This service communicates with other microservices, such as the product-app (to validate product information and manage stock) and the cart-app (to clear the user's cart after a successful order). All communication is handled asynchronously via a NATS message broker, receiving commands from the API Gateway.
Architecture and Components
The order-app is built using the NestJS framework and organized into modules for orders and order items. It relies on a NATS client for inter-service communication and Prisma for database interactions.
Sources: apps/order-app/src/order-app.module.ts
Module Dependencies
The main OrderAppModule imports and configures the necessary modules and clients for its operation.
// apps/order-app/src/order-app.module.ts:10-39
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
PrismaModule,
NatsClientModule.register({
name: 'PRODUCT_SERVICE',
}),
NatsClientModule.register({
name: 'CART_SERVICE',
}),
OrdersModule,
OrderItemModule,
],
// ...
})
export class OrderAppModule {}
The diagram below illustrates the key components and their dependencies.
Database Schema
The service uses its own dedicated database with two primary tables: Order and OrderItem. The schema is managed by Prisma.
Sources: apps/order-app/prisma/schema.prisma
Entity Relationship Diagram
This diagram shows the one-to-many relationship between the Order and OrderItem entities.
Order Model
This table stores high-level information about each order.
| Field | Type | Description |
|---|---|---|
id | String | Unique identifier (CUID). |
userId | String | The ID of the user who placed the order. Indexed. |
addressId | String? | The ID of the shipping address. Optional. |
status | OrderStatus | The current status of the order (e.g., PENDING, PROCESSING). |
paymentStatus | PaymentStatus | The payment status of the order (e.g., UNPAID, PAID). |
totalInt | Int | The total cost of the order in the smallest currency unit (e.g., cents). |
items | OrderItem[] | A list of all items included in the order. |
createdAt | DateTime | Timestamp of when the order was created. |
updatedAt | DateTime | Timestamp of the last update. |
Sources: apps/order-app/prisma/schema.prisma:19-32
OrderItem Model
This table stores details for each line item within an order.
| Field | Type | Description |
|---|---|---|
id | String | Unique identifier (CUID). |
orderId | String | Foreign key linking to the Order. |
productId | String | The ID of the product. |
productName | String | A snapshot of the product's name at the time of order. |
imageUrls | String[] | A snapshot of the product's image URLs. |
quantity | Int | The number of units of the product ordered. |
priceInt | Int | The price per unit in the smallest currency unit. |
createdAt | DateTime | Timestamp of when the item was added to the order. |
Sources: apps/order-app/prisma/schema.prisma:34-45
Core Business Logic
The OrdersService contains the primary logic for handling order operations.
Sources: apps/order-app/src/orders/orders.service.ts
Order Creation
The create method orchestrates the creation of a new order. It involves validation, communication with other services, and database insertion.
The process is as follows:
- Validates that the order contains at least one item.
- Fetches product details and stock information from the
product-appby sending aPRODUCT.GET_BY_IDSevent. - Validates that all products exist and have sufficient stock.
- Calculates the total order value.
- Creates the
Orderand associatedOrderItemrecords in the database. - Emits a
PRODUCT.DEC_STOCKevent for each item to decrement stock in theproduct-app. - Emits a
CART.CLEARevent to thecart-appto empty the user's shopping cart.
Sources: apps/order-app/src/orders/orders.service.ts:63-138, apps/order-app/src/orders/orders.service.spec.ts:182-293
Order Status Management
The updateStatus method manages the state transitions of an order. The status flow is strictly defined to ensure logical progression.
The valid transitions are:
PENDING->PROCESSINGPENDING->CANCELLEDPROCESSING->SHIPPEDPROCESSING->CANCELLEDSHIPPED->DELIVERED
Any other transition will result in a ValidationRpcException. If an order is moved to CANCELLED, the service calls restoreStock to emit PRODUCT.INC_STOCK events to the product-app.
Sources: apps/order-app/src/orders/orders.service.ts:312-358, apps/order-app/src/orders/orders.service.spec.ts:510-534
The following diagram illustrates the order status state machine.
Order Cancellation
The cancel method provides a dedicated way to cancel an order.
- It checks if the order exists.
- It throws a
ConflictRpcExceptionif the order is alreadyCANCELLED. - It throws a
ValidationRpcExceptionif the order status isSHIPPEDorDELIVERED, as these cannot be cancelled. - If cancellation is successful, it updates the status to
CANCELLEDand restores product stock.
Sources: apps/order-app/src/orders/orders.service.ts:360-388, apps/order-app/src/orders/orders.service.spec.ts:608-701
Listing and Filtering Orders
The service provides two methods for listing orders:
listByUser: Fetches a paginated list of orders for a specific user, sorted by creation date.listAll: An admin-only function that fetches all orders with advanced filtering and pagination.
The listAll method supports filtering by:
status(OrderStatus)paymentStatus(PaymentStatus)search(onidoruserId)startDateandendDate(forcreatedAtrange)
Sources: apps/order-app/src/orders/orders.service.ts:205-238, 240-310, apps/order-app/src/orders/orders.controller.spec.ts:258-305, 521-558
Order Item Management
The OrderItemService handles operations on individual items within an existing order, such as adding or removing them. These operations are performed within a database transaction to ensure data integrity.
Sources: apps/order-app/src/order-item/order-item.service.spec.ts (as order-item.service.ts was not provided, logic is inferred from its test file)
addItem: Adds a new item to an order and transactionally increments the order'stotalInt. It validates that quantity and price are positive.removeItem: Removes an item from an order and transactionally decrements the order'stotalInt.
Sources: apps/order-app/src/order-item/order-item.service.spec.ts:133-239, 241-352
NATS Events
The service exposes its functionality via NATS message patterns. The API Gateway sends requests to these patterns.
| Event Pattern | DTO Payload | Description | Source |
|---|---|---|---|
order.create | OrderCreateDto | Creates a new order. | orders.controller.spec.ts:88 |
order.get | OrderIdDto | Retrieves a single order by its ID. | orders.controller.spec.ts:154 |
order.list | OrderListDto | Lists orders for the current user. | orders.controller.spec.ts:209 |
order.list.all | OrderAdminListDto | Lists all orders with filters (admin). | orders.controller.spec.ts:530 |
order.update.status | OrderUpdateStatusDto | Updates the status of an order. | orders.controller.spec.ts:317 |
order.update.paymentStatus | OrderUpdatePaymentStatusDto | Updates the payment status of an order. | orders.controller.spec.ts:570 |
order.cancel | OrderCancelDto | Cancels an order. | orders.controller.spec.ts:390 |
Sources: apps/order-app/src/orders/orders.controller.spec.ts
Error Handling
The service uses custom RPC exceptions from the @shared/exceptions library to provide clear, structured error information to the caller (API Gateway).
ValidationRpcException: Used for invalid input, such as an empty item list, insufficient stock, or invalid status transitions.EntityNotFoundRpcException: Thrown when an order or related entity cannot be found.ConflictRpcException: Used for state conflicts, such as trying to cancel an already-cancelled order.
Sources: apps/order-app/src/orders/orders.service.ts:70, 185, 329, 375