From 8a984b3e89499a0fcab2331a784763819c6546c7 Mon Sep 17 00:00:00 2001 From: samantha Date: Sat, 21 Mar 2026 07:27:19 +0000 Subject: [PATCH] Add API Reference --- API-Reference.md | 237 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 API-Reference.md diff --git a/API-Reference.md b/API-Reference.md new file mode 100644 index 0000000..ac55ad9 --- /dev/null +++ b/API-Reference.md @@ -0,0 +1,237 @@ +# API Reference + +Base URL: `http://localhost:8080/api/v1` + +All request and response bodies are JSON. All endpoints return `Content-Type: application/json`. + +--- + +## Health + +### `GET /health` + +Returns 200 if the database is reachable. + +**Response:** +```json +{"status": "ok"} +``` + +Returns 503 if the database ping fails. + +--- + +## Reference Data + +Reference data (departments and GL accounts) must be created before budget lines or actuals, as they are foreign-key parents. + +--- + +### Departments + +#### `POST /departments` + +Create a department. + +**Request body:** +```json +{ + "code": "ENG", + "name": "Engineering" +} +``` + +#### `GET /departments` + +List all departments. + +**Response:** +```json +[ + {"id": 1, "code": "ENG", "name": "Engineering"}, + {"id": 2, "code": "MKT", "name": "Marketing"} +] +``` + +#### `DELETE /departments/{id}` + +Delete a department by ID. + +--- + +### GL Accounts + +#### `POST /gl-accounts` + +Create a GL account. + +**Request body:** +```json +{ + "code": "6100", + "description": "Salaries & Wages", + "type": "headcount", + "favour_high": false +} +``` + +`favour_high` drives the favourability logic. Set to `true` for revenue accounts (higher actual = good), `false` for cost accounts (lower actual = good). + +**Account types:** `revenue`, `cogs`, `opex`, `capex`, `headcount` + +#### `GET /gl-accounts` + +List all GL accounts. + +#### `DELETE /gl-accounts/{id}` + +Delete a GL account by ID. + +--- + +## Budgets + +#### `POST /budgets` + +Create a budget line. + +**Request body:** +```json +{ + "department_id": 1, + "gl_account_id": 3, + "fiscal_year": 2024, + "fiscal_period": 9, + "version": "original", + "amount": 4200000, + "currency": "DKK", + "notes": "Headcount plan P09" +} +``` + +**Budget versions:** `original`, `forecast1`, `forecast2`, `forecast3` + +#### `PUT /budgets/{id}` + +Update a budget line's amount or notes. + +**Request body:** +```json +{ + "amount": 4350000, + "notes": "Revised after headcount change" +} +``` + +#### `DELETE /budgets/{id}` + +Delete a budget line by ID. + +--- + +## Actuals + +#### `POST /actuals/ingest` + +Upsert an actual. Idempotent by `(fiscal_year, fiscal_period, department_id, gl_account_id)` — posting the same period twice updates the amount rather than creating a duplicate. + +**Request body:** +```json +{ + "department_id": 1, + "gl_account_id": 3, + "fiscal_year": 2024, + "fiscal_period": 9, + "amount": 4380000, + "currency": "DKK", + "source": "SAP_EXPORT" +} +``` + +Designed to accept bulk ERP export feeds. POST each line individually or build a batch wrapper around the endpoint. + +--- + +## Variance + +### Query Parameters (both variance endpoints) + +| Parameter | Example | Description | +|---|---|---| +| `year` | `2024` | Fiscal year (required) | +| `period` | `9` | Fiscal period 1–12 (required) | +| `dept` | `ENG` | Department code — omit to return all departments | +| `version` | `original` | Budget version (defaults to `original`) | + +--- + +#### `GET /variance` + +Full variance report for the given filters. + +**Example:** +``` +GET /api/v1/variance?year=2024&period=9&dept=ENG +``` + +**Response:** +```json +{ + "department": "ENG", + "fiscal_year": 2024, + "fiscal_period": 9, + "version": "original", + "currency": "DKK", + "total_budget": 6740000, + "total_actual": 7074600, + "total_variance": -334600, + "total_variance_pct": -4.97, + "lines": [ + { + "gl_code": "6100", + "gl_description": "Salaries & Wages", + "gl_type": "headcount", + "budget": 4200000, + "actual": 4380000, + "variance_abs": -180000, + "variance_pct": -4.29, + "status": "unfavourable", + "currency": "DKK" + }, + { + "gl_code": "5000", + "gl_description": "Cloud Infrastructure", + "gl_type": "cogs", + "budget": 850000, + "actual": 791000, + "variance_abs": 59000, + "variance_pct": 6.94, + "status": "favourable", + "currency": "DKK" + } + ] +} +``` + +`variance_abs` = actual − budget. Positive means over-budget for costs, under-budget for revenue. + +`status` is `"favourable"` or `"unfavourable"` based on the account's `favour_high` flag — see [Finance Concepts](Finance-Concepts). + +--- + +#### `GET /variance/alerts` + +Returns only the GL lines where absolute variance percentage exceeds the threshold. + +**Additional query parameter:** + +| Parameter | Example | Description | +|---|---|---| +| `threshold` | `15` | Alert threshold as a percentage (default: `10`) | + +**Example:** +``` +GET /api/v1/variance/alerts?year=2024&period=9&threshold=15 +``` + +Returns the same line-level structure as the full variance report, filtered to lines where `abs(variance_pct) > threshold`. \ No newline at end of file