PHPackages                             azaharizaman/nexus-product - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. azaharizaman/nexus-product

ActiveLibrary[Framework](/categories/framework)

azaharizaman/nexus-product
==========================

Framework-agnostic product catalog management with template-variant architecture, SKU generation, and barcode handling

v0.1.0-alpha1(1mo ago)001MITPHPPHP ^8.3

Since May 5Pushed 1mo agoCompare

[ Source](https://github.com/azaharizaman/nexus-product)[ Packagist](https://packagist.org/packages/azaharizaman/nexus-product)[ RSS](/packages/azaharizaman-nexus-product/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (3)Versions (2)Used By (1)

Nexus\\Product
==============

[](#nexusproduct)

**Framework-agnostic product catalog management package for the Nexus ERP monorepo.**

Overview
--------

[](#overview)

`Nexus\Product` provides a comprehensive master data management system for product catalogs, supporting both simple standalone products and complex configurable products with template-variant architecture. It integrates seamlessly with `Nexus\Uom` for dimensional data, `Nexus\Sequencing` for SKU generation, and serves as the foundation for downstream domains like Procurement, Sales, and Inventory.

Core Philosophy
---------------

[](#core-philosophy)

This package defines **WHAT** a product is (master data), not **WHERE** it's stored or **HOW MUCH** stock exists. Transactional data like inventory levels, pricing, and availability belong in domain-specific packages (`Nexus\Inventory`, `Nexus\Sales`).

Features
--------

[](#features)

### Template-Variant Architecture

[](#template-variant-architecture)

- **Product Templates**: Conceptual products with shared attributes (e.g., "T-Shirt Model X")
- **Product Variants**: Transactable SKUs with unique identifiers (e.g., "T-Shirt Model X, Red, Size M")
- **Standalone Products**: Simple products that don't require template structure

### Master Data Management

[](#master-data-management)

- **Hierarchical Categories**: Unlimited nesting with adjacency list pattern
- **Attribute Sets**: Configurable attributes (Color, Size, Material) with value management
- **SKU Generation**: Integration with `Nexus\Sequencing` for unique identifier assignment
- **Barcode Handling**: Multi-format support (EAN-13, UPC-A, CODE-128, QR) with validation

### Physical Dimensions

[](#physical-dimensions)

- **Unit-Aware Measurements**: Integration with `Nexus\Uom\Quantity` for weight, volume, dimensions
- **Dimension Sets**: Complete physical specifications (length, width, height, weight)

### Product Classification

[](#product-classification)

- **Product Types**: STORABLE (inventory-tracked), CONSUMABLE (buy/use), SERVICE (intangible)
- **Tracking Methods**: NONE, LOT\_NUMBER (batch tracking), SERIAL\_NUMBER (unique instances)

### Enterprise Features

[](#enterprise-features)

- **Variant Explosion Prevention**: Configurable limits on variant combinations
- **Duplicate Detection**: SKU and barcode uniqueness enforcement
- **Category Circular Reference Protection**: Validation for organizational hierarchies
- **Multi-Tenant Support**: Tenant scoping for SaaS deployments

Installation
------------

[](#installation)

This package is part of the Nexus monorepo. Install it in your Laravel application:

```
composer require azaharizaman/nexus-product:"*@dev"
```

Architecture
------------

[](#architecture)

### Package Structure

[](#package-structure)

```
packages/Product/
├── composer.json
├── LICENSE
├── README.md
└── src/
    ├── Contracts/              # All interface definitions
    │   ├── CategoryInterface.php
    │   ├── CategoryRepositoryInterface.php
    │   ├── ProductTemplateInterface.php
    │   ├── ProductTemplateRepositoryInterface.php
    │   ├── ProductVariantInterface.php
    │   ├── ProductVariantRepositoryInterface.php
    │   ├── AttributeSetInterface.php
    │   └── AttributeRepositoryInterface.php
    ├── Enums/                  # PHP 8.3 native enums
    │   ├── ProductType.php
    │   ├── TrackingMethod.php
    │   └── BarcodeFormat.php
    ├── ValueObjects/           # Immutable value objects
    │   ├── Sku.php
    │   ├── Barcode.php
    │   └── DimensionSet.php
    ├── Services/               # Business logic
    │   ├── ProductManager.php
    │   ├── VariantGenerator.php
    │   ├── SkuGenerator.php
    │   └── BarcodeService.php
    └── Exceptions/             # Domain-specific exceptions
        ├── ProductException.php
        ├── ProductNotFoundException.php
        ├── DuplicateSkuException.php
        ├── VariantExplosionException.php
        ├── InvalidBarcodeException.php
        └── CircularCategoryReferenceException.php

```

### Framework Agnostic Design

[](#framework-agnostic-design)

This package contains **ZERO** Laravel-specific code. All dependencies are injected via constructor:

- ✅ Pure PHP 8.3 with strict types
- ✅ PSR-3 `LoggerInterface` for logging
- ✅ Constructor property promotion with `readonly`
- ✅ Native enums with `match` expressions
- ❌ NO Laravel Facades (`Log::`, `Cache::`, `DB::`)
- ❌ NO global helpers (`now()`, `config()`, `app()`)
- ❌ NO Eloquent models or migrations

Usage Examples
--------------

[](#usage-examples)

### Creating a Simple Product (Standalone Variant)

[](#creating-a-simple-product-standalone-variant)

```
use Nexus\Product\Services\ProductManager;
use Nexus\Product\Enums\ProductType;
use Nexus\Product\Enums\TrackingMethod;
use Nexus\Product\ValueObjects\Sku;
use Nexus\Uom\ValueObjects\Quantity;

$productManager->createStandaloneVariant(
    tenantId: 'tenant-123',
    code: 'WIDGET-001',
    name: 'Premium Widget',
    type: ProductType::STORABLE,
    trackingMethod: TrackingMethod::SERIAL_NUMBER,
    weight: new Quantity(2.5, 'kg'),
    categoryCode: 'HARDWARE'
);
```

### Creating a Configurable Product (Template + Variants)

[](#creating-a-configurable-product-template--variants)

```
// 1. Create template
$template = $productManager->createTemplate(
    tenantId: 'tenant-123',
    code: 'TSHIRT-X',
    name: 'T-Shirt Model X',
    description: 'Premium cotton t-shirt',
    categoryCode: 'APPAREL'
);

// 2. Define attributes
$colorAttribute = $attributeRepository->findByCode('COLOR');
$sizeAttribute = $attributeRepository->findByCode('SIZE');

// 3. Generate variants
$variants = $variantGenerator->generateVariants(
    templateId: $template->getId(),
    attributes: [
        'COLOR' => ['Red', 'Blue', 'Green'],
        'SIZE' => ['S', 'M', 'L', 'XL']
    ]
);
// Creates 12 variants (3 colors × 4 sizes)
```

### Working with Barcodes

[](#working-with-barcodes)

```
use Nexus\Product\ValueObjects\Barcode;
use Nexus\Product\Enums\BarcodeFormat;

// EAN-13 validation
$barcode = new Barcode('5901234123457', BarcodeFormat::EAN13);

// Barcode service
$barcodeService->validate($barcode); // true if valid checksum
$barcodeService->lookupVariant($barcode); // Find product by barcode
```

### Preventing Variant Explosion

[](#preventing-variant-explosion)

```
// Configuration via Nexus\Setting
$settings->setInt('product.max_variants_per_template', 1000);

// This will throw VariantExplosionException if > 1000 combinations
$variantGenerator->generateVariants($templateId, [
    'COLOR' => [...], // 10 values
    'SIZE' => [...],  // 10 values
    'STYLE' => [...], // 10 values
    'FABRIC' => [...] // 10 values = 10,000 variants!
]);
```

Integration Points
------------------

[](#integration-points)

### Nexus\\Uom (Unit of Measure)

[](#nexusuom-unit-of-measure)

All physical dimensions use `Nexus\Uom\Quantity`:

```
use Nexus\Product\ValueObjects\DimensionSet;
use Nexus\Uom\ValueObjects\Quantity;

$dimensions = new DimensionSet(
    weight: new Quantity(5.5, 'kg'),
    length: new Quantity(30, 'cm'),
    width: new Quantity(20, 'cm'),
    height: new Quantity(10, 'cm'),
    volume: new Quantity(6, 'L')
);
```

### Nexus\\Sequencing (SKU Generation)

[](#nexussequencing-sku-generation)

SKU generation integrates with the sequencing engine:

```
use Nexus\Product\Services\SkuGenerator;
use Nexus\Sequencing\Contracts\SequenceGeneratorInterface;

$skuGenerator = new SkuGenerator($sequenceGenerator);
$sku = $skuGenerator->generateSku('tenant-123', 'PRODUCT');
// Result: "PRD-2024-00001"
```

### Nexus\\Finance (Default GL Accounts)

[](#nexusfinance-default-gl-accounts)

Products can reference default GL account codes (resolved at application layer):

```
interface ProductVariantInterface {
    public function getDefaultRevenueAccountCode(): ?string;
    public function getDefaultCostAccountCode(): ?string;
    public function getDefaultInventoryAccountCode(): ?string;
}
```

### Nexus\\Procurement (Purchase Orders)

[](#nexusprocurement-purchase-orders)

Update `PurchaseOrderLineInterface` to reference products:

```
interface PurchaseOrderLineInterface {
    public function getProductVariantId(): ?string;
    public function getItemDescription(): string; // Fallback for legacy
}
```

Value Objects
-------------

[](#value-objects)

### Sku

[](#sku)

Immutable, validated SKU identifier:

```
use Nexus\Product\ValueObjects\Sku;

$sku = new Sku('PRD-2024-00001');
$sku->getValue(); // "PRD-2024-00001"
$sku->toArray(); // ['value' => 'PRD-2024-00001']
```

### Barcode

[](#barcode)

Format-aware barcode with validation:

```
use Nexus\Product\ValueObjects\Barcode;
use Nexus\Product\Enums\BarcodeFormat;

$barcode = new Barcode('5901234123457', BarcodeFormat::EAN13);
$barcode->getValue(); // "5901234123457"
$barcode->getFormat(); // BarcodeFormat::EAN13
```

### DimensionSet

[](#dimensionset)

Complete physical specifications:

```
use Nexus\Product\ValueObjects\DimensionSet;
use Nexus\Uom\ValueObjects\Quantity;

$dimensions = new DimensionSet(
    weight: new Quantity(2.5, 'kg'),
    length: new Quantity(30, 'cm'),
    width: new Quantity(20, 'cm'),
    height: new Quantity(15, 'cm')
);

$dimensions->toArray();
// [
//     'weight' => ['value' => 2.5, 'unit' => 'kg'],
//     'length' => ['value' => 30, 'unit' => 'cm'],
//     ...
// ]
```

Enums
-----

[](#enums)

### ProductType

[](#producttype)

```
enum ProductType: string {
    case STORABLE = 'storable';     // Physical goods with inventory tracking
    case CONSUMABLE = 'consumable'; // Items consumed without stock tracking
    case SERVICE = 'service';       // Intangible services
}
```

### TrackingMethod

[](#trackingmethod)

```
enum TrackingMethod: string {
    case NONE = 'none';                   // No tracking
    case LOT_NUMBER = 'lot_number';       // Batch/lot tracking
    case SERIAL_NUMBER = 'serial_number'; // Unique instance tracking
}
```

### BarcodeFormat

[](#barcodeformat)

```
enum BarcodeFormat: string {
    case EAN13 = 'ean13';       // European Article Number (13 digits)
    case UPCA = 'upca';         // Universal Product Code (12 digits)
    case CODE128 = 'code128';   // High-density alphanumeric
    case QR = 'qr';             // QR Code (2D)
    case CUSTOM = 'custom';     // Custom format
}
```

Exception Hierarchy
-------------------

[](#exception-hierarchy)

```
Exception
└── ProductException
    ├── ProductNotFoundException
    ├── ProductTemplateNotFoundException
    ├── CategoryNotFoundException
    ├── DuplicateSkuException
    ├── DuplicateBarcodeException
    ├── VariantExplosionException
    ├── InvalidBarcodeException
    ├── CircularCategoryReferenceException
    └── InvalidProductDataException

```

Configuration
-------------

[](#configuration)

Product-related settings (managed via `Nexus\Setting`):

Setting KeyDefaultDescription`product.max_variants_per_template`1000Maximum variants allowed per template`product.default_category``GENERAL`Default category for uncategorized products`product.require_barcode``false`Whether barcodes are mandatory`product.auto_generate_sku``true`Auto-generate SKUs via sequencingContributing
------------

[](#contributing)

This package follows the Nexus monorepo architectural principles:

1. **Framework Agnostic**: Zero Laravel dependencies
2. **Contract-Driven**: All external needs defined via interfaces
3. **Immutable Value Objects**: All VOs use `readonly` modifier
4. **Modern PHP**: Constructor promotion, native enums, `match` expressions
5. **Dependency Injection**: All dependencies via constructor

📖 Documentation
---------------

[](#-documentation)

### Package Documentation

[](#package-documentation)

- [Getting Started Guide](docs/getting-started.md)
- [API Reference](docs/api-reference.md)
- [Integration Guide](docs/integration-guide.md)
- [Examples](docs/examples/)

### Additional Resources

[](#additional-resources)

- `IMPLEMENTATION_SUMMARY.md` - Implementation progress
- `REQUIREMENTS.md` - Requirements
- `TEST_SUITE_SUMMARY.md` - Tests
- `VALUATION_MATRIX.md` - Valuation

License
-------

[](#license)

MIT License - see LICENSE file for details.

Related Packages
----------------

[](#related-packages)

- `Nexus\Uom` - Unit of measure management
- `Nexus\Sequencing` - Auto-numbering and sequence generation
- `Nexus\Procurement` - Purchase order management
- `Nexus\Inventory` - Stock and warehouse management
- `Nexus\Finance` - Financial accounting
- `Nexus\Setting` - Configuration management
- `Nexus\Tenant` - Multi-tenancy support

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance93

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity34

Early-stage or recently created project

 Bus Factor1

Top contributor holds 76.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

36d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/117408?v=4)[Azahari Zaman](/maintainers/azaharizaman)[@azaharizaman](https://github.com/azaharizaman)

---

Top Contributors

[![azaharizaman](https://avatars.githubusercontent.com/u/117408?v=4)](https://github.com/azaharizaman "azaharizaman (461 commits)")[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (139 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (2 commits)")

### Embed Badge

![Health badge](/badges/azaharizaman-nexus-product/health.svg)

```
[![Health](https://phpackages.com/badges/azaharizaman-nexus-product/health.svg)](https://phpackages.com/packages/azaharizaman-nexus-product)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.7k532.1M19.2k](/packages/laravel-framework)[symfony/symfony

The Symfony PHP framework

31.4k86.9M2.2k](/packages/symfony-symfony)[cakephp/cakephp

The CakePHP framework

8.8k19.1M1.7k](/packages/cakephp-cakephp)[matomo/matomo

Matomo is the leading Free/Libre open analytics platform

21.6k38.2k](/packages/matomo-matomo)[tempest/framework

The PHP framework that gets out of your way.

2.2k31.1k11](/packages/tempest-framework)[drupal/core

Drupal is an open source content management platform powering millions of websites and applications.

21764.8M1.6k](/packages/drupal-core)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
