Add bounded chart loading, per-layer retry states, and shared SVG skeletons. Add report block downloads with SVG, localized metadata, and inline deletion. Record verification and retain CRLF export, full-build, and controlled-device acceptance blockers. User authorized staging delivery with these gaps documented. Co-Authored-By: Claude Code <noreply@anthropic.com>
69 lines
2.6 KiB
TypeScript
69 lines
2.6 KiB
TypeScript
import { type ChartBirthFailureReason } from "./chart-birth-truth.ts";
|
|
import type { ChartViewFailureStatus, ChartViewMessage } from "./chart-view-contract.ts";
|
|
|
|
type ChartFailureReason = ChartBirthFailureReason | "client_timeout";
|
|
import { CHART_VIEW_COPY } from "./chart-view-labels.ts";
|
|
|
|
const FAILURE_COPY: Record<ChartFailureReason, string> = {
|
|
client_timeout: CHART_VIEW_COPY.timedOut,
|
|
profile_query_error: CHART_VIEW_COPY.profileQueryError,
|
|
profile_incomplete: CHART_VIEW_COPY.incomplete,
|
|
adopted_calculation_incomplete: CHART_VIEW_COPY.adoptedIncomplete,
|
|
timezone_resolver_failure: CHART_VIEW_COPY.timezoneFailure,
|
|
engine_busy: CHART_VIEW_COPY.busy,
|
|
engine_timeout: CHART_VIEW_COPY.unavailable,
|
|
engine_bad_payload: CHART_VIEW_COPY.unavailable,
|
|
engine_http_error: CHART_VIEW_COPY.unavailable,
|
|
response_schema_failure: CHART_VIEW_COPY.schemaFailure,
|
|
};
|
|
|
|
const FAILURE_STATUS: Record<ChartFailureReason, ChartViewMessage["status"]> = {
|
|
client_timeout: "client_timeout",
|
|
profile_query_error: "chart_unavailable",
|
|
profile_incomplete: "birth_profile_incomplete",
|
|
adopted_calculation_incomplete: "chart_unavailable",
|
|
timezone_resolver_failure: "chart_unavailable",
|
|
engine_busy: "chart_unavailable",
|
|
engine_timeout: "chart_unavailable",
|
|
engine_bad_payload: "chart_unavailable",
|
|
engine_http_error: "chart_unavailable",
|
|
response_schema_failure: "chart_unavailable",
|
|
};
|
|
|
|
export function chartViewFailureResponse(reason: ChartFailureReason): ChartViewMessage {
|
|
return {
|
|
status: FAILURE_STATUS[reason],
|
|
billed: false,
|
|
message: FAILURE_COPY[reason],
|
|
...(reason === "client_timeout" ? {} : { reason }),
|
|
};
|
|
}
|
|
|
|
export function chartViewFailureStatus(reason: ChartFailureReason): ChartViewMessage["status"] {
|
|
return FAILURE_STATUS[reason];
|
|
}
|
|
|
|
export function chartLayerFailureCopy(status: ChartViewFailureStatus): string {
|
|
if (status === "unavailable") return CHART_VIEW_COPY.unavailable;
|
|
if (status === "unauthenticated") return CHART_VIEW_COPY.unauthenticated;
|
|
if (status === "rate_limited") return CHART_VIEW_COPY.rateLimited;
|
|
return FAILURE_COPY[status];
|
|
}
|
|
|
|
export function chartClientFailureStatus(error: unknown): "client_timeout" | "unavailable" {
|
|
return error instanceof Error && error.name === "TimeoutError" ? "client_timeout" : "unavailable";
|
|
}
|
|
|
|
export function logChartViewFailure(input: {
|
|
reason: ChartBirthFailureReason;
|
|
elapsedMs?: number;
|
|
httpStatus?: number | null;
|
|
}): void {
|
|
console.warn("chart_view_failure", {
|
|
reason: input.reason,
|
|
route: "/api/chart-view",
|
|
elapsedMs: input.elapsedMs ?? null,
|
|
httpStatus: input.httpStatus ?? null,
|
|
});
|
|
}
|