---
name: report-template
description: Standardized report structure, recommendations, and reportlab PLATYPUS patterns for all Biotrackr health reports
---

# Report Template

All Biotrackr health reports must follow this standardized structure and use these reportlab patterns. Each report type (activity, sleep, food, vitals) adapts the template to its domain while maintaining consistent formatting, page flow, and required sections.

## Reportlab Framework Setup

```python
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    Image as RLImage, PageBreak, HRFlowable
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
```

* Page size: A4 with 2cm margins all sides
* Output path: `/tmp/reports/report.pdf`
* Use `SimpleDocTemplate` with a `story` list of flowables

### Paragraph Styles

* **Title**: 24pt, bold, centered, color #1a3a5c
* **Heading1**: 14pt bold, section headers
* **Heading2**: 11pt bold, subsection headers
* **Body**: 9pt normal, leading=13, content text
* **Disclaimer**: 7.5pt grey, centered
* **Small**: 8pt for compact content

### Chart Embedding

```python
story.append(RLImage("chart_path.png", width=16*cm, height=8*cm))
```

* Width: 16cm for full-width charts, height: 7.5-9cm
* Add `Spacer(1, 0.3*cm)` between charts and other content
* Verify chart file exists with `os.path.exists()` before embedding

## Required Report Sections (in order)

### Page 1 — Cover and Executive Summary

1. **Title**: Report type + date range (e.g., "Weekly Sleep Report — April 5–11, 2026")
2. **Subtitle**: "Generated by Biotrackr · Powered by Fitbit data" (centered, grey, 12pt)
3. **Horizontal rule**: Full-width, dark blue (#1a3a5c), 1.5pt
4. **Summary metrics box**: 4-column table with the 4 most important metrics for the report type, using dark header + large bold values
5. **Best/Worst highlight box**: Two-row table — green row for best day, orange row for needs-improvement day
6. **Weekly overview chart**: Full-width embedded PNG showing the multi-panel overview chart
7. **Disclaimer**: Via `onPage` footer callback (see below)

### Page 2 — Daily Breakdown

1. **Section heading**: "Daily [Domain] Breakdown"
2. **Daily metrics table**: One row per day + averages row at bottom (highlighted blue #d0e8ff). Include all key metrics as columns.
3. **Primary chart**: The most important single-metric chart for the domain (e.g., steps chart for activity, duration chart for sleep)

### Page 3 — Detailed Analysis

1. **Section heading**: Domain-specific (e.g., "Sleep Stages Analysis", "Calories & Active Minutes")
2. **Supporting charts**: 2 charts showing secondary metrics
3. **Brief narrative paragraph**: 2-3 sentences contextualizing the charts

### Page 4 — Trends and Patterns

1. **Section heading**: "[Domain] Trends & Patterns"
2. **Trend chart**: Multi-line or multi-panel chart showing metric trends over the period
3. **Observations list**: Bullet points with notable findings (see Notable Observations format below)

### Page 5 — Recommendations (REQUIRED)

1. **Section heading**: "Personalized Recommendations"
2. **Recommendations table or list**: 4-6 actionable recommendations based on the data (see Recommendations format below)
3. **AI disclaimer banner**: Prominent warning box (see below)
4. **Performance highlights table**: Best/worst days for each metric, color-coded (green for best, red/orange for worst)

### Every Page — Disclaimer Footer

Use the `onPage` callback to render a fixed footer on every page:

```python
DISCLAIMER = (
    "This report is generated from personal health data and is not medical advice. "
    "Consult a healthcare provider for medical guidance."
)

def add_disclaimer_footer(canvas, doc):
    canvas.saveState()
    canvas.setFont("Helvetica", 7)
    canvas.setFillColor(colors.grey)
    canvas.drawCentredString(A4[0] / 2, 1.2 * cm, DISCLAIMER)
    canvas.restoreState()

doc.build(story, onFirstPage=add_disclaimer_footer, onLaterPages=add_disclaimer_footer)
```

## Recommendations Section Format

The recommendations section must follow this structure:

### Recommendation Categories

Generate 4-6 recommendations across these categories (pick the most relevant):

| Category | Icon | Example |
|----------|------|---------|
| Consistency | 🎯 | "Maintain your 22:30–23:15 bedtime window for optimal sleep quality" |
| Improvement | 📈 | "Consider a short lunchtime walk on lower-step days to hit the 10,000 step goal" |
| Strength | 💪 | "Your resting heart rate trended down 5 bpm — continue your current exercise routine" |
| Awareness | 👁️ | "Friday showed the lowest sleep efficiency (91.4%) — monitor for patterns" |
| Goal tracking | ✅ | "You met your step goal on 4/7 days — aim for 5/7 next week" |
| Recovery | 🔄 | "Your deep sleep peaked mid-week — consider lighter evening activities on weekends" |

### Recommendation Rules

* Each recommendation must be **specific to the data** — reference actual numbers, dates, and trends
* Use **positive framing** — lead with strengths, suggest improvements gently
* Keep each recommendation to **1-2 sentences**
* Always ground recommendations in the analyzed data — never make up numbers
* Never diagnose conditions or prescribe treatments

### AI Recommendations Disclaimer (inline)

After the recommendations list, include this prominent warning box:

```python
# Render as a colored table cell or bordered paragraph
AI_RECOMMENDATION_DISCLAIMER = (
    "⚠️ AI-Generated Recommendations: These suggestions are generated by an AI system "
    "based on your personal health and fitness data. They are provided for informational "
    "purposes only and do not constitute medical advice. Always consult a qualified "
    "healthcare professional before making changes to your health, fitness, or nutrition "
    "routine. Individual health needs vary and these recommendations may not be "
    "appropriate for your specific situation."
)
```

Style the disclaimer as:
* Background: light yellow (#FFF9C4) or light orange (#FFF3E0)
* Border: 1pt orange (#F57C00)
* Font: 9pt, bold header "⚠️ Important Notice", then regular body text
* Full page width

## Notable Observations Format

Observations are bullet-pointed findings from the data analysis:

* Start each with a **bold topic**: "**Sleep duration trend**: decreased 11% from first half to second half of the week"
* Include **specific numbers**: dates, percentages, minutes, counts
* Flag **anomalies**: naps, missed goals, unusually high/low values
* Note **consistency patterns**: wake time spread, bedtime regularity, goal achievement streaks
* Compare to **recommended ranges**: adult sleep 7-9 hours, step goals, active minutes targets

## Table Styling Standard

All tables must use this consistent styling:

* Header row: dark blue (#1a3a5c) with white bold text, 8-9pt
* Body rows: alternating white and light grey (#f0f4f8), 8-9pt
* Grid: thin lines in #ccd6e0
* Padding: 4-6pt top/bottom, 6-8pt left
* Summary/average rows: highlighted with light blue (#d0e8ff) and bold text
* Goal-met cells: green text (#27AE60), goal-missed: red text (#E74C3C)

## Output Requirements

* All files saved to `/tmp/reports/`
* PDF named `report.pdf`
* Charts named descriptively (e.g., `sleep_duration_chart.png`, `steps_chart.png`)
* Print each file path to stdout after saving
