# ADR-121 Dispatch-Target Consolidation into the Counter/Store Master via Tiered Matching

## Status

Proposed, 2026-07-27.

## Status History

```yaml
status_history:
  - date: 2026-07-27
    status: Proposed
    changed_by: hkl
    reason: Initial proposal — store consolidation for DispatchWithAutomation.
    changed_via: adr-kit (360lm) — authored from DL CLI via SSH
```

## Context

Every dispatch targets a dealer store. The owner wants uploaded targets **consolidated into a
persistent store master** (enrich if the store already exists, add if new, so future campaigns
reuse it) rather than re-typed per campaign. Real dealer data is messy: names like
"TANISHA S E-WORLD", partial addresses, and Indian PINs that cover whole towns where many dealers
cluster. Fable's review (DL 2026-07-27) flagged the decisive risk: a **false-merge** (treating two
distinct dealers as one) silently ships one dealer's material to another and pollutes that store's
historical analytics forever — strictly worse than a duplicate. The owner chose the tiered approach
**with explicit user approval on merges**.

## Decision

On intake, consolidate each target into a `dispatch.stores` master via **tiered matching, with human
approval before any link is committed**:
- **Tier 1 (exact):** normalized name + PIN (or exact 10-digit phone). Proposed as a high-confidence
  match but **still surfaced for user approval** before linking/enriching (per owner: "option 1 and
  user approval"). Enrich blank fields only; never silently overwrite (conflicts → review note).
- **Tier 2 (fuzzy suggest):** same PIN + `pg_trgm` name trigram (~0.45–0.55), or same phone +
  different PIN → one-click confirm/reject worklist.
- **Tier 3 (no match):** hold for review with a default-accept "insert as new" one-click.
- On every **confirmed** match, write a `dispatch.store_aliases(alias_normalized, store_id)` row so
  the next upload of that spelling is a Tier-1 exact hit.
- Log which upload + rule + approver created every link (traceable, reversible).

**Decision Maker:** hkl

## Implementation Notes

- **Tables:** `dispatch.stores` (normalized name/address/city/state/PIN/phone(s)/geo), `dispatch.store_aliases`. Normalization: uppercase, strip punctuation/`&`/`-`, drop noise tokens (M/S, THE), collapse whitespace; phone → last 10 digits.
- **Matching:** `pg_trgm` extension for Tier-2 similarity (in-DB). Approval worklist is a PostgREST + vanilla-JS screen (ADR-013).
- **Counters integration:** where a shared org-wide store/counter master is appropriate, read it cross-schema via the ADR-010/106 grant-gated pattern (final decision on shared-vs-module-local master tracked in MDD §19.6 — module-local `dispatch.stores` for v1, alias-linkable to counters later).
- **Find sites:** `grep -rn "store_aliases\|match_store" /var/www/360lm/dispatch /opt/shiprocket-proxy`

## Alternatives Considered

- **Auto-merge on fuzzy similarity without human confirm.** Rejected: false-merge risk (mis-ship + poisoned analytics), Fable-flagged as decisively worse than duplication.
- **Phone as the sole primary key.** Rejected: phones are often shared/missing/reused across dealer outlets; good as a Tier-1 *signal*, not the only key.
- **No master; per-campaign store lists.** Rejected: loses cross-campaign reuse and the whole point of consolidation.

## Consequences

**Positive:**
- Growing reusable store master; enrichment over time; alias-learning makes re-uploads clean; human approval prevents mis-ships.

**Negative / Trade-offs:**
- Adds an approval step to intake (even Tier-1) — deliberate friction the owner accepted for safety.

**Risks and mitigations:**
- *False-merge* → bias every threshold to "ask the human"; approval required on all links; every link logged + reversible.
- *Duplicate proliferation if reviewers rubber-stamp "new"* → alias-learning + Tier-2 suggestions reduce repeat prompts.

## Related Decisions

- ADR-053/054 (counter/store master + sync patterns), ADR-010/106 (cross-schema access), ADR-009 (own schema), ADR-117 (proxy does AI field-mapping pre-match).

## References

- `/var/www/360lm/docs/MDD_dispatch_automation.md` §7, §19.6.
- Fable review (tiered matching, false-merge risk), DL 2026-07-27.
