159 lines
6.1 KiB
Go
159 lines
6.1 KiB
Go
package processreport
|
|
|
|
import (
|
|
"time"
|
|
|
|
"gitea.maximumdirect.net/eric/audita/internal/core/chunking"
|
|
"gitea.maximumdirect.net/eric/audita/internal/core/diagnostics"
|
|
"gitea.maximumdirect.net/eric/audita/internal/core/normalization"
|
|
"gitea.maximumdirect.net/eric/audita/internal/core/reporting"
|
|
"gitea.maximumdirect.net/eric/audita/internal/framework/runner"
|
|
stagewarnings "gitea.maximumdirect.net/eric/audita/internal/framework/warnings"
|
|
)
|
|
|
|
// BuildInput contains already-computed process execution facts for report assembly.
|
|
type BuildInput struct {
|
|
Status string
|
|
TranscriptPath string
|
|
GlossaryPath string
|
|
OutputPath string
|
|
Modules []string
|
|
OutputSchema string
|
|
ConfigVersion *int
|
|
StartedAt time.Time
|
|
CompletedAt time.Time
|
|
ErrorMessage string
|
|
ErrorPhase string
|
|
RunDirectoryPath string
|
|
NormalizationSummary *normalization.NormalizationSummary
|
|
ChunkingSummary *chunking.Summary
|
|
RunOutput *runner.RunOutput
|
|
}
|
|
|
|
// Build creates the public process report without owning command parsing or config loading.
|
|
func Build(input BuildInput) reporting.ProcessReport {
|
|
report := reporting.ProcessReport{
|
|
ReportMetadata: reporting.ReportMetadata{
|
|
ReportSchemaName: reporting.DefaultProcessReportSchemaName,
|
|
ReportSchemaVersion: reporting.DefaultProcessReportSchemaVersion,
|
|
OutputSchema: input.OutputSchema,
|
|
ConfigVersion: input.ConfigVersion,
|
|
},
|
|
Phase: "default_pipeline",
|
|
Status: input.Status,
|
|
Operation: "process",
|
|
TranscriptPath: input.TranscriptPath,
|
|
GlossaryPath: input.GlossaryPath,
|
|
OutputPath: input.OutputPath,
|
|
Modules: append([]string(nil), input.Modules...),
|
|
StartedAt: input.StartedAt,
|
|
CompletedAt: &input.CompletedAt,
|
|
ErrorPhase: input.ErrorPhase,
|
|
}
|
|
if input.RunDirectoryPath != "" {
|
|
runSucceeded := input.Status == "success"
|
|
metadata := diagnostics.BuildDiagnosticsMetadata(input.RunDirectoryPath, runSucceeded)
|
|
report.Diagnostics = &metadata
|
|
}
|
|
if input.ErrorMessage != "" {
|
|
report.ErrorMessage = input.ErrorMessage
|
|
}
|
|
if input.NormalizationSummary != nil {
|
|
report.InputSegmentCount = &input.NormalizationSummary.InputSegmentCount
|
|
report.NormalizedSegmentCount = &input.NormalizationSummary.OutputSegmentCount
|
|
report.NormalizationMerges = &input.NormalizationSummary.MergesPerformed
|
|
report.NormalizationIDReassignments = &input.NormalizationSummary.IDsReassigned
|
|
report.NormalizationSkipped.DifferentSpeakers = &input.NormalizationSummary.SkippedMerges.DifferentSpeakers
|
|
report.NormalizationSkipped.GapTooLarge = &input.NormalizationSummary.SkippedMerges.GapTooLarge
|
|
report.NormalizationSkipped.DurationExceeded = &input.NormalizationSummary.SkippedMerges.DurationExceeded
|
|
report.NormalizationSkipped.TokenLimitExceeded = &input.NormalizationSummary.SkippedMerges.TokenLimitExceeded
|
|
}
|
|
if input.ChunkingSummary != nil {
|
|
report.Chunking = &reporting.ChunkingSummary{
|
|
ChunkCount: input.ChunkingSummary.ChunkCount,
|
|
MinEstimatedTokens: input.ChunkingSummary.MinEstimatedTokens,
|
|
MaxEstimatedTokens: input.ChunkingSummary.MaxEstimatedTokens,
|
|
TotalEstimatedTokens: input.ChunkingSummary.TotalEstimatedTokens,
|
|
TargetSections: input.ChunkingSummary.TargetSections,
|
|
MaxSectionTokens: input.ChunkingSummary.MaxSectionTokens,
|
|
MinSectionTokens: input.ChunkingSummary.MinSectionTokens,
|
|
}
|
|
}
|
|
report.ModulesSummary, report.ModuleResults = buildModuleReporting(input.RunOutput)
|
|
return report
|
|
}
|
|
|
|
func buildModuleReporting(runOutput *runner.RunOutput) (*reporting.ModulesSummary, []reporting.ModuleReport) {
|
|
if runOutput == nil || len(runOutput.ModuleResults) == 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
moduleReports := make([]reporting.ModuleReport, 0, len(runOutput.ModuleResults))
|
|
summary := &reporting.ModulesSummary{ModuleCount: len(runOutput.ModuleResults)}
|
|
for _, r := range runOutput.ModuleResults {
|
|
startedAt := r.StartedAt
|
|
completedAt := r.CompletedAt
|
|
moduleReports = append(moduleReports, reporting.ModuleReport{
|
|
ModuleKey: r.ModuleKey,
|
|
ModuleInstance: r.ModuleInstance,
|
|
ReplacementPolicy: string(r.ReplacementPolicy),
|
|
Status: r.Status,
|
|
ProposalCount: r.ProposalCount,
|
|
Warnings: append([]stagewarnings.StageWarning(nil), r.Warnings...),
|
|
ValidatorDecisions: mapValidatorDecisions(r.ValidatorDecisions),
|
|
ValidatorRejected: mapValidatorRejected(r.ValidatorRejected),
|
|
AppliedChanges: r.AppliedChanges,
|
|
SkippedChanges: r.SkippedChanges,
|
|
ErrorMessage: r.ErrorMessage,
|
|
StartedAt: &startedAt,
|
|
CompletedAt: &completedAt,
|
|
})
|
|
summary.TotalAppliedChanges += len(r.AppliedChanges)
|
|
summary.TotalSkippedChanges += len(r.SkippedChanges) + len(r.ValidatorRejected)
|
|
if r.Status == runner.ModuleStatusFailed && summary.FailedModuleInstance == "" {
|
|
summary.FailedModuleInstance = r.ModuleInstance
|
|
}
|
|
}
|
|
|
|
return summary, moduleReports
|
|
}
|
|
|
|
func mapValidatorDecisions(in []runner.ValidatorDecisionRecord) []reporting.ValidatorDecisionReport {
|
|
if len(in) == 0 {
|
|
return nil
|
|
}
|
|
out := make([]reporting.ValidatorDecisionReport, len(in))
|
|
for i, d := range in {
|
|
out[i] = reporting.ValidatorDecisionReport{
|
|
ValidatorName: d.ValidatorName,
|
|
ProposalIndex: d.ProposalIndex,
|
|
Approved: d.Approved,
|
|
ReasonCode: d.ReasonCode,
|
|
Message: d.Message,
|
|
DiagnosticArtifactPath: d.DiagnosticArtifactPath,
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func mapValidatorRejected(in []runner.ValidatorRejectedChange) []reporting.ValidatorRejectedReport {
|
|
if len(in) == 0 {
|
|
return nil
|
|
}
|
|
out := make([]reporting.ValidatorRejectedReport, len(in))
|
|
for i, d := range in {
|
|
out[i] = reporting.ValidatorRejectedReport{
|
|
ValidatorName: d.ValidatorName,
|
|
ProposalIndex: d.ProposalIndex,
|
|
ModuleKey: d.ModuleKey,
|
|
ModuleInstance: d.ModuleInstance,
|
|
TargetSegmentID: d.TargetSegmentID,
|
|
OriginalText: d.OriginalText,
|
|
CorrectedText: d.CorrectedText,
|
|
ReasonCode: d.ReasonCode,
|
|
Message: d.Message,
|
|
}
|
|
}
|
|
return out
|
|
}
|