feat(devops): diagnose slow HK requests and dependency timings

This commit is contained in:
Simo committed 2026-09-11 09:48:19 +02:00
1 parent 3b76d063a6
commit 00e33623f7
42 files changed
+1335 -132

No files matched your search

+4
View File
@@ -53,6 +53,7 @@ export default async function DevOpsPage() {
const t = await getTranslations("pages.admin.devops");
const data = await getDevOpsData();
const performance = await getTranslations("pages.admin.performance");
const installation = await getTranslations("pages.admin.installation");
return (
@@ -63,6 +64,9 @@ export default async function DevOpsPage() {
<Link href="/admin/devops/installation" className="btn btn-outline">
{installation("title")}
</Link>
<Link href="/admin/devops/performance" className="btn btn-outline">
{performance("title")}
</Link>
{/* Status cards */}
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-5">
<Card>
@@ -0,0 +1,77 @@
import { createTranslator } from "next-intl";
import { renderToStaticMarkup } from "react-dom/server";
import { expect, it, vi } from "vitest";
import messages from "@/messages/en.json";
const mocks = vi.hoisted(() => ({ read: vi.fn(), allowed: false }));
vi.mock("@/lib/permissions", () => ({
getAdminContext: async () => ({
session: { user: { rank: 1 } },
permissions: {},
}),
canAccess: () => mocks.allowed,
PERMS: { DEVOPS_VIEW: "devops.view" },
}));
vi.mock("next/navigation", () => ({
redirect: () => {
throw new Error("redirect");
},
}));
vi.mock("@/lib/performance-store", () => ({ readPerformance: mocks.read }));
vi.mock("@/components/link", () => ({ default: () => null }));
vi.mock("next-intl/server", () => ({
getTranslations: async () =>
createTranslator({
locale: "en",
messages: messages.pages.admin.performance,
}),
}));
import Page from "./page";
it("rejects unauthorized users before reading timing records", async () => {
await expect(Page({ searchParams: Promise.resolve({}) })).rejects.toThrow(
"redirect",
);
expect(mocks.read).not.toHaveBeenCalled();
});
it("renders filtered slow records and explains incomplete streaming timings", async () => {
mocks.allowed = true;
const metrics = {
durationMs: 1500,
database: { count: 2, durationMs: 300, errors: 0 },
external: { count: 1, durationMs: 400, errors: 1 },
};
mocks.read.mockResolvedValue({
shared: false,
samples: [
{
operationId: "slow-op",
route: "/api/admin/studio",
method: "GET",
status: 200,
at: 1000,
streaming: true,
metrics,
},
{
operationId: "fast-op",
route: "/api/admin/users",
method: "GET",
status: 200,
at: 1001,
streaming: false,
metrics: { ...metrics, durationMs: 10 },
},
],
});
const html = renderToStaticMarkup(
await Page({ searchParams: Promise.resolve({ slow: "1" }) }),
);
expect(html).toContain("slow-op");
expect(html).not.toContain("fast-op");
expect(html).toContain("Streaming response");
expect(html).toContain("Local diagnostics");
});
File diff suppressed because it is too large. Load diff