Sizes Module
Overview
The Sizes module manages product size definitions (e.g., S, M, L, XL, 38, 40, 42) for a business. Sizes are used in the product variant system to define one of the option dimensions for sellable SKUs.
Each size is scoped to a businessId for multi-tenant isolation.
Architecture
Follows hexagonal architecture:
sizes/
├── sizes.module.ts # NestJS module (DI wiring)
├── domain/
│ └── sizes-repository.domain.ts # Repository port (interface + injection symbol)
├── application/
│ └── sizes.service.ts # Use cases (depends on domain port)
├── infrastructure/
│ └── sizes.repository.ts # Kysely adapter (implements domain port)
└── interfaces/
├── sizes.controller.ts # HTTP adapter (REST endpoints)
├── dtos/
│ ├── create-size.dto.ts # Create request validation
│ └── update-size.dto.ts # Update request validation
└── query/
└── paginate-sizes.query.ts # List query parameters
Dependency flow: Controller → Service → Repository Interface ← Repository Implementation
Domain Concepts
- Size — A named product size belonging to a business. Fields:
id,name,businessId,isActive,createdBy,updatedBy,createdAt,updatedAt. - Sizes are referenced by the product variant system (
product_variant→product_option_value→ size).
API Endpoints
All endpoints require Bearer authentication and role-based permissions (PolicyResource.Size).
| Method | Path | Description | Auth |
|---|---|---|---|
POST | /sizes | Create a new size | Create |
GET | /sizes | List sizes (paginated) | Read |
GET | /sizes/:id?businessId= | Get size by ID | Read |
PATCH | /sizes/:id | Update a size | Update |
DELETE | /sizes/:id?businessId= | Delete a size | Delete |
Create Size
POST /sizes
{
"name": "M",
"businessId": "uuid",
"isActive": true,
"createdBy": "uuid"
}
List Sizes
GET /sizes?businessId=uuid&size=10&page=1&orderBy=name&order=asc&search=medium
Get Size by ID
GET /sizes/:id?businessId=uuid
Update Size
PATCH /sizes/:id
{
"name": "Medium",
"businessId": "uuid",
"updatedBy": "uuid"
}
Delete Size
DELETE /sizes/:id?businessId=uuid
Design Decisions
- Business scoping on all mutations and reads by ID —
findById,update, anddeleteall requirebusinessIdto enforce multi-tenant isolation at the query level. - Symbol-based DI —
SIZES_REPOSITORYsymbol decouples the service from the concrete Kysely implementation, following the same pattern as brands and models. isActivedefaults to true — Optional in the create DTO; the database column default handles it.UpdateSizeDTOrequiresbusinessId— Passed through to the repository for scoped update queries.