Integrate UI with Engine Contract
After this page, you can connect a frontend report builder UI to the engine input/output contracts for preview and export.
How the architecture works
Parse error on line 1: flowchart LR Dev ^ Expecting 'NEWLINE', 'SPACE', 'GRAPH', got 'ALPHA'
This flow keeps the trust boundary clear: the UI sends intent, and the engine executes only allowlisted fields and operators.
Step 1: Build the report definition payload in UI
ts
const payload = {
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',
},
],
},
sorts: [{ field_key: 'total_amount', direction: 'desc' }],
output: { format: 'csv', filename: 'orders-report.csv' },
};Step 2: Send preview request
ts
const previewResponse = await fetch('/app/reports/preview', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
const previewBody = await previewResponse.json();Expected success shape:
json
{
"columns": [],
"rows": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"total_pages": 0
}
}Step 3: Send export request
ts
const exportResponse = await fetch('/app/reports/export', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
const exportBody = await exportResponse.json();Expected success shape:
json
{
"filename": "orders-report.csv",
"mime_type": "text/csv; charset=UTF-8",
"content": "Customer,status,Total\nAlice,paid,250\n"
}Step 4: Handle validation errors in UI
ts
if (previewResponse.status === 422) {
// Example: { errors: [{ path: 'sorts.0.field_key', message: 'Sort field is not sortable.' }] }
const errorsByPath = Object.groupBy(previewBody.errors ?? [], (e: { path: string }) => e.path);
// Map path-specific messages to form fields.
}Verify
- Preview requests return
columns,rows, andpagination. - Export requests return
filename,mime_type, andcontent. - Invalid definitions return
errorswithpathandmessage.
Common mistakes
- Sending old operator names like
eqinstead of=. - Using
betweenwith one value instead of two values. - Ignoring
pathand showing all errors as a generic message. - Mixing preview and export payload shapes in one UI handler.
Next
Use task guides in How-to for production patterns.