From 853792ca065fb9921846eba15b130e2c6f642cbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 21 May 2026 12:41:13 +0200 Subject: [PATCH] fix(intake,dashboard): use Promise.allSettled around bulk-projection compliance recompute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recompute helper swallows errors internally today, but the contract is fragile — any future refactor that lets a throw escape would turn the intake POST or dashboard summary GET into a 5xx for a strictly best-effort hook. Wrap both call sites in `Promise.allSettled` so the fail-soft contract is explicit at the call site, not buried in the helper. Closes specialist H1 from the v1.4.40 QA round. --- src/app/api/dashboard/summary/route.ts | 7 ++++++- src/app/api/medications/intake/route.ts | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/app/api/dashboard/summary/route.ts b/src/app/api/dashboard/summary/route.ts index b0e24bcf2..816e122e4 100644 --- a/src/app/api/dashboard/summary/route.ts +++ b/src/app/api/dashboard/summary/route.ts @@ -373,7 +373,12 @@ async function projectAndReadTodaysIntakes( }), ); } - await Promise.all(recomputeJobs); + // Defence in depth (specialist H1): the helper swallows internally + // today, but any future refactor that lets a throw escape would + // turn the dashboard summary into a 5xx. `allSettled` keeps the + // best-effort contract explicit at the call site so the request + // stays 200-OK regardless of helper behaviour. + await Promise.allSettled(recomputeJobs); } } diff --git a/src/app/api/medications/intake/route.ts b/src/app/api/medications/intake/route.ts index 6200f0e0a..5a8d475e3 100644 --- a/src/app/api/medications/intake/route.ts +++ b/src/app/api/medications/intake/route.ts @@ -183,7 +183,12 @@ export const GET = apiHandler(async (request: NextRequest) => { }), ); } - await Promise.all(recomputeJobs); + // Defence in depth (specialist H1): the helper swallows internally + // today, but any future refactor that lets a throw escape would + // turn the intake POST into a 5xx. `allSettled` keeps the + // best-effort contract explicit at the call site so the request + // stays 200-OK regardless of helper behaviour. + await Promise.allSettled(recomputeJobs); } const events = await prisma.medicationIntakeEvent.findMany({