Render dashboard release health summary in UI#32
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a release health summary feature to the dashboard, providing visibility into release-readiness artifacts, validation checks, and recommended actions. Changes include the new ReleaseHealthSummaryCard component, API integration for fetching health data, and backend support for serving the summary JSON. A review comment identifies a UI issue where an 'unavailable' warning flashes during the loading state and recommends adding a guard clause to handle undefined state and removing a redundant check.
| function ReleaseHealthSummaryCard({ state }: { state?: ReleaseHealthState }) { | ||
| const summary = state?.summary; | ||
| const missingRequired = summary?.missing_artifacts?.required_local ?? []; | ||
| const missingOptional = summary?.missing_artifacts?.optional_cross_repo ?? []; | ||
| const missingArtifacts = [...missingRequired, ...missingOptional]; | ||
| const contractStatus = checkStatus(summary?.checks?.contract_validation_report); | ||
| const apiStatus = checkStatus(summary?.checks?.api_export_validation_report); | ||
| const projectStatus = checkStatus(summary?.checks?.project_health_report); | ||
| const overall = summary?.overall_status ?? 'unknown'; | ||
|
|
||
| return ( | ||
| <article className="card release-health-card"> | ||
| <div className="card-header"> | ||
| <div> | ||
| <h3>Release health summary</h3> | ||
| <p>Static release-readiness artifact for sanitized dashboard review.</p> | ||
| </div> | ||
| <span className={`badge ${healthTone(overall)}`}>{statusLabel(overall)}</span> | ||
| </div> | ||
| {state?.unavailable ? <div className="notice warning"><FileWarning size={16} /><span>{state.message ?? `Health summary unavailable. Expected ${RELEASE_HEALTH_SUMMARY_PATH}.`}</span></div> : null} | ||
| {!summary ? <div className="notice warning"><FileWarning size={16} /><span>Health summary unavailable. Expected {RELEASE_HEALTH_SUMMARY_PATH}.</span></div> : null} |
There was a problem hiding this comment.
The ReleaseHealthSummaryCard component currently displays a 'Health summary unavailable' warning while the data is still being fetched. This occurs because state is undefined during the loading phase, causing summary to be undefined and triggering the condition on line 55.
Furthermore, line 55 is redundant because the fetchReleaseHealthSummary helper is designed to always return a valid ReleaseHealthState object (using a fallback summary on error), so summary will only be falsy when the query is still loading.
I recommend adding a guard clause to return null if state is undefined to prevent the loading flash, and removing the redundant check on line 55.
function ReleaseHealthSummaryCard({ state }: { state?: ReleaseHealthState }) {
if (!state) return null;
const summary = state.summary;
const missingRequired = summary?.missing_artifacts?.required_local ?? [];
const missingOptional = summary?.missing_artifacts?.optional_cross_repo ?? [];
const missingArtifacts = [...missingRequired, ...missingOptional];
const contractStatus = checkStatus(summary?.checks?.contract_validation_report);
const apiStatus = checkStatus(summary?.checks?.api_export_validation_report);
const projectStatus = checkStatus(summary?.checks?.project_health_report);
const overall = summary?.overall_status ?? 'unknown';
return (
<article className="card release-health-card">
<div className="card-header">
<div>
<h3>Release health summary</h3>
<p>Static release-readiness artifact for sanitized dashboard review.</p>
</div>
<span className={`badge ${healthTone(overall)}`}>{statusLabel(overall)}</span>
</div>
{state.unavailable ? <div className="notice warning"><FileWarning size={16} /><span>{state.message ?? `Health summary unavailable. Expected ${RELEASE_HEALTH_SUMMARY_PATH}.`}</span></div> : null}
Motivation
docs/reports/dashboard-health-summary.jsonin the existing dashboard UI so release-readiness information is visible without a live external service or Daimler data.Description
dashboard/app/src/types/domain.tsand introduced a release health normalization/fetch helper atdashboard/app/src/lib/releaseHealth.tsthat returns aReleaseHealthStatewith a robust fallback.dashboard/app/src/mocks/releaseHealthSummary.tsand exposed the fetch via the client API asapi.releaseHealthindashboard/app/src/lib/api.ts.ReleaseHealthSummaryCardinside the overview page atdashboard/app/src/features/overview/OverviewPage.tsxthat displaysoverall_status, contract/API/project check badges,missing_artifacts,next_recommended_actions, andsafety_notesusing existing badge styles and responsive layout.docs/reports/into the Vite public bundle viadashboard/app/vite.config.tsand added a stdlib backend route for/dashboard-health-summary.jsonindashboard/industrial_dashboard.py.dashboard/app/src/styles/app.cssand updateddocs/API_SURFACE.mdto document the new route and UI behavior.Testing
npm run typecheckandnpm run build(both succeeded).python scripts/run_checks.py && python scripts/validate_contracts.py && python scripts/generate_contract_fixtures.py && python scripts/validate_api_exports.py && python scripts/generate_dashboard_health_summary.py(succeeded and wrotedocs/reports/dashboard-health-summary.json).python -m py_compile dashboard/industrial_dashboard.py(compile ok) and a runtime fetch ofhttp://127.0.0.1:8765/dashboard-health-summary.jsonreturned expected keys (verifiedoverall_statusandchecksvalues).Closes #31.
Codex Task