Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .server-changes/report-messages-not-treeshaken.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
area: webapp
type: fix
---

Fix the health report failing with an internal error when requested through the API.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* metrics / evidence — meaning lives here, numbers stay facts.
*/

import { registerReportMessages, type ReportMessages } from "../report-messages";
import { type ReportMessages } from "../report-messages";
import { type ReasonCode, type Severity } from "../report-view-model";

/** Metric id -> expanded display label. */
Expand Down Expand Up @@ -166,5 +166,3 @@ export const healthMessages: ReportMessages = {
statementMessage,
actionMessage: (code) => ACTIONS[code] ?? code,
};

registerReportMessages("health", healthMessages);
1 change: 0 additions & 1 deletion apps/webapp/app/presenters/v3/reports/health/health.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import { applyFlowPolicy, buildFlowRead, interpretFlow } from "./flow";
import { interpretLiveness } from "./liveness";
// Registers the "health" message catalog (side effect) so the renderer resolves this report's
// codes. Kept here — the health report's entry module — so loading it always registers its prose.
import "./health-messages";

// Re-exported so the data layer + tests keep a single import path (`./health`).
export { HEALTH_THRESHOLDS, isPendingIncreasing, type HealthInput } from "./health-core";
Expand Down
11 changes: 11 additions & 0 deletions apps/webapp/app/presenters/v3/reports/report-message-catalogs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Catalogs by value, in a module that imports ONLY the per-report `*-messages`
* files — no loaders, no IO. Presentation stays decoupled from the data layer,
* and a value import can't be tree-shaken away.
*/
import { healthMessages } from "./health/health-messages";
import { type ReportMessages } from "./report-messages";

export const REPORT_MESSAGE_CATALOGS: Record<string, ReportMessages> = {
health: healthMessages,
};
14 changes: 5 additions & 9 deletions apps/webapp/app/presenters/v3/reports/report-messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* No report vocabulary here — that would re-couple the renderer to a specific report.
*/

import { REPORT_MESSAGE_CATALOGS } from "./report-message-catalogs";
import { type ReasonCode, type Severity } from "./report-view-model";

/**
Expand All @@ -22,16 +23,11 @@ export type ReportMessages = {
actionMessage(code: ReasonCode): string;
};

const catalogs = new Map<string, ReportMessages>();

/** Register a report's catalog under its title (e.g. "health"). Called for its side effect. */
export function registerReportMessages(title: string, messages: ReportMessages): void {
catalogs.set(title, messages);
}

/** Look up a report's catalog by `vm.title`. Throws if the report never registered one. */
/** Look up a report's catalog by `vm.title`. Catalogs are values, never
* registered at import time — side-effect registration is what the production
* bundle tree-shakes away. */
export function reportMessages(title: string): ReportMessages {
const messages = catalogs.get(title);
const messages = REPORT_MESSAGE_CATALOGS[title];
if (!messages) {
throw new Error(`report-messages: no catalog registered for report "${title}"`);
}
Expand Down
Loading