@uptimizr/db 1.0.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +103 -1
- package/README.md +100 -3
- package/dist/cli/createProject.js +23 -6
- package/dist/cli/createProject.js.map +1 -1
- package/dist/cli/seed.js +12 -4
- package/dist/cli/seed.js.map +1 -1
- package/dist/duckdb/audit.d.ts +13 -0
- package/dist/duckdb/audit.d.ts.map +1 -0
- package/dist/duckdb/audit.js +67 -0
- package/dist/duckdb/audit.js.map +1 -0
- package/dist/duckdb/client.d.ts.map +1 -1
- package/dist/duckdb/client.js +4 -0
- package/dist/duckdb/client.js.map +1 -1
- package/dist/duckdb/migrations.d.ts.map +1 -1
- package/dist/duckdb/migrations.js +97 -0
- package/dist/duckdb/migrations.js.map +1 -1
- package/dist/duckdb/projects.d.ts +9 -5
- package/dist/duckdb/projects.d.ts.map +1 -1
- package/dist/duckdb/projects.js +54 -24
- package/dist/duckdb/projects.js.map +1 -1
- package/dist/duckdb/queries.d.ts +7 -0
- package/dist/duckdb/queries.d.ts.map +1 -1
- package/dist/duckdb/queries.js +10 -1
- package/dist/duckdb/queries.js.map +1 -1
- package/dist/duckdb/sceneRegions.d.ts +24 -0
- package/dist/duckdb/sceneRegions.d.ts.map +1 -0
- package/dist/duckdb/sceneRegions.js +72 -0
- package/dist/duckdb/sceneRegions.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +195 -9
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +192 -0
- package/dist/metadata.js.map +1 -1
- package/dist/parity/compare.d.ts +22 -0
- package/dist/parity/compare.d.ts.map +1 -1
- package/dist/parity/compare.js +31 -0
- package/dist/parity/compare.js.map +1 -1
- package/dist/query/aggregations.d.ts +8 -0
- package/dist/query/aggregations.d.ts.map +1 -1
- package/dist/query/aggregations.js +78 -0
- package/dist/query/aggregations.js.map +1 -1
- package/dist/query/coerce.d.ts +94 -0
- package/dist/query/coerce.d.ts.map +1 -0
- package/dist/query/coerce.js +191 -0
- package/dist/query/coerce.js.map +1 -0
- package/dist/query/summary/cluster.d.ts +78 -0
- package/dist/query/summary/cluster.d.ts.map +1 -0
- package/dist/query/summary/cluster.js +200 -0
- package/dist/query/summary/cluster.js.map +1 -0
- package/dist/query/summary/columns.d.ts +66 -0
- package/dist/query/summary/columns.d.ts.map +1 -0
- package/dist/query/summary/columns.js +98 -0
- package/dist/query/summary/columns.js.map +1 -0
- package/dist/query/summary/format.d.ts +31 -0
- package/dist/query/summary/format.d.ts.map +1 -0
- package/dist/query/summary/format.js +119 -0
- package/dist/query/summary/format.js.map +1 -0
- package/dist/query/summary/index.d.ts +19 -0
- package/dist/query/summary/index.d.ts.map +1 -0
- package/dist/query/summary/index.js +16 -0
- package/dist/query/summary/index.js.map +1 -0
- package/dist/query/summary/reading.d.ts +26 -0
- package/dist/query/summary/reading.d.ts.map +1 -0
- package/dist/query/summary/reading.js +169 -0
- package/dist/query/summary/reading.js.map +1 -0
- package/dist/query/summary/schema.d.ts +217 -0
- package/dist/query/summary/schema.d.ts.map +1 -0
- package/dist/query/summary/schema.js +167 -0
- package/dist/query/summary/schema.js.map +1 -0
- package/dist/query/summary/stats.d.ts +33 -0
- package/dist/query/summary/stats.d.ts.map +1 -0
- package/dist/query/summary/stats.js +73 -0
- package/dist/query/summary/stats.js.map +1 -0
- package/dist/query/summary/summarize.d.ts +57 -0
- package/dist/query/summary/summarize.d.ts.map +1 -0
- package/dist/query/summary/summarize.js +424 -0
- package/dist/query/summary/summarize.js.map +1 -0
- package/dist/query/summary/types.d.ts +223 -0
- package/dist/query/summary/types.d.ts.map +1 -0
- package/dist/query/summary/types.js +8 -0
- package/dist/query/summary/types.js.map +1 -0
- package/dist/query/types.d.ts +13 -0
- package/dist/query/types.d.ts.map +1 -1
- package/llms.txt +7 -3
- package/package.json +10 -4
package/AGENTS.md
CHANGED
|
@@ -9,7 +9,9 @@ The OSS storage contracts plus the single-file **DuckDB** store (ADR 0020):
|
|
|
9
9
|
|
|
10
10
|
- **DuckDB** — one persisted `.duckdb` file holding both events and metadata. A wide `events`
|
|
11
11
|
table (hot fields promoted to columns; the full event preserved as JSON in `payload` so reads
|
|
12
|
-
stay replay-complete) plus `projects` / `api_keys` (stored only as SHA-256 hashes
|
|
12
|
+
stay replay-complete) plus `projects` / `api_keys` (stored only as SHA-256 hashes, each key
|
|
13
|
+
carrying a capability set, an optional label and an optional per-key rate limit) and the
|
|
14
|
+
`agent_audit` trail.
|
|
13
15
|
- **Engine-neutral contracts** — the dialect-agnostic query layer (`buildX` + `Dialect`), the
|
|
14
16
|
neutral event-row mapper (`toEventRow`, `formatUtcTimestamp`), and the metadata types
|
|
15
17
|
(`Project`, `ApiKeyRecord`, `SceneRepresentation*`). An optional, separately-licensed
|
|
@@ -64,12 +66,112 @@ every tool (collector + CLIs) shares one canonical file regardless of cwd.
|
|
|
64
66
|
- A new aggregation = a pure `buildX(projectId, opts, dialect)` builder returning a `QuerySpec`
|
|
65
67
|
(`{ query, query_params }`), run with `runDuckdbQuery`. Keep builders pure, dialect-agnostic,
|
|
66
68
|
and unit-tested without a live database; add a `PARITY_CASES` entry so both engines stay equal.
|
|
69
|
+
- **A new aggregation is not done until it has a metric-registry entry** (see below). The build
|
|
70
|
+
fails without one.
|
|
67
71
|
- Validate events upstream at the collector boundary; this layer assumes valid input.
|
|
68
72
|
- API keys are only ever stored as SHA-256 hashes — never persist raw keys.
|
|
73
|
+
- **Key capabilities are a set, not a role** (ADR 0051 §7): `ingest`, `query`, `annotate`,
|
|
74
|
+
`query:raw`, persisted as a canonical comma-separated token list in `api_keys.capabilities`.
|
|
75
|
+
Always read it with `parseApiKeyCapabilities(capabilities, capability)` so a key issued before
|
|
76
|
+
the set existed still resolves via the legacy singular column; always write it with
|
|
77
|
+
`toApiKeyColumns()` so ordering, validation and the per-key rate-limit columns stay consistent
|
|
78
|
+
across all four engines. `query:raw` is only ever honoured by a collector running with
|
|
79
|
+
`ENABLE_RAW_SESSION_RETENTION` (ADR 0003).
|
|
80
|
+
- **The audit log records key ids, never keys.** `agent_audit` rows carry `key_id`; serialize
|
|
81
|
+
parameters with `serializeAuditParams()` (drops credential-shaped keys, bounds the document)
|
|
82
|
+
before they reach a store, and clamp the endpoint with `clampAuditTool()`.
|
|
69
83
|
- **Single-writer store.** DuckDB allows only one read-write process per file; assume a single
|
|
70
84
|
collector per `.duckdb` file. Back up = copy the file. Multi-writer / horizontal scale is the
|
|
71
85
|
optional ClickHouse scale tier, not this package.
|
|
72
86
|
|
|
87
|
+
## Metric registry (ADR 0051 §1)
|
|
88
|
+
|
|
89
|
+
[`@uptimizr/metrics`](../metrics) is the semantic layer over the aggregations: one
|
|
90
|
+
`MetricDefinition` per exported `build*` (plus two builder-less resource entries — `session_meta`,
|
|
91
|
+
`scene_representation`) declaring id, title, agent-facing description, builder, collector endpoint,
|
|
92
|
+
`grain`, `dimensions`, `filters`, the output `row` Zod schema, per-column semantics (unit /
|
|
93
|
+
measure / label / axis / `rateOf`), row `limits`, `interpretation`, `caveats`, `sourceChannels`
|
|
94
|
+
(the ADR 0012 capture dials that must be on for the metric to have data), `related` metrics,
|
|
95
|
+
`comparable` semantics and a `category`. `DimensionId` / `FilterId` are closed unions declared
|
|
96
|
+
once; `FILTER_TARGETS` maps each filter to the `query/types.ts` option field it drives.
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import { getMetric, allMetrics, METRIC_IDS } from "@uptimizr/metrics";
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Its own **package**, not a subpath here, because this one depends on the ~37 MB
|
|
103
|
+
`@duckdb/node-api` native binding and the registry's consumers (`@uptimizr/agent-core`,
|
|
104
|
+
`@uptimizr/mcp`, `@uptimizr/react`) can never use a database driver. `@uptimizr/metrics` imports
|
|
105
|
+
**only** `zod` plus a type-only `@uptimizr/schema` declaration, performs no I/O and holds no store
|
|
106
|
+
or dialect reference.
|
|
107
|
+
|
|
108
|
+
### Numeric coercion at the store edge (ADR 0051 §2)
|
|
109
|
+
|
|
110
|
+
Numeric columns are strict `z.number()` — the schema describes the API, not the wire. Every
|
|
111
|
+
`build*` tags its `QuerySpec` with the metric id, and each store's runner (`runDuckdbQuery`,
|
|
112
|
+
`runClickhouseQuery`, `runPostgresQuery`, `runMssqlQuery`) calls `coerceRows(spec.metric, rows)` at
|
|
113
|
+
the one point rows leave the driver, so a string-encoded 64-bit integer or decimal becomes a number
|
|
114
|
+
before any consumer sees it. `null` passes through — an aggregate over an empty set is "no
|
|
115
|
+
samples", not `0`, which is why nine perf/resource metrics declare nullable columns.
|
|
116
|
+
|
|
117
|
+
- **Do not** reintroduce `z.coerce.number()` in `registry.ts`: a registry test proves that
|
|
118
|
+
string-encoded rows _fail_ the strict schema and _pass_ after `coerceRows`, which is what pins
|
|
119
|
+
the work to the edge.
|
|
120
|
+
- A new store must call `coerceRows` in its runner; the parity suite asserts
|
|
121
|
+
`typeof === "number"` for every registry-numeric column on every engine (`numericColumnsForSpec`).
|
|
122
|
+
- Junk in a numeric column throws under a test runner and is left untouched with a one-per-column
|
|
123
|
+
warning in production (`coerceRows(..., { strict })` pins either).
|
|
124
|
+
|
|
125
|
+
**Rules for agents:**
|
|
126
|
+
|
|
127
|
+
- A `build*` aggregation added here must also be added to `AGGREGATION_BUILDER_NAMES` in
|
|
128
|
+
`@uptimizr/metrics`, and given a registry entry. Missing the entry is a **compile error**
|
|
129
|
+
(`NoUnregisteredAggregations` names the missing builder); missing the list entry fails this
|
|
130
|
+
package's `registry.test.ts` at runtime and names it too.
|
|
131
|
+
- **Never import `@uptimizr/db` from `@uptimizr/metrics`.** The dependency runs one way only —
|
|
132
|
+
that is the whole point of the split. The builder-name list is literal data for that reason.
|
|
133
|
+
- The 20 ids that are already `@uptimizr/agent-core` tool names (`top_meshes`, `perf_summary`,
|
|
134
|
+
`list_sessions`, …) are frozen — renaming one breaks every MCP client.
|
|
135
|
+
- `row` must match what the SQL actually projects, not what `types.ts` declares. It is also the
|
|
136
|
+
collector's **response schema**, so an undeclared column is stripped from the API and a `null` in
|
|
137
|
+
a non-nullable one is a 500. Four suites enforce this: `@uptimizr/metrics`' `registry.test.ts`
|
|
138
|
+
(coverage, internal consistency), this package's `registry.test.ts` (the builder link, plus `row`
|
|
139
|
+
parsing against real DuckDB output over the parity fixtures and the string-encoded ClickHouse
|
|
140
|
+
shape through `coerceRows`), the collector's `registryRoutes.test.ts` (endpoint exists;
|
|
141
|
+
querystring keys === `filters`) and its `queryResponseSchemas.test.ts` (every endpoint, against a
|
|
142
|
+
seeded store, an empty one, and the in-memory store).
|
|
143
|
+
|
|
144
|
+
### Result envelopes (ADR 0051 §2, `@uptimizr/db/summary`)
|
|
145
|
+
|
|
146
|
+
`summarizeRows(metric, rows, ctx)` and `tableResult(metric, rows, ctx)` build the collector's
|
|
147
|
+
`format=table | summary` envelopes. Pure, registry-driven, browser-safe; the collector calls them
|
|
148
|
+
from one `preSerialization` hook, so no route handler knows they exist.
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
import { summarizeRows, tableResult, clusterCells, wilsonInterval } from "@uptimizr/db/summary";
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The `grain` selects the shape — `ranked` (top rows + `rest`), `series` (first/last/min/max/trend/
|
|
155
|
+
slope over the `axis` column), `clusters` (`clusterCells`: deterministic greedy merge of adjacent
|
|
156
|
+
occupied cells above a density threshold, 8-neighbourhood in 2D / 26 in 3D), or `record` (the single
|
|
157
|
+
row plus its `rateOf` rates). Everything is bounded by `limits.maxSummaryRows`.
|
|
158
|
+
|
|
159
|
+
**Rules for agents:**
|
|
160
|
+
|
|
161
|
+
- A metric's summary comes from its **column semantics**, never from a per-metric special case. If a
|
|
162
|
+
metric summarises badly, fix its `unit` / `measure` / `label` / `axis` / `rateOf` declarations.
|
|
163
|
+
- A `bucket`-grain metric must declare exactly one `axis: true` column, and no other grain may
|
|
164
|
+
declare one (`@uptimizr/metrics`' `registry.test.ts`). `label` cannot stand in — `mesh_trend`
|
|
165
|
+
labels rows by mesh.
|
|
166
|
+
- **`reading` is templated, never model-written**, and must never contain `undefined` or `NaN`; run
|
|
167
|
+
every value through `format.ts`'s total formatters.
|
|
168
|
+
- Report `total`/`share` only for an **additive** unit. Summing FPS, a ratio or a percentile across
|
|
169
|
+
rows is meaningless, and a share derived from it is worse than none.
|
|
170
|
+
- Clustering must stay a pure function of the cell _set_: accumulate in sorted coordinate order so a
|
|
171
|
+
reordered input is bit-identical (`summary.test.ts` rotates every fixture).
|
|
172
|
+
- Adding `format` to a metric's `filters` and to the collector's querystring is one change — the
|
|
173
|
+
collector's `registryRoutes.test.ts` fails if they drift.
|
|
174
|
+
|
|
73
175
|
## Cross-engine parity (ADR 0020)
|
|
74
176
|
|
|
75
177
|
The dialect-agnostic aggregations (`buildX(projectId, opts, dialect)`) are rendered per engine
|
package/README.md
CHANGED
|
@@ -7,10 +7,17 @@ The OSS storage contracts plus the single-file **DuckDB** store:
|
|
|
7
7
|
table (hot fields like camera `position`/`direction`, pointer `screen`, `mesh`, `fps` promoted to
|
|
8
8
|
columns; the full event preserved as JSON in `payload` so reads stay replay-complete) plus a
|
|
9
9
|
dedicated `node_samples` table for high-cardinality `node_transform` rows, and `projects` /
|
|
10
|
-
`api_keys` (stored only as SHA-256 hashes,
|
|
10
|
+
`api_keys` (stored only as SHA-256 hashes, each carrying a **capability set** —
|
|
11
|
+
`query` / `query:raw` / `annotate` / `ingest` — an optional label and an optional per-key rate
|
|
12
|
+
limit), plus an `agent_audit` trail of what each key asked for (ADR 0051 §7).
|
|
11
13
|
- **Engine-neutral contracts** — the dialect-agnostic query layer (`buildX` + `Dialect`), the
|
|
12
14
|
neutral event-row mappers (`toEventRow`, `toNodeSampleRow`, `formatUtcTimestamp`), and the
|
|
13
|
-
metadata types (`Project`, `ApiKeyRecord`, `ResolvedApiKey`, `SceneRepresentation
|
|
15
|
+
metadata types (`Project`, `ApiKeyRecord`, `ResolvedApiKey`, `SceneRepresentation*`,
|
|
16
|
+
`SceneRegionRecord` / `SceneRegionSummary`).
|
|
17
|
+
- **Scene registry metadata** — `scene_representations` (one proxy per scene) and
|
|
18
|
+
`scene_regions` (named, labelled boxes per scene, keyed `(project_id, scene_id, region_id)`).
|
|
19
|
+
`duckdbPutSceneRegions` replaces a scene's whole set in one transaction; `duckdbGetSceneRegions`
|
|
20
|
+
/ `duckdbListSceneRegions` read it back.
|
|
14
21
|
|
|
15
22
|
This package carries **no ClickHouse/Postgres dependency**. Optional scale adapters such as
|
|
16
23
|
`@uptimizr/db-clickhouse` compose these contracts behind the same interface. Server/Node only — no
|
|
@@ -63,6 +70,95 @@ CLIs all share one canonical file regardless of which package they run from. The
|
|
|
63
70
|
its backend with `COLLECTOR_STORE` (`duckdb` by default; `clickhouse` and `memory` are also wired in
|
|
64
71
|
`@uptimizr/collector-server`).
|
|
65
72
|
|
|
73
|
+
## Metric registry (`@uptimizr/metrics`)
|
|
74
|
+
|
|
75
|
+
The semantic layer over these aggregations — **what every aggregation means** — lives in its own
|
|
76
|
+
package, [`@uptimizr/metrics`](../metrics). It is a `Readonly<Record<MetricId, MetricDefinition>>`
|
|
77
|
+
with one entry per exported `build*` aggregation (plus two builder-less "resource" entries for the
|
|
78
|
+
session descriptor and the scene representation), declaring the metric's id, title, agent-facing
|
|
79
|
+
description, the builder behind it, its collector endpoint, result `grain`, group-by `dimensions`,
|
|
80
|
+
accepted `filters`, the output `row` schema (Zod), per-column semantics (unit, measure, label,
|
|
81
|
+
`rateOf`), row `limits`, how to read the result (`interpretation`), the `caveats` that make it
|
|
82
|
+
untrustworthy, the capture channels that feed it (`sourceChannels`, ADR 0012), `related` metrics
|
|
83
|
+
and comparison semantics. `DimensionId` and `FilterId` are closed unions declared once, and
|
|
84
|
+
`FILTER_TARGETS` maps each filter to the option field in `query/types.ts` it drives. (ADR 0051 §1.)
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { METRIC_REGISTRY, getMetric, allMetrics } from "@uptimizr/metrics";
|
|
88
|
+
|
|
89
|
+
const metric = getMetric("top_meshes");
|
|
90
|
+
metric?.endpoint; // { method: "GET", path: "/api/v1/meshes/top" }
|
|
91
|
+
metric?.row.parse(row); // validates one result row
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
It is a **separate package**, not a subpath of this one, because this package depends on
|
|
95
|
+
`@duckdb/node-api` — a ~37 MB native binding — while the registry's consumers
|
|
96
|
+
(`@uptimizr/agent-core`, `@uptimizr/mcp`, `@uptimizr/react`) run in a browser or over `npx` and
|
|
97
|
+
can never use a database driver. `@uptimizr/metrics` imports nothing but `zod` and a _type-only_
|
|
98
|
+
declaration from `@uptimizr/schema`, so it is pure data with no I/O.
|
|
99
|
+
|
|
100
|
+
### Numbers are numbers (ADR 0051 §2)
|
|
101
|
+
|
|
102
|
+
Every numeric column in a `row` schema is a strict `z.number()`, because that is what the collector
|
|
103
|
+
actually emits. Engines disagree about the wire — ClickHouse renders 64-bit integers and decimals
|
|
104
|
+
as JSON **strings** over HTTP, `pg` returns `int8`/`numeric` as strings without a type parser — so
|
|
105
|
+
each store's query runner normalises them at the single point rows leave its driver:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { coerceRows, numericColumns } from "@uptimizr/db";
|
|
109
|
+
|
|
110
|
+
coerceRows("top_meshes", [{ mesh: "box", count: "42" }]); // [{ mesh: "box", count: 42 }]
|
|
111
|
+
numericColumns(getMetric("top_meshes")!.row); // ["count"]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`build*` aggregations tag their `QuerySpec` with the metric id, so `runDuckdbQuery`,
|
|
115
|
+
`runClickhouseQuery`, `runPostgresQuery` and `runMssqlQuery` each apply `coerceRows` with no work
|
|
116
|
+
at the call site. `null` stays `null` — an aggregate over an empty set is "no samples", never `0`.
|
|
117
|
+
A value that is neither a number, `null`, nor a finite numeric string **throws** under a test runner
|
|
118
|
+
and is left untouched with a one-per-column warning in production; pass `{ strict }` to pin either.
|
|
119
|
+
The parity suites assert `typeof === "number"` for every registry-numeric column on every engine.
|
|
120
|
+
|
|
121
|
+
> **A new aggregation is not done until it has a registry entry.** Add the `build*` name to
|
|
122
|
+
> `AGGREGATION_BUILDER_NAMES` and a `MetricDefinition` to `METRIC_REGISTRY` in
|
|
123
|
+
> `@uptimizr/metrics`; its `NoUnregisteredAggregations` guard fails to typecheck and names the
|
|
124
|
+
> missing builder. This package's `src/__tests__/registry.test.ts` then asserts at runtime that
|
|
125
|
+
> `AGGREGATION_BUILDER_NAMES` is exactly the set of `build*` exports, and parses every `row`
|
|
126
|
+
> schema against real DuckDB output over the parity fixtures; the collector's
|
|
127
|
+
> `registryRoutes.test.ts` asserts that every `endpoint.path` is served and that its Zod
|
|
128
|
+
> querystring keys equal the registry `filters`.
|
|
129
|
+
|
|
130
|
+
### Result envelopes (`@uptimizr/db/summary`, ADR 0051 §2)
|
|
131
|
+
|
|
132
|
+
The registry knows enough about a metric to **summarise** it, so the collector's
|
|
133
|
+
`format=table | summary` envelopes are built here rather than in a route handler. Pure, browser-safe
|
|
134
|
+
functions with no store and no I/O — published on their own subpath for the same reason the registry
|
|
135
|
+
is, and re-exported from the package root for Node consumers:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { summarizeRows, tableResult, clusterCells } from "@uptimizr/db/summary";
|
|
139
|
+
|
|
140
|
+
tableResult("top_meshes", rows, { range, filters, limit });
|
|
141
|
+
// { meta: { metric, range, filters, sampleSize, rows, truncated, limits }, rows }
|
|
142
|
+
|
|
143
|
+
summarizeRows("top_meshes", rows, { range, filters });
|
|
144
|
+
// { kind: "ranked", total, measure, top: [{ label, value, share, … }], rest, reading, caveats, … }
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The metric's `grain` picks the shape: `ranked` top rows for a leaderboard, a `series`
|
|
148
|
+
(first/last/min/max/trend/slope over the column flagged `axis`) for a time bucket, merged `clusters`
|
|
149
|
+
for a `bin`/`voxel` grid (`clusterCells` — a deterministic greedy merge of adjacent occupied cells
|
|
150
|
+
above a density threshold, 8-neighbourhood in 2D and 26 in 3D), and the `record` itself plus its
|
|
151
|
+
`rateOf` rates for a single-row metric. Everything is capped at `limits.maxSummaryRows`.
|
|
152
|
+
|
|
153
|
+
Two invariants worth knowing before extending it:
|
|
154
|
+
|
|
155
|
+
- **`reading` is templated, not generated.** It is assembled from `ColumnSemantics` alone, so the
|
|
156
|
+
same rows always produce the same sentence. Every number goes through total formatters — a
|
|
157
|
+
`reading` containing `undefined` or `NaN` is a test failure.
|
|
158
|
+
- **Shares are only claimed where they are true.** `total`, `share` and the Wilson `confidence` note
|
|
159
|
+
appear only when the measure's unit is additive; an FPS or ratio measure reports `null` and says
|
|
160
|
+
so in the `reading` rather than summing values that cannot be summed.
|
|
161
|
+
|
|
66
162
|
## Extending
|
|
67
163
|
|
|
68
164
|
- **New columns / tables:** append a migration to `DUCKDB_MIGRATIONS`. Forward-only and additive —
|
|
@@ -73,7 +169,8 @@ its backend with `COLLECTOR_STORE` (`duckdb` by default; `clickhouse` and `memor
|
|
|
73
169
|
`QuerySpec` (`{ query, query_params }`) using the `Dialect` fragments (never hard-code
|
|
74
170
|
engine-specific SQL). Run it with `runDuckdbQuery(db, buildX(..., duckdbDialect))`; the scale
|
|
75
171
|
path runs the _same_ builder with `clickhouseDialect`. Add a `PARITY_CASES` entry so both engines
|
|
76
|
-
stay provably equal
|
|
172
|
+
stay provably equal, **and a `METRIC_REGISTRY` entry so consumers know what it means**. Builders
|
|
173
|
+
are pure and unit-tested without a live database.
|
|
77
174
|
|
|
78
175
|
## Develop
|
|
79
176
|
|
|
@@ -3,6 +3,7 @@ import { createApiKey as duckdbCreateApiKey, createProject as duckdbCreateProjec
|
|
|
3
3
|
import { createDuckdbClient } from "../duckdb/client.js";
|
|
4
4
|
import { migrateDuckdb } from "../duckdb/migrations.js";
|
|
5
5
|
import { readDbSettings } from "../env.js";
|
|
6
|
+
import { parseCapabilityList } from "../metadata.js";
|
|
6
7
|
/**
|
|
7
8
|
* Create a project and issue an API key, then print the pair. Unlike `seed.ts`
|
|
8
9
|
* (which writes the single demo project into the root `.env`), this CLI is meant
|
|
@@ -12,20 +13,36 @@ import { readDbSettings } from "../env.js";
|
|
|
12
13
|
*
|
|
13
14
|
* ```bash
|
|
14
15
|
* pnpm --filter @uptimizr/db run new-project -- "My Scene"
|
|
16
|
+
* pnpm --filter @uptimizr/db run new-project -- --capabilities query,query:raw "My Scene"
|
|
15
17
|
* ```
|
|
16
18
|
*
|
|
19
|
+
* The key is read-only (`query`) by default. Session replay and the live
|
|
20
|
+
* per-session follow additionally need `query:raw` (#309, ADR 0051 §7), which
|
|
21
|
+
* the collector only honours when `ENABLE_RAW_SESSION_RETENTION` is on
|
|
22
|
+
* (ADR 0003).
|
|
23
|
+
*
|
|
17
24
|
* Targets the OSS DuckDB store.
|
|
18
25
|
*/
|
|
19
26
|
async function main() {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
const args = process.argv.slice(2).filter((arg) => arg !== "--");
|
|
28
|
+
let capabilities = ["query"];
|
|
29
|
+
const words = [];
|
|
30
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
31
|
+
const arg = args[i];
|
|
32
|
+
if (arg === "--capabilities" || arg.startsWith("--capabilities=")) {
|
|
33
|
+
const value = arg.includes("=") ? arg.slice(arg.indexOf("=") + 1) : args[++i];
|
|
34
|
+
if (!value)
|
|
35
|
+
throw new Error("Missing value for --capabilities");
|
|
36
|
+
capabilities = parseCapabilityList(value);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
words.push(arg);
|
|
40
|
+
}
|
|
41
|
+
const name = words.join(" ").trim() || "Playground Project";
|
|
25
42
|
const db = await createDuckdbClient(readDbSettings().duckdb.path);
|
|
26
43
|
await migrateDuckdb(db);
|
|
27
44
|
const project = await duckdbCreateProject(db, name);
|
|
28
|
-
const { key } = await duckdbCreateApiKey(db, project.id);
|
|
45
|
+
const { key } = await duckdbCreateApiKey(db, project.id, { capabilities });
|
|
29
46
|
await db.close();
|
|
30
47
|
printResult(project.id, project.name, key);
|
|
31
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createProject.js","sourceRoot":"","sources":["../../src/cli/createProject.ts"],"names":[],"mappings":";AACA,OAAO,EACL,YAAY,IAAI,kBAAkB,EAClC,aAAa,IAAI,mBAAmB,GACrC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"createProject.js","sourceRoot":"","sources":["../../src/cli/createProject.ts"],"names":[],"mappings":";AACA,OAAO,EACL,YAAY,IAAI,kBAAkB,EAClC,aAAa,IAAI,mBAAmB,GACrC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAyB,MAAM,gBAAgB,CAAC;AAE5E;;;;;;;;;;;;;;;;;;GAkBG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;IACjE,IAAI,YAAY,GAAuB,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACrB,IAAI,GAAG,KAAK,gBAAgB,IAAI,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAClE,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9E,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;YAChE,YAAY,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAC1C,SAAS;QACX,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,oBAAoB,CAAC;IAE5D,MAAM,EAAE,GAAG,MAAM,kBAAkB,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,aAAa,CAAC,EAAE,CAAC,CAAC;IACxB,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,kBAAkB,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;IAC3E,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IACjB,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,WAAW,CAAC,SAAiB,EAAE,IAAY,EAAE,MAAc;IAClE,OAAO,CAAC,KAAK,CAAC,sBAAsB,SAAS,KAAK,IAAI,GAAG,CAAC,CAAC;IAC3D,OAAO,CAAC,KAAK,CAAC,kDAAkD,MAAM,EAAE,CAAC,CAAC;IAC1E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;AAC3E,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/cli/seed.js
CHANGED
|
@@ -133,14 +133,22 @@ async function main() {
|
|
|
133
133
|
const baseName = args[0] ?? "Demo Project";
|
|
134
134
|
const db = await createDuckdbClient(readDbSettings().duckdb.path);
|
|
135
135
|
await migrateDuckdb(db);
|
|
136
|
+
// Local development seed: the demo projects back the playground + dashboard,
|
|
137
|
+
// whose session replay and live-follow read raw per-session streams. Those
|
|
138
|
+
// need `query:raw` alongside `query` (#309, ADR 0051 §7) — the collector still
|
|
139
|
+
// only honours it when `ENABLE_RAW_SESSION_RETENTION` is on, which the repo's
|
|
140
|
+
// `.env.example` sets for local dev. Production keys keep the read-only
|
|
141
|
+
// `query` default (`uptimizr init` / `new-project`); grant `query:raw`
|
|
142
|
+
// deliberately with `uptimizr new-key --capabilities query,query:raw`.
|
|
143
|
+
const devCapabilities = { capabilities: ["query", "query:raw"] };
|
|
136
144
|
const viewer = await createProject(db, `${baseName} (Viewer)`);
|
|
137
|
-
const viewerKey = (await createApiKey(db, viewer.id)).key;
|
|
145
|
+
const viewerKey = (await createApiKey(db, viewer.id, devCapabilities)).key;
|
|
138
146
|
const walkable = await createProject(db, `${baseName} (Walkable)`);
|
|
139
|
-
const walkableKey = (await createApiKey(db, walkable.id)).key;
|
|
147
|
+
const walkableKey = (await createApiKey(db, walkable.id, devCapabilities)).key;
|
|
140
148
|
const showcase = await createProject(db, `${baseName} (Showcase)`);
|
|
141
|
-
const showcaseKey = (await createApiKey(db, showcase.id)).key;
|
|
149
|
+
const showcaseKey = (await createApiKey(db, showcase.id, devCapabilities)).key;
|
|
142
150
|
const gallery = await createProject(db, `${baseName} (Gallery)`);
|
|
143
|
-
const galleryKey = (await createApiKey(db, gallery.id)).key;
|
|
151
|
+
const galleryKey = (await createApiKey(db, gallery.id, devCapabilities)).key;
|
|
144
152
|
await db.close();
|
|
145
153
|
console.log(`✓ project created: ${viewer.id} (${viewer.name})`);
|
|
146
154
|
console.log(` API key (store securely, shown once): ${viewerKey}`);
|
package/dist/cli/seed.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/cli/seed.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/cli/seed.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type AgentAuditEntry, type AgentAuditInput, type AuditQueryOptions } from "../metadata.js";
|
|
2
|
+
import type { DuckdbClient } from "./client.js";
|
|
3
|
+
/** Append one audit row. */
|
|
4
|
+
export declare function recordAudit(client: DuckdbClient, entry: AgentAuditInput): Promise<void>;
|
|
5
|
+
/** Read a project's audit rows, newest first, within an optional time range. */
|
|
6
|
+
export declare function listAudit(client: DuckdbClient, projectId: string, opts?: AuditQueryOptions): Promise<AgentAuditEntry[]>;
|
|
7
|
+
/**
|
|
8
|
+
* Delete audit rows older than `cutoffMs` (epoch ms). Idempotent — deleting an
|
|
9
|
+
* already-empty range is a no-op — so the collector can run it on a timer.
|
|
10
|
+
* Returns nothing; the caller only needs to know it did not throw.
|
|
11
|
+
*/
|
|
12
|
+
export declare function pruneAudit(client: DuckdbClient, cutoffMs: number): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/duckdb/audit.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAEvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA6ChD,4BAA4B;AAC5B,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB7F;AAED,gFAAgF;AAChF,wBAAsB,SAAS,CAC7B,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,eAAe,EAAE,CAAC,CAqB5B;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAItF"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { clampAuditTool, } from "../metadata.js";
|
|
3
|
+
const AUDIT_COLS = `id, project_id, key_id, epoch_ms("at") AS at_ms, surface, tool_or_path,
|
|
4
|
+
params, row_count, duration_ms, status`;
|
|
5
|
+
function toEntry(row) {
|
|
6
|
+
return {
|
|
7
|
+
id: row.id,
|
|
8
|
+
projectId: row.project_id,
|
|
9
|
+
keyId: row.key_id,
|
|
10
|
+
at: new Date(Number(row.at_ms)),
|
|
11
|
+
surface: row.surface,
|
|
12
|
+
toolOrPath: row.tool_or_path,
|
|
13
|
+
params: row.params,
|
|
14
|
+
rowCount: row.row_count == null ? null : Number(row.row_count),
|
|
15
|
+
durationMs: Number(row.duration_ms),
|
|
16
|
+
status: Number(row.status),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/** Append one audit row. */
|
|
20
|
+
export async function recordAudit(client, entry) {
|
|
21
|
+
await client.run(`INSERT INTO agent_audit (id, project_id, key_id, "at", surface, tool_or_path, params,
|
|
22
|
+
row_count, duration_ms, status)
|
|
23
|
+
VALUES ($id, $projectId, $keyId, make_timestamp($atUs), $surface, $toolOrPath, $params,
|
|
24
|
+
CAST($rowCount AS BIGINT), $durationMs, $status)`, {
|
|
25
|
+
id: randomUUID(),
|
|
26
|
+
projectId: entry.projectId,
|
|
27
|
+
keyId: entry.keyId,
|
|
28
|
+
atUs: (entry.at?.getTime() ?? Date.now()) * 1000,
|
|
29
|
+
surface: entry.surface,
|
|
30
|
+
toolOrPath: clampAuditTool(entry.toolOrPath),
|
|
31
|
+
params: entry.params,
|
|
32
|
+
rowCount: entry.rowCount ?? null,
|
|
33
|
+
durationMs: Math.trunc(entry.durationMs),
|
|
34
|
+
status: Math.trunc(entry.status),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/** Read a project's audit rows, newest first, within an optional time range. */
|
|
38
|
+
export async function listAudit(client, projectId, opts = {}) {
|
|
39
|
+
const limit = Math.min(Math.max(Math.trunc(opts.limit ?? 100), 1), 1000);
|
|
40
|
+
const params = { projectId };
|
|
41
|
+
const where = ["project_id = $projectId"];
|
|
42
|
+
if (opts.since != null) {
|
|
43
|
+
where.push(`"at" >= make_timestamp($since)`);
|
|
44
|
+
params.since = Math.trunc(opts.since) * 1000;
|
|
45
|
+
}
|
|
46
|
+
if (opts.until != null) {
|
|
47
|
+
where.push(`"at" < make_timestamp($until)`);
|
|
48
|
+
params.until = Math.trunc(opts.until) * 1000;
|
|
49
|
+
}
|
|
50
|
+
const rows = await client.all(`SELECT ${AUDIT_COLS}
|
|
51
|
+
FROM agent_audit
|
|
52
|
+
WHERE ${where.join(" AND ")}
|
|
53
|
+
ORDER BY "at" DESC
|
|
54
|
+
LIMIT ${limit}`, params);
|
|
55
|
+
return rows.map(toEntry);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Delete audit rows older than `cutoffMs` (epoch ms). Idempotent — deleting an
|
|
59
|
+
* already-empty range is a no-op — so the collector can run it on a timer.
|
|
60
|
+
* Returns nothing; the caller only needs to know it did not throw.
|
|
61
|
+
*/
|
|
62
|
+
export async function pruneAudit(client, cutoffMs) {
|
|
63
|
+
await client.run(`DELETE FROM agent_audit WHERE "at" < make_timestamp($cutoff)`, {
|
|
64
|
+
cutoff: Math.trunc(cutoffMs) * 1000,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/duckdb/audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/duckdb/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzE,mDAAmD;AACnD,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,2DAA2D;IAC3D,GAAG,CAAC,CAAC,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAChF;;;OAGG;IACH,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACpE,qDAAqD;IACrD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAUpD;AAQD;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/duckdb/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzE,mDAAmD;AACnD,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,2DAA2D;IAC3D,GAAG,CAAC,CAAC,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAChF;;;OAGG;IACH,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACpE,qDAAqD;IACrD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAUpD;AAQD;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAkD5E"}
|
package/dist/duckdb/client.js
CHANGED
|
@@ -86,6 +86,10 @@ export async function createDuckdbClient(path) {
|
|
|
86
86
|
close() {
|
|
87
87
|
return enqueue(async () => {
|
|
88
88
|
connection.closeSync();
|
|
89
|
+
// Closing the connection alone leaves the instance holding the database
|
|
90
|
+
// file. POSIX tolerates reopening it anyway; Windows keeps an exclusive
|
|
91
|
+
// lock, so the next `createDuckdbClient(path)` on the same file fails.
|
|
92
|
+
instance.closeSync();
|
|
89
93
|
});
|
|
90
94
|
},
|
|
91
95
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/duckdb/client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/duckdb/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/duckdb/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/duckdb/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAoaxE,CAAC;AAEF;;GAEG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAQvE"}
|
|
@@ -331,6 +331,103 @@ export const DUCKDB_MIGRATIONS = [
|
|
|
331
331
|
ALTER TABLE events ADD COLUMN IF NOT EXISTS near DOUBLE;
|
|
332
332
|
`,
|
|
333
333
|
},
|
|
334
|
+
// --- Agent-scoped keys (#309, ADR 0051 §7) --------------------------------
|
|
335
|
+
// The singular `capability` column becomes a capability *set*, stored as a
|
|
336
|
+
// canonical comma-separated token list in a plain text column (every engine
|
|
337
|
+
// stores and compares text natively — no JSON type needed). Forward-only and
|
|
338
|
+
// additive: `0027_api_keys_capability` stays untouched and keeps feeding the
|
|
339
|
+
// read path as the fallback for any row this backfill has not reached.
|
|
340
|
+
{
|
|
341
|
+
id: "0031_api_keys_capabilities",
|
|
342
|
+
sql: /* sql */ `
|
|
343
|
+
ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS capabilities VARCHAR;
|
|
344
|
+
`,
|
|
345
|
+
},
|
|
346
|
+
// Idempotent backfill: promote each legacy single capability to a one-element
|
|
347
|
+
// set, exactly once. Guarded on NULL/'' so re-running the migration on every
|
|
348
|
+
// boot is a no-op after the first (and never clobbers a key minted with a set).
|
|
349
|
+
{
|
|
350
|
+
id: "0032_api_keys_capabilities_backfill",
|
|
351
|
+
sql: /* sql */ `
|
|
352
|
+
UPDATE api_keys
|
|
353
|
+
SET capabilities = coalesce(nullif(capability, ''), 'query')
|
|
354
|
+
WHERE capabilities IS NULL OR capabilities = '';
|
|
355
|
+
`,
|
|
356
|
+
},
|
|
357
|
+
// Operator-supplied key name (`uptimizr new-key --label "weekly-report-agent"`).
|
|
358
|
+
{
|
|
359
|
+
id: "0033_api_keys_label",
|
|
360
|
+
sql: /* sql */ `
|
|
361
|
+
ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS label VARCHAR;
|
|
362
|
+
`,
|
|
363
|
+
},
|
|
364
|
+
// Optional per-key request budget. NULL on either half falls back to the
|
|
365
|
+
// collector's global COLLECTOR_RATE_LIMIT_* defaults.
|
|
366
|
+
{
|
|
367
|
+
id: "0034_api_keys_rate_limit_max",
|
|
368
|
+
sql: /* sql */ `
|
|
369
|
+
ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS rate_limit_max BIGINT;
|
|
370
|
+
`,
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
id: "0035_api_keys_rate_limit_window_ms",
|
|
374
|
+
sql: /* sql */ `
|
|
375
|
+
ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS rate_limit_window_ms BIGINT;
|
|
376
|
+
`,
|
|
377
|
+
},
|
|
378
|
+
// Agent audit log: one row per authenticated request made with a non-dashboard
|
|
379
|
+
// key. `params` is bounded and redacted before it is written (never the key);
|
|
380
|
+
// rows expire after AUDIT_RETENTION_DAYS. Metadata, not events — no event type
|
|
381
|
+
// is added (`@uptimizr/schema` untouched).
|
|
382
|
+
//
|
|
383
|
+
// `at` is a DuckDB keyword, so it is double-quoted here and in every accessor
|
|
384
|
+
// (`duckdb/audit.ts`). The column name matches the other three engines, where
|
|
385
|
+
// it needs no quoting.
|
|
386
|
+
{
|
|
387
|
+
id: "0036_agent_audit",
|
|
388
|
+
sql: /* sql */ `
|
|
389
|
+
CREATE TABLE IF NOT EXISTS agent_audit (
|
|
390
|
+
id VARCHAR PRIMARY KEY,
|
|
391
|
+
project_id VARCHAR NOT NULL,
|
|
392
|
+
key_id VARCHAR NOT NULL,
|
|
393
|
+
"at" TIMESTAMP NOT NULL DEFAULT now(),
|
|
394
|
+
surface VARCHAR NOT NULL DEFAULT 'http',
|
|
395
|
+
tool_or_path VARCHAR NOT NULL,
|
|
396
|
+
params VARCHAR NOT NULL DEFAULT '',
|
|
397
|
+
row_count BIGINT,
|
|
398
|
+
duration_ms BIGINT NOT NULL DEFAULT 0,
|
|
399
|
+
status INTEGER NOT NULL DEFAULT 200
|
|
400
|
+
);
|
|
401
|
+
`,
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
id: "0037_agent_audit_idx",
|
|
405
|
+
sql: /* sql */ `
|
|
406
|
+
CREATE INDEX IF NOT EXISTS agent_audit_project_at_idx
|
|
407
|
+
ON agent_audit (project_id, "at");
|
|
408
|
+
`,
|
|
409
|
+
},
|
|
410
|
+
// Scene regions (ADR 0051 §2 / sketch §B.2): developer-named, labelled boxes
|
|
411
|
+
// that extend the scene registry (ADR 0014) with a vocabulary for *where* —
|
|
412
|
+
// "the entrance", "the checkout counter". One row per region, keyed by
|
|
413
|
+
// (project, scene, region); regions may overlap. `bounds` is JSON text (the
|
|
414
|
+
// `[minX,…,maxZ]` tuple) parsed by the row mapper, exactly as
|
|
415
|
+
// `scene_representations.bounds` is.
|
|
416
|
+
{
|
|
417
|
+
id: "0038_scene_regions",
|
|
418
|
+
sql: /* sql */ `
|
|
419
|
+
CREATE TABLE IF NOT EXISTS scene_regions (
|
|
420
|
+
project_id VARCHAR NOT NULL,
|
|
421
|
+
scene_id VARCHAR NOT NULL,
|
|
422
|
+
region_id VARCHAR NOT NULL,
|
|
423
|
+
label VARCHAR NOT NULL,
|
|
424
|
+
description VARCHAR,
|
|
425
|
+
bounds VARCHAR NOT NULL,
|
|
426
|
+
updated_at TIMESTAMP NOT NULL DEFAULT now(),
|
|
427
|
+
PRIMARY KEY (project_id, scene_id, region_id)
|
|
428
|
+
);
|
|
429
|
+
`,
|
|
430
|
+
},
|
|
334
431
|
];
|
|
335
432
|
/**
|
|
336
433
|
* Apply all DuckDB migrations in order. Idempotent — safe to run on every boot.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/duckdb/migrations.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/duckdb/migrations.ts"],"names":[],"mappings":"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"}
|