Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,21 @@ on:
permissions:
contents: write
jobs:
build-arc42:
runs-on: ubuntu-latest
container: texlive/texlive:latest
steps:
- uses: actions/checkout@v4
- name: Build arc42 documentation
working-directory: documentation
run: make
- uses: actions/upload-artifact@v4
with:
name: arc42-pdf
path: documentation/documentation.pdf

deploy:
needs: build-arc42
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -27,4 +41,12 @@ jobs:
restore-keys: |
mkdocs-material-
- run: pip install -r docs/requirements.txt
- run: mkdocs gh-deploy --force
- run: mkdocs build
- uses: actions/download-artifact@v4
with:
name: arc42-pdf
path: site/
- uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./site
225 changes: 41 additions & 184 deletions docs/api.md
Original file line number Diff line number Diff line change
@@ -1,186 +1,43 @@
# API reference

Base URL: `http://localhost:8080/api/v1`

All responses are JSON. All endpoints are read-only — ignis does not modify the database.

---

## Health check

```
GET /health
```

Returns `200 OK` when the server is running. Does not check the database connection.

**Response**

```json
{ "status": "OK" }
```

---

## List variants

```
GET /api/v1/variants/{country_iso2}
```

Returns all available building variant codes for a country.

**Path parameters**

| Parameter | Description | Example |
|---|---|---|
| `country_iso2` | ISO 3166-1 alpha-2 country code | `DE` |

**Response**

```json
{
"country": "germany",
"data": ["DE.N.SFH.01.Gen", "DE.N.SFH.01.ReEx", ...]
}
```

---

## Match variants

```
GET /api/v1/variants/{country_iso2}/match?type={type}&period={period}
```

Returns all refurbishment levels for a specific building type and construction period, ordered from existing state to most-refurbished.

**Path parameters**

| Parameter | Description | Example |
|---|---|---|
| `country_iso2` | ISO 3166-1 alpha-2 country code | `DE` |

**Query parameters**

| Parameter | Description | Example |
|---|---|---|
| `type` | Building type code | `SFH`, `MFH`, `TH`, `AB` |
| `period` | Construction period code | `01`, `02`, `03` |

**Response**

```json
{
"country": "germany",
"prefix": "DE.N.SFH.01",
"data": [
{ "code": "DE.N.SFH.01.Gen", "label": "Existing state" },
{ "code": "DE.N.SFH.01.ReEx", "label": "Medium refurbishment" },
{ "code": "DE.N.SFH.01.ReAd", "label": "Advanced refurbishment" }
]
}
```

---

## Get variant data

```
GET /api/v1/data/{code}
```

Returns the raw TABULA parameters for a building variant. Used by client applications to populate their own forms or models.

**Path parameters**

| Parameter | Description | Example |
|---|---|---|
| `code` | TABULA variant code | `DE.N.SFH.01.Gen` |

**Response**

```json
{
"country": "germany",
"variant_code": "DE.N.SFH.01.Gen",
"tabula_data": { ... },
"expected_q_h_nd": 123.45
}
```

!!! note
`tabula_data` contains the full set of ~200 TABULA parameters. `expected_q_h_nd` is the reference value from the workbook, used for validation.

---

## List field metadata

```
GET /api/v1/fields
```

Returns a static description of every TABULA input field used by ignis's clients: where to find it in a `GET /api/v1/data/:code` response (`path`), its unit, a short label, and two descriptions — a plain-language one for non-experts and a technical one. This list is identical for every country, since the underlying database schema is uniform across all 20 TABULA countries.

**Response**

```json
{
"data": [
{
"key": "HeatingDays",
"group": "ClimateConditions",
"path": "AdvancedParameters.ClimateConditions.HeatingDays",
"unit": "days/year",
"label": "Heating days",
"simple_description": "How many days a year the building typically needs heating, based on local climate.",
"expert_description": "Number of heating days per year."
}
]
}
```

!!! note
This endpoint is intended to power a future interactive building-description questionnaire in client applications: `simple_description` becomes the question text, and the field's own value from the matched TABULA variant (via `/api/v1/data/:code`) becomes the suggested default a user can accept if they don't know the answer.

---

## Calculate heat demand

```
POST /api/v1/calculate/{code}
```

Runs the 17-level ISO 13790 pipeline for the specified building variant and returns the annual heating energy demand.

**Path parameters**

| Parameter | Description | Example |
|---|---|---|
| `code` | TABULA variant code | `DE.N.SFH.01.Gen` |

**Request body** (optional)

```json
{ "A_ref": 150.0 }
```

`A_ref` overrides the reference floor area stored in the TABULA record. Omit the body to use the TABULA default.

**Response**

```json
{
"variant_code": "DE.N.SFH.01.Gen",
"q_h_nd": 123.45,
"unit": "kWh/(m2.a)"
}
```

**Error responses**

| Status | Condition |
|---|---|
| `400` | Invalid variant code format, unknown country, invalid `A_ref` |
| `404` | Variant code not found in database |
| `500` | Pipeline execution failed or returned a non-finite result |
The interactive reference below is generated from the OpenAPI spec
([`openapi.yaml`](openapi.yaml)), the machine-readable source of truth for
every endpoint, schema, and error. Download it to generate a client, load it
into Postman, or import it into another tool.

## How to consume the API

ignis has no authentication of its own. It runs behind a reverse proxy, and
that proxy is the only way in: any backend service that wants to use ignis
sends a valid `X-Api-Key` header, and the proxy rejects anything else with
`403` before ignis ever sees the request. ignis is meant to be called by a
trusted server-side caller, never directly by a browser or an end user's
client, since the key must not be visible outside that caller. If the system
in front of ignis has its own user-facing login (EnerPlanET, for example,
uses Keycloak), that login authenticates the user **to that system**, not to
ignis; that system's own backend then calls ignis on the user's behalf, using
the API key. The full model is in the spec's description.

!!! note "Base URL"
All paths are served through the reverse proxy. In local development that is
`https://localhost`; in a deployment it is whatever host the proxy is
published on.

## Testing it yourself

The Swagger UI below can call a locally running ignis directly.

1. Start the stack, from `environment/`: `docker compose up -d`. On a first
run, load the TABULA data once: `docker compose exec ignis-app ./bin/build_db`.
2. Serve these docs locally with `mkdocs serve`. The reverse proxy already
allows requests from `http://localhost:8000` (its default port).
3. If your browser has never trusted the local proxy's certificate, open
`https://localhost` directly once and accept it (or run `caddy trust`).
4. Click **Authorize** below and enter the API key checked by the reverse
proxy (`X-Api-Key`; the prototype default is set in
`environment/Caddyfile`). It applies to every **Try it out** call from
then on.
5. Expand an endpoint, click **Try it out**, fill in the parameters, and
**Execute**.

<swagger-ui src="openapi.yaml"/>
10 changes: 4 additions & 6 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ cp .env.example .env
| `DB_HOST` | PostgreSQL host | `localhost` |
| `DB_PORT` | PostgreSQL port | `5432` |
| `DB_USER` | Database user | `postgres` |
| `DB_PASSWORD` | Database password | required, no default |
| `DB_PASSWORD` | Database password | required, no default |
| `DB_NAME` | Database name | `ignis` |
| `DB_SSL_MODE` | TLS mode (`require` / `disable`) | `require` |
| `ALLOWED_ORIGINS` | Comma-separated list of allowed CORS origins | unset rejects all cross-origin requests |
| `ALLOWED_ORIGINS` | Comma-separated list of allowed CORS origins | unset rejects all cross-origin requests |

!!! info "ALLOWED_ORIGINS"
Only needed when a browser-based client calls ignis directly. For server-to-server calls (the intended deployment model), leave it unset.
Expand All @@ -44,7 +44,7 @@ go build -o bin/validate cmd/validate/main.go

## Load the database

Loads the TABULA workbook into PostgreSQL. This is destructive it drops and recreates the `tabula` schema.
Loads the TABULA workbook into PostgreSQL. This is destructive: it drops and recreates the `tabula` schema.

```bash
./bin/build_db
Expand All @@ -68,7 +68,5 @@ See the [validation report](validation.md) for current results.

## Deployment

ignis is a microservice — it should run on a private Docker network with no public port exposed. The parent application (e.g. EnerPlanET) proxies requests to it. Authentication and rate limiting are the parent application's responsibility.

!!! danger "Do not expose ignis directly to the internet"
The API has no authentication. Restrict network access at the infrastructure level.
The API has no authentication of its own. Run it behind a reverse proxy on a private network, with no public port exposed on ignis itself. See the [arc42 architecture documentation](https://github.com/thd-spatial-ai/ignis/tree/main/documentation) for the deployment topology, reverse-proxy setup, and access-control design.
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Go microservice implementing the ISO 13790 annual heating energy demand calculat

ignis is designed as an internal microservice. Given a TABULA building variant code, it returns the annual heating energy demand in kWh/(m²·a) via a simple REST API.

**19/20 countries at 100% accuracy 2,091 / 2,147 buildings validated.** See the [validation report](validation.md).
**19/20 countries at 100% accuracy: 2,091 / 2,147 buildings validated.** See the [validation report](validation.md).

---

Expand All @@ -14,8 +14,8 @@ ignis is designed as an internal microservice. Given a TABULA building variant c
|---|---|
| [Getting started](getting-started.md) | Installation, configuration, building, running |
| [API reference](api.md) | All endpoints with request/response examples |
| [Pipeline](pipeline.md) | How the 17-level ISO 13790 calculation works |
| [Validation](validation.md) | Per-country accuracy results |
| [Architecture (PDF)](documentation.pdf) | Full arc42 architecture documentation |

---

Expand Down
12 changes: 6 additions & 6 deletions docs/open-source-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Quick links: [LICENSE](#license) · [README](#readme) · [CONTRIBUTING](#contrib
### LICENSE

- [x] `LICENSE` file present in repository root
- [x] Appropriate license chosen MIT
- [x] Appropriate license chosen: MIT
- [x] License committed to repository

### README
Expand Down Expand Up @@ -71,7 +71,7 @@ If your repository contains large files (e.g. datasets, binaries, media, generat

- [x] Git LFS installed locally
- [x] Git LFS initialised in repository (`git lfs install`)
- [x] Large file types tracked `*.xlsx`, `*.csv`, archives, media (`data/tabula-calculator.xlsx`)
- [x] Large file types tracked: `*.xlsx`, `*.csv`, archives, media (`data/tabula-calculator.xlsx`)
- [x] `.gitattributes` committed to repository
- [x] Large files added and committed properly
- [ ] Release strategy for LFS files documented (if applicable)
Expand All @@ -90,7 +90,7 @@ If your project uses third-party components, assets, or generated code that requ
- [x] `ATTRIBUTIONS.md` file created in repository root
- [x] TABULA building typology data (IWU) listed
- [x] Source platform or author identified
- [x] License type specified CC BY 4.0
- [x] License type specified: CC BY 4.0
- [x] Links to original sources included
- [x] Go dependencies noted

Expand All @@ -110,10 +110,10 @@ For full specification details, see [Citation File Format](https://citation-file

- [x] `CITATION.cff` file created in repository root
- [x] `cff-version` set to `1.2.0`
- [x] Project title specified ignis
- [x] Author listed THD-Spatial-AI Research Group, Technische Hochschule Deggendorf
- [x] Project title specified: ignis
- [x] Author listed: THD-Spatial-AI Research Group, Technische Hochschule Deggendorf
- [ ] ORCID included for each author (add when individual authors are listed)
- [x] License field matches `LICENSE` MIT
- [x] License field matches `LICENSE`: MIT
- [x] Repository URL included
- [x] Version and release date set
- [ ] File validates against the CFF schema (use [cff-validator](https://github.com/citation-file-format/cff-initializer-javascript))
Expand Down
Loading
Loading