File Storage (Minio)
Relevant source files
The following files were used as context for generating this wiki page:The Minio integration provides an S3-compatible object storage solution for the product-app microservice. Its primary purpose is to handle the storage and retrieval of product-related images, including standard product photos and special "try-on" images. The system is designed to be self-initializing, creating and configuring the necessary storage bucket on startup.
A separate set of helper scripts is also available for bulk-uploading images during database seeding, ensuring that a new environment can be populated with both product data and its associated media files. The MinioService is a core component, encapsulating all interactions with the Minio server, from uploading and validation to deletion.
Configuration
The connection to the Minio server is configured through environment variables, with sensible defaults for local development. The configuration is defined in two separate but similar locations: one for the application runtime and one for the seeding scripts.
Sources: apps/product-app/src/minio/minio.config.ts:1-7, scripts/lib/minio-helper.ts:5-12
Connection Parameters
| Parameter | Environment Variable | Default Value | Description |
|---|---|---|---|
endPoint | MINIO_ENDPOINT | '127.0.0.1' | The hostname or IP address of the Minio server. |
port | MINIO_PORT | 9000 | The port number for the Minio server. |
useSSL | MINIO_USE_SSL | false | Whether to use SSL/TLS for the connection. |
accessKey | MINIO_ACCESS_KEY | 'minio' | The access key for authentication. |
secretKey | MINIO_SECRET_KEY | 'supersecret' | The secret key for authentication. |
The application consistently uses a single bucket named web-ban-kinh.
Sources: apps/product-app/src/minio/minio.config.ts:9, scripts/lib/minio-helper.ts:14
Core Service (MinioService)
The MinioService, located in the product-app, is the central component for managing file storage operations. It handles bucket initialization, file uploads with validation, and file deletion.
Source: apps/product-app/src/minio/minio.service.ts
Initialization
On module initialization (onModuleInit), the service ensures that the designated Minio bucket exists. If it does not, the service creates it and applies a public-read policy, allowing anyone to view the uploaded files via their URL.
This diagram illustrates the bucket initialization logic.
The public read policy is defined as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "AWS": ["*"] },
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::web-ban-kinh/*"]
}
]
}
Source: apps/product-app/src/minio/minio.service.ts:28-37
File Uploads
The service provides two distinct methods for uploading files, each with its own set of validation rules and storage paths.
Standard Image Upload (uploadImage)
This method is used for general product images. It performs validation on file type and size before uploading.
Validation Rules:
| Rule | Constraint | Error Message |
|---|---|---|
| Mime Type | image/jpeg, image/jpg, image/png, image/webp | Invalid file type. Only JPEG, PNG, and WebP are allowed. |
| File Size | <= 5 MB | File size exceeds 5MB limit. |
Sources: apps/product-app/src/minio/minio.service.ts:42-56, apps/product-app/src/minio/minio.service.spec.ts:90-108
Uploaded files are given a unique name and stored in the products/ directory within the bucket. The filename is generated using a timestamp and a random string.
Source: apps/product-app/src/minio/minio.service.ts:59-61
This sequence diagram shows the standard image upload process.
Try-On Image Upload (uploadTryOnImage)
This specialized method is for uploading PNG images used for virtual try-on features. These images require a transparent background, so only the image/png mimetype is accepted. They are also allowed a larger file size.
Validation Rules:
| Rule | Constraint | Error Message |
|---|---|---|
| Mime Type | image/png | Invalid file type for try-on image. Only PNG is allowed. |
| File Size | <= 20 MB | Try-on file size exceeds 5MB limit. (Note: The error message incorrectly states 5MB, but the code checks for 20MB) |
Sources: apps/product-app/src/minio/minio.service.ts:73-84, apps/product-app/src/minio/minio.service.spec.ts:115-132
These files are stored in the try-on/ directory to keep them separate from standard product images.
Source: apps/product-app/src/minio/minio.service.ts:86
Image Deletion (deleteImage)
The deleteImage method removes a specified file from the Minio bucket. A key feature of this method is its fault tolerance: if the deletion fails (e.g., the file doesn't exist), it logs the error to the console but does not throw an exception. This prevents the failure of a file deletion from halting a larger operation, such as deleting a product record from the database.
Sources: apps/product-app/src/minio/minio.service.ts:94-100, apps/product-app/src/minio/minio.service.spec.ts:144-154
Seeding Script Integration
The project includes a robust seeding script (scripts/seed.ts) that populates the database and Minio with initial data. The Minio-related logic is abstracted into scripts/lib/minio-helper.ts.
Seeding Flow
The main seed script orchestrates the entire process, first initializing the Minio bucket and then uploading all necessary images before creating product records in the database.
This flowchart outlines the seeding process involving Minio.
Source: scripts/seed.ts:194-206
Helper Functions
The minio-helper.ts file provides functions to support the seeding process:
initMinIOBucket(): Ensures the bucket exists and is public, similar to theMinioService.uploadAllImages(imagesDir): Reads all.jpgfiles from a specified directory, uploads them to the root of the Minio bucket, and returns a map of filenames to their public URLs.uploadTryOnImages(tryOnDir): Scans subdirectories for.pngfiles, uploads them to thetry-on/path in Minio, and returns a map of the source directory name (e.g.,glasses-01) to the public URL.
Sources: scripts/lib/minio-helper.ts:19-125, scripts/seed.ts:114-120
Integration with ProductsService
The MinioService is injected into the ProductsService to manage image lifecycles in coordination with product database operations. The products.service.spec.ts file clearly demonstrates this relationship.
Source: apps/product-app/src/products/products.service.spec.ts:40-44
When an administrator performs CRUD operations on products, the ProductsService calls the MinioService:
- Create (
adminCreate): If image or try-on file data is provided, it callsminioService.uploadImageorminioService.uploadTryOnImagerespectively. The returned URL and filename are then saved in the product's database record. - Update (
adminUpdate): If a new image is provided, it first callsminioService.deleteImageto remove the old image (if it exists) and thenminioService.uploadImageto upload the new one. - Delete (
adminDelete): After the product is confirmed to exist, it callsminioService.deleteImageto remove the associated image file before deleting the product record from the database.
This sequence diagram illustrates the flow for updating a product with a new try-on image.