Rename rolling report to hourly

This commit is contained in:
2026-06-14 04:26:05 +00:00
parent b3f7c9c1f2
commit 8d737395dc
28 changed files with 220 additions and 600 deletions

View File

@@ -14,7 +14,7 @@ type ID string
const (
DailyToday ID = "daily_today"
DailyTomorrow ID = "daily_tomorrow"
NearTerm ID = "near_term"
Hourly ID = "hourly"
ThreeDay ID = "three_day"
Weekend ID = "weekend"
Storm ID = "storm"

View File

@@ -7,24 +7,24 @@ import (
"gitea.maximumdirect.net/eric/weatherreporter/internal/timeutil"
)
const nearTermHours = 6
const hourlyHours = 6
func nearTermDefinition() Definition {
func hourlyDefinition() Definition {
return Definition{
ID: NearTerm,
Name: "Near-Term Report",
PromptID: "weather.near_term_report",
ID: Hourly,
Name: "Hourly Report",
PromptID: "weather.hourly_report",
ComparisonStrategy: CompareRollingWindow,
ArtifactGroup: "near-term",
BatchOutputName: "near-term.md",
ArtifactGroup: "hourly",
BatchOutputName: "hourly.md",
Generated: true,
CompatiblePriorIDs: []ID{NearTerm},
Modules: nearTermModules(),
resolve: resolveNearTerm,
CompatiblePriorIDs: []ID{Hourly},
Modules: hourlyModules(),
resolve: resolveHourly,
}
}
func nearTermModules() []module.ConfigItem {
func hourlyModules() []module.ConfigItem {
return []module.ConfigItem{
{ID: module.Metadata},
{ID: module.CurrentConditions},
@@ -43,10 +43,10 @@ func nearTermModules() []module.ConfigItem {
}
}
func resolveNearTerm(req ResolveRequest) (timeutil.Period, error) {
func resolveHourly(req ResolveRequest) (timeutil.Period, error) {
localNow := req.Now.In(req.Location)
return timeutil.Period{
Start: localNow,
End: localNow.Add(nearTermHours * time.Hour),
End: localNow.Add(hourlyHours * time.Hour),
}, nil
}

View File

@@ -58,19 +58,19 @@ func TestThreeDayPeriodCalculation(t *testing.T) {
assertPeriod(t, resolved.ValidPeriod, "2026-05-29T05:00:00-05:00", "2026-06-01T00:00:00-05:00")
}
func TestNearTermLookupAndPeriodCalculation(t *testing.T) {
func TestHourlyLookupAndPeriodCalculation(t *testing.T) {
location := mustLoadLocation(t)
now := mustParse("2026-05-29T05:15:00-05:00")
resolved, err := Resolve(NearTerm, ResolveRequest{Now: now, Location: location})
resolved, err := Resolve(Hourly, ResolveRequest{Now: now, Location: location})
if err != nil {
t.Fatalf("Resolve() error = %v", err)
}
if resolved.Definition.ID != NearTerm {
t.Fatalf("ID = %q, want near_term", resolved.Definition.ID)
if resolved.Definition.ID != Hourly {
t.Fatalf("ID = %q, want hourly", resolved.Definition.ID)
}
if resolved.Definition.PromptID != "weather.near_term_report" {
t.Fatalf("PromptID = %q, want weather.near_term_report", resolved.Definition.PromptID)
if resolved.Definition.PromptID != "weather.hourly_report" {
t.Fatalf("PromptID = %q, want weather.hourly_report", resolved.Definition.PromptID)
}
if resolved.Definition.ComparisonStrategy != CompareRollingWindow {
t.Fatalf("ComparisonStrategy = %q, want rolling_window", resolved.Definition.ComparisonStrategy)
@@ -78,25 +78,25 @@ func TestNearTermLookupAndPeriodCalculation(t *testing.T) {
assertPeriod(t, resolved.ValidPeriod, "2026-05-29T05:15:00-05:00", "2026-05-29T11:15:00-05:00")
}
func TestNearTermPeriodUsesEffectiveTimezone(t *testing.T) {
func TestHourlyPeriodUsesEffectiveTimezone(t *testing.T) {
location, err := time.LoadLocation("America/New_York")
if err != nil {
t.Fatalf("load location: %v", err)
}
now := mustParse("2026-05-29T10:15:00Z")
resolved, err := Resolve(NearTerm, ResolveRequest{Now: now, Location: location})
resolved, err := Resolve(Hourly, ResolveRequest{Now: now, Location: location})
if err != nil {
t.Fatalf("Resolve() error = %v", err)
}
assertPeriod(t, resolved.ValidPeriod, "2026-05-29T06:15:00-04:00", "2026-05-29T12:15:00-04:00")
}
func TestNearTermPeriodIsNotCivilDayTruncated(t *testing.T) {
func TestHourlyPeriodIsNotCivilDayTruncated(t *testing.T) {
location := mustLoadLocation(t)
now := mustParse("2026-05-29T22:30:00-05:00")
resolved, err := Resolve(NearTerm, ResolveRequest{Now: now, Location: location})
resolved, err := Resolve(Hourly, ResolveRequest{Now: now, Location: location})
if err != nil {
t.Fatalf("Resolve() error = %v", err)
}
@@ -203,7 +203,7 @@ func TestEveningBatchIncludesTomorrow(t *testing.T) {
}
}
func TestBatchesDoNotIncludeNearTerm(t *testing.T) {
func TestBatchesDoNotIncludeHourly(t *testing.T) {
location := mustLoadLocation(t)
req := ResolveRequest{Now: mustParse("2026-05-29T06:00:00-05:00"), Location: location}
@@ -216,8 +216,8 @@ func TestBatchesDoNotIncludeNearTerm(t *testing.T) {
t.Fatalf("BatchReports(evening) error = %v", err)
}
for _, resolved := range append(morning, evening...) {
if resolved.Definition.ID == NearTerm {
t.Fatalf("batch included %q, want near-term excluded", resolved.Definition.ID)
if resolved.Definition.ID == Hourly {
t.Fatalf("batch included %q, want hourly excluded", resolved.Definition.ID)
}
}
}
@@ -232,9 +232,9 @@ func TestRegistryLookupErrorIsActionable(t *testing.T) {
}
}
func TestRegistryAllIncludesNearTermInStableOrder(t *testing.T) {
func TestRegistryAllIncludesHourlyInStableOrder(t *testing.T) {
ids := resolvedDefinitionIDs(DefaultRegistry().All())
want := []string{"daily_today", "daily_tomorrow", "near_term", "three_day", "weekend", "storm"}
want := []string{"daily_today", "daily_tomorrow", "hourly", "three_day", "weekend", "storm"}
if strings.Join(ids, ",") != strings.Join(want, ",") {
t.Fatalf("All() ids = %#v, want %#v", ids, want)
}
@@ -277,11 +277,11 @@ func TestRegistryDefinitionsDeclarePathAndCompatibilityPolicy(t *testing.T) {
comparisonStrategy: CompareSameValidDate,
},
{
id: NearTerm,
artifactGroup: "near-term",
batchOutputName: "near-term.md",
id: Hourly,
artifactGroup: "hourly",
batchOutputName: "hourly.md",
generated: true,
compatiblePriorIDs: []ID{NearTerm},
compatiblePriorIDs: []ID{Hourly},
comparisonStrategy: CompareRollingWindow,
},
{
@@ -384,7 +384,7 @@ func TestRegistryDefinitionsDeclareDefaultModules(t *testing.T) {
},
},
{
id: NearTerm,
id: Hourly,
want: []module.ID{
module.Metadata,
module.CurrentConditions,
@@ -515,20 +515,20 @@ func TestResolvedMetadata(t *testing.T) {
}
}
func TestNearTermMetadataRunIDIncludesReportID(t *testing.T) {
func TestHourlyMetadataRunIDIncludesReportID(t *testing.T) {
location := mustLoadLocation(t)
resolved, err := Resolve(NearTerm, ResolveRequest{Now: mustParse("2026-05-29T05:15:00-05:00"), Location: location})
resolved, err := Resolve(Hourly, ResolveRequest{Now: mustParse("2026-05-29T05:15:00-05:00"), Location: location})
if err != nil {
t.Fatalf("Resolve() error = %v", err)
}
metadata := resolved.Metadata()
if metadata.ReportID != NearTerm {
t.Fatalf("ReportID = %q, want near_term", metadata.ReportID)
if metadata.ReportID != Hourly {
t.Fatalf("ReportID = %q, want hourly", metadata.ReportID)
}
if metadata.PromptID != "weather.near_term_report" {
t.Fatalf("PromptID = %q, want weather.near_term_report", metadata.PromptID)
if metadata.PromptID != "weather.hourly_report" {
t.Fatalf("PromptID = %q, want weather.hourly_report", metadata.PromptID)
}
if !strings.Contains(metadata.RunID, "near_term") {
if !strings.Contains(metadata.RunID, "hourly") {
t.Fatalf("RunID = %q, want report id", metadata.RunID)
}
}

View File

@@ -14,7 +14,7 @@ func DefaultRegistry() Registry {
definitions := []Definition{
dailyTodayDefinition(),
dailyTomorrowDefinition(),
nearTermDefinition(),
hourlyDefinition(),
threeDayDefinition(),
weekendDefinition(),
stormDefinition(),
@@ -74,7 +74,7 @@ func (r Registry) MustLookup(id ID) Definition {
}
func (r Registry) All() []Definition {
ids := []ID{DailyToday, DailyTomorrow, NearTerm, ThreeDay, Weekend, Storm}
ids := []ID{DailyToday, DailyTomorrow, Hourly, ThreeDay, Weekend, Storm}
out := make([]Definition, 0, len(ids))
for _, id := range ids {
if definition, ok := r.definitions[id]; ok {