PDF Report Generation System
Executive Summary
The PDF report is the client-facing deliverable — the tangible output of the entire 21-phase audit. Report quality directly impacts perceived value. A well-designed PDF report converts audit findings into client trust: 87% of clients who receive a visually professional audit report retain the agency vs. 34% who receive a plain text output (AgencyAnalytics survey, 2024). Every phase must produce its own PDF; the final master report compiles all phases into a single document.
2025–2026 reporting context:
- Include SEO Health Index = (LOCAL-IMPACT × 0.55) + (SERP-TRUST × 0.45) as the master metric
- AI Overviews impact must be called out per relevant finding (20–35% of local queries)
- All CWV thresholds use 2025 values: INP < 200ms (not FID), LCP < 2.5s, CLS < 0.1
- Score grades: A (90–100) / B (75–89) / C (60–74) / D (45–59) / F (< 45)
- Source data for reports comes from: Ahrefs (backlinks, keywords), SEMrush (traffic, gaps), Screaming Frog (technical crawl), Google Search Console (GSC) (coverage, performance), PageSpeed Insights + Lighthouse (CWV), BrightLocal (citations, GBP rank), Majestic (TF:CF), Google Business Profile (GBP), ChatGPT/Perplexity (AI visibility tests)
- GBP 2025 features to include in reports: Q&A section completeness, service menu with prices, review velocity (last 90 days), Google Reserve/Booking integration, AI Overview local pack eligibility (≥4.3 stars, 50+ reviews), GBP Posts frequency
- AI crawler access status must be reported in technical findings (14 crawlers, 3 tiers)
- llms.txt presence/absence should be flagged in AI SEO section
- Brand mention authority score (YouTube/Reddit/Wikipedia correlation with AI citations) in reputation section
- Platform-specific AI optimization status (AIO, ChatGPT, Perplexity, Gemini, Copilot) in AI SEO section
Numbered Action Steps:
- Confirm
{AUDIT_DIR}/has all required phase.mdfiles — runpython3 scripts/audit_status.py --project projects/[slug]— Effort: 1 min - Run
python3 scripts/report_compiler.py --project projects/[slug]→ generates{AUDIT_DIR}/master-report.md— Effort: 2 min - Build HTML report for each phase — use full design system (SVG gauges, color cards, tables) — Effort: 30–60 min per phase
- Save HTML to
{REPORTS_DIR}/phase-[N]-[slug].html— Effort: 1 min per phase - Run
python3 scripts/generate_pdf.py --html {REPORTS_DIR}/phase-[N]-[slug].html— generates PDF — Effort: 30 sec per phase - Confirm PDF size and page count — alert if <2 pages (likely rendering error) or >30 pages (likely runaway content) — Effort: 1 min
- Repeat steps 3–6 for all 21 phases + LOCAL-IMPACT + SERP-TRUST + master report — Effort: varies
- Deliver master-report.pdf + all phase PDFs in
{REPORTS_DIR}/folder to client — Effort: 5 min
Tools for This Phase
| Tool | Purpose | Cost | |---|---|---| | python3 scripts/generate_pdf.py | Chrome headless + WeasyPrint fallback PDF generation | Free (local) | | Google Chrome headless | Primary PDF engine — highest fidelity HTML→PDF | Free | | WeasyPrint | Fallback PDF engine — no Chrome needed | Free | | Google Chrome browser | Preview HTML before PDF conversion | Free | | python3 scripts/report_compiler.py | Compile all phase .md files into master-report.md | Free (local) |
Report Quality Standards (2025)
| Report Element | Minimum Standard | Excellent Standard | |---|---|---| | Cover page | Business name, score, date, URL | + SVG gauge chart, grade badge, key verdict | | Dashboard page | Score cards per dimension | + Competitor comparison bars, trend arrows | | Issue cards | Status + issue + fix | + Priority score, effort estimate, competitor context | | Priority matrix | Impact × Feasibility table | + Visual heat map, 30/90-day roadmap | | File size | < 5MB | < 2MB (optimized images) | | Page count | 15–30 pages | 20–40 pages (comprehensive) | | Completeness | All completed phases | All 21 phases + both scoring frameworks |
Required Report Sections by Report Type
| Report Type | Cover Page | Score Gauge | Issue Cards | Priority Matrix | Competitor Table | Quick Wins | Roadmap | AI Visibility Callout | |---|---|---|---|---|---|---|---|---| | Per-phase PDF | Yes | Yes (phase score) | Yes | Yes | Yes (phase-specific) | Yes (top 3) | No | Yes (if content/on-page/AI phase) | | LOCAL-IMPACT PDF | Yes | Yes (composite) | No | No | Yes (benchmarks) | Yes (top 5) | No | Yes (AI readiness dimension) | | SERP-TRUST PDF | Yes | Yes (composite) | No | No | Yes (benchmarks) | Yes (top 5) | No | Yes (T2 dimension) | | Master Report PDF | Yes | Yes (SEO Health Index) | Yes (all phases) | Yes (master) | Yes (full competitor summary) | Yes (top 10) | Yes (30/90/180-day) | Yes (dedicated section) |
2025–2026 Report Content Requirements
| Section | What to Include | Why It Matters | |---|---|---| | AI Visibility Dashboard | AIO citation status, ChatGPT/Perplexity mentions, AI crawler access score | AI search drives 20–35% of local queries; clients need to see their AI presence | | GBP Health Summary | Q&A completeness, review velocity (last 90 days), service menu, Google Reserve status, AI Overview eligibility | GBP is the #1 local ranking factor; 2025 features (Q&A, service menu) directly affect AIO inclusion | | Brand Mention Authority | YouTube/Reddit/Wikipedia presence, brand mention score vs. backlink profile | Brand mentions correlate 3× more with AI visibility than backlinks (Ahrefs Dec 2025) | | AI Crawler Access | Tier 1/2/3 crawler status, llms.txt presence, IndexNow status | Blocked AI crawlers = invisible to that platform regardless of content quality | | Platform Readiness | Per-platform scores (AIO, ChatGPT, Perplexity, Gemini, Copilot) | Only 11% of domains cited by both ChatGPT and AIO — platform-specific optimization required | | Citability Score | Answer block quality, self-containment, statistical density | AI models cite passages meeting specific structural criteria (134–167 word blocks, answer-first) |
Architecture
- Read
{AUDIT_DIR}/intake-data.mdto get PROJECT_DIR, business name, URL - Aggregate all audit findings from
{AUDIT_DIR}/*.mdfiles - Generate a complete HTML file using the design system below with real audit data
- Write the HTML file to
{REPORTS_DIR}/phase-[N]-[slug].html - Convert to PDF using the Python script (auto-detects Chrome or WeasyPrint):
``bash python3 scripts/generate_pdf.py --html {REPORTS_DIR}/phase-[N]-[slug].html ` Or directly via Chrome: `bash "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \ --headless=new --disable-gpu --no-sandbox --print-to-pdf-no-header \ --print-to-pdf="{REPORTS_DIR}/phase-[N]-[slug].pdf" \ "file:///[absolute-path-to-html]" ``
- Report PDF path + file size to user
Step 1: Detect Chrome Path (Manual Fallback)
If not using the Python script, detect the Chrome binary:
if [ -f "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" ]; then
CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
elif command -v google-chrome &> /dev/null; then
CHROME="google-chrome"
elif command -v chromium-browser &> /dev/null; then
CHROME="chromium-browser"
elif command -v chromium &> /dev/null; then
CHROME="chromium"
else
echo "ERROR: Chrome not found. Install with: brew install --cask google-chrome"
exit 1
fi
echo "Chrome found at: $CHROME"
Step 2: Generate HTML Report
Write a complete HTML file using the template structure and design system below. Replace ALL placeholder values with real audit data from the conversation.
File Naming Convention
reports/{business-name-slug}-seo-audit-{YYYY-MM-DD}.html
reports/{business-name-slug}-seo-audit-{YYYY-MM-DD}.pdf
Step 3: Convert to PDF
mkdir -p reports
"$CHROME" --headless --disable-gpu --no-sandbox \
--print-to-pdf="reports/{filename}.pdf" \
"file://{abs