mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
The insights read path served a cold cache by generating inline — up to ten seconds on first visit — and the nightly warm pass structurally excluded evening visitors: their visit stamped the cache, the half-four run skipped it as fresh, and it expired exactly at the next evening's visit. Stale content now serves immediately with its timestamp while one background job revalidates, the warm threshold drops to an hour, forced warming fills both message locales, the analytics caches serve stale-while-revalidate, the profile endpoint parallelises its reads, the bug-report status drops a write per call, the umami proxy degrades to a no-op script instead of an error, the insights route sheds its heaviest static imports, and the medication page prefetches on intent.
75 lines
2.3 KiB
TypeScript
75 lines
2.3 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { apiHandler } from "@/lib/api-handler";
|
|
import { annotate } from "@/lib/logging/context";
|
|
import { getPublicMonitoringSettings } from "@/lib/monitoring-settings";
|
|
import { safeFetch } from "@/lib/safe-fetch";
|
|
|
|
export const dynamic = "force-dynamic";
|
|
|
|
const NOOP_SCRIPT = "/* umami disabled */";
|
|
|
|
export const GET = apiHandler(async () => {
|
|
annotate({ action: { name: "monitoring.umami-script" } });
|
|
|
|
const settings = await getPublicMonitoringSettings();
|
|
if (
|
|
!settings.umamiEnabled ||
|
|
!settings.umamiScriptUrl ||
|
|
!settings.umamiWebsiteId
|
|
) {
|
|
return new NextResponse(NOOP_SCRIPT, {
|
|
status: 200,
|
|
headers: {
|
|
"Content-Type": "application/javascript; charset=utf-8",
|
|
"Cache-Control": "public, max-age=60",
|
|
},
|
|
});
|
|
}
|
|
|
|
// Fail-soft: an unreachable / slow / rebinding-refused upstream must
|
|
// degrade to the noop script, not 500 the proxy route — `safeFetch`
|
|
// THROWS on its 15 s timeout and on the connect-time public-host
|
|
// refusal, and an uncaught throw here surfaced as a 500 on every
|
|
// mount whenever the operator's Umami host was down or unresolvable.
|
|
let response: Response;
|
|
try {
|
|
response = await safeFetch(
|
|
settings.umamiScriptUrl,
|
|
{
|
|
next: { revalidate: 3600 },
|
|
},
|
|
// Operator-configured host — pin the connect-time IP so a low-TTL
|
|
// DNS record cannot rebind the fetch at an internal range between
|
|
// the input-time `isPublicUrl` accept and the socket connect.
|
|
{ requirePublicHost: true },
|
|
);
|
|
} catch {
|
|
annotate({ meta: { umami_script_fetch_failed: true } });
|
|
return new NextResponse(NOOP_SCRIPT, {
|
|
status: 200,
|
|
headers: {
|
|
"Content-Type": "application/javascript; charset=utf-8",
|
|
"Cache-Control": "public, max-age=60",
|
|
},
|
|
});
|
|
}
|
|
if (!response.ok) {
|
|
return new NextResponse(NOOP_SCRIPT, {
|
|
status: 200,
|
|
headers: {
|
|
"Content-Type": "application/javascript; charset=utf-8",
|
|
"Cache-Control": "public, max-age=60",
|
|
},
|
|
});
|
|
}
|
|
|
|
const script = await response.text();
|
|
return new NextResponse(script, {
|
|
status: 200,
|
|
headers: {
|
|
"Content-Type": "application/javascript; charset=utf-8",
|
|
"Cache-Control": "public, max-age=1800",
|
|
},
|
|
});
|
|
});
|