From 32ced351309a8b487f844d9e0b5f8ac49f17b625 Mon Sep 17 00:00:00 2001 From: Nathan Coad Date: Thu, 29 Jan 2026 12:27:08 +1100 Subject: [PATCH] more metadata in reports --- internal/report/snapshots.go | 110 +++++++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 4 deletions(-) diff --git a/internal/report/snapshots.go b/internal/report/snapshots.go index 13d05c4..6a62b3a 100644 --- a/internal/report/snapshots.go +++ b/internal/report/snapshots.go @@ -6,6 +6,7 @@ import ( "database/sql" "fmt" "log/slog" + "math" "os" "path/filepath" "sort" @@ -748,7 +749,20 @@ func CreateTableReport(logger *slog.Logger, Database db.Database, ctx context.Co } if isDailySummary || isMonthlySummary { - addReportMetadataSheet(logger, xlsx) + meta := reportMetadata{ + TableName: tableName, + ReportType: reportTypeFromTable(tableName), + GeneratedAt: time.Now(), + Duration: time.Since(start), + RowCount: rowCount, + ColumnCount: len(columns), + DBDriver: Database.DB().DriverName(), + } + if windowStart, windowEnd, ok := reportWindowFromTable(tableName); ok { + meta.WindowStart = &windowStart + meta.WindowEnd = &windowEnd + } + addReportMetadataSheet(logger, xlsx, meta) } addTotalsChartSheet(logger, Database, ctx, xlsx, tableName) @@ -1057,14 +1071,102 @@ func summaryReportOrder() []string { } } -func addReportMetadataSheet(logger *slog.Logger, xlsx *excelize.File) { +type reportMetadata struct { + TableName string + ReportType string + GeneratedAt time.Time + Duration time.Duration + RowCount int + ColumnCount int + WindowStart *time.Time + WindowEnd *time.Time + DBDriver string +} + +func reportTypeFromTable(tableName string) string { + switch { + case strings.HasPrefix(tableName, "inventory_daily_summary_"): + return "daily" + case strings.HasPrefix(tableName, "inventory_monthly_summary_"): + return "monthly" + default: + return "unknown" + } +} + +func reportWindowFromTable(tableName string) (time.Time, time.Time, bool) { + if strings.HasPrefix(tableName, "inventory_daily_summary_") { + suffix := strings.TrimPrefix(tableName, "inventory_daily_summary_") + dayStart, err := time.ParseInLocation("20060102", suffix, time.Local) + if err != nil { + return time.Time{}, time.Time{}, false + } + return dayStart, dayStart.AddDate(0, 0, 1), true + } + if strings.HasPrefix(tableName, "inventory_monthly_summary_") { + suffix := strings.TrimPrefix(tableName, "inventory_monthly_summary_") + monthStart, err := time.ParseInLocation("200601", suffix, time.Local) + if err != nil { + return time.Time{}, time.Time{}, false + } + return monthStart, monthStart.AddDate(0, 1, 0), true + } + return time.Time{}, time.Time{}, false +} + +func addReportMetadataSheet(logger *slog.Logger, xlsx *excelize.File, meta reportMetadata) { sheetName := "Metadata" if _, err := xlsx.NewSheet(sheetName); err != nil { logger.Error("Error creating metadata sheet", "error", err) return } - xlsx.SetCellValue(sheetName, "A1", "ReportGeneratedAt") - xlsx.SetCellValue(sheetName, "B1", time.Now().Format(time.RFC3339)) + rows := []struct { + key string + value interface{} + }{ + {"ReportTable", meta.TableName}, + {"ReportType", meta.ReportType}, + {"ReportGeneratedAt", meta.GeneratedAt.Format(time.RFC3339)}, + {"ReportGeneratedAtUTC", meta.GeneratedAt.UTC().Format(time.RFC3339)}, + {"ReportDuration", meta.Duration.String()}, + {"ReportDurationSeconds", math.Round(meta.Duration.Seconds()*1000) / 1000}, + {"RowCount", meta.RowCount}, + {"ColumnCount", meta.ColumnCount}, + } + if meta.WindowStart != nil && meta.WindowEnd != nil { + rows = append(rows, + struct { + key string + value interface{} + }{"DataWindowStart", meta.WindowStart.Format(time.RFC3339)}, + struct { + key string + value interface{} + }{"DataWindowEnd", meta.WindowEnd.Format(time.RFC3339)}, + struct { + key string + value interface{} + }{"DataWindowTimezone", time.Local.String()}, + ) + } + if meta.DBDriver != "" { + rows = append(rows, struct { + key string + value interface{} + }{"DatabaseDriver", meta.DBDriver}) + } + if meta.Duration > 0 && meta.RowCount > 0 { + rows = append(rows, struct { + key string + value interface{} + }{"RowsPerSecond", math.Round((float64(meta.RowCount)/meta.Duration.Seconds())*1000) / 1000}) + } + for i, row := range rows { + cellKey := fmt.Sprintf("A%d", i+1) + cellVal := fmt.Sprintf("B%d", i+1) + xlsx.SetCellValue(sheetName, cellKey, row.key) + xlsx.SetCellValue(sheetName, cellVal, row.value) + } if err := SetColAutoWidth(xlsx, sheetName); err != nil { logger.Error("Error setting metadata auto width", "error", err) }