Skip to main content
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


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 for the tags, filters, and expressions the language offers.

Data sources


A data source is a database Reporter reads, registered entirely through environment configuration. Reporter connects to PostgreSQL and MongoDB. Access is read-only by construction: the extraction path issues SELECT statements and MongoDB finds, and no write path to a data source exists. DATASOURCE_<NAME>_CONFIG_NAME is the variable that makes a data source exist. Its value is the configName that templates and filters use, and it stays stable while hosts and credentials change around it. The rest of the block supplies the connection itself. The API surface over data sources is read-only too. You can list the configured sources and get one by identifier, which is how you confirm that a deployment sees the source a template expects. There is no create, update, or delete operation, because the environment owns that decision. Read 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:
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 when the report was created. 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 up to the point where the work is queued. POST answers 201 Created with a report already in Processing, and a worker takes it from there. 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: one that already settled as Finished or Error is left as it is, rather than generated 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. Status is derived, never stored. 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, and only when it was marked delivered. 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 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: a request whose tenant cannot be resolved is rejected, and nothing falls back to a shared pool. Single-tenant operation is the default and needs no tenant configuration at all. See Multi-tenancy for the platform-wide model.

Next steps


Architecture

One binary, two surfaces, and the queue between them.

Quick start

Upload a template and generate your first report.

Template reference

The tags, filters, and expressions available to a template.

Managing deadlines

Create, track, and deliver a reporting obligation.