|
1 | 1 | package summary |
2 | 2 |
|
3 | | -import "time" |
| 3 | +import ( |
| 4 | + "encoding/json" |
| 5 | + "time" |
| 6 | +) |
4 | 7 |
|
5 | 8 | // TeamSection represents results from a single agent or validation area. |
6 | 9 | type TeamSection struct { |
@@ -33,7 +36,8 @@ func (t *TeamSection) ComputeStatus() Status { |
33 | 36 | } |
34 | 37 |
|
35 | 38 | // SummaryReport is the top-level report for summary-style evaluations. |
36 | | -// It aggregates results from multiple teams/agents. |
| 39 | +// It aggregates results from multiple teams/agents and can embed full |
| 40 | +// EvaluationReport and ClaimsReport for complete fidelity. |
37 | 41 | type SummaryReport struct { |
38 | 42 | // Schema is the JSON Schema URL for validation. |
39 | 43 | Schema string `json:"$schema,omitempty"` |
@@ -61,6 +65,28 @@ type SummaryReport struct { |
61 | 65 |
|
62 | 66 | // GeneratedBy identifies what created this report. |
63 | 67 | GeneratedBy string `json:"generated_by,omitempty"` |
| 68 | + |
| 69 | + // EmbeddedReports contains full-fidelity embedded reports. |
| 70 | + // This allows the SummaryReport to serve as a container for |
| 71 | + // detailed reports while providing a summary view. |
| 72 | + EmbeddedReports *EmbeddedReports `json:"embeddedReports,omitempty"` |
| 73 | +} |
| 74 | + |
| 75 | +// EmbeddedReports contains full-fidelity embedded reports. |
| 76 | +// Reports are stored as json.RawMessage to avoid circular imports |
| 77 | +// and allow flexible report types. |
| 78 | +type EmbeddedReports struct { |
| 79 | + // Evaluations contains embedded EvaluationReport(s). |
| 80 | + // Key is a report identifier (e.g., "prd-review", "article-quality"). |
| 81 | + Evaluations map[string]json.RawMessage `json:"evaluations,omitempty"` |
| 82 | + |
| 83 | + // Claims contains embedded ClaimsReport(s). |
| 84 | + // Key is a report identifier (e.g., "source-validation"). |
| 85 | + Claims map[string]json.RawMessage `json:"claims,omitempty"` |
| 86 | + |
| 87 | + // Custom contains any other embedded reports. |
| 88 | + // Key is a report identifier, value is the full report JSON. |
| 89 | + Custom map[string]json.RawMessage `json:"custom,omitempty"` |
64 | 90 | } |
65 | 91 |
|
66 | 92 | // ComputeOverallStatus calculates the overall status from all teams. |
@@ -110,3 +136,108 @@ func (r *SummaryReport) AddTeam(team TeamSection) { |
110 | 136 | team.ComputeStatus() |
111 | 137 | r.Teams = append(r.Teams, team) |
112 | 138 | } |
| 139 | + |
| 140 | +// EnsureEmbeddedReports initializes the EmbeddedReports field if nil. |
| 141 | +func (r *SummaryReport) EnsureEmbeddedReports() { |
| 142 | + if r.EmbeddedReports == nil { |
| 143 | + r.EmbeddedReports = &EmbeddedReports{ |
| 144 | + Evaluations: make(map[string]json.RawMessage), |
| 145 | + Claims: make(map[string]json.RawMessage), |
| 146 | + Custom: make(map[string]json.RawMessage), |
| 147 | + } |
| 148 | + } |
| 149 | + if r.EmbeddedReports.Evaluations == nil { |
| 150 | + r.EmbeddedReports.Evaluations = make(map[string]json.RawMessage) |
| 151 | + } |
| 152 | + if r.EmbeddedReports.Claims == nil { |
| 153 | + r.EmbeddedReports.Claims = make(map[string]json.RawMessage) |
| 154 | + } |
| 155 | + if r.EmbeddedReports.Custom == nil { |
| 156 | + r.EmbeddedReports.Custom = make(map[string]json.RawMessage) |
| 157 | + } |
| 158 | +} |
| 159 | + |
| 160 | +// EmbedEvaluationReport embeds an EvaluationReport with the given key. |
| 161 | +// The report is marshaled to JSON for storage. |
| 162 | +func (r *SummaryReport) EmbedEvaluationReport(key string, report any) error { |
| 163 | + r.EnsureEmbeddedReports() |
| 164 | + data, err := json.Marshal(report) |
| 165 | + if err != nil { |
| 166 | + return err |
| 167 | + } |
| 168 | + r.EmbeddedReports.Evaluations[key] = data |
| 169 | + return nil |
| 170 | +} |
| 171 | + |
| 172 | +// EmbedClaimsReport embeds a ClaimsReport with the given key. |
| 173 | +// The report is marshaled to JSON for storage. |
| 174 | +func (r *SummaryReport) EmbedClaimsReport(key string, report any) error { |
| 175 | + r.EnsureEmbeddedReports() |
| 176 | + data, err := json.Marshal(report) |
| 177 | + if err != nil { |
| 178 | + return err |
| 179 | + } |
| 180 | + r.EmbeddedReports.Claims[key] = data |
| 181 | + return nil |
| 182 | +} |
| 183 | + |
| 184 | +// EmbedCustomReport embeds a custom report with the given key. |
| 185 | +// The report is marshaled to JSON for storage. |
| 186 | +func (r *SummaryReport) EmbedCustomReport(key string, report any) error { |
| 187 | + r.EnsureEmbeddedReports() |
| 188 | + data, err := json.Marshal(report) |
| 189 | + if err != nil { |
| 190 | + return err |
| 191 | + } |
| 192 | + r.EmbeddedReports.Custom[key] = data |
| 193 | + return nil |
| 194 | +} |
| 195 | + |
| 196 | +// GetEmbeddedEvaluation retrieves and unmarshals an embedded EvaluationReport. |
| 197 | +// Returns nil if not found. The target should be a pointer to the report struct. |
| 198 | +func (r *SummaryReport) GetEmbeddedEvaluation(key string, target any) error { |
| 199 | + if r.EmbeddedReports == nil || r.EmbeddedReports.Evaluations == nil { |
| 200 | + return nil |
| 201 | + } |
| 202 | + data, ok := r.EmbeddedReports.Evaluations[key] |
| 203 | + if !ok { |
| 204 | + return nil |
| 205 | + } |
| 206 | + return json.Unmarshal(data, target) |
| 207 | +} |
| 208 | + |
| 209 | +// GetEmbeddedClaims retrieves and unmarshals an embedded ClaimsReport. |
| 210 | +// Returns nil if not found. The target should be a pointer to the report struct. |
| 211 | +func (r *SummaryReport) GetEmbeddedClaims(key string, target any) error { |
| 212 | + if r.EmbeddedReports == nil || r.EmbeddedReports.Claims == nil { |
| 213 | + return nil |
| 214 | + } |
| 215 | + data, ok := r.EmbeddedReports.Claims[key] |
| 216 | + if !ok { |
| 217 | + return nil |
| 218 | + } |
| 219 | + return json.Unmarshal(data, target) |
| 220 | +} |
| 221 | + |
| 222 | +// GetEmbeddedCustom retrieves and unmarshals an embedded custom report. |
| 223 | +// Returns nil if not found. The target should be a pointer to the report struct. |
| 224 | +func (r *SummaryReport) GetEmbeddedCustom(key string, target any) error { |
| 225 | + if r.EmbeddedReports == nil || r.EmbeddedReports.Custom == nil { |
| 226 | + return nil |
| 227 | + } |
| 228 | + data, ok := r.EmbeddedReports.Custom[key] |
| 229 | + if !ok { |
| 230 | + return nil |
| 231 | + } |
| 232 | + return json.Unmarshal(data, target) |
| 233 | +} |
| 234 | + |
| 235 | +// HasEmbeddedReports returns true if any embedded reports exist. |
| 236 | +func (r *SummaryReport) HasEmbeddedReports() bool { |
| 237 | + if r.EmbeddedReports == nil { |
| 238 | + return false |
| 239 | + } |
| 240 | + return len(r.EmbeddedReports.Evaluations) > 0 || |
| 241 | + len(r.EmbeddedReports.Claims) > 0 || |
| 242 | + len(r.EmbeddedReports.Custom) > 0 |
| 243 | +} |
0 commit comments