Score as percentages

This commit is contained in:
nemunaire 2025-10-21 12:52:20 +07:00
commit 74aee54432
23 changed files with 1027 additions and 1488 deletions

View file

@ -36,6 +36,7 @@ type ReportGenerator struct {
dnsAnalyzer *DNSAnalyzer
rblChecker *RBLChecker
contentAnalyzer *ContentAnalyzer
headerAnalyzer *HeaderAnalyzer
scorer *DeliverabilityScorer
}
@ -51,6 +52,7 @@ func NewReportGenerator(
dnsAnalyzer: NewDNSAnalyzer(dnsTimeout),
rblChecker: NewRBLChecker(dnsTimeout, rbls),
contentAnalyzer: NewContentAnalyzer(httpTimeout),
headerAnalyzer: NewHeaderAnalyzer(),
scorer: NewDeliverabilityScorer(),
}
}
@ -63,7 +65,6 @@ type AnalysisResults struct {
DNS *DNSResults
RBL *RBLResults
Content *ContentResults
Score *ScoringResult
}
// AnalyzeEmail performs complete email analysis
@ -79,15 +80,6 @@ func (r *ReportGenerator) AnalyzeEmail(email *EmailMessage) *AnalysisResults {
results.RBL = r.rblChecker.CheckEmail(email)
results.Content = r.contentAnalyzer.AnalyzeContent(email)
// Calculate overall score
results.Score = r.scorer.CalculateScore(
results.Authentication,
results.SpamAssassin,
results.RBL,
results.Content,
email,
)
return results
}
@ -99,20 +91,9 @@ func (r *ReportGenerator) GenerateReport(testID uuid.UUID, results *AnalysisResu
report := &api.Report{
Id: utils.UUIDToBase32(reportID),
TestId: utils.UUIDToBase32(testID),
Score: results.Score.OverallScore,
Grade: ScoreToReportGrade(results.Score.OverallScore),
CreatedAt: now,
}
// Build score summary
report.Summary = &api.ScoreSummary{
AuthenticationScore: results.Score.AuthScore,
SpamScore: results.Score.SpamScore,
BlacklistScore: results.Score.BlacklistScore,
ContentScore: results.Score.ContentScore,
HeaderScore: results.Score.HeaderScore,
}
// Collect all checks from different analyzers
checks := []api.Check{}
@ -147,11 +128,40 @@ func (r *ReportGenerator) GenerateReport(testID uuid.UUID, results *AnalysisResu
}
// Header checks
headerChecks := r.scorer.GenerateHeaderChecks(results.Email)
headerChecks := r.headerAnalyzer.GenerateHeaderChecks(results.Email)
checks = append(checks, headerChecks...)
report.Checks = checks
// Summarize scores by category
categoryCounts := make(map[api.CheckCategory]int)
categoryTotals := make(map[api.CheckCategory]int)
for _, check := range checks {
if check.Status == "info" {
continue
}
categoryCounts[check.Category]++
categoryTotals[check.Category] += check.Score
}
// Calculate mean scores for each category
calcCategoryScore := func(category api.CheckCategory) int {
if count := categoryCounts[category]; count > 0 {
return categoryTotals[category] / count
}
return 0
}
report.Summary = &api.ScoreSummary{
AuthenticationScore: calcCategoryScore(api.Authentication),
BlacklistScore: calcCategoryScore(api.Blacklist),
ContentScore: calcCategoryScore(api.Content),
HeaderScore: calcCategoryScore(api.Headers),
SpamScore: calcCategoryScore(api.Spam),
}
// Add authentication results
report.Authentication = results.Authentication
@ -202,6 +212,30 @@ func (r *ReportGenerator) GenerateReport(testID uuid.UUID, results *AnalysisResu
report.RawHeaders = &results.Email.RawHeaders
}
// Calculate overall score as mean of all category scores
categoryScores := []int{
report.Summary.AuthenticationScore,
report.Summary.BlacklistScore,
report.Summary.ContentScore,
report.Summary.HeaderScore,
report.Summary.SpamScore,
}
var totalScore int
var categoryCount int
for _, score := range categoryScores {
totalScore += score
categoryCount++
}
if categoryCount > 0 {
report.Score = totalScore / categoryCount
} else {
report.Score = 0
}
report.Grade = ScoreToReportGrade(report.Score)
return report
}
@ -330,21 +364,3 @@ func (r *ReportGenerator) GenerateRawEmail(email *EmailMessage) string {
return raw
}
// GetRecommendations returns actionable recommendations based on the score
func (r *ReportGenerator) GetRecommendations(results *AnalysisResults) []string {
if results == nil || results.Score == nil {
return []string{}
}
return results.Score.Recommendations
}
// GetScoreSummaryText returns a human-readable score summary
func (r *ReportGenerator) GetScoreSummaryText(results *AnalysisResults) string {
if results == nil || results.Score == nil {
return ""
}
return r.scorer.GetScoreSummary(results.Score)
}