> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Reporter core concepts

> The Reporter model in one place: templates, data sources, reports, deadlines, the four report states, and the tenant boundary that separates them.

Reporter has a small model. You upload a **template** that describes a document. An operator configures the **data sources** Reporter may read. You request a **report** against a template, and Reporter renders an artifact you download. A **deadline** tracks when a report is due and whether someone delivered it.

This page defines each noun and the rules that connect them.

## The model at a glance

***

| Concept     | Definition                                                                                               |
| ----------- | -------------------------------------------------------------------------------------------------------- |
| Template    | A plain-text document definition, uploaded as a file, that declares one output format.                   |
| Data source | A persisted, read-only database connection that an operator manages through the API or seeds at startup. |
| Report      | One rendering of one template, under the filters you asked for.                                          |
| Artifact    | The file a finished report produces, held in object storage.                                             |
| Filter      | A per-field condition that narrows the rows a report reads.                                              |
| Deadline    | A due date and a recurrence rule, optionally bound to a template.                                        |
| Tenant      | The isolation boundary. Every operation resolves exactly one.                                            |

## Templates

***

A template is a plain-text `.tpl` file that you upload as `multipart/form-data`, together with the output format it produces and a short description. Reporter keeps the file in object storage and its metadata in MongoDB. The template language is Pongo2, so a template mixes literal document text with variables, loops, conditionals, filters, and aggregation tags.

One template declares one output format: `PDF`, `HTML`, `XML`, `TXT`, or `CSV`. PDF renders as HTML first and then converts through a headless-browser worker pool.

A template addresses data by `configName`, the stable name of a data source, and by table: `{{ midaz_onboarding.accounts }}`. When more than one schema is in play, qualify it as `{{ midaz_onboarding:public.accounts }}`.

At upload, Reporter reads the template text and derives the fields it touches, per data source and per table. It then checks every referenced table and field against the live schema of that data source. A data source that is unreachable produces a warning rather than a rejection, so a template still uploads while a database is down.

Read [Template reference](/en/products/reporter/template-reference) for the tags, filters, and expressions the language offers.

## Data sources

***

A data source is a PostgreSQL or MongoDB connection stored in Reporter's registry. The API creates and manages registry entries. A single-tenant deployment can also seed them from `DATASOURCE_*` variables at startup. Data extraction remains read-only by construction: Reporter issues `SELECT` statements and MongoDB finds, and it has no write path into the source database.

Each entry has two identifiers. The `dataSourceId` is the UUID that registry operations use. The `configName` is the stable name that templates and filters use, so keep it stable while hosts and credentials change. Reporter encrypts passwords at rest with `DATASOURCE_CRED_ENC_KEY` and never returns them.

The registry exposes seven operations: list, create, get, partially update, soft-delete, inspect the live schema, and test the connection. Reporter refuses deletion while a live template still references the source.

Read [Connecting Reporter to Midaz](/en/products/reporter/connecting-reporter-to-midaz) for a worked configuration.

## Reports

***

A report request names a template and, optionally, the filters that narrow the data behind it. Filters nest three levels (data source, then table, then field), and each field carries one condition:

```json theme={null}
{
  "templateId": "0198c0f6-6d4d-7a34-a9ba-2c2b3ad2f1a0",
  "filters": {
    "midaz_onboarding": {
      "accounts": {
        "status": { "in": ["ACTIVE"] },
        "type": { "nin": ["internal"] }
      }
    }
  }
}
```

Eight operators exist: `eq`, `gt`, `gte`, `lt`, `lte`, `between`, `in`, and `nin`.

A report keeps its own copy of the output format and description that the template carried at creation time. That snapshot is why an artifact stays downloadable in its original shape after the template moves on.

Reports are create-and-retain. Four operations exist: create one, get it by identifier, list them, and download the artifact of a finished one. A report and its artifact remain in place once created. Retention is a lifecycle policy on the object-storage bucket, set by whoever operates the deployment.

### The four report states

Creation is synchronous only until the work reaches the queue. The `POST` operation answers `201 Created` with a report already in `Processing`, and a worker takes it from there.

| State        | Meaning                                                                                                                                |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| `Processing` | Accepted and queued. The worker has not finished.                                                                                      |
| `Finished`   | Every data section succeeded and the artifact is stored.                                                                               |
| `Partial`    | Some data sections failed. The report records which ones, by section, so you can fix those data sources and generate the report again. |
| `Error`      | Every attempted section failed, or the request never reached the worker.                                                               |

`Processing` is the only entry state, and nothing returns to it once the worker settles the report. A queue can deliver the same command twice, so the worker reads the report before it starts a run. The worker skips a report that already settled as `Finished` or `Error`, and does not generate it again.

The download operation serves the artifact once a report is `Finished`. Poll `GET /v1/reports/{id}` until the state settles, or subscribe to the terminal events Reporter emits and skip the polling.

## Deadlines

***

A deadline models an obligation: a due date, a recurrence rule, and optionally the template that satisfies it. Its `type` is `regulatory` or `custom`. Its `frequency` is `once`, `daily`, `weekly`, `monthly`, `semiannual`, or `annual`, and the semiannual and annual rules also carry the months they fall in.

Reporter derives status and never stores it. A deadline is `delivered` once someone marks it so, `overdue` once its due date passes undelivered, and `pending` otherwise. A recurring deadline rolls forward on the first read after its due date passes. It rolls forward only when it carries the delivery mark. That roll-forward clears the delivery mark, so the record returns to `pending` for the next occurrence and one record carries the whole series.

Notification is pull-based. A single operation returns the deadlines inside their alert window, ranked overdue first, then warning, then informational. Reporter sends no mail and calls no endpoint of yours.

Read [Managing deadlines](/en/products/reporter/managing-deadlines) for the full lifecycle.

## Tenants

***

The tenant is the isolation boundary in Reporter. Reporter resolves it from the authenticated request itself. The bearer token that authorizes the call carries the tenant in its `tenantId` claim. No API operation takes a tenant from a request header, and no client-supplied value can widen the scope of a call.

Isolation runs the whole depth of the stack. Each tenant gets its own metadata database, its own message-broker virtual host, its own connection pools, and its own event outbox. Resolution is fail-closed. Reporter rejects a request when it cannot resolve the tenant, and nothing falls back to a shared pool.

Single-tenant operation is the default and needs no tenant configuration at all. See [Multi-tenancy](/en/platform/multi-tenancy) for the platform-wide model.

## Next steps

***

<CardGroup cols={2}>
  <Card title="Architecture" icon="sitemap" href="/en/products/reporter/reporter-architecture">
    One binary, two surfaces, and the queue between them.
  </Card>

  <Card title="Quick start" icon="rocket" href="/en/products/reporter/reporter-quick-start">
    Upload a template and generate your first report.
  </Card>

  <Card title="Template reference" icon="code" href="/en/products/reporter/template-reference">
    The tags, filters, and expressions available to a template.
  </Card>

  <Card title="Managing deadlines" icon="calendar" href="/en/products/reporter/managing-deadlines">
    Create, track, and deliver a reporting obligation.
  </Card>
</CardGroup>
