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
# 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
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)