@mongrov/analytics 0.6.0 → 0.8.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/README.md +23 -10
- package/UPGRADING.md +456 -0
- package/dist/core/device-events.d.ts +14 -0
- package/dist/core/device-events.d.ts.map +1 -0
- package/dist/core/device-events.js +13 -0
- package/dist/core/device-events.js.map +1 -0
- package/dist/core/errors.d.ts +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/core/extensions.d.ts +21 -4
- package/dist/core/extensions.d.ts.map +1 -1
- package/dist/core/extensions.js +21 -4
- package/dist/core/extensions.js.map +1 -1
- package/dist/core/factory.d.ts.map +1 -1
- package/dist/core/factory.js +125 -23
- package/dist/core/factory.js.map +1 -1
- package/dist/core/hooks.js +1 -1
- package/dist/core/hooks.js.map +1 -1
- package/dist/core/index.d.ts +13 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +18 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/insight.d.ts +44 -0
- package/dist/core/insight.d.ts.map +1 -0
- package/dist/core/insight.js +62 -0
- package/dist/core/insight.js.map +1 -0
- package/dist/core/metric_metadata.d.ts +55 -0
- package/dist/core/metric_metadata.d.ts.map +1 -1
- package/dist/core/metric_metadata.js +35 -7
- package/dist/core/metric_metadata.js.map +1 -1
- package/dist/core/migrations.d.ts.map +1 -1
- package/dist/core/migrations.js +103 -2
- package/dist/core/migrations.js.map +1 -1
- package/dist/core/retention.d.ts +44 -13
- package/dist/core/retention.d.ts.map +1 -1
- package/dist/core/retention.js +49 -22
- package/dist/core/retention.js.map +1 -1
- package/dist/core/sampling.d.ts +70 -0
- package/dist/core/sampling.d.ts.map +1 -0
- package/dist/core/sampling.js +107 -0
- package/dist/core/sampling.js.map +1 -0
- package/dist/core/schemas.d.ts +73 -2
- package/dist/core/schemas.d.ts.map +1 -1
- package/dist/core/schemas.js +160 -5
- package/dist/core/schemas.js.map +1 -1
- package/dist/core/table_metadata.d.ts.map +1 -1
- package/dist/core/table_metadata.js +3 -0
- package/dist/core/table_metadata.js.map +1 -1
- package/dist/core/types.d.ts +45 -10
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/warehouse.d.ts +28 -0
- package/dist/core/warehouse.d.ts.map +1 -1
- package/dist/core/warehouse.js +44 -0
- package/dist/core/warehouse.js.map +1 -1
- package/dist/core/watermark-cache.d.ts +75 -0
- package/dist/core/watermark-cache.d.ts.map +1 -0
- package/dist/core/watermark-cache.js +0 -0
- package/dist/core/watermark-cache.js.map +1 -0
- package/dist/rules/__fakes__/fakeEngine.d.ts +2 -0
- package/dist/rules/__fakes__/fakeEngine.d.ts.map +1 -1
- package/dist/rules/__fakes__/fakeEngine.js +4 -0
- package/dist/rules/__fakes__/fakeEngine.js.map +1 -1
- package/dist/rules/baseline-reader.d.ts +55 -0
- package/dist/rules/baseline-reader.d.ts.map +1 -0
- package/dist/rules/baseline-reader.js +111 -0
- package/dist/rules/baseline-reader.js.map +1 -0
- package/dist/rules/compiler.d.ts +36 -1
- package/dist/rules/compiler.d.ts.map +1 -1
- package/dist/rules/compiler.js +185 -39
- package/dist/rules/compiler.js.map +1 -1
- package/dist/rules/defaults/luminx.d.ts.map +1 -1
- package/dist/rules/defaults/luminx.js +8 -0
- package/dist/rules/defaults/luminx.js.map +1 -1
- package/dist/rules/defaults/viva.d.ts.map +1 -1
- package/dist/rules/defaults/viva.js +7 -0
- package/dist/rules/defaults/viva.js.map +1 -1
- package/dist/rules/defaults/yogaring.d.ts.map +1 -1
- package/dist/rules/defaults/yogaring.js +7 -0
- package/dist/rules/defaults/yogaring.js.map +1 -1
- package/dist/rules/defaults/ziva.d.ts.map +1 -1
- package/dist/rules/defaults/ziva.js +100 -24
- package/dist/rules/defaults/ziva.js.map +1 -1
- package/dist/rules/evaluator.d.ts +14 -3
- package/dist/rules/evaluator.d.ts.map +1 -1
- package/dist/rules/evaluator.js +157 -5
- package/dist/rules/evaluator.js.map +1 -1
- package/dist/rules/factory.d.ts.map +1 -1
- package/dist/rules/factory.js +5 -1
- package/dist/rules/factory.js.map +1 -1
- package/dist/rules/index.d.ts +2 -1
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/index.js +2 -1
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/schema.d.ts +75 -4
- package/dist/rules/schema.d.ts.map +1 -1
- package/dist/rules/schema.js +44 -0
- package/dist/rules/schema.js.map +1 -1
- package/dist/rules/types.d.ts +16 -1
- package/dist/rules/types.d.ts.map +1 -1
- package/dist/rules/validator.d.ts.map +1 -1
- package/dist/rules/validator.js +89 -0
- package/dist/rules/validator.js.map +1 -1
- package/dist/sync/baseline-compute.d.ts +63 -0
- package/dist/sync/baseline-compute.d.ts.map +1 -0
- package/dist/sync/baseline-compute.js +211 -0
- package/dist/sync/baseline-compute.js.map +1 -0
- package/dist/sync/events.d.ts +19 -5
- package/dist/sync/events.d.ts.map +1 -1
- package/dist/sync/events.js +17 -0
- package/dist/sync/events.js.map +1 -1
- package/dist/sync/factory.d.ts +54 -8
- package/dist/sync/factory.d.ts.map +1 -1
- package/dist/sync/factory.js +145 -46
- package/dist/sync/factory.js.map +1 -1
- package/dist/sync/fetcher.d.ts +15 -2
- package/dist/sync/fetcher.d.ts.map +1 -1
- package/dist/sync/fetcher.js +43 -7
- package/dist/sync/fetcher.js.map +1 -1
- package/dist/sync/flusher.d.ts +52 -2
- package/dist/sync/flusher.d.ts.map +1 -1
- package/dist/sync/flusher.js +78 -9
- package/dist/sync/flusher.js.map +1 -1
- package/dist/sync/index.d.ts +3 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +1 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/mapper/activity.d.ts.map +1 -1
- package/dist/sync/mapper/activity.js +2 -1
- package/dist/sync/mapper/activity.js.map +1 -1
- package/dist/sync/mapper/firmware.d.ts +3 -12
- package/dist/sync/mapper/firmware.d.ts.map +1 -1
- package/dist/sync/mapper/firmware.js +2 -8
- package/dist/sync/mapper/firmware.js.map +1 -1
- package/dist/sync/mapper/ring-config.d.ts +76 -28
- package/dist/sync/mapper/ring-config.d.ts.map +1 -1
- package/dist/sync/mapper/ring-config.js +118 -35
- package/dist/sync/mapper/ring-config.js.map +1 -1
- package/dist/sync/mapper/schema.d.ts +669 -0
- package/dist/sync/mapper/schema.d.ts.map +1 -0
- package/dist/sync/mapper/schema.js +160 -0
- package/dist/sync/mapper/schema.js.map +1 -0
- package/dist/sync/mapper/sleep.d.ts +58 -13
- package/dist/sync/mapper/sleep.d.ts.map +1 -1
- package/dist/sync/mapper/sleep.js +141 -44
- package/dist/sync/mapper/sleep.js.map +1 -1
- package/dist/sync/mapper/types.d.ts +118 -29
- package/dist/sync/mapper/types.d.ts.map +1 -1
- package/dist/sync/pending_closes.js +2 -2
- package/dist/sync/pending_closes.js.map +1 -1
- package/dist/sync/pusher.js +2 -2
- package/dist/sync/pusher.js.map +1 -1
- package/dist/sync/scheduler.d.ts +7 -0
- package/dist/sync/scheduler.d.ts.map +1 -1
- package/dist/sync/scheduler.js +14 -0
- package/dist/sync/scheduler.js.map +1 -1
- package/dist/tools/__fakes__/engine.d.ts +2 -0
- package/dist/tools/__fakes__/engine.d.ts.map +1 -1
- package/dist/tools/__fakes__/engine.js +10 -0
- package/dist/tools/__fakes__/engine.js.map +1 -1
- package/dist/tools/authorize.d.ts +19 -12
- package/dist/tools/authorize.d.ts.map +1 -1
- package/dist/tools/authorize.js +31 -40
- package/dist/tools/authorize.js.map +1 -1
- package/dist/tools/factory.d.ts +2 -0
- package/dist/tools/factory.d.ts.map +1 -1
- package/dist/tools/factory.js +12 -1
- package/dist/tools/factory.js.map +1 -1
- package/dist/tools/formatters/copy-guidelines.d.ts +57 -0
- package/dist/tools/formatters/copy-guidelines.d.ts.map +1 -0
- package/dist/tools/formatters/copy-guidelines.js +110 -0
- package/dist/tools/formatters/copy-guidelines.js.map +1 -0
- package/dist/tools/formatters/index.d.ts +14 -0
- package/dist/tools/formatters/index.d.ts.map +1 -0
- package/dist/tools/formatters/index.js +14 -0
- package/dist/tools/formatters/index.js.map +1 -0
- package/dist/tools/formatters/spo2.d.ts +21 -0
- package/dist/tools/formatters/spo2.d.ts.map +1 -0
- package/dist/tools/formatters/spo2.js +79 -0
- package/dist/tools/formatters/spo2.js.map +1 -0
- package/dist/tools/{formatters.d.ts → formatters/text.d.ts} +1 -1
- package/dist/tools/formatters/text.d.ts.map +1 -0
- package/dist/tools/{formatters.js → formatters/text.js} +1 -1
- package/dist/tools/formatters/text.js.map +1 -0
- package/dist/tools/impls/activity.d.ts +2 -2
- package/dist/tools/impls/activity.js +7 -3
- package/dist/tools/impls/activity.js.map +1 -1
- package/dist/tools/impls/anomaly.d.ts +2 -2
- package/dist/tools/impls/anomaly.js +8 -4
- package/dist/tools/impls/anomaly.js.map +1 -1
- package/dist/tools/impls/compare.d.ts +2 -2
- package/dist/tools/impls/compare.js +8 -4
- package/dist/tools/impls/compare.js.map +1 -1
- package/dist/tools/impls/hrv.d.ts +2 -2
- package/dist/tools/impls/hrv.js +6 -2
- package/dist/tools/impls/hrv.js.map +1 -1
- package/dist/tools/impls/insights.d.ts +4 -4
- package/dist/tools/impls/insights.d.ts.map +1 -1
- package/dist/tools/impls/insights.js +10 -3
- package/dist/tools/impls/insights.js.map +1 -1
- package/dist/tools/impls/sleep.d.ts +2 -2
- package/dist/tools/impls/sleep.js +6 -2
- package/dist/tools/impls/sleep.js.map +1 -1
- package/dist/tools/impls/spo2.d.ts +52 -0
- package/dist/tools/impls/spo2.d.ts.map +1 -0
- package/dist/tools/impls/spo2.js +65 -0
- package/dist/tools/impls/spo2.js.map +1 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/mcp/guard.d.ts +28 -11
- package/dist/tools/mcp/guard.d.ts.map +1 -1
- package/dist/tools/mcp/guard.js +45 -15
- package/dist/tools/mcp/guard.js.map +1 -1
- package/dist/tools/mcp/index.d.ts +1 -1
- package/dist/tools/mcp/index.d.ts.map +1 -1
- package/dist/tools/mcp/index.js +1 -1
- package/dist/tools/mcp/index.js.map +1 -1
- package/dist/tools/mcp/server.d.ts.map +1 -1
- package/dist/tools/mcp/server.js +4 -0
- package/dist/tools/mcp/server.js.map +1 -1
- package/dist/tools/mcp/transports/http.d.ts.map +1 -1
- package/dist/tools/mcp/transports/http.js +4 -0
- package/dist/tools/mcp/transports/http.js.map +1 -1
- package/package.json +8 -5
- package/dist/tools/formatters.d.ts.map +0 -1
- package/dist/tools/formatters.js.map +0 -1
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Effective sampling cadence (Sprint 5 T-41, principle 22).
|
|
3
|
+
*
|
|
4
|
+
* > **Hardware-agnostic cadence.** Chart rendering, rule evaluation windows,
|
|
5
|
+
* > and gap detection derive sampling interval from
|
|
6
|
+
* > `device_config.interval_minutes`, never from constants.
|
|
7
|
+
*
|
|
8
|
+
* The point is that a firmware upgrade changing sampling rate should
|
|
9
|
+
* propagate to charts and rules without an app release. A chart that
|
|
10
|
+
* hard-codes "SpO₂ every 30 minutes" draws the wrong gaps the day a ring
|
|
11
|
+
* ships at 5-minute sampling; a rule whose window was sized against 30
|
|
12
|
+
* minutes silently stops being satisfiable.
|
|
13
|
+
*
|
|
14
|
+
* `metric_metadata.sampling_minutes` remains the fallback — it is what we
|
|
15
|
+
* know before a device has ever reported its schedule, which is every
|
|
16
|
+
* install until the first sync.
|
|
17
|
+
*
|
|
18
|
+
* ## Why this is a runtime read, not a constant
|
|
19
|
+
*
|
|
20
|
+
* `device_config` is SCD-2: one open row per (device, metric), with history.
|
|
21
|
+
* The effective cadence is therefore a property of a *device*, not of the
|
|
22
|
+
* metric, and two family members on one account can legitimately differ.
|
|
23
|
+
*
|
|
24
|
+
* ## Caching
|
|
25
|
+
*
|
|
26
|
+
* Memoized per `(deviceId, metric)`. Ring config changes rarely — it only
|
|
27
|
+
* moves when the user or firmware alters the schedule — so a long TTL is
|
|
28
|
+
* safe, and `invalidate()` covers the case where a sync just wrote a new
|
|
29
|
+
* config row.
|
|
30
|
+
*/
|
|
31
|
+
import { METRIC_METADATA, } from './metric_metadata';
|
|
32
|
+
/** Default memo lifetime. Ring schedules change on the order of never. */
|
|
33
|
+
export const SAMPLING_CACHE_TTL_MS = 10 * 60 * 1000;
|
|
34
|
+
/** The fallback, with no I/O. */
|
|
35
|
+
export function fallbackSampling(metric) {
|
|
36
|
+
return {
|
|
37
|
+
minutes: METRIC_METADATA[metric].sampling_minutes,
|
|
38
|
+
source: 'metric_metadata',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export function createSamplingResolver(config) {
|
|
42
|
+
const ttlMs = config.ttlMs ?? SAMPLING_CACHE_TTL_MS;
|
|
43
|
+
const now = config.now ?? (() => Date.now());
|
|
44
|
+
const cache = new Map();
|
|
45
|
+
const keyOf = (deviceId, metric) => `${deviceId} ${metric}`;
|
|
46
|
+
return {
|
|
47
|
+
async resolve(metric, deviceId) {
|
|
48
|
+
// Register-time validation has no device. Returning the fallback here
|
|
49
|
+
// is deliberately permissive: a denser real device only ever makes a
|
|
50
|
+
// rule MORE satisfiable, never less, so validating against the
|
|
51
|
+
// nominal cadence cannot produce a false pass.
|
|
52
|
+
if (!deviceId)
|
|
53
|
+
return fallbackSampling(metric);
|
|
54
|
+
const key = keyOf(deviceId, metric);
|
|
55
|
+
const hit = cache.get(key);
|
|
56
|
+
if (hit && hit.expiresAt > now())
|
|
57
|
+
return hit.value;
|
|
58
|
+
let value = fallbackSampling(metric);
|
|
59
|
+
try {
|
|
60
|
+
const rows = await config.analytics.execute(`SELECT interval_minutes FROM device_config
|
|
61
|
+
WHERE device_id = $deviceId AND metric = $metric
|
|
62
|
+
AND valid_to IS NULL
|
|
63
|
+
ORDER BY valid_from DESC LIMIT 1`, { deviceId, metric });
|
|
64
|
+
const interval = rows[0]?.interval_minutes;
|
|
65
|
+
if (typeof interval === 'number' && interval > 0) {
|
|
66
|
+
value = { minutes: interval, source: 'device_config' };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
// A missing config row is normal (pre-first-sync). A failed read is
|
|
71
|
+
// not, but falling back beats failing a chart render or an
|
|
72
|
+
// evaluation pass over a cadence lookup.
|
|
73
|
+
config.logger?.warn('sampling: device_config read failed, using fallback', {
|
|
74
|
+
metric,
|
|
75
|
+
deviceId,
|
|
76
|
+
err: err.message,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
cache.set(key, { value, expiresAt: now() + ttlMs });
|
|
80
|
+
return value;
|
|
81
|
+
},
|
|
82
|
+
invalidate(deviceId) {
|
|
83
|
+
if (deviceId === undefined) {
|
|
84
|
+
cache.clear();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const prefix = `${deviceId} `;
|
|
88
|
+
for (const key of cache.keys()) {
|
|
89
|
+
if (key.startsWith(prefix))
|
|
90
|
+
cache.delete(key);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Minimum window, in minutes, that can hold `consecutive` samples at a
|
|
97
|
+
* given cadence. Used by the rules validator and by gap detection.
|
|
98
|
+
*
|
|
99
|
+
* `per_session` metrics return `null` — "consecutive nights" is bounded by
|
|
100
|
+
* the rule's window in days, not by a sampling interval.
|
|
101
|
+
*/
|
|
102
|
+
export function minimumWindowMinutes(sampling, consecutive) {
|
|
103
|
+
if (sampling === 'per_session')
|
|
104
|
+
return null;
|
|
105
|
+
return sampling * Math.max(1, consecutive);
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=sampling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sampling.js","sourceRoot":"","sources":["../../src/core/sampling.ts"],"names":[],"mappings":"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"}
|
package/dist/core/schemas.d.ts
CHANGED
|
@@ -23,13 +23,82 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import type { HybridDuckDB } from './engine';
|
|
25
25
|
/** Ordered list of every warehouse table. Order = creation order. */
|
|
26
|
-
export declare const TABLE_NAMES: readonly ["hrv", "heart_rate", "spo2", "temperature", "activity", "activity_bucket", "sleep_session", "sleep_stage", "sleep_raw", "device_event", "device_battery", "device_config", "insight", "sync_watermark", "tool_call_audit"];
|
|
26
|
+
export declare const TABLE_NAMES: readonly ["hrv", "heart_rate", "spo2", "temperature", "activity", "activity_bucket", "sleep_session", "sleep_stage", "sleep_raw", "device_event", "device_battery", "device_config", "insight", "sync_watermark", "tool_call_audit", "user_baseline"];
|
|
27
27
|
export type TableName = (typeof TABLE_NAMES)[number];
|
|
28
|
+
/**
|
|
29
|
+
* Tables that exist only in the local catalog and are never created in the
|
|
30
|
+
* attached R2 zone.
|
|
31
|
+
*
|
|
32
|
+
* `user_baseline` is derived data: it is recomputed from the union views
|
|
33
|
+
* after each sync cycle and is cheap to rebuild, so pushing it would add an
|
|
34
|
+
* Iceberg table nobody reads and invite two devices in the same family to
|
|
35
|
+
* race on the same composite PK.
|
|
36
|
+
*
|
|
37
|
+
* `sync_watermark` is deliberately NOT here, despite being per-device
|
|
38
|
+
* bookkeeping that is never pushed (`TABLE_METADATA.syncable: false`).
|
|
39
|
+
* Excluding it broke the T-18 retention integration cases, which exercise
|
|
40
|
+
* the sweep against the real attached Iceberg catalog and need the table
|
|
41
|
+
* present there. An empty remote copy is harmless; a failing sweep is not.
|
|
42
|
+
*/
|
|
43
|
+
export declare const LOCAL_ONLY_TABLES: ReadonlySet<TableName>;
|
|
28
44
|
/**
|
|
29
45
|
* Frozen DDL for every warehouse table. Copied verbatim from spec §Table
|
|
30
46
|
* schema; rewrite happens in `ensureSchemas` at issue time.
|
|
31
47
|
*/
|
|
32
48
|
export declare const SCHEMAS: Readonly<Record<TableName, string>>;
|
|
49
|
+
/**
|
|
50
|
+
* Lookup index for the `insight` table (spec §Table schema). Local catalog
|
|
51
|
+
* only — Iceberg has no CREATE INDEX; remote-side query pruning comes from
|
|
52
|
+
* the `day(ts)` partition instead. Issued by migration step 3.
|
|
53
|
+
*/
|
|
54
|
+
export declare function insightIndexDdl(catalog: string): string;
|
|
55
|
+
/**
|
|
56
|
+
* Sensor tables exposed through a `v_{table}` union view (Sprint 5 §3).
|
|
57
|
+
*
|
|
58
|
+
* Registry queries, rule SQL, and tool SQL all target `v_{table}` and never
|
|
59
|
+
* `local.{table}` or `r2.default.{table}` directly (principle 19). Internal
|
|
60
|
+
* tables are absent deliberately: `insight`, `sync_watermark`,
|
|
61
|
+
* `tool_call_audit`, `user_baseline` and `device_config` are local-authoritative
|
|
62
|
+
* or local-only, so a union would either duplicate rows or read a remote
|
|
63
|
+
* copy that is never authoritative.
|
|
64
|
+
*/
|
|
65
|
+
export declare const VIEWED_TABLES: readonly ["hrv", "heart_rate", "spo2", "temperature", "activity", "activity_bucket", "sleep_session", "sleep_stage", "device_event", "device_battery"];
|
|
66
|
+
export type ViewedTable = (typeof VIEWED_TABLES)[number];
|
|
67
|
+
/** Timestamp column the watermark partitions on, per table. */
|
|
68
|
+
export declare function watermarkColumnFor(table: ViewedTable): string;
|
|
69
|
+
/**
|
|
70
|
+
* Build the `CREATE OR REPLACE VIEW v_{table}` DDL for one sensor table.
|
|
71
|
+
*
|
|
72
|
+
* The view is what makes freshness honest: rows the device has flushed
|
|
73
|
+
* locally but not yet pushed to R2 are invisible in `r2.default.{table}`,
|
|
74
|
+
* and rows already pushed exist in BOTH catalogs. The push watermark
|
|
75
|
+
* partitions the two sources exactly —
|
|
76
|
+
*
|
|
77
|
+
* local: rows strictly AFTER the watermark (not yet pushed)
|
|
78
|
+
* remote: everything (pushed)
|
|
79
|
+
*
|
|
80
|
+
* — so the union is complete with no duplicates at the boundary, and a row
|
|
81
|
+
* becomes remote-visible at the same instant it stops being local-visible.
|
|
82
|
+
*
|
|
83
|
+
* The watermark subquery reads `sync_watermark` rather than taking a bound
|
|
84
|
+
* parameter because DuckDB views cannot close over query-time params; the
|
|
85
|
+
* view must resolve the current cursor on every scan. `$brand` /
|
|
86
|
+
* `$family_id` are likewise unavailable inside a view body, so the tenant
|
|
87
|
+
* filter is baked in at creation time from the attach context — which is
|
|
88
|
+
* safe precisely because views are dropped and recreated on every attach
|
|
89
|
+
* (T-06), so a brand switch cannot leave a view scoped to the old tenant.
|
|
90
|
+
*
|
|
91
|
+
* `remoteCatalog` omitted (local mode) produces a local-only view with no
|
|
92
|
+
* UNION, so consumers write one SQL string that works in both modes.
|
|
93
|
+
*/
|
|
94
|
+
export declare function generateViewDdl(table: ViewedTable, ctx: {
|
|
95
|
+
brand: string;
|
|
96
|
+
familyId: string;
|
|
97
|
+
localCatalog: string;
|
|
98
|
+
remoteCatalog?: string;
|
|
99
|
+
}): string;
|
|
100
|
+
/** `DROP VIEW IF EXISTS v_{table}` for detach + brand switch. */
|
|
101
|
+
export declare function dropViewDdl(table: ViewedTable): string;
|
|
33
102
|
/**
|
|
34
103
|
* Rewrite one base DDL to `CREATE TABLE IF NOT EXISTS <catalog>.<table>`.
|
|
35
104
|
*
|
|
@@ -62,5 +131,7 @@ export declare const LOCAL_SCHEMAS: Readonly<Record<TableName, string>>;
|
|
|
62
131
|
* catalog (without). Default is `SCHEMAS` for back-compat with 0.4.x
|
|
63
132
|
* callers that only wrote to the attached remote.
|
|
64
133
|
*/
|
|
65
|
-
export declare function ensureSchemas(db: HybridDuckDB, catalog: string, schemas?: Readonly<Record<TableName, string
|
|
134
|
+
export declare function ensureSchemas(db: HybridDuckDB, catalog: string, schemas?: Readonly<Record<TableName, string>>, opts?: {
|
|
135
|
+
skipLocalOnly?: boolean;
|
|
136
|
+
}): Promise<void>;
|
|
66
137
|
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/core/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAE5C,qEAAqE;AACrE,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/core/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAE5C,qEAAqE;AACrE,eAAO,MAAM,WAAW,uPAiBd,CAAA;AAEV,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAA;AAEpD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,SAAS,CAEnD,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CA4MtD,CAAA;AAEF;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,wJAWhB,CAAA;AAEV,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAExD,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAE7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACrF,MAAM,CA0BR;AAkBD,iEAAiE;AACjE,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAKrF;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKlD;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAI7D,CAAA;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,EAAE,EAAE,YAAY,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAW,EACtD,IAAI,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GACrC,OAAO,CAAC,IAAI,CAAC,CAmBf"}
|
package/dist/core/schemas.js
CHANGED
|
@@ -39,7 +39,26 @@ export const TABLE_NAMES = [
|
|
|
39
39
|
'insight',
|
|
40
40
|
'sync_watermark',
|
|
41
41
|
'tool_call_audit',
|
|
42
|
+
'user_baseline',
|
|
42
43
|
];
|
|
44
|
+
/**
|
|
45
|
+
* Tables that exist only in the local catalog and are never created in the
|
|
46
|
+
* attached R2 zone.
|
|
47
|
+
*
|
|
48
|
+
* `user_baseline` is derived data: it is recomputed from the union views
|
|
49
|
+
* after each sync cycle and is cheap to rebuild, so pushing it would add an
|
|
50
|
+
* Iceberg table nobody reads and invite two devices in the same family to
|
|
51
|
+
* race on the same composite PK.
|
|
52
|
+
*
|
|
53
|
+
* `sync_watermark` is deliberately NOT here, despite being per-device
|
|
54
|
+
* bookkeeping that is never pushed (`TABLE_METADATA.syncable: false`).
|
|
55
|
+
* Excluding it broke the T-18 retention integration cases, which exercise
|
|
56
|
+
* the sweep against the real attached Iceberg catalog and need the table
|
|
57
|
+
* present there. An empty remote copy is harmless; a failing sweep is not.
|
|
58
|
+
*/
|
|
59
|
+
export const LOCAL_ONLY_TABLES = new Set([
|
|
60
|
+
'user_baseline',
|
|
61
|
+
]);
|
|
43
62
|
/**
|
|
44
63
|
* Frozen DDL for every warehouse table. Copied verbatim from spec §Table
|
|
45
64
|
* schema; rewrite happens in `ensureSchemas` at issue time.
|
|
@@ -151,32 +170,39 @@ export const SCHEMAS = Object.freeze({
|
|
|
151
170
|
device_id VARCHAR NOT NULL,
|
|
152
171
|
battery_pct DOUBLE NOT NULL
|
|
153
172
|
) PARTITIONED BY (day(ts), device_id);`,
|
|
173
|
+
// Sprint 5 §2 — `metric VARCHAR`, not the firmware's `data_type` integer.
|
|
174
|
+
// Principle 21: firmware enums never leak into the schema. The mapper
|
|
175
|
+
// translates `dataType` (1=heartRate, 2=spo2, 3=temperature, 4=HRV per
|
|
176
|
+
// the JStyle J2301A SDK) at the ingestion boundary.
|
|
154
177
|
device_config: `CREATE TABLE device_config (
|
|
155
178
|
device_id VARCHAR NOT NULL,
|
|
156
179
|
brand VARCHAR NOT NULL,
|
|
157
180
|
family_id VARCHAR NOT NULL,
|
|
158
181
|
user_id VARCHAR NOT NULL,
|
|
159
|
-
|
|
182
|
+
metric VARCHAR NOT NULL,
|
|
160
183
|
interval_minutes INTEGER NOT NULL,
|
|
161
184
|
start_time VARCHAR,
|
|
162
185
|
end_time VARCHAR,
|
|
163
186
|
weeks INTEGER,
|
|
164
187
|
valid_from TIMESTAMP NOT NULL,
|
|
165
188
|
valid_to TIMESTAMP,
|
|
166
|
-
PRIMARY KEY (device_id,
|
|
189
|
+
PRIMARY KEY (device_id, metric, valid_from)
|
|
167
190
|
);`,
|
|
168
191
|
insight: `CREATE TABLE insight (
|
|
169
|
-
|
|
192
|
+
insight_id VARCHAR PRIMARY KEY,
|
|
170
193
|
ts TIMESTAMP NOT NULL,
|
|
171
194
|
brand VARCHAR NOT NULL,
|
|
172
195
|
family_id VARCHAR NOT NULL,
|
|
173
196
|
user_id VARCHAR NOT NULL,
|
|
174
197
|
rule_id VARCHAR,
|
|
198
|
+
metric VARCHAR NOT NULL,
|
|
199
|
+
kind VARCHAR NOT NULL,
|
|
175
200
|
severity VARCHAR NOT NULL,
|
|
176
201
|
title VARCHAR NOT NULL,
|
|
177
202
|
body TEXT,
|
|
178
203
|
evidence VARCHAR,
|
|
179
|
-
acknowledged_at TIMESTAMP
|
|
204
|
+
acknowledged_at TIMESTAMP,
|
|
205
|
+
dismissed_at TIMESTAMP
|
|
180
206
|
) PARTITIONED BY (day(ts));`,
|
|
181
207
|
sync_watermark: `CREATE TABLE sync_watermark (
|
|
182
208
|
brand VARCHAR NOT NULL,
|
|
@@ -200,7 +226,131 @@ export const SCHEMAS = Object.freeze({
|
|
|
200
226
|
outcome VARCHAR NOT NULL,
|
|
201
227
|
error_message VARCHAR
|
|
202
228
|
) PARTITIONED BY (day(ts));`,
|
|
229
|
+
// Sprint 5 §7 — shared baseline source of truth for rules, tools, and
|
|
230
|
+
// screens. Quantiles are computed DAY-FIRST (principle 27): readings
|
|
231
|
+
// collapse to one value per local day, then quantiles run across days.
|
|
232
|
+
// `sample_count` therefore counts DAYS, not readings — a row is only
|
|
233
|
+
// written at >= 20 days (BASELINE_MIN_DAYS).
|
|
234
|
+
//
|
|
235
|
+
// Not partitioned: the table holds at most
|
|
236
|
+
// (metrics x windows) = 21 rows per user, and the composite PK is the
|
|
237
|
+
// only access path any consumer uses.
|
|
238
|
+
user_baseline: `CREATE TABLE user_baseline (
|
|
239
|
+
brand VARCHAR NOT NULL,
|
|
240
|
+
family_id VARCHAR NOT NULL,
|
|
241
|
+
user_id VARCHAR NOT NULL,
|
|
242
|
+
metric VARCHAR NOT NULL,
|
|
243
|
+
window_days SMALLINT NOT NULL,
|
|
244
|
+
p05 DOUBLE,
|
|
245
|
+
p10 DOUBLE,
|
|
246
|
+
p50 DOUBLE,
|
|
247
|
+
p90 DOUBLE,
|
|
248
|
+
p95 DOUBLE,
|
|
249
|
+
mean DOUBLE,
|
|
250
|
+
stddev DOUBLE,
|
|
251
|
+
sample_count INTEGER,
|
|
252
|
+
computed_at TIMESTAMP NOT NULL,
|
|
253
|
+
PRIMARY KEY (brand, family_id, user_id, metric, window_days)
|
|
254
|
+
);`,
|
|
203
255
|
});
|
|
256
|
+
/**
|
|
257
|
+
* Lookup index for the `insight` table (spec §Table schema). Local catalog
|
|
258
|
+
* only — Iceberg has no CREATE INDEX; remote-side query pruning comes from
|
|
259
|
+
* the `day(ts)` partition instead. Issued by migration step 3.
|
|
260
|
+
*/
|
|
261
|
+
export function insightIndexDdl(catalog) {
|
|
262
|
+
return `CREATE INDEX IF NOT EXISTS idx_insight_lookup ON ${catalog}.insight (user_id, metric, dismissed_at, ts);`;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Sensor tables exposed through a `v_{table}` union view (Sprint 5 §3).
|
|
266
|
+
*
|
|
267
|
+
* Registry queries, rule SQL, and tool SQL all target `v_{table}` and never
|
|
268
|
+
* `local.{table}` or `r2.default.{table}` directly (principle 19). Internal
|
|
269
|
+
* tables are absent deliberately: `insight`, `sync_watermark`,
|
|
270
|
+
* `tool_call_audit`, `user_baseline` and `device_config` are local-authoritative
|
|
271
|
+
* or local-only, so a union would either duplicate rows or read a remote
|
|
272
|
+
* copy that is never authoritative.
|
|
273
|
+
*/
|
|
274
|
+
export const VIEWED_TABLES = [
|
|
275
|
+
'hrv',
|
|
276
|
+
'heart_rate',
|
|
277
|
+
'spo2',
|
|
278
|
+
'temperature',
|
|
279
|
+
'activity',
|
|
280
|
+
'activity_bucket',
|
|
281
|
+
'sleep_session',
|
|
282
|
+
'sleep_stage',
|
|
283
|
+
'device_event',
|
|
284
|
+
'device_battery',
|
|
285
|
+
];
|
|
286
|
+
/** Timestamp column the watermark partitions on, per table. */
|
|
287
|
+
export function watermarkColumnFor(table) {
|
|
288
|
+
return table === 'sleep_session' ? 'ts_start' : 'ts';
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Build the `CREATE OR REPLACE VIEW v_{table}` DDL for one sensor table.
|
|
292
|
+
*
|
|
293
|
+
* The view is what makes freshness honest: rows the device has flushed
|
|
294
|
+
* locally but not yet pushed to R2 are invisible in `r2.default.{table}`,
|
|
295
|
+
* and rows already pushed exist in BOTH catalogs. The push watermark
|
|
296
|
+
* partitions the two sources exactly —
|
|
297
|
+
*
|
|
298
|
+
* local: rows strictly AFTER the watermark (not yet pushed)
|
|
299
|
+
* remote: everything (pushed)
|
|
300
|
+
*
|
|
301
|
+
* — so the union is complete with no duplicates at the boundary, and a row
|
|
302
|
+
* becomes remote-visible at the same instant it stops being local-visible.
|
|
303
|
+
*
|
|
304
|
+
* The watermark subquery reads `sync_watermark` rather than taking a bound
|
|
305
|
+
* parameter because DuckDB views cannot close over query-time params; the
|
|
306
|
+
* view must resolve the current cursor on every scan. `$brand` /
|
|
307
|
+
* `$family_id` are likewise unavailable inside a view body, so the tenant
|
|
308
|
+
* filter is baked in at creation time from the attach context — which is
|
|
309
|
+
* safe precisely because views are dropped and recreated on every attach
|
|
310
|
+
* (T-06), so a brand switch cannot leave a view scoped to the old tenant.
|
|
311
|
+
*
|
|
312
|
+
* `remoteCatalog` omitted (local mode) produces a local-only view with no
|
|
313
|
+
* UNION, so consumers write one SQL string that works in both modes.
|
|
314
|
+
*/
|
|
315
|
+
export function generateViewDdl(table, ctx) {
|
|
316
|
+
const tsCol = watermarkColumnFor(table);
|
|
317
|
+
const brand = sqlLiteral(ctx.brand);
|
|
318
|
+
const familyId = sqlLiteral(ctx.familyId);
|
|
319
|
+
const local = `${ctx.localCatalog}.${table}`;
|
|
320
|
+
const watermark = `COALESCE((SELECT cursor_ts FROM ${ctx.localCatalog}.sync_watermark `
|
|
321
|
+
+ `WHERE table_name = '${table}' AND kind = 'push' `
|
|
322
|
+
+ `AND brand = ${brand} AND family_id = ${familyId}), `
|
|
323
|
+
+ `'1970-01-01'::TIMESTAMP)`;
|
|
324
|
+
if (!ctx.remoteCatalog) {
|
|
325
|
+
// Local mode: nothing is ever pushed, so every local row is visible and
|
|
326
|
+
// the watermark filter would be a no-op that only costs a scan.
|
|
327
|
+
return `CREATE OR REPLACE VIEW v_${table} AS SELECT * FROM ${local};`;
|
|
328
|
+
}
|
|
329
|
+
const remote = `${ctx.remoteCatalog}.${REMOTE_NAMESPACE_VIEW}.${table}`;
|
|
330
|
+
return (`CREATE OR REPLACE VIEW v_${table} AS\n`
|
|
331
|
+
+ ` SELECT * FROM ${local}\n`
|
|
332
|
+
+ ` WHERE ${tsCol} > ${watermark}\n`
|
|
333
|
+
+ ` UNION ALL\n`
|
|
334
|
+
+ ` SELECT * FROM ${remote};`);
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Iceberg namespace remote tables live under. Duplicated from
|
|
338
|
+
* `migrations.ts` rather than imported to keep `schemas.ts` free of a
|
|
339
|
+
* migrations dependency (migrations already imports schemas).
|
|
340
|
+
*/
|
|
341
|
+
const REMOTE_NAMESPACE_VIEW = 'default';
|
|
342
|
+
/**
|
|
343
|
+
* Single-quote a SQL string literal. View bodies cannot take bound
|
|
344
|
+
* parameters, so brand/familyId are inlined — escaping is mandatory, not
|
|
345
|
+
* optional, even though both values are server-issued.
|
|
346
|
+
*/
|
|
347
|
+
function sqlLiteral(value) {
|
|
348
|
+
return `'${value.replace(/'/g, `''`)}'`;
|
|
349
|
+
}
|
|
350
|
+
/** `DROP VIEW IF EXISTS v_{table}` for detach + brand switch. */
|
|
351
|
+
export function dropViewDdl(table) {
|
|
352
|
+
return `DROP VIEW IF EXISTS v_${table};`;
|
|
353
|
+
}
|
|
204
354
|
/**
|
|
205
355
|
* Rewrite one base DDL to `CREATE TABLE IF NOT EXISTS <catalog>.<table>`.
|
|
206
356
|
*
|
|
@@ -240,8 +390,13 @@ export const LOCAL_SCHEMAS = Object.freeze(Object.fromEntries(TABLE_NAMES.map(ta
|
|
|
240
390
|
* catalog (without). Default is `SCHEMAS` for back-compat with 0.4.x
|
|
241
391
|
* callers that only wrote to the attached remote.
|
|
242
392
|
*/
|
|
243
|
-
export async function ensureSchemas(db, catalog, schemas = SCHEMAS) {
|
|
393
|
+
export async function ensureSchemas(db, catalog, schemas = SCHEMAS, opts = {}) {
|
|
244
394
|
for (const table of TABLE_NAMES) {
|
|
395
|
+
// Remote passes `skipLocalOnly` so derived/bookkeeping tables never get
|
|
396
|
+
// created in the user's R2 zone.
|
|
397
|
+
if (opts.skipLocalOnly && LOCAL_ONLY_TABLES.has(table)) {
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
245
400
|
const sql = qualifyDdl(schemas[table], table, catalog);
|
|
246
401
|
try {
|
|
247
402
|
await db.execute(sql);
|
package/dist/core/schemas.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/core/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAGzC,qEAAqE;AACrE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,KAAK;IACL,YAAY;IACZ,MAAM;IACN,aAAa;IACb,UAAU;IACV,iBAAiB;IACjB,eAAe;IACf,aAAa;IACb,WAAW;IACX,cAAc;IACd,gBAAgB;IAChB,eAAe;IACf,SAAS;IACT,gBAAgB;IAChB,iBAAiB;
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/core/schemas.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table_metadata.d.ts","sourceRoot":"","sources":["../../src/core/table_metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,iBAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"table_metadata.d.ts","sourceRoot":"","sources":["../../src/core/table_metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAmBxE,CAAA;AAEF;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAE7D"}
|
|
@@ -30,6 +30,9 @@ export const TABLE_METADATA = Object.freeze({
|
|
|
30
30
|
device_config: { timeColumn: 'valid_from', syncable: true },
|
|
31
31
|
insight: { timeColumn: 'ts', syncable: true },
|
|
32
32
|
sync_watermark: { timeColumn: 'updated_at', syncable: false },
|
|
33
|
+
// Derived, local-only, and UPSERTed in place — never pushed, and its
|
|
34
|
+
// `computed_at` is a recompute stamp rather than a sync cursor.
|
|
35
|
+
user_baseline: { timeColumn: 'computed_at', syncable: false },
|
|
33
36
|
tool_call_audit: { timeColumn: 'ts', syncable: false },
|
|
34
37
|
});
|
|
35
38
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table_metadata.js","sourceRoot":"","sources":["../../src/core/table_metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,MAAM,CAAC,MAAM,cAAc,GAAmD,MAAM,CAAC,MAAM,CAAC;IAC1F,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IACzC,UAAU,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAChD,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC1C,WAAW,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IACjD,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC9C,eAAe,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IACrD,aAAa,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE;IACzD,WAAW,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IACjD,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC/C,YAAY,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAClD,cAAc,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IACpD,aAAa,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC3D,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC7C,cAAc,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC7D,eAAe,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;CACvD,CAAC,CAAA;AAEF;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,OAAQ,cAAoD,CAAC,KAAK,CAAC,EAAE,UAAU,IAAI,IAAI,CAAA;AACzF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAyB;IAClD,OAAQ,cAAoD,CAAC,KAAK,CAAC,EAAE,QAAQ,IAAI,KAAK,CAAA;AACxF,CAAC"}
|
|
1
|
+
{"version":3,"file":"table_metadata.js","sourceRoot":"","sources":["../../src/core/table_metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,MAAM,CAAC,MAAM,cAAc,GAAmD,MAAM,CAAC,MAAM,CAAC;IAC1F,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IACzC,UAAU,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAChD,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC1C,WAAW,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IACjD,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC9C,eAAe,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IACrD,aAAa,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE;IACzD,WAAW,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IACjD,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC/C,YAAY,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAClD,cAAc,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IACpD,aAAa,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC3D,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC7C,cAAc,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC7D,qEAAqE;IACrE,gEAAgE;IAChE,aAAa,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC7D,eAAe,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;CACvD,CAAC,CAAA;AAEF;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,OAAQ,cAAoD,CAAC,KAAK,CAAC,EAAE,UAAU,IAAI,IAAI,CAAA;AACzF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAyB;IAClD,OAAQ,cAAoD,CAAC,KAAK,CAAC,EAAE,QAAQ,IAAI,KAAK,CAAA;AACxF,CAAC"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -139,6 +139,31 @@ export interface AnalyticsEngine {
|
|
|
139
139
|
*/
|
|
140
140
|
readonly mode: AnalyticsMode;
|
|
141
141
|
subscribe(listener: (s: AnalyticsState) => void): Unsubscribe;
|
|
142
|
+
/**
|
|
143
|
+
* Family member userIds for the current attach context (principle 39 —
|
|
144
|
+
* "Rules engine and AI tools share the same source of truth").
|
|
145
|
+
*
|
|
146
|
+
* Delegates to the `familyMembersProvider` configured at
|
|
147
|
+
* `createAnalytics`, so rules + tools never reach for RxDB or auth state
|
|
148
|
+
* themselves. Result is cached in-engine for 60s and invalidated on
|
|
149
|
+
* `family:update` (analytics-core/spec.md §Family membership resolution).
|
|
150
|
+
*
|
|
151
|
+
* Returns `[]` when not attached, when `tenantScope === 'org'`, or in
|
|
152
|
+
* local mode (no family fanout) — callers treat empty as "no fanout",
|
|
153
|
+
* never as "denied".
|
|
154
|
+
*/
|
|
155
|
+
getFamilyMembers(): Promise<string[]>;
|
|
156
|
+
/**
|
|
157
|
+
* Stamp `dismissed_at` on one insight (Sprint 5 §7b). Backs the app
|
|
158
|
+
* registry's `insight.dismiss` mutation — `@mongrov/data-access` types
|
|
159
|
+
* this exact shape on `MutationContext.analytics`.
|
|
160
|
+
*
|
|
161
|
+
* Authorized by ownership: `userId` must match the insight's owner.
|
|
162
|
+
*/
|
|
163
|
+
dismissInsight(args: {
|
|
164
|
+
insightId: string;
|
|
165
|
+
userId: string;
|
|
166
|
+
}): Promise<void>;
|
|
142
167
|
setRetention(days: number): Promise<void>;
|
|
143
168
|
/**
|
|
144
169
|
* Return the last successfully-attached ctx (persisted via KVStore) if it
|
|
@@ -148,22 +173,32 @@ export interface AnalyticsEngine {
|
|
|
148
173
|
getLastAttach(brand: string): Promise<AttachContext | null>;
|
|
149
174
|
close(): Promise<void>;
|
|
150
175
|
}
|
|
176
|
+
/** Insight categories per spec §Table schema (`insight.kind`). */
|
|
177
|
+
export type InsightKind = 'threshold' | 'pattern' | 'baseline_shift' | 'factor';
|
|
178
|
+
/** Insight severity per spec §Table schema (`insight.severity`). */
|
|
179
|
+
export type InsightSeverity = 'info' | 'warn' | 'urgent';
|
|
151
180
|
/**
|
|
152
|
-
* Insight row shape as read from the `insight` DuckDB table
|
|
153
|
-
*
|
|
154
|
-
* columns needed by `useInsight()` in v0.1.0.
|
|
181
|
+
* Insight row shape as read from the `insight` DuckDB table — mirrors the
|
|
182
|
+
* DDL in schemas.ts (camelCase field names, snake_case columns).
|
|
155
183
|
*/
|
|
156
184
|
export interface Insight {
|
|
157
|
-
|
|
185
|
+
insightId: string;
|
|
186
|
+
/** fired_at semantic; adapters may surface TIMESTAMP as ISO string. */
|
|
187
|
+
ts: Date | string;
|
|
158
188
|
brand: string;
|
|
159
189
|
familyId: string;
|
|
160
190
|
userId: string;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
191
|
+
/** Nullable — non-rule insights (patterns, factors) carry no rule_id. */
|
|
192
|
+
ruleId?: string | null;
|
|
193
|
+
metric: string;
|
|
194
|
+
kind: InsightKind;
|
|
195
|
+
severity: InsightSeverity;
|
|
196
|
+
title: string;
|
|
197
|
+
body?: string | null;
|
|
198
|
+
/** JSON payload (readings, thresholds, …) serialized as VARCHAR. */
|
|
199
|
+
evidence?: string | null;
|
|
200
|
+
acknowledgedAt?: Date | string | null;
|
|
201
|
+
dismissedAt?: Date | string | null;
|
|
167
202
|
}
|
|
168
203
|
export {};
|
|
169
204
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
package/dist/core/warehouse.d.ts
CHANGED
|
@@ -105,4 +105,32 @@ export declare function probeLocalCatalog(db: HybridDuckDB): Promise<string>;
|
|
|
105
105
|
* the state machine's `detachEngine` actor can dispatch symmetrically.
|
|
106
106
|
*/
|
|
107
107
|
export declare function detachLocal(_db: HybridDuckDB, _tenantId: string): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Create every `v_{table}` union view for the current attach.
|
|
110
|
+
*
|
|
111
|
+
* Called after migrations, so the underlying tables are guaranteed to
|
|
112
|
+
* exist — a view over a missing table fails at creation in DuckDB, not
|
|
113
|
+
* lazily at scan.
|
|
114
|
+
*
|
|
115
|
+
* The view bodies bake in `brand` + `family_id` (see `generateViewDdl` for
|
|
116
|
+
* why they cannot be bound parameters), which makes recreation on every
|
|
117
|
+
* attach a correctness requirement rather than housekeeping: a brand
|
|
118
|
+
* switch that reused the previous attach's views would serve the previous
|
|
119
|
+
* tenant's rows. `CREATE OR REPLACE` handles the overwrite; `dropViews` on
|
|
120
|
+
* detach closes the window where a stale view exists with no attach behind
|
|
121
|
+
* it.
|
|
122
|
+
*/
|
|
123
|
+
export declare function createViews(db: HybridDuckDB, ctx: {
|
|
124
|
+
brand: string;
|
|
125
|
+
familyId: string;
|
|
126
|
+
localCatalog: string;
|
|
127
|
+
remoteCatalog?: string;
|
|
128
|
+
}): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* Drop every union view. Idempotent (`DROP VIEW IF EXISTS`), and tolerant
|
|
131
|
+
* of individual failures: detach must not be blockable by a view that is
|
|
132
|
+
* already gone or whose catalog vanished first, or the engine would strand
|
|
133
|
+
* in `detaching`.
|
|
134
|
+
*/
|
|
135
|
+
export declare function dropViews(db: HybridDuckDB): Promise<void>;
|
|
108
136
|
//# sourceMappingURL=warehouse.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"warehouse.d.ts","sourceRoot":"","sources":["../../src/core/warehouse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"warehouse.d.ts","sourceRoot":"","sources":["../../src/core/warehouse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAE5C,OAAO,KAAK,EACV,aAAa,EACb,qBAAqB,EACrB,WAAW,EAEX,WAAW,EACZ,MAAM,SAAS,CAAA;AAchB,mFAAmF;AACnF,MAAM,WAAW,UAAU;IACzB,mBAAmB,EAAE,CACnB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,MAAM,KACb,MAAM,CAAA;IACX,WAAW,EAAE,WAAW,CAAA;IACxB,qBAAqB,EAAE,qBAAqB,CAAA;IAC5C,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,8EAA8E;AAC9E,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,eAAe,EAAE,MAAM,CAAA;IACvB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAA;IACpB,sEAAsE;IACtE,cAAc,EAAE,IAAI,CAAA;IACpB,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,YAAY,CAAC,CA0FvB;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAaf;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,YAAY,CAAC,CA8BvB;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAczE;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAEf;AAID;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE;IACH,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,GACA,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/D"}
|