# ADR-043: sales.catalog Is the Shared Product Master — Vendor Management Links to It

## Status

Accepted, 2026-06-22.

## Status History

```yaml
status_history:
  - date: 2026-06-22
    status: Proposed
    changed_by: hkl
    reason: Formalising cross-schema product reuse between Vendors and Sales PWA
    changed_via: adr-kit (360lm)
  - date: 2026-06-22
    status: Accepted
    changed_by: hkl
    reason: Vendor catalog links to sales.catalog (285-row product master); inline add writes there
    changed_via: adr-kit (360lm)
```

## Context

Vendor Management needs to record which products each vendor supplies. Sales PWA already has a complete 285-row product catalog (`sales.catalog`). Building a separate `vendors.products` table would duplicate this catalog. Any product added in Vendors would be invisible in Sales quotes, and vice versa. The product identity problem mirrors the employee identity problem (ADR-032) and the payee identity problem (ADR-036): the first complete, stable implementation becomes the canonical source.

## Decision

`sales.catalog` is the platform-wide product master. Vendor Management's catalog tab records vendor–product links by referencing `sales.catalog` rows. When a new product does not yet exist in `sales.catalog`, the Vendor Management inline quick-add form writes the new product directly to `sales.catalog` — not to a local vendors table.

This is the product-domain analog to ADR-032 (expense.employees) and ADR-036 (custodian.payees): `sales.catalog` is the shared product identity anchor.

**Decision Maker:** hkl

## Alternatives Considered

- **Separate `vendors.products` table with sync to sales.catalog.** Rejected: sync creates lag and divergence; a product added as "Cement Bag 50kg" in Vendors and "Cement Bag" in Sales are silently different products in the database.
- **New shared `catalog` schema (not sales).** Rejected: sales.catalog was already complete and stable (285 rows); migrating to a new schema adds migration overhead with no functional benefit; the platform is managed by one team, schema ownership is not the bottleneck.
- **Vendor Management maintains its own product list with no link to Sales.** Rejected: Sales team uses vendor-supplied products in quotes; if vendor products are separate from sales catalog, Sales cannot verify whether a quoted product has a known vendor.

## Consequences

**Positive:**
- Products added via Vendor Management are immediately available in Sales quotes.
- Single 285-row product master maintained without duplication.
- Vendor–product pricing links to the same product ID that Sales invoices reference.

**Negative / Trade-offs:**
- Vendor Management depends on the `sales` schema — cannot be isolated or run without Sales.
- `web_anon` must have READ on `sales.catalog` and INSERT for quick-add (or via RPC) for Vendor Management to work.
- If Sales team restructures `sales.catalog` (e.g. adds a required field), Vendor Management quick-add form must be updated.

**Risks and mitigations:**
- Developer creates `vendors.products` for a new vendor-specific field: mitigated by this ADR; add the field to `sales.catalog` instead (nullable columns for vendor-specific metadata are fine).

## Related Decisions

- ADR-032 (expense.employees cross-schema FK anchor) — same pattern for employee identity.
- ADR-036 (custodian.payees shared payee master) — same pattern for payee identity.
- ADR-038 (capture-to-catalog trigger) — the auto-enriched vendor_catalog references sales.catalog product IDs.
- ADR-009 (per-PWA schema isolation) — documented exception.

## References

- `memory/dbt_vendors.md` — "Catalog management (Phase 3a) — links vendor to entries in sales.catalog (reuses existing 285-row product master); inline quick-add writes new rows directly to sales.catalog"
- `finance/vendors/index.html` — vendor catalog tab, product quick-add form
- `sales/index.html` — sales.catalog product master
