From 94ebd0733ad2c769196923866dbafba68c0af5d2 Mon Sep 17 00:00:00 2001 From: shawn Date: Fri, 11 Sep 2026 14:54:14 +1000 Subject: [PATCH 1/2] fix: make order search case-insensitive Searching "JOHN" or "ord-1001" returned no orders because SQLite instr() is case-sensitive. Compare lowercased values for order number, customer name, and email. Adds API regression tests for both cases. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01HUfxyr6EcRi4EYSX1wLoRh --- apps/api/src/orders/order-repository.ts | 8 +++++--- apps/api/src/orders/orders-routes.test.ts | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/apps/api/src/orders/order-repository.ts b/apps/api/src/orders/order-repository.ts index 5a904e1..21cd809 100644 --- a/apps/api/src/orders/order-repository.ts +++ b/apps/api/src/orders/order-repository.ts @@ -37,11 +37,13 @@ function toOrderItemDetail(row: { export async function listOrderSummaries(context: DatabaseContext, query?: string) { const search = query?.trim(); + // Support staff type search terms in any case. instr() is case-sensitive, so compare lowercased + // values; LIKE is avoided because it would treat % and _ in the search text as wildcards. const filters = search ? or( - sql`instr(${orders.orderNumber}, ${search}) > 0`, - sql`instr(${users.name}, ${search}) > 0`, - sql`instr(${users.email}, ${search}) > 0` + sql`instr(lower(${orders.orderNumber}), lower(${search})) > 0`, + sql`instr(lower(${users.name}), lower(${search})) > 0`, + sql`instr(lower(${users.email}), lower(${search})) > 0` ) : undefined; diff --git a/apps/api/src/orders/orders-routes.test.ts b/apps/api/src/orders/orders-routes.test.ts index 9266907..8885282 100644 --- a/apps/api/src/orders/orders-routes.test.ts +++ b/apps/api/src/orders/orders-routes.test.ts @@ -44,6 +44,20 @@ describe("order routes", () => { expect(response.json()).toHaveLength(7); }); + test("finds orders by customer name regardless of letter case", async () => { + const response = await app.inject({ method: "GET", url: "/api/orders?query=JOHN", headers: { cookie: employeeCookie } }); + + expect(response.statusCode).toBe(200); + expect(response.json().map((order: { orderNumber: string }) => order.orderNumber)).toEqual(["ORD-1001", "ORD-1003"]); + }); + + test("finds orders by order number regardless of letter case", async () => { + const response = await app.inject({ method: "GET", url: "/api/orders?query=ord-1001", headers: { cookie: employeeCookie } }); + + expect(response.statusCode).toBe(200); + expect(response.json().map((order: { orderNumber: string }) => order.orderNumber)).toEqual(["ORD-1001"]); + }); + test("returns order detail", async () => { const response = await app.inject({ method: "GET", url: "/api/orders/order_1", headers: { cookie: employeeCookie } }); const order = response.json(); -- 2.54.0 From e0972d80fab18fb13eb3b5299720db84ebcee7f5 Mon Sep 17 00:00:00 2001 From: shawn Date: Fri, 11 Sep 2026 15:05:31 +1000 Subject: [PATCH 2/2] test: pin customer-name search to the name column Search "JOHN SMITH" instead of "JOHN" so the regression test only matches through the customer name column ("john" alone also matched the email), ensuring case-insensitive name matching is verified on its own. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01HUfxyr6EcRi4EYSX1wLoRh --- apps/api/src/orders/orders-routes.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api/src/orders/orders-routes.test.ts b/apps/api/src/orders/orders-routes.test.ts index 8885282..edc44a1 100644 --- a/apps/api/src/orders/orders-routes.test.ts +++ b/apps/api/src/orders/orders-routes.test.ts @@ -45,7 +45,7 @@ describe("order routes", () => { }); test("finds orders by customer name regardless of letter case", async () => { - const response = await app.inject({ method: "GET", url: "/api/orders?query=JOHN", headers: { cookie: employeeCookie } }); + const response = await app.inject({ method: "GET", url: "/api/orders?query=JOHN%20SMITH", headers: { cookie: employeeCookie } }); expect(response.statusCode).toBe(200); expect(response.json().map((order: { orderNumber: string }) => order.orderNumber)).toEqual(["ORD-1001", "ORD-1003"]); -- 2.54.0