Cart Service (cart-app)
Relevant source files
The following files were used as context for generating this wiki page:
The Cart Service (cart-app) is a microservice within the e-commerce platform responsible for managing user shopping carts. It handles operations such as adding, updating, viewing, and clearing cart items. The service maintains its own state using a PostgreSQL database via Prisma and communicates with other microservices, primarily the product-app, over a NATS message broker to retrieve product details.
This service is designed to be stateful, persisting cart data for both guest sessions and authenticated users. It plays a crucial role in the checkout process, providing the necessary cart information to the order-app and being cleared upon successful order creation.
Sources: apps/cart-app/src/cart/cart.service.ts, deploys/README.md:18-26, apps/order-app/src/orders/orders.service.spec.ts:200-208
Architecture and Components
The cart-app is a standard NestJS application configured for a monorepo structure. It exposes its functionality via NATS message patterns, which are consumed by the API Gateway.
Sources: nest-cli.json:20-28
Key Components
| Component | Description | Source File |
|---|---|---|
CartService | The core of the service, containing all business logic for cart management. | apps/cart-app/src/cart/cart.service.ts |
CartController | (Implied) Listens for NATS messages and delegates them to CartService. | apps/cart-app/src/cart/cart.controller.spec.ts |
PrismaService | Provides database access to the Cart and CartItem models. | apps/cart-app/src/cart/cart.service.ts:43-44 |
ClientProxy | A NATS client used to communicate with the PRODUCT_SERVICE. | apps/cart-app/src/cart/cart.service.ts:44-45 |
Service Dependencies
The following diagram illustrates the dependencies and communication flow of the Cart Service.
This diagram shows that the API Gateway sends commands to the Cart Service, which interacts with its own database and fetches product data from the Product Service. The Order Service can command the Cart Service to clear a cart.
Sources: apps/cart-app/src/cart/cart.service.ts:45, apps/order-app/src/orders/orders.service.spec.ts:205-207, apps/gateway/REFACTORING-GUIDE.md:27-30
Database Schema
The service uses its own dedicated PostgreSQL database, cart_db, to store cart information. The schema is defined using Prisma and consists of two main models: Cart and CartItem.
Sources: deploys/README.md:105
Entity Relationship Diagram
This diagram shows the one-to-many relationship between the Cart and CartItem tables.
Cart Model
A Cart is uniquely identified by a sessionId. It can optionally be associated with a userId if the user is authenticated.
| Field | Type | Attributes | Description |
|---|---|---|---|
id | String | @id @default(cuid()) | Unique identifier for the cart. |
sessionId | String | @unique | Session identifier, used to track carts for guests and users. |
userId | String? | The ID of the authenticated user, if any. | |
items | CartItem[] | A list of items in the cart. | |
createdAt | DateTime | @default(now()) | Timestamp of cart creation. |
updatedAt | DateTime | @updatedAt | Timestamp of the last update. |
CartItem Model
A CartItem represents a product and its quantity within a specific cart. A composite key on cartId and productId ensures a product appears only once per cart.
| Field | Type | Attributes | Description |
|---|---|---|---|
id | String | @id @default(cuid()) | Unique identifier for the cart item. |
cart | Cart | @relation(...) | The parent cart. |
cartId | String | Foreign key to the Cart model. | |
productId | String | The ID of the product. | |
quantity | Int | The quantity of the product in the cart. | |
createdAt | DateTime | @default(now()) | Timestamp of item creation. |
updatedAt | DateTime | @updatedAt | Timestamp of the last update. |
Core Functionality
The CartService implements the ICartService interface and provides the primary business logic.
Sources: apps/cart-app/src/cart/cart.service.ts:33-39
get(dto: CartGetDto)
This method retrieves the full state of a user's cart.
- It calls the internal
getOrCreateCarthelper to find an existing cart or create a new one based on theuserId. - If the cart is empty, it returns the cart with an empty items array and a total of 0.
- If the cart has items, it collects all
productIds. - It sends a
product.getByIdsmessage to thePRODUCT_SERVICEvia NATS to fetch detailed product information. - It enriches the cart items with the fetched product data.
- It calculates the total price (
totalInt) by summingitem.quantity * product.priceInt. - It returns a
CartWithProductsResponsecontaining the cart, enriched items, and total.
Sources: apps/cart-app/src/cart/cart.service.ts:50-78, apps/cart-app/src/cart/cart.service.spec.ts:114-130
get() Sequence Diagram
This diagram shows the sequence of operations for retrieving a cart, including the external call to the Product Service.
Sources: apps/cart-app/src/cart/cart.service.ts:68-70, 219-222
getOrCreateCart(userId, sessionId)
This private helper method is central to the service's operation.
This flowchart details the logic for retrieving or creating a cart based on user and session identifiers.
Sources: apps/cart-app/src/cart/cart.service.ts:193-216
addItem(dto: CartAddItemDto)
Adds a product to the cart.
- Validates that
quantityis greater than 0. - Gets or creates a cart for the user.
- Uses
prisma.cartItem.upsertto either create a new cart item or increment the quantity if the product is already in the cart. - Calls
get()to return the updated cart state.
Sources: apps/cart-app/src/cart/cart.service.ts:83-110, apps/cart-app/src/cart/cart.service.spec.ts:250-260
updateItem(dto: CartUpdateItemDto)
Updates the quantity of an existing item.
- Validates that
quantityis not negative. - Gets or creates a cart for the user.
- If
quantityis 0, it deletes the item from the cart usingprisma.cartItem.deleteMany. - If
quantityis greater than 0, it updates the item's quantity usingprisma.cartItem.updateMany. - Calls
get()to return the updated cart state.
Sources: apps/cart-app/src/cart/cart.service.ts:115-149, apps/cart-app/src/cart/cart.service.spec.ts:365-381
removeItem(dto: CartRemoveItemDto)
Removes a product from the cart regardless of quantity.
- Gets or creates a cart for the user.
- Deletes the item using
prisma.cartItem.deleteMany. - Returns a
{ success: true }response.
Sources: apps/cart-app/src/cart/cart.service.ts:154-174, apps/cart-app/src/cart/cart.service.spec.ts:405-415
clear(userId: string)
Removes all items from a user's cart. This is typically called by the order-app after an order is successfully created.
- Finds the cart associated with the
userId. - If no cart is found, throws an
EntityNotFoundRpcException. - Deletes all
CartItemrecords associated with thecartId. - Returns a
{ success: true }response.
Sources: apps/cart-app/src/cart/cart.service.ts:303-326, apps/order-app/src/orders/orders.service.spec.ts:205-207
API and Communication
The service communicates via NATS. The following table details the message patterns it handles.
| NATS Pattern | DTO | Description | Source |
|---|---|---|---|
cart.get | CartGetDto | Retrieves the user's cart. | apps/cart-app/src/cart/cart.controller.spec.ts:52-55 |
cart.addItem | CartAddItemDto | Adds a product to the cart. | apps/cart-app/src/cart/cart.controller.spec.ts:70-73 |
cart.updateItem | CartUpdateItemDto | Updates a product's quantity. | apps/cart-app/src/cart/cart.controller.spec.ts:88-91 |
cart.removeItem | CartRemoveItemDto | Removes a product from the cart. | apps.cart-app/src/cart/cart.controller.spec.ts:106-109 |
cart.clear | { userId: string } | Clears all items from the cart. | apps/cart-app/src/cart/cart.controller.spec.ts:129-132 |
The Postman collection also documents these interactions from the perspective of the API Gateway.
Sources: postman-collection.json:1102-1250
Error Handling
The service uses a set of custom RPC exceptions to communicate errors back to the gateway. All public methods in CartService are wrapped in try...catch blocks to handle and re-throw errors in a standardized format.
| Exception | Scenario | Source |
|---|---|---|
ValidationRpcException | - quantity is <= 0 when adding. - quantity is < 0 when updating. - userId or sessionId is missing. | apps/cart-app/src/cart/cart.service.ts:85 |
EntityNotFoundRpcException | Cart not found when trying to clear. | apps/cart-app/src/cart/cart.service.ts:311 |
ServiceUnavailableRpcException | The PRODUCT_SERVICE times out or is unavailable. | apps/cart-app/src/cart/cart.service.ts:231 |
InternalServerRpcException | - Generic database errors. - Unexpected errors during processing. - Invalid response format from PRODUCT_SERVICE. | apps/cart-app/src/cart/cart.service.ts:76 |
Sources: apps/cart-app/src/cart/cart.service.spec.ts:161-168, 298-309, apps/cart-app/src/cart/cart.service.ts:230-232
Summary
The Cart Service is a well-defined microservice that encapsulates all logic related to shopping cart management. It effectively separates concerns by managing its own data while relying on the Product Service for product information. Its robust error handling and clear, event-based API make it a reliable component in the e-commerce architecture. The getOrCreateCart logic ensures a seamless experience for both guest and logged-in users.