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

5.7 KiB

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)