Saltar al contenido principal

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_variantproduct_option_value → size).

API Endpoints

All endpoints require Bearer authentication and role-based permissions (PolicyResource.Size).

MethodPathDescriptionAuth
POST/sizesCreate a new sizeCreate
GET/sizesList sizes (paginated)Read
GET/sizes/:id?businessId=Get size by IDRead
PATCH/sizes/:idUpdate a sizeUpdate
DELETE/sizes/:id?businessId=Delete a sizeDelete

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

  1. Business scoping on all mutations and reads by IDfindById, update, and delete all require businessId to enforce multi-tenant isolation at the query level.
  2. Symbol-based DISIZES_REPOSITORY symbol decouples the service from the concrete Kysely implementation, following the same pattern as brands and models.
  3. isActive defaults to true — Optional in the create DTO; the database column default handles it.
  4. UpdateSizeDTO requires businessId — Passed through to the repository for scoped update queries.