# Product

## Description

Product is the central entity in the Product Management module. A product represents a commercial product -- identified by a unique code, along with its name, description, and unit of measure. Products serve as the parent entity from which variants are generated via attribute combinations. Each product has a lifecycle state machine (DRAFT -> ACTIVE <-> ARCHIVED) that controls when variant generation and downstream operations are permitted.

Products provide the commercial/marketing view of a product, separate from the operational SKU-level Item in item-management. Only ACTIVE products can generate variants. Only DRAFT products can be permanently deleted.

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> DRAFT: createProduct
    DRAFT --> ACTIVE: activateProduct
    ACTIVE --> ARCHIVED: deactivateProduct
    ARCHIVED --> ACTIVE: reactivateProduct
    DRAFT --> [*]: deleteProduct
```

| Operation | From | To | Command |
|-----------|------|----|---------|
| activate | DRAFT | ACTIVE | [activateProduct](../commands/ActivateProduct.md) |
| deactivate | ACTIVE | ARCHIVED | [deactivateProduct](../commands/DeactivateProduct.md) |
| reactivate | ARCHIVED | ACTIVE | [reactivateProduct](../commands/ReactivateProduct.md) |

### Command Definitions

- [createProduct](../commands/CreateProduct.md) - Create a new product in DRAFT status
- [updateProduct](../commands/UpdateProduct.md) - Update mutable fields of an existing product
- [activateProduct](../commands/ActivateProduct.md) - Transition product from DRAFT to ACTIVE
- [deactivateProduct](../commands/DeactivateProduct.md) - Transition product from ACTIVE to ARCHIVED
- [reactivateProduct](../commands/ReactivateProduct.md) - Transition product from ARCHIVED to ACTIVE
- [deleteProduct](../commands/DeleteProduct.md) - Permanently delete a DRAFT product

### Query Definitions

- GetProduct - Retrieve a product by id or code

### Models

- Product

### Invariants

- Product code is required, globally unique, and immutable after creation
- Product name is required and must be non-empty
- Products are always created in DRAFT status
- Only DRAFT products can be deleted; ACTIVE and ARCHIVED products are preserved
- Assigned attributes are freely modifiable in DRAFT status; on ACTIVE products only additive changes are allowed (new values for existing attributes); on ARCHIVED products all attribute changes are blocked
- Archiving a product does not affect existing Items generated from its variants
- UoM must reference an existing active Unit from the primitives module

### Relationships

- **References Unit**: Each product references a Unit from the primitives module as its unit of measure
- **Has Many ProductAttributeAssignments**: Product attribute assignments link attributes and their values to this product
- **Has Many ProductVariants**: Variants are generated from this product's attribute combinations
- **Has Many ProductCategoryAssignments**: Products are linked to ProductCategories via many-to-many assignments
