Items Domain
Overview
The Items domain is the foundational master data module for the inventory system, managing all product and item catalog information. It uses a composition-based architecture pattern that provides maximum flexibility for different item types without rigid inheritance hierarchies.
Core Concepts
Composition Over Inheritance
The Items domain adopts a composition-based architecture instead of traditional class inheritance. This design decision enables:
- Flexibility: Items can have behaviors added or removed dynamically
- Simplicity: No complex inheritance hierarchies to manage
- Extensibility: Easy to add new behaviors without modifying existing code
- Clear Separation: Each behavior is self-contained and testable
Item Classification
Items in the system fall into two main categories based on behavior:
-
Stockable Items: Items that have inventory tracking enabled via
StockableBehavior- Examples: Raw materials, finished goods, components
- Tracked across locations and transactions
- Support negative stock control (configurable)
- Location-based tracking capabilities
-
Non-Stockable Items: Items without inventory tracking
- Examples: Services, labor, intangible items
- No inventory quantities maintained
- Used for reference and billing purposes only
Unit Class System
Instead of forcing items to use specific units of measure, the Items domain uses a UnitClass system:
- Items reference a UnitClass (e.g., "Weight", "Length", "Volume")
- Transactions can use any UnitOfMeasure within that class
- Example: Item uses "Weight" class → transactions can use kg, lb, g, oz, tons, etc.
- Provides maximum flexibility at transaction time
Domain Structure
Aggregates
items/
├── aggregates/
│ └── item.aggregate.md # Core Item aggregate documentation
Entities
items/
└── entities/
├── behaviors/
│ └── stockable-behavior.md # Stockable behavior composition
└── item.md # Item entity (aggregate root)
Value Objects
The Items domain currently uses simple value types. Future enhancements may include:
- Item pricing value objects
- Dimension specifications (size, weight, color)
- Product identifiers (SKU, UPC, EAN)
Key Aggregates
Item
Aggregate Root: Item
Purpose: Core catalog entity representing any product, material, or service in the system.
Key Characteristics:
- Uses composition pattern with optional behaviors
- References category for hierarchical classification
- Uses UnitClass for flexible measurement
- Supports tax group integration
- Maintains item lifecycle (active/inactive)
Relationships:
- Belongs to one
Category(optional) - References one
UnitClass(optional) - References one
TaxGroup(optional) - Can have one
StockableBehavior(optional composition)
Core Operations:
- Create item with basic properties
- Add/remove/update stockable behavior
- Update item information
- Category assignment
- Tax group assignment
Business Rules
Item Creation Rules
- Item Number Required: Every item must have a unique item number (identifier)
- Name Required: Item name cannot be empty
- Description Optional: Description provides additional details but is not mandatory
- Category Optional: Items can exist without category assignment
- Unit Class Optional: Items can be created without a unit class (assigned later)
Stockable Behavior Rules
- Single Behavior: An item can have at most one stockable behavior at a time
- Cannot Duplicate: Cannot add stockable behavior if already present
- Cannot Remove Missing: Cannot remove stockable behavior that doesn't exist
- Negative Stock Control: Each stockable item configures whether negative stock is allowed
- Location Tracking: Each stockable item configures whether location-based tracking is required
Update Rules
- Immutable Item Number: Item number cannot be changed after creation
- Name Cannot Be Empty: Updates must provide valid item name
- Behavior Updates: Stockable behavior settings can be updated independently
- Category Reassignment: Category can be changed or cleared at any time
- Tax Group Flexibility: Tax group assignment can be updated as needed
Integration Points
With Transaction Module
- Transaction Creation: Validates that item is stockable for inventory transactions
- Negative Stock Validation: Checks item's negative stock setting before allowing negative inventory
- Location Tracking: Enforces location requirements based on item's tracking settings
- Unit Validation: Ensures transaction units match item's unit class
With Inventory Module
- Inventory Records: Only stockable items have inventory records
- Stock Queries: Non-stockable items return zero or no inventory data
- Location-Based Tracking: Inventory tracks per-location if item requires it
With BOM Module
- Parent Items: Items can be parent items in BOMs (finished goods)
- Component Items: Items can be components in BOMs (raw materials)
- Assembly Validation: Verifies items are stockable for assembly operations
With Finance Module
- Tax Group Integration: Item tax group used for financial transaction tax calculations
- Revenue/COGS Accounts: Item properties used to determine GL accounts for posting
- Integration Events: Purchase/sale events trigger inventory updates for stockable items
Common Patterns
Creating Stockable Items
// 1. Create basic item
var item = Item.Create(
itemNumber: "WIDGET-001",
name: "Premium Widget",
description: "High-quality widget for manufacturing",
categoryId: widgetCategoryId,
defaultUnitClassId: weightUnitClassId,
taxGroupId: standardTaxGroupId);
// 2. Add stockable behavior to enable inventory tracking
item.AddStockableBehavior(
allowNegativeStock: false, // Prevent negative inventory
trackByLocation: true); // Require location for transactions
// 3. Save via repository
await itemRepository.AddAsync(item);
await unitOfWork.CommitAsync();
Creating Non-Stockable Items (Services)
// Create item without adding stockable behavior
var serviceItem = Item.Create(
itemNumber: "SRV-INSTALL",
name: "Installation Service",
description: "Professional installation service",
categoryId: servicesCategoryId);
// No stockable behavior added - item remains non-stockable
await itemRepository.AddAsync(serviceItem);
await unitOfWork.CommitAsync();
Converting Between Stockable and Non-Stockable
// Make item stockable
item.AddStockableBehavior(
allowNegativeStock: true,
trackByLocation: true);
// Later, make it non-stockable
// (Note: Should validate no inventory exists first)
item.RemoveStockableBehavior();
Updating Stockable Settings
// Update behavior settings without removing/re-adding
item.UpdateStockableBehavior(
allowNegativeStock: true, // Now allow negative stock
trackByLocation: false); // Disable location tracking
Repository Pattern
IItemRepository
Query Methods:
GetByIdAsync(Guid id): Get item with all related dataGetAllAsync(): Get all active itemsGetByItemNumberAsync(string itemNumber): Find item by unique numberGetStockableItemsAsync(): Get only items with stockable behaviorGetByCategoryAsync(Guid categoryId): Get items in specific category
Command Methods:
AddAsync(Item item): Create new itemUpdate(Item item): Update existing itemArchive(Item item): Soft delete (sets IsActive = false)UnArchive(Item item): Restore archived item
Validation Methods:
ExistsByItemNumberAsync(string itemNumber): Check uniquenessIsItemNumberUniqueAsync(string itemNumber, Guid? excludeId): Validate for updates
Domain Services
IItemService
Purpose: Coordinates complex operations involving multiple aggregates.
Key Methods:
ValidateItemForTransactionAsync(Guid itemId, TransactionType type): Ensures item can be used in transactionGetAvailableUnitsForItemAsync(Guid itemId): Gets valid units based on item's unit classConvertStockableStatusAsync(Guid itemId, bool makeStockable): Safely converts with validation
Testing Strategy
Unit Tests
- Factory Method Tests: Validate item creation with various combinations
- Behavior Tests: Add/remove/update stockable behavior scenarios
- Validation Tests: Business rule enforcement (required fields, duplicates)
- Update Tests: Property updates and constraint validation
Integration Tests
- Repository Tests: Database operations and query correctness
- Relationship Tests: Category, UnitClass, TaxGroup associations
- Behavior Persistence: Stockable behavior correctly saved/loaded
- Soft Delete Tests: Archive/UnArchive functionality
Domain Event Tests
Future enhancement when domain events are added for:
- Item created events
- Stockable behavior changed events
- Item archived/restored events
Future Enhancements
Planned Features
- Item Variants: Support for size/color/style variants of a base item
- Item Attributes: Flexible attribute system for product specifications
- Pricing Management: Built-in price lists and pricing tiers
- Supplier Relationships: Link items to preferred suppliers
- Item Images: Support for product images and documents
- Serial/Batch Tracking: Enhanced tracking for lot-controlled items
Extensibility Points
-
Additional Behaviors: New behaviors can be added via composition
- PurchasableBehavior: Purchase-specific rules
- SellableBehavior: Sales-specific rules
- ManufacturableBehavior: Production-specific rules
-
Custom Validation: Domain service can be extended for business-specific rules
-
Integration Events: Publish events for cross-module integration
- ItemCreated
- ItemStockableStatusChanged
- ItemCategoryChanged
Related Documentation
Domain Documentation
- Item Aggregate - Detailed aggregate documentation
- Stockable Behavior - Behavior composition details
API Documentation
- Items API - REST endpoints for item management
Concept Documentation
- Composition Over Inheritance - Architecture pattern explanation
- Unit Class System - Measurement system design
Architecture Documentation
- Item Domain Architecture - Architectural decisions
Last Updated: 2025-10-24 | Status: Active Development | Version: 1.0