Route report projections through prepared identity
This commit is contained in:
@@ -25,7 +25,7 @@ const (
|
||||
|
||||
type validator func([]byte) (any, []byte, error)
|
||||
|
||||
type renderContextBuilder func(report.ID, string, briefing.Metadata, module.Snapshot, facts.CollectedFacts, facts.DerivedFacts, any) (any, error)
|
||||
type renderContextBuilder func(report.ID, string, briefing.PreparedIdentity, module.Snapshot, facts.CollectedFacts, facts.DerivedFacts, any) (any, error)
|
||||
|
||||
type catalogEntry struct {
|
||||
reportID report.ID
|
||||
@@ -140,11 +140,11 @@ func (h Handler) Validate(data []byte) (any, []byte, error) {
|
||||
return h.validate(data)
|
||||
}
|
||||
|
||||
func (h Handler) BuildRenderContext(metadata briefing.Metadata, snapshot module.Snapshot, collected facts.CollectedFacts, derived facts.DerivedFacts, generated any) (any, error) {
|
||||
func (h Handler) BuildRenderContext(identity briefing.PreparedIdentity, snapshot module.Snapshot, collected facts.CollectedFacts, derived facts.DerivedFacts, generated any) (any, error) {
|
||||
if h.renderContextBuilder == nil {
|
||||
return nil, fmt.Errorf("render-context builder is not registered for template %q on report %q", h.templateID, h.reportID)
|
||||
}
|
||||
return h.renderContextBuilder(h.reportID, h.templateID, metadata, snapshot, collected, derived, generated)
|
||||
return h.renderContextBuilder(h.reportID, h.templateID, identity, snapshot, collected, derived, generated)
|
||||
}
|
||||
|
||||
func (h Handler) Render(data any) ([]byte, error) {
|
||||
@@ -171,34 +171,34 @@ func validateTomorrow(data []byte) (any, []byte, error) {
|
||||
return ValidateTomorrow(data)
|
||||
}
|
||||
|
||||
func buildHourlyContext(reportID report.ID, templateID string, metadata briefing.Metadata, snapshot module.Snapshot, collected facts.CollectedFacts, derived facts.DerivedFacts, generated any) (any, error) {
|
||||
func buildHourlyContext(reportID report.ID, templateID string, identity briefing.PreparedIdentity, snapshot module.Snapshot, collected facts.CollectedFacts, derived facts.DerivedFacts, generated any) (any, error) {
|
||||
hourly, ok := generated.(Hourly)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("report template %q requires hourly generated text for report %q", templateID, reportID)
|
||||
}
|
||||
return BuildHourlyRenderContext(metadata, snapshot, hourly, collected, derived)
|
||||
return BuildHourlyRenderContext(identity, snapshot, hourly, collected, derived)
|
||||
}
|
||||
|
||||
func buildDailyContext(reportID report.ID, templateID string, metadata briefing.Metadata, snapshot module.Snapshot, collected facts.CollectedFacts, derived facts.DerivedFacts, generated any) (any, error) {
|
||||
func buildDailyContext(reportID report.ID, templateID string, identity briefing.PreparedIdentity, snapshot module.Snapshot, collected facts.CollectedFacts, derived facts.DerivedFacts, generated any) (any, error) {
|
||||
daily, ok := generated.(Daily)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("report template %q requires daily generated text for report %q", templateID, reportID)
|
||||
}
|
||||
return BuildDailyRenderContext(metadata, snapshot, daily, collected, derived)
|
||||
return BuildDailyRenderContext(identity, snapshot, daily, collected, derived)
|
||||
}
|
||||
|
||||
func buildTodayContext(reportID report.ID, templateID string, metadata briefing.Metadata, snapshot module.Snapshot, collected facts.CollectedFacts, derived facts.DerivedFacts, generated any) (any, error) {
|
||||
func buildTodayContext(reportID report.ID, templateID string, identity briefing.PreparedIdentity, snapshot module.Snapshot, collected facts.CollectedFacts, derived facts.DerivedFacts, generated any) (any, error) {
|
||||
today, ok := generated.(Today)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("report template %q requires today generated text for report %q", templateID, reportID)
|
||||
}
|
||||
return BuildTodayRenderContext(metadata, snapshot, today, collected, derived)
|
||||
return BuildTodayRenderContext(identity, snapshot, today, collected, derived)
|
||||
}
|
||||
|
||||
func buildTomorrowContext(reportID report.ID, templateID string, metadata briefing.Metadata, snapshot module.Snapshot, collected facts.CollectedFacts, derived facts.DerivedFacts, generated any) (any, error) {
|
||||
func buildTomorrowContext(reportID report.ID, templateID string, identity briefing.PreparedIdentity, snapshot module.Snapshot, collected facts.CollectedFacts, derived facts.DerivedFacts, generated any) (any, error) {
|
||||
tomorrow, ok := generated.(Tomorrow)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("report template %q requires tomorrow generated text for report %q", templateID, reportID)
|
||||
}
|
||||
return BuildTomorrowRenderContext(metadata, snapshot, tomorrow, collected, derived)
|
||||
return BuildTomorrowRenderContext(identity, snapshot, tomorrow, collected, derived)
|
||||
}
|
||||
|
||||
@@ -188,15 +188,15 @@ type dayStyleTemplateModules struct {
|
||||
WeatherStory *briefing.WeatherStoryModule
|
||||
}
|
||||
|
||||
func BuildHourlyRenderContext(metadata briefing.Metadata, snapshot module.Snapshot, generated Hourly, collected facts.CollectedFacts, derived facts.DerivedFacts) (HourlyRenderContext, error) {
|
||||
location, err := timeutil.LoadLocation(metadata.Timezone)
|
||||
func BuildHourlyRenderContext(identity briefing.PreparedIdentity, snapshot module.Snapshot, generated Hourly, collected facts.CollectedFacts, derived facts.DerivedFacts) (HourlyRenderContext, error) {
|
||||
location, err := timeutil.LoadLocation(identity.Timezone)
|
||||
if err != nil {
|
||||
return HourlyRenderContext{}, fmt.Errorf("build hourly render context: %w", err)
|
||||
}
|
||||
if metadata.GeneratedAt.IsZero() {
|
||||
if identity.GeneratedAt.IsZero() {
|
||||
return HourlyRenderContext{}, fmt.Errorf("build hourly render context: generatedAt is required")
|
||||
}
|
||||
if !metadata.ValidPeriod.IsValid() {
|
||||
if !identity.ValidPeriod.IsValid() {
|
||||
return HourlyRenderContext{}, fmt.Errorf("build hourly render context: valid period is required")
|
||||
}
|
||||
modules, err := hourlyTemplateModules(snapshot)
|
||||
@@ -206,12 +206,12 @@ func BuildHourlyRenderContext(metadata briefing.Metadata, snapshot module.Snapsh
|
||||
return HourlyRenderContext{
|
||||
Report: HourlyReportContext{
|
||||
Title: "Hourly Report",
|
||||
LocationName: locationName(metadata),
|
||||
GeneratedAt: metadata.GeneratedAt,
|
||||
GeneratedAtLabel: generatedAtLabel(metadata.GeneratedAt, location),
|
||||
ValidPeriod: metadata.ValidPeriod,
|
||||
ValidPeriodLabel: periodLabel(metadata.ValidPeriod, location),
|
||||
Timezone: metadata.Timezone,
|
||||
LocationName: locationName(identity),
|
||||
GeneratedAt: identity.GeneratedAt,
|
||||
GeneratedAtLabel: generatedAtLabel(identity.GeneratedAt, location),
|
||||
ValidPeriod: identity.ValidPeriod,
|
||||
ValidPeriodLabel: periodLabel(identity.ValidPeriod, location),
|
||||
Timezone: identity.Timezone,
|
||||
},
|
||||
GeneratedText: generated,
|
||||
Modules: modules,
|
||||
@@ -220,8 +220,8 @@ func BuildHourlyRenderContext(metadata briefing.Metadata, snapshot module.Snapsh
|
||||
}, nil
|
||||
}
|
||||
|
||||
func BuildDailyRenderContext(metadata briefing.Metadata, snapshot module.Snapshot, generated Daily, collected facts.CollectedFacts, derived facts.DerivedFacts) (DailyRenderContext, error) {
|
||||
reportContext, err := buildDayStyleReportContext(metadata, "daily", func(dayName string) string {
|
||||
func BuildDailyRenderContext(identity briefing.PreparedIdentity, snapshot module.Snapshot, generated Daily, collected facts.CollectedFacts, derived facts.DerivedFacts) (DailyRenderContext, error) {
|
||||
reportContext, err := buildDayStyleReportContext(identity, "daily", func(dayName string) string {
|
||||
return dayName + "'s Weather"
|
||||
})
|
||||
if err != nil {
|
||||
@@ -240,8 +240,8 @@ func BuildDailyRenderContext(metadata briefing.Metadata, snapshot module.Snapsho
|
||||
}, nil
|
||||
}
|
||||
|
||||
func BuildTodayRenderContext(metadata briefing.Metadata, snapshot module.Snapshot, generated Today, collected facts.CollectedFacts, derived facts.DerivedFacts) (TodayRenderContext, error) {
|
||||
reportContext, err := buildDayStyleReportContext(metadata, "today", func(string) string {
|
||||
func BuildTodayRenderContext(identity briefing.PreparedIdentity, snapshot module.Snapshot, generated Today, collected facts.CollectedFacts, derived facts.DerivedFacts) (TodayRenderContext, error) {
|
||||
reportContext, err := buildDayStyleReportContext(identity, "today", func(string) string {
|
||||
return "Today's Weather"
|
||||
})
|
||||
if err != nil {
|
||||
@@ -260,8 +260,8 @@ func BuildTodayRenderContext(metadata briefing.Metadata, snapshot module.Snapsho
|
||||
}, nil
|
||||
}
|
||||
|
||||
func BuildTomorrowRenderContext(metadata briefing.Metadata, snapshot module.Snapshot, generated Tomorrow, collected facts.CollectedFacts, derived facts.DerivedFacts) (TomorrowRenderContext, error) {
|
||||
reportContext, err := buildDayStyleReportContext(metadata, "tomorrow", func(dayName string) string {
|
||||
func BuildTomorrowRenderContext(identity briefing.PreparedIdentity, snapshot module.Snapshot, generated Tomorrow, collected facts.CollectedFacts, derived facts.DerivedFacts) (TomorrowRenderContext, error) {
|
||||
reportContext, err := buildDayStyleReportContext(identity, "tomorrow", func(dayName string) string {
|
||||
return dayName + "'s Weather"
|
||||
})
|
||||
if err != nil {
|
||||
@@ -280,29 +280,29 @@ func BuildTomorrowRenderContext(metadata briefing.Metadata, snapshot module.Snap
|
||||
}, nil
|
||||
}
|
||||
|
||||
func buildDayStyleReportContext(metadata briefing.Metadata, name string, title func(string) string) (dayStyleReportContext, error) {
|
||||
location, err := timeutil.LoadLocation(metadata.Timezone)
|
||||
func buildDayStyleReportContext(identity briefing.PreparedIdentity, name string, title func(string) string) (dayStyleReportContext, error) {
|
||||
location, err := timeutil.LoadLocation(identity.Timezone)
|
||||
if err != nil {
|
||||
return dayStyleReportContext{}, fmt.Errorf("build %s render context: %w", name, err)
|
||||
}
|
||||
if metadata.GeneratedAt.IsZero() {
|
||||
if identity.GeneratedAt.IsZero() {
|
||||
return dayStyleReportContext{}, fmt.Errorf("build %s render context: generatedAt is required", name)
|
||||
}
|
||||
if !metadata.ValidPeriod.IsValid() {
|
||||
if !identity.ValidPeriod.IsValid() {
|
||||
return dayStyleReportContext{}, fmt.Errorf("build %s render context: valid period is required", name)
|
||||
}
|
||||
|
||||
forecastDate := metadata.ValidPeriod.Start.In(location)
|
||||
forecastDate := identity.ValidPeriod.Start.In(location)
|
||||
forecastDayName := forecastDate.Format("Monday")
|
||||
return dayStyleReportContext{
|
||||
Title: title(forecastDayName),
|
||||
ForecastDate: forecastDate,
|
||||
ForecastDateLabel: forecastDate.Format("Monday, January 2, 2006"),
|
||||
ForecastDayName: forecastDayName,
|
||||
GeneratedAt: metadata.GeneratedAt,
|
||||
GeneratedAtLabel: generatedAtLabel(metadata.GeneratedAt, location),
|
||||
ValidPeriod: metadata.ValidPeriod,
|
||||
Timezone: metadata.Timezone,
|
||||
GeneratedAt: identity.GeneratedAt,
|
||||
GeneratedAtLabel: generatedAtLabel(identity.GeneratedAt, location),
|
||||
ValidPeriod: identity.ValidPeriod,
|
||||
Timezone: identity.Timezone,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -706,20 +706,20 @@ func daypartModuleKeyCandidates(daypart forecast.DaypartSummary) []string {
|
||||
return []string{key, daypart.Period.Start.Format(timeutil.DateLayout) + "_" + key}
|
||||
}
|
||||
|
||||
func locationName(metadata briefing.Metadata) string {
|
||||
if metadata.Location != nil {
|
||||
if metadata.Location.Name != "" && metadata.Location.Region != "" {
|
||||
return metadata.Location.Name + ", " + metadata.Location.Region
|
||||
func locationName(identity briefing.PreparedIdentity) string {
|
||||
if identity.Location != nil {
|
||||
if identity.Location.Name != "" && identity.Location.Region != "" {
|
||||
return identity.Location.Name + ", " + identity.Location.Region
|
||||
}
|
||||
if metadata.Location.Name != "" {
|
||||
return metadata.Location.Name
|
||||
if identity.Location.Name != "" {
|
||||
return identity.Location.Name
|
||||
}
|
||||
}
|
||||
if metadata.SourceLocation != "" {
|
||||
return metadata.SourceLocation
|
||||
if identity.SourceLocation != "" {
|
||||
return identity.SourceLocation
|
||||
}
|
||||
if metadata.SourceLocationID != "" {
|
||||
return metadata.SourceLocationID
|
||||
if identity.SourceLocationID != "" {
|
||||
return identity.SourceLocationID
|
||||
}
|
||||
return "Unknown location"
|
||||
}
|
||||
|
||||
@@ -741,9 +741,9 @@ func TestBuildTomorrowRenderContextAllowsOmittedOptionalModules(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testMetadata() briefing.Metadata {
|
||||
func testMetadata() briefing.PreparedIdentity {
|
||||
generatedAt := time.Date(2026, 5, 29, 13, 30, 0, 0, time.UTC)
|
||||
return briefing.Metadata{
|
||||
return briefing.PreparedIdentity{
|
||||
RunID: "run-1",
|
||||
ReportID: report.Hourly,
|
||||
PromptID: "weather.hourly_generated_text",
|
||||
@@ -761,9 +761,9 @@ func testMetadata() briefing.Metadata {
|
||||
}
|
||||
}
|
||||
|
||||
func testTomorrowMetadata() briefing.Metadata {
|
||||
func testTomorrowMetadata() briefing.PreparedIdentity {
|
||||
generatedAt := time.Date(2026, 6, 14, 14, 14, 0, 0, time.UTC)
|
||||
return briefing.Metadata{
|
||||
return briefing.PreparedIdentity{
|
||||
RunID: "run-tomorrow",
|
||||
ReportID: report.Tomorrow,
|
||||
PromptID: "weather.tomorrow_generated_text",
|
||||
@@ -781,9 +781,9 @@ func testTomorrowMetadata() briefing.Metadata {
|
||||
}
|
||||
}
|
||||
|
||||
func testDailyMetadata() briefing.Metadata {
|
||||
func testDailyMetadata() briefing.PreparedIdentity {
|
||||
generatedAt := time.Date(2026, 6, 13, 14, 14, 0, 0, time.UTC)
|
||||
return briefing.Metadata{
|
||||
return briefing.PreparedIdentity{
|
||||
RunID: "run-daily",
|
||||
ReportID: report.Daily,
|
||||
PromptID: "weather.daily_generated_text",
|
||||
@@ -801,9 +801,9 @@ func testDailyMetadata() briefing.Metadata {
|
||||
}
|
||||
}
|
||||
|
||||
func testTodayMetadata() briefing.Metadata {
|
||||
func testTodayMetadata() briefing.PreparedIdentity {
|
||||
generatedAt := time.Date(2026, 6, 15, 12, 14, 0, 0, time.UTC)
|
||||
return briefing.Metadata{
|
||||
return briefing.PreparedIdentity{
|
||||
RunID: "run-today",
|
||||
ReportID: report.Today,
|
||||
PromptID: "weather.today_generated_text",
|
||||
|
||||
Reference in New Issue
Block a user