fix(orders): the restaurant is the merchant, not the courier
ci / lint-test (push) Successful in 43s
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:
@@ -177,7 +177,7 @@ describe("Order ingestion — invariants", () => {
|
||||
expect(b.skipped).toBe("already_ingested");
|
||||
expect(b.metadataId).toBe(a.metadataId);
|
||||
const n = await queryRow<{ c: string }>(
|
||||
`SELECT count(*)::text c FROM transactions WHERE description = 'Order - Mad Mex (DoorDash)'`
|
||||
`SELECT count(*)::text c FROM transactions WHERE description = 'Order - Mad Mex'`
|
||||
);
|
||||
expect(Number(n!.c)).toBe(1);
|
||||
});
|
||||
@@ -389,15 +389,17 @@ describe("owner scoping", () => {
|
||||
});
|
||||
|
||||
describe("how an ingested order presents in the app", () => {
|
||||
it("names the platform in the description", async () => {
|
||||
// "Order - Burger Corner" gives no way to know where to look for the
|
||||
// detail, and the same restaurant can be on both platforms.
|
||||
it("names the restaurant, not the courier", async () => {
|
||||
// Reversed 2026-07-28. The platform was in the headline on request, but it
|
||||
// fragmented the merchant — the same restaurant read differently depending
|
||||
// on who delivered — and it already has a home: the Order details panel
|
||||
// renders expense_metadata.platform next to its heading.
|
||||
const p = parseOrderHTML(html("dd-01"), meta({ messageId: `desc-${Date.now()}` }));
|
||||
const res = await processOrderIngestion(p);
|
||||
const row = await queryRow<{ description: string }>(
|
||||
`SELECT description FROM transactions WHERE id = $1`, [res.transactionId]
|
||||
);
|
||||
expect(row!.description).toMatch(/\(DoorDash\)$/);
|
||||
expect(row!.description).toBe('Order - Mad Mex');
|
||||
});
|
||||
|
||||
it("reads as 'Gift Card', not 'Manual', and stays out of the reconcile queue", async () => {
|
||||
|
||||
Reference in New Issue
Block a user