Now I have the complete picture. Here's the comprehensive audit report:

---

## Audit Report: Test Coverage of `generate_*_figure()` Methods

### Source Files Found (19 figure-generating methods across 18 service files)

| # | Service File | Figure Method(s) | Lines |
|---|-------------|-------------------|-------|
| 1 | `inflation_service.py` | `generate_inflation_figure()` | 36 |
| 2 | `freezer_service.py` | `generate_comparison_figure()` | 40 |
| 3 | `caffeine_service.py` | `generate_decay_figure()` | 61 |
| 4 | `kettle_service.py` | `generate_waste_figure()` | 74 |
| 5 | `tv_service.py` | `generate_comparison_figure()` | 53 |
| 6 | `reading_service.py` | `generate_reading_figure()` | 36 |
| 7 | `fitness_service.py` | `generate_comparison_figures()` *(returns 2 figs)* | 52 |
| 8 | `dashboard_service.py` | `generate_scenario_figure()`, `generate_depot_figure()`, `generate_monthly_category_flow_figure()`, `generate_monthly_income_expense_figure()`, `generate_priority_expense_pie_figure()`, `generate_sankey_diagram()` | 79,112,150,212,276,423 |
| 9 | `coffee_service.py` | `generate_comparison_figures()` *(returns 2 figs)* | 60 |
| 10 | `washing_machine_service.py` | `generate_comparison_figure()` | 49 |
| 11 | `calorie_service.py` | `generate_comparison_figure()` | 36 |
| 12 | `car_service.py` | `generate_comparison_figure()` | 85 |
| 13 | `dishwasher_service.py` | `generate_comparison_figure()` | 50 |
| 14 | `stove_service.py` | `generate_comparison_figure()` | 46 |
| 15 | `lighting_service.py` | `generate_comparison_figure()` | 38 |
| 16 | `pc_service.py` | `generate_comparison_figure()` | 50 |
| 17 | `dryer_service.py` | `generate_comparison_figure()` | 41 |
| 18 | `oven_service.py` | `generate_comparison_figure()` | 107 |
| — | `protein_service.py` | `generate_chart()` (also Plotly fig) | 21 |

---

### Coverage Status

#### ✅ COVERED (6 methods in 4 services)
| Method | Test File | Test Name |
|--------|-----------|-----------|
| `FreezerService.generate_comparison_figure()` | `test_freezer_service.py` | `test_generate_comparison_figure` |
| `WashingMachineService.generate_comparison_figure()` | `test_washing_machine_service.py` | `test_generate_comparison_figure` |
| `ReadingService.generate_reading_figure()` | `test_reading_service.py` | `test_generate_reading_figure` |
| `DashboardManager.generate_scenario_figure()` | `test_dashboard_service.py` | `test_generate_scenario_figure` |
| `DashboardManager.generate_monthly_category_flow_figure()` | `test_dashboard_service.py` | `test_generate_monthly_category_flow_figure` |
| `DashboardManager.generate_monthly_income_expense_figure()` | `test_dashboard_service.py` | `test_generate_monthly_income_expense_figure` |
| `DashboardManager.generate_priority_expense_pie_figure()` | `test_dashboard_service.py` | `test_generate_priority_expense_pie_figure` |
| `DashboardManager.generate_sankey_diagram()` | `test_dashboard_service.py` | `test_generate_sankey_diagram` |

#### ⚠️ PARTIALLY COVERED — Dashboard gap (1 method)
| Method | Status |
|--------|--------|
| `DashboardManager.generate_depot_figure()` | **NOT tested** — test file exists and covers all other Dashboard figure methods, but this one is missing. |

#### ❌ UNCOVERED — test file exists but lacks figure tests (10 methods in 10 services)
| Service Method | Existing Test File | What's Missing |
|----------------|-------------------|----------------|
| `InflationService.generate_inflation_figure()` | `test_inflation_service.py` | No figure test |
| `CaffeineService.generate_decay_figure()` | `test_caffeine_service.py` | No figure test |
| `KettleService.generate_waste_figure()` | `test_kettle_service.py` | No figure test |
| `TVService.generate_comparison_figure()` | `test_tv_service.py` | No figure test |
| `CoffeeService.generate_comparison_figures()` | `test_coffee_service.py` | No figure test (returns 2 figures) |
| `CalorieService.generate_comparison_figure()` | `test_calorie_service.py` | No figure test |
| `StoveService.generate_comparison_figure()` | `test_stove_service.py` | No figure test |
| `PCService.generate_comparison_figure()` | `test_pc_service.py` | No figure test |
| `OvenAirFryerService.generate_comparison_figure()` | `test_oven_service.py` | No figure test |
| `ProteinService.generate_chart()` | `test_protein_service.py` | No figure test |

#### ❌ MISSING — no test file exists at all (5 services)
| Service Method | Recommended Test File |
|----------------|----------------------|
| `FitnessService.generate_comparison_figures()` | **`test_fitness_service.py`** — needs full new file |
| `CarService.generate_comparison_figure()` | **`test_car_service.py`** — needs full new file |
| `DishwasherService.generate_comparison_figure()` | **`test_dishwasher_service.py`** — needs full new file |
| `LightingService.generate_comparison_figure()` | **`test_lighting_service.py`** — needs full new file |
| `DryerService.generate_comparison_figure()` | **`test_dryer_service.py`** — needs full new file |

---

### Summary Statistics

| Category | Count |
|----------|-------|
| **Total figure methods** | **20** (19 generate_*_figure + 1 generate_chart in protein) |
| **Fully covered** | **9** (45%) |
| **Dashboard gap (partially covered)** | **1** (5%) |
| **Existing test file, no figure test** | **10** (50%) |
| **No test file at all** | **5** (5 services — the figure methods in those count above) |

### Recommended Actions (Priority Order)

1. **`test_dashboard_service.py`** — Add `test_generate_depot_figure()` method (smallest gap, high-value code path with Monte Carlo branching).

2. **`test_inflation_service.py`** — Add test for `generate_inflation_figure()` — produces a simple line chart, easy to validate trace data and layout.

3. **`test_caffeine_service.py`** — Add test for `generate_decay_figure()` — involves datetime handling and shape/annotation verification.

4. **`test_kettle_service.py`** — Add test for `generate_waste_figure()` — produces a pie/donut chart, unique among the comparison figures.

5. **`test_tv_service.py`** — Add test for `generate_comparison_figure()` — Scatter plot with `add_vline` for guarantee markers.

6. **`test_stove_service.py`** — Add test for `generate_comparison_figure()` — same pattern as TV, with `add_vline` guarantees.

7. **`test_coffee_service.py`** — Add test for `generate_comparison_figures()` — returns **two** figures (cost + time), unique return pattern.

8. **`test_fitness_service.py`** — **New file** needed — same dual-figure pattern as coffee service (cost + time).

9. **`test_car_service.py`** — **New file** needed — most complex comparison figure with buy/rent/leasing modes.

10. **`test_dishwasher_service.py`** — **New file** needed — follows freezer/washing machine pattern.

11. **`test_dryer_service.py`** — **New file** needed — follows freezer/dishwasher pattern.

12. **`test_lighting_service.py`** — **New file** needed — unique `LightingScenario` dataclass, simpler without repair logic.

13. **`test_pc_service.py`** — Add test for `generate_comparison_figure()` — has `add_vline` for hardware refresh points.

14. **`test_oven_service.py`** — Add test for `generate_comparison_figure()` — oven vs air fryer comparison, dual traces.

15. **`test_calorie_service.py`** — Add test for `generate_comparison_figure()` — bar chart, unique among the comparison figures.

16. **`test_protein_service.py`** — Add test for `generate_chart()` — horizontal bar chart, separate from comparison figure pattern.

### Testing Pattern to Follow

The existing covered tests (freezer, washing machine, reading, dashboard) all follow this pattern:
- Create service with inputs/dataclasses
- Call the figure method
- Assert `isinstance(fig, go.Figure)`
- Assert `len(fig.data) == N` (expected trace count)
- Assert trace properties: `.name`, `.type`, `.x`, `.y`, `.mode`
- For comparison figures: create multiple items and verify correct trace count/names
