Skip to content

Attribute documents to a Customer via the buyer identifier, derive the company #24

Description

@jbagsik

Parent

#21

What to build

An e-billing document is attributed to the Customer it was billed under, resolved from the buyer
identifier on the invoice. The company attribution remains, but is now derived from the customer
rather than guessed from a name — and is documented as reporting only, never an access boundary.

This is the identity change. A company can hold several customer records (one per plant, price list
or settlement purpose); attributing to the company collapses them, and a company attribution frozen
at match time goes stale the moment a customer is reassigned. Consumers are told to gate visibility
on the customer attribution, which callers resolve live.

Corroboration — checking that the name, VAT identifier, country and address agree with the matched
record — is deliberately not in this ticket. Here the identifier decides alone.

Acceptance criteria

  • The document carries a nullable, indexed customer attribution; the company attribution remains
    and is populated by derivation from the matched customer.
  • A document whose identifier resolves to exactly one customer is attributed to it.
  • Identifier comparison normalises by trim, whitespace collapse and uppercase only — no numeric
    interpretation, no stripping or padding of leading zeros. 0815 and 815 resolve to different
    customers.
  • Lookups include soft-deleted customers, so a deleted customer resolves and is reported as
    found but deleted rather than not found. Same for an inactive customer.
  • A customer resolving to more than one company yields a null company attribution — never a
    silently chosen first row.
  • A customer with no company yields a null company attribution and still keeps the customer
    attribution.
  • With no identifier present, the name fallback from the unified resolver still runs and sets the
    company attribution — and never the customer attribution.
  • The package depends on moox/customer. No resolver interface is introduced.
  • Covered through the field validator's public validate entry point — the matcher gets no seam of
    its own. This adds the first test for that entry point.

Blocked by

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentSpec is ready for an agent to implement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions