Skip to content

Completeness Check

The completeness check evaluates how thoroughly a PRD is filled out across all sections.

Purpose

Unlike scoring (which evaluates quality), completeness checks:

  • How many sections are filled
  • Required vs optional section coverage
  • Field-level completeness
  • Overall document maturity

Quick Start

import "github.com/grokify/structured-plan/prd"

report := prd.CheckCompleteness(doc)

fmt.Printf("Overall: %.0f%%\n", report.OverallScore*100)
fmt.Printf("Grade: %s\n", report.Grade)
fmt.Printf("Status: %s\n", report.Status)

CompletenessReport Structure

type CompletenessReport struct {
    OverallScore  float64            `json:"overall_score"`  // 0.0-1.0
    Grade         string             `json:"grade"`          // A, B, C, D, F
    Status        string             `json:"status"`         // Complete, Partial, Minimal
    Sections      []SectionReport    `json:"sections"`
    MissingSections []string         `json:"missing_sections,omitempty"`
    Recommendations []string         `json:"recommendations,omitempty"`
}

type SectionReport struct {
    Name          string  `json:"name"`
    Score         float64 `json:"score"`
    Required      bool    `json:"required"`
    FieldsFilled  int     `json:"fields_filled"`
    FieldsTotal   int     `json:"fields_total"`
    Issues        []string `json:"issues,omitempty"`
}

Grading Scale

Score Grade Status
≥90% A Complete
≥80% B Near Complete
≥70% C Partial
≥60% D Partial
<60% F Minimal

Section Weights

Section Weight Required
Metadata 10% Yes
Executive Summary 15% Yes
Objectives 15% Yes
Personas 15% Yes
Requirements 20% Yes
Roadmap 10% No
Risks 5% No
Technical Architecture 5% No
Goals Alignment 5% No

Example Report

report := prd.CheckCompleteness(doc)

// Overall status
fmt.Printf("Completeness: %.0f%% (%s)\n",
    report.OverallScore*100, report.Grade)

// Section breakdown
for _, section := range report.Sections {
    icon := "✓"
    if section.Score < 0.7 {
        icon = "!"
    }
    fmt.Printf("%s %s: %.0f%% (%d/%d fields)\n",
        icon,
        section.Name,
        section.Score*100,
        section.FieldsFilled,
        section.FieldsTotal,
    )
}

// Recommendations
fmt.Println("\nRecommendations:")
for _, rec := range report.Recommendations {
    fmt.Printf("  - %s\n", rec)
}

Output

Completeness: 72% (C)

✓ Metadata: 100% (5/5 fields)
✓ Executive Summary: 80% (4/5 fields)
! Objectives: 60% (3/5 fields)
✓ Personas: 85% (6/7 fields)
! Requirements: 50% (5/10 fields)
! Roadmap: 0% (0/4 fields)
! Risks: 33% (1/3 fields)

Recommendations:
  - Add success metrics to objectives
  - Add acceptance criteria to requirements
  - Define roadmap phases
  - Add risk mitigation strategies

Checking Individual Sections

// Check metadata completeness
metadataScore := prd.CheckMetadataCompleteness(doc.Metadata)

// Check persona completeness
for _, persona := range doc.Personas {
    score := prd.CheckPersonaCompleteness(persona)
    if score < 0.7 {
        fmt.Printf("Incomplete persona: %s (%.0f%%)\n",
            persona.Name, score*100)
    }
}

// Check requirements completeness
for _, req := range doc.Requirements.Functional {
    if !prd.IsRequirementComplete(req) {
        fmt.Printf("Incomplete: %s\n", req.Title)
    }
}

Format Report

Generate formatted output:

// Plain text
text := prd.FormatCompletenessReport(report, "text")
fmt.Println(text)

// Markdown
markdown := prd.FormatCompletenessReport(report, "markdown")

// JSON
json := prd.FormatCompletenessReport(report, "json")

Persona Completeness

Personas are evaluated for:

Field Weight
Name Required
Role Required
Goals 20%
Pain Points 20%
Description 10%
Demographics 10%
Technical Proficiency 10%
func IsPersonaComplete(p Persona) bool {
    return len(p.Goals) > 0 &&
           len(p.PainPoints) > 0 &&
           p.Role != ""
}

Requirements Completeness

Requirements are evaluated for:

Field Weight
Title Required
Description Required
Priority 20%
Acceptance Criteria 30%
Persona Links 10%

NFR Category Coverage

Non-functional requirements should cover key categories:

categories := prd.GetNFRCategoryCoverage(doc.Requirements.NonFunctional)

// Returns map of coverage
// {
//   "performance": true,
//   "security": true,
//   "scalability": false,
//   ...
// }

Filter by Priority

Focus on high-priority sections:

report := prd.CheckCompleteness(doc)

// Filter to only must-have sections
criticalSections := prd.FilterByPriority(report.Sections, "critical")

for _, s := range criticalSections {
    if s.Score < 1.0 {
        fmt.Printf("Critical section incomplete: %s\n", s.Name)
    }
}

Completeness vs Scoring vs Validation

Check Purpose Output
Validation Structure correctness Valid/Invalid + Errors
Completeness Document coverage Percentage + Grade
Scoring Content quality Score + Decision
// 1. First validate structure
result := prd.Validate(doc)
if !result.Valid {
    // Fix structural issues first
}

// 2. Then check completeness
report := prd.CheckCompleteness(doc)
if report.Grade < "C" {
    // Fill in missing sections
}

// 3. Finally score quality
scores := prd.Score(doc)
if scores.Decision == prd.ReviewReject {
    // Improve content quality
}

Next Steps