From 93796ccb9970ff782080c8c3257799e38a05d1c0 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 15 Sep 2026 13:38:49 +0000 Subject: [PATCH] fix: Replace EmDash .where queries with fetch+filter for Postgres compatibility EmDash's .query({ where: ... }) builds SQLite-style SQL that fails on Postgres with 'syntax error at or near "="'. This affects live Railway demo on Neon (Postgres). Changes: - cart/shipping-methods: Fetch all methods, filter by zoneId + enabled in JS - cart/shipping-method: Same fetch+filter pattern - admin-api deleteShippingZone: Fetch all methods, check zoneId match in JS All queries now fetch with limit and filter in JavaScript, working across both SQLite and Postgres. Handles enabled field as both boolean (true) and numeric (1) for cross-database compatibility. Verified: - All tests pass (85 pass, 0 fail) - Typecheck clean - Build succeeds Co-authored-by: Timchosen Uzua --- packages/core/src/routes/admin-api.ts | 8 ++- packages/core/src/routes/cart.ts | 94 +++++++++++++-------------- 2 files changed, 52 insertions(+), 50 deletions(-) diff --git a/packages/core/src/routes/admin-api.ts b/packages/core/src/routes/admin-api.ts index 49e592c..c0ce682 100644 --- a/packages/core/src/routes/admin-api.ts +++ b/packages/core/src/routes/admin-api.ts @@ -709,11 +709,13 @@ async function deleteShippingZone( if (!current) return json({ error: "Zone not found" }, 404); // Zones own methods; fail fast if any method still references this zone // rather than leaving orphaned methods in the store. + // Use fetch+filter instead of .where — EmDash's where clause building + // breaks on Postgres (syntax error near "="). const methods = await storeOf(ctx, "shipping_methods").query({ - where: { zoneId: id }, - limit: 1, + limit: 500, }); - if (methods.items.length > 0) { + const zoneHasMethods = methods.items.some((r) => (r.data as ShippingMethod).zoneId === id); + if (zoneHasMethods) { return json( { error: diff --git a/packages/core/src/routes/cart.ts b/packages/core/src/routes/cart.ts index 359f3a8..8b678ff 100644 --- a/packages/core/src/routes/cart.ts +++ b/packages/core/src/routes/cart.ts @@ -612,29 +612,29 @@ export const cartRoutes = { }; } ).shipping_zones; - const methodsStore = ( - ctx.storage as unknown as { - shipping_methods: { - query(opts: { - where: Record; - limit: number; - }): Promise<{ items: Array<{ id: string; data: ShippingMethod }> }>; - }; - } - ).shipping_methods; - - const zones = (await zonesStore.query({ limit: 200 })).items.map((r) => ({ - ...r.data, - id: r.id, - })); - const zone = pickZone(cart.shippingAddress, zones); - if (!zone) return jsonResponse({ options: [] }, withSessionCookie(setCookie)); - const methods = ( - await methodsStore.query({ - where: { zoneId: zone.id, enabled: 1 }, - limit: 50, - }) - ).items.map((r) => ({ ...r.data, id: r.id })); + const methodsStore = ( + ctx.storage as unknown as { + shipping_methods: { + query(opts: { + where?: Record; + limit: number; + }): Promise<{ items: Array<{ id: string; data: ShippingMethod }> }>; + }; + } + ).shipping_methods; + + const zones = (await zonesStore.query({ limit: 200 })).items.map((r) => ({ + ...r.data, + id: r.id, + })); + const zone = pickZone(cart.shippingAddress, zones); + if (!zone) return jsonResponse({ options: [] }, withSessionCookie(setCookie)); + // Fetch all methods and filter in JS — EmDash's .where builds SQLite-style + // SQL that breaks on Postgres (syntax error near "="). This fetch+filter + // approach works across both databases. + const methods = (await methodsStore.query({ limit: 200 })).items + .map((r) => ({ ...r.data, id: r.id })) + .filter((m) => m.zoneId === zone.id && (m.enabled === true || (m.enabled as unknown) === 1)); const options = calculateRates({ items: cart.items, @@ -669,31 +669,31 @@ export const cartRoutes = { }; } ).shipping_zones; - const methodsStore = ( - ctx.storage as unknown as { - shipping_methods: { - get(id: string): Promise; - query(opts: { - where: Record; - limit: number; - }): Promise<{ items: Array<{ id: string; data: ShippingMethod }> }>; - }; - } - ).shipping_methods; - const zones = (await zonesStore.query({ limit: 200 })).items.map((r) => ({ - ...r.data, - id: r.id, - })); - const zone = pickZone(cart.shippingAddress, zones); - if (!zone) { - return errorResponse("No shipping zone matches the address", 409, setCookie); + const methodsStore = ( + ctx.storage as unknown as { + shipping_methods: { + get(id: string): Promise; + query(opts: { + where?: Record; + limit: number; + }): Promise<{ items: Array<{ id: string; data: ShippingMethod }> }>; + }; } - const methods = ( - await methodsStore.query({ - where: { zoneId: zone.id, enabled: 1 }, - limit: 50, - }) - ).items.map((r) => ({ ...r.data, id: r.id })); + ).shipping_methods; + const zones = (await zonesStore.query({ limit: 200 })).items.map((r) => ({ + ...r.data, + id: r.id, + })); + const zone = pickZone(cart.shippingAddress, zones); + if (!zone) { + return errorResponse("No shipping zone matches the address", 409, setCookie); + } + // Fetch all methods and filter in JS — EmDash's .where builds SQLite-style + // SQL that breaks on Postgres (syntax error near "="). This fetch+filter + // approach works across both databases. + const methods = (await methodsStore.query({ limit: 200 })).items + .map((r) => ({ ...r.data, id: r.id })) + .filter((m) => m.zoneId === zone.id && (m.enabled === true || (m.enabled as unknown) === 1)); const options = calculateRates({ items: cart.items, currency: cart.currency,