fix(orders): the restaurant is the merchant, not the courier
ci / lint-test (push) Successful in 43s

Reverses a change made on request. The platform in the headline
fragmented the merchant: the same restaurant read as two, depending on
who carried the bag, and that is not a distinction anyone rating the food
cares about. It also already has a home — the expandable Order details
panel renders expense_metadata.platform next to its heading, which is
where the user asked for it.

The fragmentation was worse than cosmetic. merchantVerdict joined on an
exact merchant_normalized, and the platforms capitalise differently
("TEG Kebabs & Biryani" on Uber Eats, "TEG KEBABS & BIRYANI" on
DoorDash), so one restaurant kept two separate histories and a "never
again" recorded through one app never warned in the other — silently
defeating the point of the memory. Now case-folded; verified on real
data, where the DoorDash order sees 1 prior verdict against 0 before.

81 existing descriptions backfilled in one transaction, dry-run first and
dumped beforehand. The regex is anchored to the end so suburb parens
survive: "Order - Coles (Wyndham Vale) (Uber Eats)" becomes
"Order - Coles (Wyndham Vale)", not "Order - Coles".
This commit is contained in:
2026-07-28 17:51:36 +10:00
parent 50c5b7c430
commit 0595d49d5c
5 changed files with 53 additions and 20 deletions
@@ -154,6 +154,19 @@ describe("merchant history", () => {
expect(body.merchant.history.map((h: any) => h.transaction_id)).toEqual([older]);
});
it("treats the same restaurant as one merchant across platforms", async () => {
// DoorDash and Uber Eats capitalise differently — "TEG Kebabs & Biryani"
// vs "TEG KEBABS & BIRYANI". An exact match split one restaurant's history
// in two, so a "never again" recorded through one app never warned in the
// other, silently defeating the point of the memory.
const shouty = await seedOrder("THAI PALACE", "2026-06-01");
await PUT(req({ participant_id: ownerId, rating: "never" }), params(shouty));
const body = await (await GET(req(), params(txnId))).json();
expect(body.merchant.warn).toBe(true);
expect(body.merchant.history.map((h: any) => h.transaction_id)).toContain(shouty);
});
it("does not carry a verdict across different merchants", async () => {
const other = await seedOrder("Pizza Place", "2026-06-01");
await PUT(req({ participant_id: ownerId, rating: "never" }), params(other));