PHPackages                             azaharizaman/nexus-party - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. azaharizaman/nexus-party

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

azaharizaman/nexus-party
========================

Party master data package - Universal entity abstraction for individuals and organizations

v0.1.0-alpha1(2mo ago)024MITPHPPHP ^8.3

Since May 5Pushed 2mo agoCompare

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

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

Nexus\\Party
============

[](#nexusparty)

**Master Data Management for Entities**

A framework-agnostic PHP package implementing the **Party Pattern** to provide a unified abstraction for individuals and organizations across the Nexus ERP monorepo.

Purpose
-------

[](#purpose)

The Party package solves the "God Object" anti-pattern by separating the universal concept of **WHO** (name, contact info, legal identity) from **WHAT ROLE** they play in your business (customer, vendor, employee).

### The Problem

[](#the-problem)

Without Party abstraction:

- Vendor table has: `name`, `email`, `phone`, `tax_id`
- Employee table has: `first_name`, `last_name`, `email`, `phone`
- Customer table has: `name`, `email`, `phone`, `address`

**Result:** Duplicated data, synchronization nightmares, and no way to track when the same person/organization plays multiple roles.

### The Solution

[](#the-solution)

With Party abstraction:

- **Party table:** Single source of truth for identity and contact information
- **Vendor table:** Links to Party + adds vendor-specific data (payment terms, tolerances)
- **Employee table:** Links to Party + adds employment data (salary, job title)
- **Customer table:** Links to Party + adds customer data (credit limit, price list)

**Result:** Zero duplication, single canonical source, complete relationship history.

---

Core Concepts
-------------

[](#core-concepts)

### Party Types

[](#party-types)

1. **INDIVIDUAL** - A natural person (employee, customer contact, vendor representative)
2. **ORGANIZATION** - A legal entity (company, vendor, customer organization)

### Party Relationships

[](#party-relationships)

Track connections between parties with effective dates:

- `EMPLOYMENT_AT` - Individual works at Organization
- `CONTACT_FOR` - Individual is a contact person for Organization
- `SUBSIDIARY_OF` - Organization is owned by parent Organization

### Key Features

[](#key-features)

✅ **Individual Mobility** - When a person changes companies, their transaction history follows them
✅ **Circular Reference Prevention** - Automatic validation for organization hierarchies
✅ **Multi-Contact Support** - Organizations can have multiple contact persons with roles
✅ **Address Versioning** - Track address changes with effective dates
✅ **Tax Identity Management** - Store multiple tax IDs per party (VAT, GST, EIN, etc.)

---

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

[](#architecture)

```
packages/Party/
├── src/
│   ├── Contracts/          # Interfaces
│   │   ├── PartyInterface.php
│   │   ├── PartyRepositoryInterface.php
│   │   ├── AddressInterface.php
│   │   ├── ContactMethodInterface.php
│   │   └── PartyRelationshipInterface.php
│   ├── Services/           # Business logic
│   │   ├── PartyManager.php
│   │   └── PartyRelationshipManager.php
│   ├── ValueObjects/       # Immutable data structures
│   │   ├── TaxIdentity.php
│   │   └── PostalAddress.php
│   ├── Enums/              # Type definitions
│   │   ├── PartyType.php
│   │   ├── AddressType.php
│   │   ├── ContactMethodType.php
│   │   └── RelationshipType.php
│   └── Exceptions/         # Domain exceptions
│       ├── PartyNotFoundException.php
│       ├── DuplicatePartyException.php
│       └── CircularRelationshipException.php

```

---

Usage Example
-------------

[](#usage-example)

### Creating an Organization (Vendor)

[](#creating-an-organization-vendor)

```
use Nexus\Party\Services\PartyManager;
use Nexus\Party\Enums\PartyType;

// Create the party first
$party = $partyManager->createOrganization(
    tenantId: 'tenant-123',
    legalName: 'Acme Corporation',
    tradingName: 'Acme',
    taxIdentity: new TaxIdentity(
        country: 'MYS',
        number: '201901012345',
        issueDate: new \DateTimeImmutable('2019-01-01')
    )
);

// Add address
$partyManager->addAddress(
    partyId: $party->getId(),
    type: AddressType::LEGAL,
    address: new PostalAddress(
        streetLine1: '123 Main Street',
        city: 'Kuala Lumpur',
        postalCode: '50000',
        country: 'MYS'
    ),
    isPrimary: true
);

// Add contact method
$partyManager->addContactMethod(
    partyId: $party->getId(),
    type: ContactMethodType::EMAIL,
    value: 'info@acme.com',
    isPrimary: true
);

// Now create the vendor using the party_id
$vendor = $vendorManager->createVendor(
    tenantId: 'tenant-123',
    partyId: $party->getId(),
    code: 'VEN-001',
    paymentTerms: 'net_30'
);
```

### Creating an Individual (Employee)

[](#creating-an-individual-employee)

```
// Create individual party
$party = $partyManager->createIndividual(
    tenantId: 'tenant-123',
    fullName: 'Jane Smith',
    dateOfBirth: new \DateTimeImmutable('1990-05-15')
);

// Create employee linking to party
$employee = $employeeManager->createEmployee(
    tenantId: 'tenant-123',
    partyId: $party->getId(),
    employeeCode: 'EMP-001',
    hireDate: new \DateTimeImmutable('2024-01-15')
);

// Create employment relationship
$partyRelationshipManager->createRelationship(
    tenantId: 'tenant-123',
    fromPartyId: $party->getId(), // Individual
    toPartyId: $companyPartyId,   // Organization
    type: RelationshipType::EMPLOYMENT_AT,
    effectiveFrom: new \DateTimeImmutable('2024-01-15')
);
```

### Tracking Individual Mobility

[](#tracking-individual-mobility)

```
// Jane moves to a new company
$partyRelationshipManager->endRelationship(
    relationshipId: $oldRelationship->getId(),
    effectiveTo: new \DateTimeImmutable('2025-06-30')
);

$partyRelationshipManager->createRelationship(
    tenantId: 'tenant-123',
    fromPartyId: $janePartyId,
    toPartyId: $newCompanyPartyId,
    type: RelationshipType::EMPLOYMENT_AT,
    effectiveFrom: new \DateTimeImmutable('2025-07-01')
);

// All historical transactions reference $janePartyId
// Her purchasing patterns are preserved across companies
```

---

Integration with Domain Packages
--------------------------------

[](#integration-with-domain-packages)

### Nexus\\Payable (Vendor)

[](#nexuspayable-vendor)

**Before:**

```
interface VendorInterface {
    public function getName(): string;
    public function getEmail(): ?string;
    public function getTaxId(): ?string;
}
```

**After:**

```
interface VendorInterface {
    public function getPartyId(): string;
    public function getPaymentTerms(): string;
    // ... vendor-specific methods only
}

// To get name/email/tax:
$vendor->getParty()->getLegalName();
$vendor->getParty()->getPrimaryEmail();
$vendor->getParty()->getTaxIdentity()->getNumber();
```

### Nexus\\Hrm (Employee)

[](#nexushrm-employee)

**Before:**

```
interface EmployeeInterface {
    public function getFirstName(): string;
    public function getLastName(): string;
    public function getEmail(): string;
}
```

**After:**

```
interface EmployeeInterface {
    public function getPartyId(): string;
    public function getHireDate(): \DateTimeInterface;
    // ... employment-specific methods only
}

// To get name/email:
$employee->getParty()->getLegalName();
$employee->getParty()->getPrimaryEmail();
```

---

Requirements
------------

[](#requirements)

- PHP 8.3 or higher
- No framework dependencies (pure PHP)

---

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

[](#-documentation)

### Package Documentation

[](#package-documentation)

- **[Getting Started Guide](docs/getting-started.md)** - Quick start guide with prerequisites, concepts, and first integration
- **[API Reference](docs/api-reference.md)** - Complete documentation of all interfaces, value objects, enums, and exceptions
- **[Integration Guide](docs/integration-guide.md)** - Laravel and Symfony integration examples
- **[Basic Usage Example](docs/examples/basic-usage.php)** - Simple usage patterns
- **[Advanced Usage Example](docs/examples/advanced-usage.php)** - Advanced scenarios including relationships and duplicate detection

### Additional Resources

[](#additional-resources)

- `IMPLEMENTATION_SUMMARY.md` - Implementation progress, metrics, and key design decisions
- `REQUIREMENTS.md` - Detailed requirements with traceability (52 requirements, 100% complete)
- `TEST_SUITE_SUMMARY.md` - Test coverage and results (tests planned, not yet implemented)
- `VALUATION_MATRIX.md` - Package valuation metrics ($30,000 estimated value)
- See root `ARCHITECTURE.md` for overall system architecture
- See root `docs/NEXUS_PACKAGES_REFERENCE.md` for package integration patterns

---

License
-------

[](#license)

MIT License - See LICENSE file for details

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance84

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 76.7% 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

81d 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 (463 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)")

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[symfony/lock

Creates and manages locks, a mechanism to provide exclusive access to a shared resource

515139.2M711](/packages/symfony-lock)[matomo/matomo

Matomo is the leading Free/Libre open analytics platform

21.7k38.9k](/packages/matomo-matomo)[ecotone/ecotone

Enterprise architecture layer for Laravel and Symfony — CQRS, Event Sourcing, Durable Workflows (Sagas, Orchestrators), Projections, and Outbox messaging via PHP attributes.

564576.7k54](/packages/ecotone-ecotone)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

751291.4k46](/packages/civicrm-civicrm-core)[illuminate/broadcasting

The Illuminate Broadcasting package.

7127.2M221](/packages/illuminate-broadcasting)[logiscape/mcp-sdk-php

Model Context Protocol SDK for PHP

367116.8k12](/packages/logiscape-mcp-sdk-php)

PHPackages © 2026

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