# README

## Overview

The Business Partner module separates globally shared counterparty identity from company-scoped transaction accounts.

- `BusinessPartner` is the global identity for an organization or individual.
- `CustomerAccount` is the sales and accounts-receivable transaction unit for one Company.
- `SupplierAccount` is the purchasing and accounts-payable transaction unit for one Company.
- `PartnerAddress` and `PartnerBankAccount` are reusable child entities owned by the `BusinessPartner` aggregate. They remain separate database tables for querying and relational integrity, but are changed through the aggregate and deactivated rather than deleted.
- Account usage records assign an address or bank account to a purpose and hold the default flag.

A single BusinessPartner can therefore have multiple customer and supplier accounts without duplicating its legal identity. Downstream documents reference the relevant Account, while identity checks continue through the Account's `partnerId`.

The main stateful concepts are implemented as aggregates under `domain/` and persisted through repositories under `repository/`:

- `BusinessPartner` owns identity details, an `ACTIVE`/`INACTIVE` lifecycle, addresses, and bank details.
- `CustomerAccount` owns customer-facing account state and customer usage collections.
- `SupplierAccount` owns supplier-facing account state and supplier usage collections.
- Commands load or create aggregates, apply domain behavior, and persist through repositories.
- BusinessPartner, PartnerAddress, and PartnerBankAccount deny physical deletion at the database permission layer.
- Queries remain read-oriented projections and do not expose repository behavior.
- Account queries expose stable projections with company, separate account and partner names, preferred currency, and separate account and partner lifecycle states; they also return unavailable accounts for historical lookups.

This keeps lifecycle rules, usage invariants, persistence mapping, and command orchestration in separate layers.

Downstream consumers follow the existing module dependency convention: derive query types from `BusinessPartnerModule["queries"]` and select the required query with `Pick`. The provider exposes `getCustomerAccount({ customerAccountId })` and `getSupplierAccount({ supplierAccountId })`, each returning account data under the `account` key, or null when not found. Each query selects and maps its own public fields directly.

`accountName` is the required, nonblank account-specific name; `partnerName` is the global BusinessPartner name. Transaction screens use the account name without falling back to the BP name.

`accountStatus` and `partnerStatus` expose the respective lifecycle states without deciding transaction eligibility. Each consumer checks its document company against `account.companyId` and owns its operation-specific eligibility rules. Business documents check Account status, not the global Partner status. An active Account remains usable when its Partner is inactive; the query still exposes both states as facts. Historical lookup remains possible after deactivation. Independent sales, billing, receipt, purchase, or payment holds are not modeled yet and must not be conflated with these lifecycle states. Address/bank Usage data is intentionally not loaded by these lookups.

Transaction modules use the two account lookups. The `listBusinessPartners` query provides the BP directory with name search, customer/supplier relationship filters, and pagination. Address, bank-account, and partner-scoped account lists use the autogenerated API. Commands use aggregate repositories internally. Account IDs are never interchangeable with partner IDs.

## Key Features

- **[Partner Availability](docs/feature/partner-lifecycle.md)**: Global BusinessPartner identity with an `ACTIVE`/`INACTIVE` lifecycle.
- **Customer Accounts**: Company-scoped customer transaction units created active, with independent deactivation and reactivation, preferred currency, address usage, and bank usage.
- **Supplier Accounts**: Company-scoped supplier transaction units with the same availability rules and configuration.
- **[Partner Address Management](docs/feature/partner-address-management.md)**: Reusable identity-level addresses, assigned to account purposes through usage records.
- **[Partner Bank Account](docs/feature/partner-bank-account.md)**: Reusable identity-level bank details, assigned to payment or collection purposes through usage records.

## Module Scope

### In Scope

- Global BusinessPartner identity and availability
- Company-scoped CustomerAccount and SupplierAccount lifecycles
- Multiple transaction accounts for the same partner and company
- Reusable partner addresses and bank accounts
- Purpose-specific and default address/bank usage per Account

### Out of Scope

- Sales pipeline and lead qualification
- Supplier qualification and performance scoring
- Supplier catalog and item sourcing rules
- Payment term and price rule definitions
- KYC and sanctions-screening workflows
- Duplicate detection and automated partner merge
- Partner-to-partner relationship definitions and lifecycle (future design)

### Scope Decision Rationale

Global identity changes less frequently than company-specific commercial settings. Keeping BusinessPartner global prevents duplicate legal-party records, while CustomerAccount and SupplierAccount provide the operational boundary needed for company, currency, address-purpose, bank-purpose, and other transaction rules. Reusable address and bank masters remain with the identity so each Account can bind them to its own purposes without copying data.

## Module Dependencies

- [organization](../organization/README.md) — Company references for CustomerAccount and SupplierAccount
- [primitives](../primitives/README.md) — Currency references for Accounts and partner bank details
