import type { DoctorCheck, DoctorCheckId, DoctorReport, DoctorResult } from "./doctor.js"; interface DoctorSection { readonly checkIds: readonly DoctorCheckId[]; readonly title: string; } function section(title: string, checkIds: readonly DoctorCheckId[]): DoctorSection { return Object.freeze({ checkIds: Object.freeze([...checkIds]), title }); } const sections: readonly DoctorSection[] = Object.freeze([ section("Platform", ["platform.runtime"]), section("Modules", ["modules.discovery", "modules.dependencies"]), section("Data definitions", ["schemas.discovery", "migrations.discovery"]), section("PostgreSQL", ["postgresql.connection", "postgresql.plan"]), section("Identity", ["identity.configuration"]), section("Object storage", ["object-storage.integration"]), ]); const statusSymbols: Readonly> = Object.freeze({ failure: "✗", pass: "✓", skipped: "○", warning: "!", }); const resultLabels: Readonly> = Object.freeze({ "not-ready": "NOT READY", ready: "READY", "ready-with-warnings": "READY WITH WARNINGS", }); export function formatDoctorReport(report: DoctorReport): readonly string[] { const checks = new Map(report.checks.map((check) => [check.id, check])); const lines = ["Ekklesia Doctor", ""]; for (const [sectionIndex, section] of sections.entries()) { lines.push(section.title); for (const checkId of section.checkIds) { const check = checks.get(checkId); if (!check) { continue; } lines.push(` ${statusSymbols[check.status]} ${check.summary}`); for (const detail of check.details) { lines.push(` ${detail}`); } } if (sectionIndex < sections.length - 1) { lines.push(""); } } lines.push("", `Result: ${resultLabels[report.result]}`); return Object.freeze(lines); }