Files
weatherreporter/internal/cli/result.go

171 lines
6.4 KiB
Go

package cli
import (
"time"
"gitea.maximumdirect.net/eric/weatherreporter/internal/app"
"gitea.maximumdirect.net/eric/weatherreporter/internal/report"
"gitea.maximumdirect.net/eric/weatherreporter/internal/timeutil"
)
const (
commandGenerate = "generate"
commandRun = "run"
summaryStatusSucceeded = "succeeded"
summaryStatusFailed = "failed"
)
type generateSummary struct {
Command string `json:"command"`
ReportID report.ID `json:"reportId"`
ReportName string `json:"reportName"`
PromptID string `json:"promptId"`
RunID string `json:"runId"`
Status string `json:"status"`
GeneratedAt time.Time `json:"generatedAt"`
ValidPeriod timeutil.Period `json:"validPeriod"`
ReportPath string `json:"reportPath,omitempty"`
OutputPath string `json:"outputPath,omitempty"`
MetadataPath string `json:"metadataPath,omitempty"`
DataPackagePath string `json:"dataPackagePath,omitempty"`
PreparationPath string `json:"preparationPath,omitempty"`
ExecutionPath string `json:"executionPath,omitempty"`
LLMDebugPath string `json:"llmDebugPath,omitempty"`
GeneratedTextRawPath string `json:"generatedTextRawPath,omitempty"`
GeneratedTextPath string `json:"generatedTextPath,omitempty"`
RenderContextPath string `json:"renderContextPath,omitempty"`
NotificationPath string `json:"notificationPath,omitempty"`
Notification *generateNotificationSummary `json:"notification,omitempty"`
Error string `json:"error,omitempty"`
}
type generateNotificationSummary struct {
Status string `json:"status,omitempty"`
UploadStatus string `json:"uploadStatus,omitempty"`
StatusError string `json:"statusError,omitempty"`
RunID string `json:"runId,omitempty"`
PipelineID string `json:"pipelineId,omitempty"`
BundleID string `json:"bundleId,omitempty"`
IdempotencyKey string `json:"idempotencyKey,omitempty"`
AcceptedAt *time.Time `json:"acceptedAt,omitempty"`
StartedAt *time.Time `json:"startedAt,omitempty"`
FinishedAt *time.Time `json:"finishedAt,omitempty"`
Error string `json:"error,omitempty"`
}
type batchSummary struct {
Command string `json:"command"`
Batch app.BatchKind `json:"batch"`
Status string `json:"status"`
StartedAt time.Time `json:"startedAt"`
FinishedAt time.Time `json:"finishedAt"`
Total int `json:"total"`
Succeeded int `json:"succeeded"`
Failed int `json:"failed"`
Notification *app.BatchNotificationResult `json:"notification,omitempty"`
Reports []app.BatchReportResult `json:"reports"`
Error string `json:"error,omitempty"`
}
func newGenerateSummary(result *app.ReportResult, err error) generateSummary {
summary := generateSummary{Command: commandGenerate}
if result == nil {
return summary
}
metadata := result.Metadata
summary.ReportID = metadata.ReportID
summary.ReportName = reportName(metadata.ReportID)
summary.PromptID = metadata.PromptID
summary.RunID = metadata.RunID
summary.Status = summaryStatusSucceeded
summary.GeneratedAt = metadata.GeneratedAt
summary.ValidPeriod = metadata.ValidPeriod
summary.ReportPath = result.ReportPath
summary.OutputPath = result.OutputPath
summary.MetadataPath = result.MetadataPath
summary.DataPackagePath = result.DataPackagePath
summary.PreparationPath = result.PreparationPath
if summary.PreparationPath == "" {
summary.PreparationPath = result.PreflightPath
}
summary.ExecutionPath = result.ExecutionPath
if summary.ExecutionPath == "" {
summary.ExecutionPath = result.Metadata.GeneratedTextResultPath
}
summary.LLMDebugPath = result.LLMDebugPath
summary.GeneratedTextRawPath = result.GeneratedTextRawPath
summary.GeneratedTextPath = result.GeneratedTextPath
summary.RenderContextPath = result.RenderContextPath
summary.NotificationPath = result.NotificationPath
summary.Notification = newGenerateNotificationSummary(result.Notification)
if err != nil {
summary.Status = summaryStatusFailed
summary.Error = err.Error()
}
return summary
}
func newGenerateNotificationSummary(result *app.NotificationResult) *generateNotificationSummary {
if result == nil {
return nil
}
summary := &generateNotificationSummary{
Status: result.Status,
UploadStatus: result.UploadStatus,
StatusError: result.StatusError,
RunID: result.RunID,
PipelineID: result.PipelineID,
BundleID: result.BundleID,
IdempotencyKey: result.IdempotencyKey,
StartedAt: result.StartedAt,
FinishedAt: result.FinishedAt,
Error: result.Error,
}
if !result.AcceptedAt.IsZero() {
acceptedAt := result.AcceptedAt
summary.AcceptedAt = &acceptedAt
}
return summary
}
func newBatchSummary(result *app.BatchResult) batchSummary {
summary := batchSummary{Command: commandRun}
if result == nil {
return summary
}
summary.Batch = result.Batch
summary.Status = batchSummaryStatus(result)
summary.StartedAt = result.StartedAt
summary.FinishedAt = result.FinishedAt
summary.Total = result.Total
summary.Succeeded = result.Succeeded
summary.Failed = result.Failed
summary.Notification = result.Notification
summary.Reports = append([]app.BatchReportResult(nil), result.Reports...)
if summary.Status == summaryStatusFailed {
summary.Error = app.BatchError{Result: result}.Error()
}
return summary
}
func batchSummaryStatus(result *app.BatchResult) string {
if result == nil {
return ""
}
if result.Failed > 0 || (result.Notification != nil && result.Notification.Status == summaryStatusFailed) {
return summaryStatusFailed
}
return summaryStatusSucceeded
}
func reportName(id report.ID) string {
definition, err := report.DefaultRegistry().Lookup(id)
if err != nil {
return string(id)
}
return definition.Name
}