Files
weatherreporter/docs/internal/reporttemplate.md

4.7 KiB

Report Template Internals

This document describes embedded Markdown templates and GeneratedText schemas in internal/reporttemplate.

Purpose

internal/reporttemplate owns repository-native report templates and companion GeneratedText JSON schemas. The implemented template assets are Daily, Today, Tomorrow, and Hourly.

The package embeds assets from:

  • internal/reporttemplate/templates/*.md.tmpl
  • internal/reporttemplate/templates/partials/*.md.tmpl
  • internal/reporttemplate/schemas/*.schema.json

Generated-text prompt source files live under internal/reporttemplate/prompts/. They are repository assets for prompt registration, not embedded lookup APIs.

Inputs And Outputs

Inputs:

  • template ID from a report definition
  • typed render context built by internal/generatedtext

Outputs:

  • template source for inspection and tests
  • GeneratedText schema bytes for prompt/schema configuration
  • rendered Markdown bytes for app orchestration to persist

The implemented template IDs are daily, today, tomorrow, and hourly. The implemented schema IDs are also daily, today, tomorrow, and hourly, backed by matching *.generated_text.schema.json files.

Generated-text prompt sources are maintained under internal/reporttemplate/prompts/, including Daily's daily.generated_text.md source for prompt ID weather.daily_generated_text.

Boundaries

This package owns embedded asset lookup, Go template parsing, and Markdown template execution. It does not fetch weather data, build module outputs, validate GeneratedText, construct render contexts, choose report definitions, write artifacts, invoke Scriptorium, or notify distributor.

GeneratedText validation is owned by internal/generatedtext. App orchestration uses internal/generatedtext catalog lookup to connect internal/report definition schema/template IDs to the matching validator, render-context builder, and embedded assets.

Template Contracts

Daily, Today, Tomorrow, and Hourly rendering use typed render contexts with:

  • report metadata labels such as title, location, valid period, and generation time
  • validated GeneratedText prose slots
  • deterministic labels derived from module outputs, including current conditions, hourly forecast rows, precipitation timing, alerts, SPC outlooks, forecast discussion, SPC discussion, and weather story

Daily, Today, and Tomorrow additionally expose forecast-date labels, ordered daypart forecast rows, daily/daypart summaries, planning facts, and a multi-paragraph forecast discussion generated-text slot. The ordered daypart slice is built in Go so templates do not range over maps.

The Daily template asset uses the same Markdown structure as Tomorrow's template and renders from generatedtext.DailyRenderContext.

Templates use text/template with missingkey=error, so missing context fields fail rendering instead of producing incomplete Markdown.

Daily and Tomorrow call the shared daypart_forecast partial. Today calls today_daypart_forecast so it can omit elapsed or missing dayparts. Daily, Today, Tomorrow, and Hourly call the shared alert_digest and precipitation_timing partials. Partial files are parsed with each top-level template at render time and receive the same typed render context as the caller. The alert_digest partial renders the combined Alerts and Risk Products section from relevant NWS alerts and curated SPC outlook digest records.

Schema Contract

The GeneratedText schemas describe the structured prose Scriptorium is expected to write for each generated-text prompt. Hourly requires:

  • summary
  • forecast_discussion

Daily, Today, and Tomorrow require summary and a nonempty forecast_discussion array. All generated-text schemas allow optional precipitation_timing and confidence, and reject additional properties. Weather truth remains in module outputs; GeneratedText is limited to prose slots consumed by the template.

Failure Behavior

  • Unknown template IDs return actionable lookup errors.
  • Unknown schema IDs return actionable lookup errors.
  • Template parse errors include the template ID.
  • Partial read or parse errors include the partial path.
  • Template execution errors include the template ID and usually identify the missing context field.

Tests

Inspect:

  • internal/reporttemplate/reporttemplate_test.go
  • internal/generatedtext/render_context_test.go
  • internal/app/app_test.go
  • internal/cli/root_test.go

Invariants

  • Embedded templates and schemas live as separate files, not inline Go strings.
  • Shared Markdown partials live under templates/partials/.
  • Report definitions select templates by ID.
  • Templates render from curated render contexts, not raw data packages.
  • GeneratedText schemas describe LLM prose slots, not deterministic weather facts.