From 6d3b6e1a9d16f4da3b9972df25b08c40a9c9db6a Mon Sep 17 00:00:00 2001 From: siddharthd Date: Sun, 26 Jul 2026 22:09:31 +1000 Subject: [PATCH] feat(orders): withdraw the ShopBack transfer guard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tests 12 & 13 asserted that every 'ShopBack Gift Cards' row becomes a transfer. Resolved against the ShopBack purchase emails, 3 of the 14 matching rows are Airbnb, 1 Shell, 1 Amazon — the bank descriptor's trailing token is a sequence counter, not a brand code, so the description cannot identify what was bought. Only $313.66 of $3,411.16 was ever reclassifiable. Withdrawn rather than narrowed: making it safe needs ShopBack purchase-email ingestion, brand resolution and an approval gate, to correctly handle 2 transactions in 20 months. Those two rows get handled by hand. --- .../integration/order-ingestion.test.ts | 46 ++++++------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/src/__tests__/integration/order-ingestion.test.ts b/src/__tests__/integration/order-ingestion.test.ts index 75bfe98..23b2521 100644 --- a/src/__tests__/integration/order-ingestion.test.ts +++ b/src/__tests__/integration/order-ingestion.test.ts @@ -84,38 +84,20 @@ describe("Order Ingestion - Integration Tests", () => { expect(res1.transactionId).toBe(res2.transactionId); }); - it("12 & 13. ShopBack rows carry category_override='transfers' and monthly spend delta matches (I2)", async () => { - // Ensure at least one ShopBack transaction exists for isolated test runs - await queryRaw(` - INSERT INTO transactions (transaction_date, description, amount, category, owner_id) - VALUES ('2025-01-05', 'ShopBack Gift Cards SP Australia AUS', 300.00, 'gifts', NULL) - ON CONFLICT DO NOTHING; - `); - - await queryRaw(` - INSERT INTO transaction_overrides (transaction_id, category_override) - SELECT id, 'transfers' FROM transactions WHERE description ILIKE '%ShopBack Gift Cards%' - ON CONFLICT (transaction_id) DO UPDATE SET category_override = 'transfers'; - `); - - const sbRows = await queryRaw<{ id: number; category_override: string }>( - `SELECT t.id, o.category_override - FROM transactions t - JOIN transaction_overrides o ON o.transaction_id = t.id - WHERE t.description ILIKE '%ShopBack Gift Cards%'` - ); - expect(sbRows.length).toBeGreaterThan(0); - sbRows.forEach((r) => expect(r.category_override).toBe("transfers")); - - // Verify EXCLUDE_NON_SPEND excludes them - const excluded = await queryRaw( - `SELECT t.id FROM transactions t - LEFT JOIN transaction_overrides o ON o.transaction_id = t.id - WHERE t.description ILIKE '%ShopBack Gift Cards%' - AND NOT (${EXCLUDE_NON_SPEND})` - ); - expect(excluded.length).toBe(sbRows.length); - }); + // Tests 12 & 13 (ShopBack -> transfers reclassification, old invariant I2) were + // REMOVED 2026-07-26. The guard they asserted is withdrawn from the slice. + // + // The bank descriptor `ShopBack Gift Cards ` cannot identify the card's + // brand -- the trailing token is a sequence counter, not a brand code. Resolved + // against the ShopBack purchase emails, 3 of the 14 matching rows were Airbnb, + // 1 Shell, 1 Amazon. Of $3,411.16, only $313.66 was ever reclassifiable; the + // rule was 91% wrong by value and would have deleted real travel/fuel/shopping + // spend. These tests asserted that wrong behaviour and would have gone green + // doing it. + // + // Rationale for withdrawing rather than narrowing: only 2 transactions in 20 + // months qualify. See memory-bank/order-ingestion-slice-plan.md and + // memory-bank/order-ingestion-review-artifacts.md §3.1z. it("14. Split on a $42 credits order => participant share computed on 42.00 (I8)", async () => { const txn = await queryRow<{ id: number }>(