Product Service (product-app)
Relevant source files
The following files were used as context for generating this wiki page:- apps/product-app/src/product-app.module.ts
- apps/product-app/src/products/products.service.ts
- apps/product-app/src/categories/categories.service.ts
- apps/product-app/prisma/schema.prisma
- libs/shared/dto/product.dto.ts
- apps/product-app/src/products/products.controller.ts
- apps/product-app/src/products/builders/product-query.builder.ts
- apps/product-app/test/products.e2e-spec.ts
The product-app is a NestJS-based microservice responsible for managing all product and category-related data within the e-commerce platform. It handles operations such as creating, reading, updating, and deleting products and categories, managing inventory levels, and providing query capabilities for product listings.
This service communicates with other parts of the system, like the API Gateway, via a NATS message broker. It uses Prisma as its ORM to interact with a dedicated PostgreSQL database and integrates with a Minio service for image storage.
Architecture
The product-app follows a standard NestJS modular architecture. It is defined in the monorepo configuration and has its own dedicated database schema.
Sources: nest-cli.json:54-62, apps/product-app/prisma/schema.prisma
Core Components
The service is composed of several key modules and providers that handle distinct responsibilities.
| Component | Description | Source File -
| ProductsController | Exposes product management endpoints via NATS message patterns. | apps/product-app/src/products/products.controller.ts -
| ProductsService | Contains the core business logic for product CRUD, stock management, and image handling. | apps/product-app/src/products/products.service.ts -
| CategoriesService | Manages category data, including hierarchical relationships and validation logic. | apps/product-app/src/categories/categories.service.ts -
| ProductQueryBuilder | A helper class to construct complex Prisma query conditions for filtering and searching products. | apps/product-app/src/products/builders/product-query.builder.ts -
| PrismaService | A singleton service that provides access to the Prisma Client for database interactions. | apps/product-app/prisma/prisma.service.ts (Inferred from usage) -
| MinioService | Handles file uploads and deletions to a Minio object storage server, used for product images. | apps/product-app/src/products/products.service.ts:13,38 (Inferred from usage) -
Sources: apps/product-app/src/product-app.module.ts:11-30
This diagram illustrates the high-level component architecture of the product-app.
NATS Event Handlers
The service listens for specific event patterns on the NATS message bus to perform actions. These are handled by the ProductsController and CategoriesController.
| Event Pattern | Handler Method | Description |
|---|---|---|
product.getById | getById | Fetches a single product by its ID. |
product.getByIds | getByIds | Fetches multiple products by their IDs. |
product.getBySlug | getBySlug | Fetches a single product by its slug. |
product.list | list | Lists products with filters and pagination. |
product.create | create | Creates a new product. |
product.update | update | Updates an existing product. |
product.delete | delete | Deletes a product. |
product.decrementStock | decrementStock | Decrements the stock of a product. |
product.incrementStock | incrementStock | Increments the stock of a product. |
product.admin.create | adminCreate | Admin-specific product creation. |
product.admin.update | adminUpdate | Admin-specific product update. |
product.admin.delete | adminDelete | Admin-specific product deletion. |
category.create | create | Creates a new category. |
category.list | list | Lists categories. |
category.getById | getById | Fetches a category by ID. |
category.getBySlug | getBySlug | Fetches a category by slug. |
category.update | update | Updates a category. |
category.delete | delete | Deletes a category. |
Sources: apps/product-app/src/products/products.controller.ts, apps/product-app/test/products.e2e-spec.ts, apps/product-app/test/categories.e2e-spec.ts
Database Schema
The database schema for the product-app is defined using Prisma and consists of two main models: Product and Category.
Sources: apps/product-app/prisma/schema.prisma
This ER diagram shows the relationship between the Product and Category entities.
Product Model
| Field | Type | Description |
|---|---|---|
id | String | Unique identifier (CUID). |
sku | String | Stock Keeping Unit, unique identifier for the product. |
name | String | The name of the product. |
slug | String | URL-friendly version of the name, must be unique. |
priceInt | Int | Price of the product in the smallest currency unit (e.g., cents) to avoid floating-point issues. |
stock | Int | Available quantity of the product. Defaults to 0. |
attributes | Json | A flexible JSON field for storing additional product attributes like color, size, or try-on image URLs. |
categoryId | String | Foreign key linking to the Category model. |
imageUrls | String[] | An array of URLs for product images. |
imageFilename | String | The filename of the main product image as stored in Minio. |
imageUrl | String | The public URL of the main product image. |
Sources: apps/product-app/prisma/schema.prisma:29-49
Category Model
| Field | Type | Description |
|---|---|---|
id | String | Unique identifier (CUID). |
name | String | The name of the category. |
slug | String | URL-friendly version of the name, must be unique. |
parentId | String | Self-referencing foreign key to create a category hierarchy. |
Sources: apps/product-app/prisma/schema.prisma:11-27
Core Features
Product Management
The ProductsService is the central point for all product-related business logic.
Sources: apps/product-app/src/products/products.service.ts
Product Creation and Update
The adminCreate and adminUpdate methods handle product creation and updates, including image uploads. If a fileBuffer is provided in the DTO, the service interacts with MinioService to upload the image and stores the resulting URL and filename. It also handles "try-on" images separately.
The following sequence diagram shows the flow for creating a new product with an image.
Product Listing and Filtering
The list method in ProductsService provides a powerful way to query products. It uses ProductQueryBuilder to construct a Prisma where clause based on the ProductListQueryDto.
Supported query parameters include:
search: Full-text search onname,description, andsku.categorySlug: Filter by a specific category.minPriceInt/maxPriceInt: Filter by a price range.page/pageSize: For pagination.
Sources: apps/product-app/src/products/products.service.ts:114-135, apps/product-app/src/products/builders/product-query.builder.ts:7-50, libs/shared/dto/product.dto.ts:88-115
Category Management
The CategoriesService handles all logic for categories. A key feature is its validation system, which prevents common issues in hierarchical data structures.
Sources: apps/product-app/src/categories/categories.service.ts
Deletion Validation
Before deleting a category, the validateCanDelete method checks two conditions:
- The category must not have any child categories.
- The category must not have any products associated with it.
If either condition is met, an RpcException is thrown, preventing the deletion and ensuring data integrity.
Circular Reference Prevention
When updating a category's parentId, the validateParentUpdate method ensures that the update does not create a circular reference (e.g., setting a category as its own child or grandchild). It traverses the descendant tree of the category being updated to ensure the new parent is not within it.
Sources: apps/product-app/src/categories/categories.service.ts:145-151
Stock Management
The ProductsService provides atomic operations for incrementing and decrementing product stock, which are crucial for order and cart management.
Decrementing Stock
The decrementStock method first checks if there is sufficient stock available. If not, it throws an RpcException. If stock is sufficient, it uses Prisma's atomic decrement operation to update the count in the database.
Conclusion
The product-app is a well-defined microservice that serves as the single source of truth for product and category information. Its architecture leverages NestJS for structure, Prisma for type-safe database access, and NATS for asynchronous communication. The service includes robust business logic for data validation, hierarchical management of categories, and atomic stock operations, making it a reliable and essential component of the e-commerce platform.