refactor(housekeeping): stabilize service contracts

This commit is contained in:
Simo committed 2026-08-26 21:04:42 +02:00
1 parent 67cb4b488d
commit b7edbca043
10 files changed
+145 -28

No files matched your search

@@ -13,6 +13,7 @@ import {
type HousekeepingSearchResult,
type HousekeepingWidgetDefinition,
type HousekeepingWorkItem,
mapUnknownError,
ok,
} from ".";
@@ -25,18 +26,32 @@ const workItem = {
domain: "people",
capability,
severity: "warning",
priority: "high",
ageMs: 60_000,
state: "open",
occurredAt: "2026-08-24T12:00:00.000Z",
titleKey: "pages.housekeeping.items.ticket",
context: { ticketId: "42" },
href: "/ase-next/people/tickets/42",
href: "/ase/people/tickets/42",
freshness: "fresh",
actions: [
{
id: "people.ticket.open",
labelKey: "pages.housekeeping.items.ticket.open",
commandId: "people.ticket.open",
capability,
},
],
} satisfies HousekeepingWorkItem;
const searchResult = {
id: "user-42",
domain: "people",
type: "entity",
title: "operator",
href: "/ase-next/people/users/42",
description: "A Housekeeping operator",
href: "/ase/people/users/42",
capability,
} satisfies HousekeepingSearchResult;
const searchProvider: HousekeepingSearchProvider = {
@@ -87,7 +102,7 @@ const manifest: HousekeepingDomainManifest = {
labelKey: "pages.housekeeping.domains.people.title",
descriptionKey: "pages.housekeeping.domains.people.description",
iconId: "users",
canonicalHref: "/ase-next/people",
canonicalHref: "/ase/people",
capability,
routes: [],
searchProviders: [searchProvider],
@@ -96,19 +111,47 @@ const manifest: HousekeepingDomainManifest = {
};
describe("housekeeping foundation contracts", () => {
it("creates typed success and error results", () => {
it("preserves correlation IDs for successful results", () => {
expect(ok({ count: 2 }, "corr-1")).toEqual({
ok: true,
data: { count: 2 },
correlationId: "corr-1",
});
expect(fail("CAPABILITY_DENIED", "corr-2")).toEqual({
});
it.each([
"UNAUTHENTICATED",
"FORBIDDEN",
"VALIDATION",
"NOT_FOUND",
"CONFLICT",
"RATE_LIMITED",
"DEPENDENCY_UNAVAILABLE",
"TIMEOUT",
"INTERNAL",
] as const)("returns the approved %s error contract", (code) => {
expect(
fail(code, `errors.housekeeping.${code.toLowerCase()}`, "corr-2", {
name: ["errors.validation.required"],
}),
).toEqual({
ok: false,
error: { code: "CAPABILITY_DENIED" },
error: {
code,
messageKey: `errors.housekeeping.${code.toLowerCase()}`,
fieldErrors: { name: ["errors.validation.required"] },
},
correlationId: "corr-2",
});
});
it("sanitizes unknown errors with the stable internal taxonomy", () => {
expect(mapUnknownError(new Error("database password exposed"))).toEqual({
code: "INTERNAL",
messageKey: "errors.housekeeping.internal",
});
});
it("rejects empty capability requirements", () => {
expect(() => anyCapability()).toThrow("capability requirement is empty");
expect(() => allCapabilities()).toThrow("capability requirement is empty");