/** * **The query DSL endpoint** (ADR 0051 §3, design sketch §C.3). * * `POST /api/v1/query` with the JSON document, and `GET /api/v1/query?q=` * for the GET-only clients (the collector client in `@uptimizr/agent-core`, a * simple MCP host, `curl`). Both are reads and both need the ordinary `query` * capability — the DSL reaches exactly the aggregations the canned endpoints * already serve, so it grants nothing new. * * ## Why this is a separate plugin * * `routes/query.ts` is seventy hand-written routes, one per metric. This is one * route that can run any of them. It shares their machinery rather than * duplicating it — the same region/`cellSize` resolution helpers, the same * summariser, the same auth and the same audit hooks — but it has no business * being appended to that file. * * ## The request's journey * * 1. **Shape** — `queryV1Schema` (`@uptimizr/schema`). Closed grammar, bounded * values, unknown keys rejected. No raw SQL can be expressed. * 2. **Vocabulary** — `validateQuery` (`@uptimizr/metrics`). Does the metric * exist, is it an aggregation, does it accept these dimensions and filters, * is the limit within its cap. Every objection is collected, so one `400` * tells the caller everything that is wrong, with the accepted values named. * 3. **Resolution** — a `region` given as a registered region id becomes bounds, * and a spatial metric with no `cellSize` gets the one derived from the * scene's registered extent (ADR 0040 §1), exactly as the canned routes do. * 4. **Compilation** — `store.runMetric` renders the metric's own builder for * the store's dialect and runs it. No second SQL path exists. * 5. **Shaping** — `format` (`full` | `table` | `summary`), applied here with * the same pure `@uptimizr/db` functions the canned routes' `preSerialization` * hook uses. The DSL defaults to `table`: it is an agent-facing surface, and * rows without the window, the sample size and the truncation flag are * exactly what the envelope exists to prevent. */ import type { FastifyPluginAsync } from "fastify"; import type { CollectorStore } from "../store.js"; interface Options { store: CollectorStore; } /** * The query DSL routes. Registered as its own plugin in `app.ts`, after * `queryRoutes` (whose `format` hook it deliberately does not rely on — this * route shapes its own response, because it knows its filters and window * first-hand rather than having to read them back off a querystring). */ export declare const queryDslRoutes: FastifyPluginAsync; export {}; //# sourceMappingURL=query-dsl.d.ts.map