Report data contract
The report builder resolves selected profile facts into one detached, JSON-serializable snapshot before HTML rendering or optional AI summarization.export-report-data.ts owns this contract. PDF/print HTML and the optional AI overview consume it; neither is a source of truth for ranges, status, provenance, or section selection.
Use collectReportData(options) from export-report.ts or the export.ts facade for the active profile:
schemaVersion before depending on the shape. REPORT_DATA_SCHEMA_VERSION is currently 1.
Snapshot shape
The top-level record contains:schemaVersionandgeneratedAt;scope, including preset, selected date range, sections, categories, range mode, status basis, and display-unit profile;- minimized
profilemetadata; - selected
labs, including results, flags, trends, and collection context; - selected
notes,supplements,genetics, context, andadditionalSectionsfor nutrition, wearables/body, light and environment; and nullor empty values for report sections that were not selected.
purpose, appendixSections, genomeMode and explicit variant selection. additionalSections contains selected, date-filtered records and aggregates; OAuth connections, chat archives and unselected profile surfaces remain outside the report. It is a sharing snapshot, not a complete profile backup. Use JSON/database export for restorable profile data.
buildPreparedReportPayload() captures the source state before asynchronous loading. Builder options filter notes, context, Genome and detailed histories before rendering or AI projection. An appendix cannot restore excluded content. The summary renderer and AI consumer use the same prepared facts.
Lab result contract
Every included marker result can carry:- collection date and draw-level context;
- source-file and collection-context provenance when recorded;
- the source report’s original range and unit when an import snapshot matches;
- numeric and formatted display values;
- marker-level and dated value notes;
- the range used for status, ranges displayed for the selected mode, and other available reference/optimal ranges; and
- resolved range label, kind, source, and
low,normal,high, orunratedstatus.
scope.rangeMode records the user’s display choice. scope.statusBasis makes the judging rule explicit. In Both mode, both reference and optimal ranges can be shown while optimal guidance judges status when available; reference is the fallback, and an eligible phase-specific reference range takes precedence.
A result is unrated when no applicable bound exists. Do not convert missing context or an intentionally suppressed range into normal.
Data-minimization boundary
Report sections are authorization and minimization inputs.buildReportDataSnapshot() includes labs only when a lab section was selected, includes notes/supplements/genetics/context only when their corresponding section was selected, and filters lab dates and categories before snapshot creation.
The optional AI overview calls formatReportDataForAgent() over this same selected snapshot. That projection is deliberately bounded and lossy: it prioritizes latest abnormalities, representative markers, notable trends, and a limited number of context sections. The full structured snapshot remains the lossless interface for a local integration that the user has authorized.
Do not let an HTML renderer or AI consumer re-read global application state. New consumers must receive the snapshot explicitly so the report builder’s selection remains the controlling boundary.
Builder and AI lifecycle
The visible templates are Health summary (clinician), Full health report (full), Nutrition and lifestyle (lifestyle) and Lab results only (personal). Keep these internal IDs stable for existing integrations. Concise output is the default; detailed records are opt-in per selected section. Genome modes are risks, risks-traits, traits and all.
Include AI overview starts checked only when a supported feature provider is available. The preview action may generate it, so disclose the request in the action label and require normal AI processing approval before loading/sending the selected context. With AI off, compilation makes no new AI request.
Track the originating profile, selection revision and prepared payload across generation. Reject stale results after changes, cancellation, profile switches or modal removal. Keep attribution on edited AI output. The renderer provides an explicitly marked AI section and a printable preview; export-report-progress.ts owns progress and cancellation.
Owners and verification
Run
tests/report-data.test.ts when the schema, range behavior, minimization, or agent projection changes. Run tests/report-export-html-runtime.test.ts for renderer consumption and the directly related report-export Playwright cases for the builder/preview boundary.
The source implementation is in js/export-report-data.ts.