basic online
This commit is contained in:
183
README.md
183
README.md
@@ -0,0 +1,183 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user