Files
FPandA-Engine/README.md
2026-03-20 14:01:46 +01:00

183 lines
5.7 KiB
Markdown

# FP&A Budgeting Engine
A production-grade REST API for corporate budgeting, variance analysis, and department-level financial reporting. Built to automate the workflows FP&A teams typically run manually in Excel.
---
## The Business Problem
Every month, FP&A analysts pull actuals from ERP systems, paste them into spreadsheets, and manually calculate budget vs. actual variances by department and cost center. This is slow, error-prone, and doesn't scale.
This engine replaces that workflow with a reliable API: budget data is structured in a normalized schema, actuals are ingested on a schedule, and variance reports are available on demand — for any department, any period, any GL account.
---
## What It Does
- **Budget management** — Create and version annual budgets by department and GL account
- **Actuals ingestion** — Load actuals from CSV or JSON (ERP export format)
- **Variance analysis** — Budget vs. actual, favourable/unfavourable, percentage and absolute
- **Rollups** — P&L rollup by department, cost center, and fiscal period
- **Alerts** — Flag accounts exceeding budget by a configurable threshold
- **Audit trail** — Every budget change is timestamped and attributed
---
## Tech Stack
| Layer | Technology |
|---|---|
| API server | Go (net/http + chi router) |
| Database | PostgreSQL |
| Schema migrations | golang-migrate |
| Config | Environment variables (.env) |
| Docs | OpenAPI 3.0 (docs/openapi.yaml) |
---
## Project Structure
```
fpa-budgeting-engine/
├── cmd/
│ └── server/
│ └── main.go # Entry point
├── internal/
│ ├── handler/ # HTTP handlers
│ │ ├── budget.go
│ │ ├── actuals.go
│ │ └── variance.go
│ ├── model/ # Domain types
│ │ ├── budget.go
│ │ ├── actuals.go
│ │ └── variance.go
│ ├── repository/ # DB layer
│ │ ├── budget_repo.go
│ │ └── actuals_repo.go
│ └── service/ # Business logic
│ ├── budget_service.go
│ └── variance_service.go
├── migrations/
│ ├── 001_create_departments.up.sql
│ ├── 002_create_gl_accounts.up.sql
│ ├── 003_create_budgets.up.sql
│ ├── 004_create_actuals.up.sql
│ └── 005_create_audit_log.up.sql
├── docs/
│ └── openapi.yaml
├── scripts/
│ └── seed_demo.sql # Sample data for demo/testing
├── .env.example
├── docker-compose.yml
├── Makefile
└── README.md
```
---
## Key API Endpoints
```
POST /api/v1/budgets Create a new budget entry
GET /api/v1/budgets?dept=&period= List budgets with filters
PUT /api/v1/budgets/{id} Update a budget line
POST /api/v1/actuals/ingest Ingest actuals (JSON or CSV)
GET /api/v1/variance?dept=&period= Variance report
GET /api/v1/variance/summary Full P&L summary
GET /api/v1/variance/alerts Accounts over threshold
GET /api/v1/rollup?by=department Rollup by dimension
```
---
## Finance Concepts Implemented
**Chart of Accounts** — GL accounts are typed (revenue, COGS, opex, capex) and roll up into P&L line items correctly.
**Variance conventions** — Revenue variances are favourable when actuals exceed budget. Cost variances are favourable when actuals are below budget. The engine handles both correctly.
**Fiscal periods** — Supports fiscal year offsets (e.g. FY starting April). Periods are stored as fiscal quarters and months, not calendar months.
**Budget versioning** — Original budget, Forecast 1, Forecast 2 are tracked separately, enabling Budget vs. Forecast vs. Actual three-way comparison.
---
## Getting Started
```bash
# Clone and configure
git clone https://gitea.yoursite.com/yourname/fpa-budgeting-engine
cp .env.example .env
# Start Postgres
docker-compose up -d db
# Run migrations
make migrate-up
# Seed demo data
psql $DATABASE_URL < scripts/seed_demo.sql
# Start the server
make run
# → API available at http://localhost:8080
```
---
## Example: Variance Report Response
```json
GET /api/v1/variance?dept=engineering&period=2024-Q3
{
"department": "Engineering",
"period": "2024-Q3",
"currency": "DKK",
"lines": [
{
"gl_account": "6100",
"description": "Salaries & Wages",
"budget": 4200000,
"actual": 4380000,
"variance": -180000,
"variance_pct": -4.3,
"status": "unfavourable"
},
{
"gl_account": "6300",
"description": "Software Subscriptions",
"budget": 320000,
"actual": 289000,
"variance": 31000,
"variance_pct": 9.7,
"status": "favourable"
}
],
"total_budget": 5180000,
"total_actual": 5290000,
"total_variance": -110000,
"total_variance_pct": -2.1
}
```
---
## Why Go for a Finance API?
Go's compile-time type safety, zero-cost abstractions, and simple concurrency model make it well-suited for financial data services:
- **No null pointer surprises** — strict typing prevents the class of bugs that corrupt financial calculations
- **Fast and predictable** — consistent sub-10ms response times under load
- **Easy to deploy** — single binary, no runtime dependencies, runs anywhere
- **Explicit error handling** — every failure path is handled, not swallowed
---
## Roadmap
- [ ] Multi-currency support with FX rate table
- [ ] Excel export of variance reports (finance teams need this)
- [ ] Webhook notifications when accounts breach threshold
- [ ] Integration adapter for SAP/NetSuite actuals export format
- [ ] Role-based access (department managers see only their cost centers)