Skip to main content

AI reporting DSL — horizontal surface (Layer B)

Tier: Public
Status: Shipped MVP (post-α H2 Wave C, 2026-05)
Audience: platform maintainers, module authors, AI consultant implementors
Related: PLATFORM-ARCHITECTURE.md §6.1 Layer B, POSTGRES-REPLICATION-ARCHITECTURE.md


1. Summary

The reporting DSL lets the AI answer bounded analytics questions without raw SQL. The model emits a typed query AST; the server validates and executes against curated Postgres views on a read-only connection.

InvariantEnforcement
No raw SQL from the modelOnly Zod-validated AST → parameterized SQL builder
Row caplimit ≤ 100 (hard reject above)
Date range requireddateFrom + dateTo on every query
Workspace scopeEvery view includes workspace_id; executor binds $workspaceId
Timeout5s statement timeout on executor connection
PIIViews exclude email/phone unless explicitly allowlisted

2. Curated view registry (MVP)

ViewMetricsDimensionsModule owner
reporting.mrp_order_status_countsorder_countstatusmrp
reporting.brewery_inventory_summaryon_hand_qtycategorybrewery (vertical)

Views are created in migrations under services/api/prisma/migrations/. Future: registerModule({ reportingViews }) (not shipped in MVP).

Execution uses DATABASE_URL_RO (replica) when set; falls back to primary with read-only transaction.


3. Query AST (subset)

{
view: "mrp_order_status_counts" | "brewery_inventory_summary",
metrics: string[], // subset of view allowlist
dimensions?: string[],
filters?: { field: string; op: "eq"; value: string | number }[],
dateFrom: string, // ISO date
dateTo: string,
limit?: number // default 50, max 100
}

Validated by ReportingQueryAstSchema in services/api/src/services/ai/reporting/reportingAst.ts.


4. Tool: platform.reportingQuery

FieldValue
Scoperead
Ownerplatform (registered beside render_document)
InputAST object above
Output{ ok: true, rows: Record<string, unknown>[], rowCount, truncated }

Platform overlay reminds the model to prefer this tool for aggregate questions instead of guessing.


5. Worked example

Question: “How many production orders per status this month?”

{
"view": "mrp_order_status_counts",
"metrics": ["order_count"],
"dimensions": ["status"],
"dateFrom": "2026-05-01",
"dateTo": "2026-05-31",
"limit": 50
}

Result rows:

[
{ "status": "planned", "order_count": 12 },
{ "status": "in_progress", "order_count": 3 }
]

6. Deferred (not MVP)

  • CRM/WMS views, cross-module joins, model-written SQL, ai_readonly role (optional hardening).

7. Maintenance