- CSV-structured template → CSV output
- XML-structured template → XML output
- HTML-structured template → HTML or PDF output
- TXT-structured template → TXT output
Test Reporter locally without deploying to Kubernetes using our plugins-docker-compose repository.Keep in mind that these services require a valid license to run. Without it, the application will not start. For license details, check our License documentation.
Why use Reporter?
Instead of writing complex SQL queries, you can use intuitive placeholders that reference your domains, tables, and fields directly. It’s a fast, flexible, and maintainable way to create reports that evolve alongside your data model.What it can do
- Dynamic queries with placeholders: Reference any data point via direct paths — no SQL required.
- Loop and condition logic: Support for loops, conditionals, and scoped blocks.
- Math operations and aggregation: Perform calculations with
sum_by
,avg_by
, and the new{% calc %}
block. - Async processing: Heavy reports are handled asynchronously to protect live workloads.
- Multiple output formats: Generate CSV, XML, HTML, TXT, or PDF documents depending on your needs.
Template Model
Reporter uses templates that mirror the final document structure. Whether you’re generating a structured XML file or a printable PDF, the content will match exactly.Even though the file content must follow the output format, make sure to save it with a
.tpl
extension. This is required for the template to work properly.Setting up your environment
Before starting, you must rename the databases used as references for searching for information while rendering reports. This configuration must be done in the project’s.env
file.
By defining unique and clear names for each database, we avoid conflicts, especially in cases where different databases have tables with the same names, and we ensure better fluidity in queries.
Example
If you are using a database calledonboarding
, we recommend renaming it to something more descriptive, such as:
midaz_onboarding
(PostgreSQL).midaz_onboarding_metadata
(MongoDB).
Using placeholders
Templates use placeholders to fetch data dynamically. A placeholder points to a field inside a table or a document collection, and it follows this structure:Building templates
You can enhance your templates with conditionals, math operators, and temporary variables, making them more dynamic and flexible.Common blocks
- Loop
- Simple condition
- Temporary scope
- Value formatting
:2
shows two decimal places: 123.45
.
Example
Conditional blocks
Reporter support rich logical conditions:Block | Description | Example |
---|---|---|
If | Runs a block if the condition is true. | {% if condition %}...{% endif %} |
If-else | Runs one block if true, another if false. | {% if condition %}...{% else %}...{% endif %} |
If - else - if | Allows multiple checks within the same block. | {% if a %}...{% elif b %}...{% else %}...{% endif %} |
Equal | Checks if two values are equal. | {% if a == b %} |
Not equal | Checks if two values are different. | {% if a != b %} |
Greater than | Checks if a is greater than b. | {% if a > b %} |
Less than | Checks if a is less than b. | {% if a < b %} |
Greater than or equal | Checks if a is greater than or equal to b. | {% if a >= b %} |
Less than or equal | Checks if a is less than or equal to b. | {% if a <= b %} |
And | Returns true if both conditions are true. | {% if a and b %} |
Or | Returns true if at least one condition is true. | {% if a or b %} |
Not | Inverts the Boolean result of a condition. | {% if not a %} |
Operators and filters
You can combine logical conditions with math operations to define rules, calculate values, and format results with precision. Example: Calculating Total Sum with FilterOther functions
- Count
- Average
- Minimum
- Maximum
- Percentage
category.amount = "6.00"
total.expenses = "20.00"
- Date
ddMMyyyy
, yyyyMMdd
, and more). Time can be included too, like in the example below.
The time is generated in UTC (Coordinated Universal Time), without regional time zones or daylight saving adjustments.
Contains
Use this filter to check if one value is partially included in another, even if they’re not identical. It’s beneficial when your data includes dynamic prefixes or suffixes, like in account aliases.midaz_transaction.transaction.body.source.from.account_alias = 0#@external/BRL
midaz_onboarding.account.alias = @external/BRL
contains
will return true
because @external/BRL
is inside 0#@external/BRL
.
Math operations
Reporter allows you to perform calculations on exported data.Keyword | Description |
---|---|
sum_by | Sum values. |
- | Subtract. |
* | Multiply. |
/ | Divide. |
avg_by | Calculate average. |
min_by | Minimum value. |
max_by | Maximum value. |
percent_of | Calculates percentage. |
filter(list, "field", value) | Filters lists as if it were a WHERE clause. |
{% calc %} | Executes inline mathematical expressions to dynamically compute values during template rendering. Supports arithmetic operations, nested expressions, and variable references — ideal for calculations like totals, balances, or derived metrics. Example: {% calc (balance.available + 1.2) * balance.on_hold - balance.available / 2 %} |
Advanced filtering
Reporter support complex filtering logic in thefilters
object of a report request.
Each filter is applied per datasource > table > field
, using a condition like:
Supported operators:
eq
: Equal to;gt
: Greater than;gte
: Greater than or equal to;lt
: Less than;lte
: Less than or equal to;between
: Value falls within a range;in
: Value is within a list;nin
: Value is not within a list.
Security recommendations
Security is foundational when working with Lerian products and plugins.Before deploying any component into your environment, we strongly recommend reviewing our Security Recommendations. Each product—along with its associated plugins—should be implemented in line with security best practices, including:
- Securing network boundaries
- Managing and rotating secrets
- Applying timely patch management
- Enforcing strict role-based access controls (RBAC)