Skip to content

Report Definition Contract

This page defines the input contract for building a report and the output contracts returned by preview and export execution.

Use this contract in your app layer or in a separate UI package.

Input shape

The core input object is ReportDefinition.

json
{
  "source_key": "orders",
  "selected_columns": [
    {"field_key": "customer_name", "label": "Customer"},
    {"field_key": "status"},
    {"field_key": "total_amount", "label": "Total"}
  ],
  "filters": {
    "type": "group",
    "boolean": "and",
    "children": [
      {
        "type": "condition",
        "field_key": "status",
        "operator": "=",
        "value": "paid"
      },
      {
        "type": "condition",
        "field_key": "total_amount",
        "operator": "between",
        "value": [100, 500]
      }
    ]
  },
  "sorts": [
    {"field_key": "total_amount", "direction": "desc"}
  ],
  "output": {
    "format": "csv",
    "filename": "orders-report.csv"
  }
}

Preview output contract

json
{
  "columns": [
    {
      "field_key": "customer_name",
      "output_key": "Customer",
      "label": "Customer",
      "type": "text"
    },
    {
      "field_key": "status",
      "output_key": "status",
      "label": "Status",
      "type": "text"
    }
  ],
  "rows": [
    {
      "Customer": "Alice",
      "status": "paid"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 1,
    "total_pages": 1
  }
}

Export output contract

json
{
  "filename": "orders-report.csv",
  "mime_type": "text/csv; charset=UTF-8",
  "content": "Customer,status\nAlice,paid\n"
}

For XLSX output, mime_type is:

application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

Validation error contract

When definitions are invalid, validation returns structured errors with path and message pairs.

json
{
  "errors": [
    {
      "path": "sorts.0.field_key",
      "message": "Sort field is not sortable."
    },
    {
      "path": "filters.children.1.value",
      "message": "Between operators require exactly two values."
    }
  ]
}

Notes

  • The engine layer is transport-agnostic. You can call it from HTTP controllers, jobs, or CLI commands.
  • Keep source definitions developer-owned and trusted.
  • Never pass raw SQL from user input into this contract.