Files
FPandA-Engine/testing/README.md
2026-03-20 21:53:55 +01:00

90 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# FP&A Test Data Platform
Python tooling to generate, validate, and load realistic FP&A data into your Go API.
## Structure
```
testing/
├── generators/
│ └── generate_data.py # Creates all CSV files
├── loaders/
│ └── api_loader.py # POSTs CSVs to your Go API
├── tests/
│ └── test_fpa.py # Data integrity + API tests
├── data/
│ └── csv/ # Generated CSV files land here
└── requirements.txt
```
## Quick Start
```bash
pip install -r requirements.txt
# 1. Generate all CSV data
python generators/generate_data.py
# 2. Validate data integrity (no API needed)
pytest tests/test_fpa.py -v
# 3. Load into your Go API (dry-run first)
python loaders/api_loader.py --dry-run
# 4. Load for real
python loaders/api_loader.py --url http://localhost:8080
```
## Generated Datasets
| File | Rows | Description |
|------|------|-------------|
| `revenue_budget_vs_actuals.csv` | 48 | Product & Service revenue — budget vs actuals, 24 months |
| `opex_budget_vs_actuals.csv` | ~2,688 | Dept × category opex — budget vs actuals |
| `pl_income_statement.csv` | 24 | Monthly P&L: revenue, COGS, gross profit, EBITDA, net income |
| `cash_flow.csv` | 24 | Operating / investing / financing cash flows, rolling balance |
| `headcount_workforce.csv` | ~1,000+ | Employee snapshots per month, with hire/term dates & salaries |
## Key Concepts
**Budget vs Actuals** — Every financial row has a `budget_amount` (what was planned) and
`actual_amount` (what really happened). The `variance` = actual budget. Positive variance
on revenue = good. Positive variance on spend = over budget.
**Product vs Service revenue** — Product is recurring SaaS subscriptions (~70%, higher margin).
Service is consulting/support (~30%, lower margin). Both grow monthly at different rates.
**Cash Flow** — Separate from revenue. Collections can lag invoicing (DSO effect). Includes
a simulated Series A raise in June 2023.
## API Endpoints (from main.go)
```
POST /api/v1/budgets ← create one budget line
PUT /api/v1/budgets/{id} ← update a budget line
DELETE /api/v1/budgets/{id} ← delete a budget line
POST /api/v1/actuals/ingest ← bulk ingest actuals { "records": [...] }
GET /api/v1/variance ← variance report (budget vs actuals)
GET /api/v1/variance/alerts ← over/under budget alerts
GET /api/v1/health ← db health check
```
## Load Order
The seeder always loads in this order — **budgets must exist before actuals**:
1. **Budgets**`POST /api/v1/budgets` individually (revenue + opex lines)
2. **Actuals**`POST /api/v1/actuals/ingest` in batches of 50
3. **Variance check**`GET /api/v1/variance` to confirm data landed
## Loader Options
```bash
python loaders/api_loader.py --help
--url API base URL (default: http://localhost:8080)
--batch Records per actuals/ingest request (default: 50)
--dry-run Print payloads without sending
--token Bearer token for auth header
--only Run one step only: budgets | actuals | variance | alerts
```