# Marketing reporting demonstration

This reproducible example uses fictional data for four campaigns over two equal 14-day periods. It demonstrates validation, deterministic calculations, and a drafted interpretation. It is not a client case study, advertising-platform connection, or measured AI performance result.

Run with Python 3.9+ from this folder:

```sh
python3 verify.py
python3 analyze.py campaigns.csv --output output.json
python3 analyze.py invalid-campaigns.csv
```

The final command intentionally exits with code 2 and prints validation errors to stderr. The verifier executes both paths, checks selected totals and expected error messages, and writes `verification.json` and `invalid-output.json`.

## Files

- `campaigns.csv`: 8 fictional observations, EUR spend and gross attributed revenue.
- `analyze.py`: standard-library validator and calculator; no external calls.
- `output.json`: actual calculated result of the included script.
- `invalid-campaigns.csv`: deliberately corrupt copy: clicks exceed impressions on line 2; revenue is negative on line 3.
- `invalid-output.json`: captured rejection from the actual invalid run.
- `verify.py` / `verification.json`: repeatable checks and recorded execution evidence.
- `analysis.md`: editorial interpretation of this exact output, including proposed next actions and limitations.
- `prompt.md`: reusable analyst instructions; not evidence of an executed model call.

## Definitions

CTR = clicks / impressions. Conversion rate = conversions / clicks. CPC = spend / clicks. CPA = spend / conversions. ROAS = attributed revenue / spend. CTR and conversion rate are expressed as percentages; ROAS is a ratio. Aggregates divide summed numerators by summed denominators. Undefined ratios become JSON null. Monetary inputs are fictional EUR values, with no currency conversion. Relative change = (comparison − baseline) / baseline × 100. Absolute change in a percentage metric is in percentage points.

The validator checks the exact schema, required values, finite non-negative numbers, integer event counts, valid ordered dates, equal non-overlapping period lengths, campaign consistency, duplicate pairs, and the required 4 × 2 coverage. This is a narrow demonstration schema, not a general ingestion service. Scripts write only named output files in this folder or a user-specified output path. No packages, credentials, network, databases, or cloud services are required.
