hazo_umetrics 1.2.1 → 1.4.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/CHANGE_LOG.md +46 -1
- package/README.md +162 -1
- package/SETUP_CHECKLIST.md +47 -6
- package/config/hazo_umetrics_config.ini.sample +16 -5
- package/dist/api/index.d.ts +17 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +126 -2
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +1 -0
- package/dist/server/actions.d.ts +44 -0
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/actions.js +95 -13
- package/dist/server/behavior.d.ts +83 -1
- package/dist/server/behavior.d.ts.map +1 -1
- package/dist/server/behavior.js +195 -0
- package/dist/server/connect.d.ts +11 -0
- package/dist/server/connect.d.ts.map +1 -0
- package/dist/server/connect.js +58 -0
- package/dist/server/types.d.ts +9 -1
- package/dist/server/types.d.ts.map +1 -1
- package/dist/ui/actions_panel.d.ts.map +1 -1
- package/dist/ui/actions_panel.js +98 -7
- package/dist/ui/analytics_panel.d.ts +9 -1
- package/dist/ui/analytics_panel.d.ts.map +1 -1
- package/dist/ui/analytics_panel.js +55 -7
- package/dist/ui/datapoint_panel.d.ts +19 -0
- package/dist/ui/datapoint_panel.d.ts.map +1 -0
- package/dist/ui/datapoint_panel.js +71 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +2 -0
- package/dist/ui/journey_panel.d.ts +51 -0
- package/dist/ui/journey_panel.d.ts.map +1 -0
- package/dist/ui/journey_panel.js +95 -0
- package/migrations/db_setup_postgres.sql +27 -10
- package/migrations/db_setup_sqlite.sql +27 -10
- package/package.json +5 -1
package/CHANGE_LOG.md
CHANGED
|
@@ -1,9 +1,54 @@
|
|
|
1
1
|
# hazo_umetrics — Change Log
|
|
2
2
|
|
|
3
|
-
## 1.
|
|
3
|
+
## 1.4.0 — Bulk catalog edits, per-action datapoints, user-journey viz, real user identity
|
|
4
|
+
|
|
5
|
+
**New features (minor bump — no breaking changes):**
|
|
6
|
+
|
|
7
|
+
### New: Bulk multiselect in Action Catalog
|
|
8
|
+
- `updateActionDefBulk(adapter, {app_id, action_keys, patch})` — update many actions at once.
|
|
9
|
+
- `applyLinksBulk(adapter, {app_id, action_keys, add_related, remove_related})` — cartesian add/remove related links.
|
|
10
|
+
- `POST /actions/bulk` API: set status, key-event flag, parent, and related actions across N actions in one request. Permission: `metrics.manage`.
|
|
11
|
+
- UI: checkbox column + `BulkActionBar` (status select, key-event toggles, parent picker, related add/remove) appear above the tree when ≥1 action selected.
|
|
12
|
+
|
|
13
|
+
### New: Per-action datapoint schema
|
|
14
|
+
- `datapoint_schema JSONB/TEXT` column on `hazo_umetrics_action_def` (migration: `ALTER TABLE hazo_umetrics_action_def ADD COLUMN datapoint_schema JSONB NOT NULL DEFAULT '[]'` for PG; `TEXT` for SQLite).
|
|
15
|
+
- `DatapointField`, `DatapointSchema` types exported from `hazo_umetrics`.
|
|
16
|
+
- JSON textarea in the Action Catalog edit form to declare which `dimensions` keys are meaningful.
|
|
17
|
+
- `datapointStats(adapter, opts)` — aggregates dimension values (numeric histograms + categorical top lists).
|
|
18
|
+
- `GET /analytics/datapoints?app_id=&action_key=` — returns `{action_key, total_events, keys[]}`.
|
|
19
|
+
- `DatapointPanel` component: action picker + per-key cards (histogram bars for numeric, ranked list for categorical).
|
|
20
|
+
|
|
21
|
+
### New: User-journey aggregation + graph
|
|
22
|
+
- `userJourney(adapter, opts)` — groups events by session, computes per-step timing, emits `JourneyGraph` (nodes + edges with avgMs).
|
|
23
|
+
- `GET /analytics/journey?app_id=[&user_id=][&session_id=]` — returns `{sessions, graph}`.
|
|
24
|
+
- `JourneyPanel` component: dagre LR graph via `hazo_canvas` (optional peer dep) with edge timing labels; falls back to ordered step list when canvas unavailable.
|
|
25
|
+
- `hazo_canvas` ≥1.9.1 required for timing labels on dagre edges (`direction:'LR'`).
|
|
26
|
+
|
|
27
|
+
### New: Host-injected user identity
|
|
28
|
+
- `resolveUserProfiles?: ResolveUserProfiles` prop on `AnalyticsPanel` and `JourneyPanel`.
|
|
29
|
+
- UserFilter dropdown now shows `name / email / avatar` when resolver is wired; falls back to truncated UUID.
|
|
30
|
+
- JourneyPanel session headers show resolved name/email/avatar.
|
|
31
|
+
- Test-app: `POST /api/hazo_umetrics/user_profiles` route wires `hazo_auth` `get_profiles` as an example host implementation.
|
|
32
|
+
|
|
33
|
+
### hazo_canvas 1.9.1
|
|
34
|
+
- Dagre edge `label` field now rendered as a midpoint `kind:'text'` child (timing labels for journey viz).
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 1.3.0 — Analytics dashboard + behavioral fixes + createUmetricsConnect
|
|
4
39
|
|
|
5
40
|
**New features + bug fixes (no breaking changes):**
|
|
6
41
|
|
|
42
|
+
### New: `createUmetricsConnect` — dedicated DB factory
|
|
43
|
+
- `createUmetricsConnect(opts?)` builds a `HazoConnectAdapter` from `HAZO_UMETRICS_DATABASE_*`
|
|
44
|
+
env vars (type / URL / API key / SQLite path), with INI `[database]` as fallback. Returns a
|
|
45
|
+
cached adapter on no-arg calls; creates fresh when opts are passed.
|
|
46
|
+
- Exported from main `hazo_umetrics` entry: `import { createUmetricsConnect } from 'hazo_umetrics'`
|
|
47
|
+
- `UmetricsConnectOptions` type exported alongside the factory.
|
|
48
|
+
- Enables wiring umetrics to a **separate DB** from the host app in one line:
|
|
49
|
+
`createStatHandlers({ getAdapter: createUmetricsConnect })`
|
|
50
|
+
- Updated `config/hazo_umetrics_config.ini.sample` `[database]` section with dedicated env-var docs.
|
|
51
|
+
|
|
7
52
|
### New: `topActions` behavior aggregation
|
|
8
53
|
- `topActions` function in `src/server/behavior.ts` — ranks all `action.*` events by frequency, no `user_id` required. Answers "what is the most common action?" without needing session segmentation.
|
|
9
54
|
- Exposed as `metric=top_actions` in `GET /api/hazo_umetrics/analytics/behavior`.
|
package/README.md
CHANGED
|
@@ -125,6 +125,128 @@ trackAction('timer.complete', { url: '/timer' });
|
|
|
125
125
|
|
|
126
126
|
Auto-tracked on mount: page views (`ui.pageview.*`), clicks (`ui.click.*`), errors (`ui.error.*`), dwell time (`ui.dwell.*`).
|
|
127
127
|
|
|
128
|
+
## Bulk Action Catalog edits
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
// POST /api/hazo_umetrics/actions/bulk
|
|
132
|
+
// Body: { app_id, action_keys, patch?, add_related?, remove_related? }
|
|
133
|
+
// Permission: metrics.manage
|
|
134
|
+
// Response: { ok: true, data: { updated: string[], missing: string[], links: { added, removed } } }
|
|
135
|
+
|
|
136
|
+
// Set status on many actions at once
|
|
137
|
+
await fetch('/api/hazo_umetrics/actions/bulk', {
|
|
138
|
+
method: 'POST',
|
|
139
|
+
body: JSON.stringify({
|
|
140
|
+
app_id: 'my-app',
|
|
141
|
+
action_keys: ['timer.start', 'timer.complete'],
|
|
142
|
+
patch: { status: 'active', is_key_event: true },
|
|
143
|
+
}),
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Add related links in bulk (cartesian: every key in action_keys ↔ every key in add_related)
|
|
147
|
+
await fetch('/api/hazo_umetrics/actions/bulk', {
|
|
148
|
+
method: 'POST',
|
|
149
|
+
body: JSON.stringify({
|
|
150
|
+
app_id: 'my-app',
|
|
151
|
+
action_keys: ['timer.start'],
|
|
152
|
+
add_related: ['timer.complete', 'timer.pause'],
|
|
153
|
+
}),
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`action_keys` must be a non-empty array — an empty array returns 400. Both `patch` and `add_related`/`remove_related` can be combined in one request.
|
|
158
|
+
|
|
159
|
+
## Per-action datapoint schema
|
|
160
|
+
|
|
161
|
+
Declare which `dimensions` keys are analytically meaningful for a given action:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
// PATCH the action to set a datapoint_schema
|
|
165
|
+
await fetch('/api/hazo_umetrics/actions?app_id=my-app', {
|
|
166
|
+
method: 'PATCH',
|
|
167
|
+
body: JSON.stringify({
|
|
168
|
+
app_id: 'my-app',
|
|
169
|
+
action_key: 'timer.complete',
|
|
170
|
+
patch: {
|
|
171
|
+
datapoint_schema: [
|
|
172
|
+
{ key: 'duration_ms', label: 'Duration (ms)', type: 'number' },
|
|
173
|
+
{ key: 'mode', label: 'Timer mode', type: 'string' },
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
}),
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Types exported from `hazo_umetrics`: `DatapointField`, `DatapointSchema`.
|
|
181
|
+
|
|
182
|
+
Once a schema is set, the `DatapointPanel` UI component shows per-key cards: histogram bars for `type:'number'` keys, ranked frequency lists for `type:'string'` keys.
|
|
183
|
+
|
|
184
|
+
## Journey analytics
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
// GET /api/hazo_umetrics/analytics/journey?app_id=<id>[&user_id=<id>][&session_id=<id>]
|
|
188
|
+
// Permission: metrics.view
|
|
189
|
+
// Response: { ok: true, data: { sessions: Session[], graph: JourneyGraph } }
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
`sessions` is an ordered list of per-session step arrays with timing. `graph.nodes` and `graph.edges` provide the aggregated action-transition graph for all sessions (or filtered by user/session). Each edge carries `avgMs` (mean inter-step latency).
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
import { JourneyPanel } from 'hazo_umetrics/ui';
|
|
196
|
+
|
|
197
|
+
// Embedded panel — fetches journey data from /api/hazo_umetrics/analytics/journey
|
|
198
|
+
<JourneyPanel
|
|
199
|
+
appId="my-app"
|
|
200
|
+
resolveUserProfiles={resolveUserProfiles} // optional — enriches session headers
|
|
201
|
+
/>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
`JourneyPanel` renders a dagre LR graph via `hazo_canvas` when installed (`npm install hazo_canvas@^1.9.1`). Without `hazo_canvas`, it falls back to an ordered step list. Dagre edge timing labels require `hazo_canvas ≥ 1.9.1`.
|
|
205
|
+
|
|
206
|
+
## Datapoint analytics
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
// GET /api/hazo_umetrics/analytics/datapoints?app_id=<id>&action_key=<key>
|
|
210
|
+
// Permission: metrics.view
|
|
211
|
+
// Response: { ok: true, data: { action_key, total_events, keys: DatapointKeyStats[] } }
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Each entry in `keys` describes one dimension: `{ key, type, total, histogram | topValues }`. Use the `DatapointPanel` component to render these automatically.
|
|
215
|
+
|
|
216
|
+
## resolveUserProfiles — wiring user identity
|
|
217
|
+
|
|
218
|
+
`AnalyticsPanel` and `JourneyPanel` both accept an optional `resolveUserProfiles` prop that enriches user IDs with real names, emails, and avatars:
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
import type { ResolveUserProfiles } from 'hazo_umetrics/ui';
|
|
222
|
+
|
|
223
|
+
const resolveUserProfiles: ResolveUserProfiles = async (ids) => {
|
|
224
|
+
const r = await fetch('/api/my-app/user_profiles', {
|
|
225
|
+
method: 'POST',
|
|
226
|
+
body: JSON.stringify({ ids }),
|
|
227
|
+
headers: { 'Content-Type': 'application/json' },
|
|
228
|
+
});
|
|
229
|
+
const j = await r.json();
|
|
230
|
+
return j.profiles ?? [];
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// Each profile: { user_id, email?, name?, profile_picture_url? }
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**Wiring with `hazo_auth` (gotimer / kinstripe pattern):**
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
// app/api/hazo_umetrics/user_profiles/route.ts
|
|
240
|
+
import { authConnect } from '@/lib/db';
|
|
241
|
+
import { hazo_get_user_profiles } from 'hazo_auth/server-lib';
|
|
242
|
+
|
|
243
|
+
export async function POST(req: Request) {
|
|
244
|
+
const { ids } = await req.json();
|
|
245
|
+
const result = await hazo_get_user_profiles(authConnect, ids);
|
|
246
|
+
return Response.json({ profiles: result.profiles ?? [] });
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
128
250
|
## API route factories
|
|
129
251
|
|
|
130
252
|
```ts
|
|
@@ -139,7 +261,46 @@ const expHandlers = createExperimentHandlers({ getAdapter: () => myAdapter });
|
|
|
139
261
|
|
|
140
262
|
## DB setup
|
|
141
263
|
|
|
142
|
-
Run `db_setup_sqlite.sql` (SQLite) or `db_setup_postgres.sql` (PostgreSQL) once
|
|
264
|
+
Run `db_setup_sqlite.sql` (SQLite) or `db_setup_postgres.sql` (PostgreSQL) once against your **umetrics DB**. Creates 7 tables, all prefixed `hazo_umetrics_`.
|
|
265
|
+
|
|
266
|
+
> Run the migration against the **dedicated umetrics database**, not the host app's main DB.
|
|
267
|
+
> If you use `createUmetricsConnect()` (recommended), the umetrics DB is the one pointed to
|
|
268
|
+
> by `HAZO_UMETRICS_DATABASE_URL`.
|
|
269
|
+
|
|
270
|
+
## Separate database for umetrics
|
|
271
|
+
|
|
272
|
+
`hazo_umetrics` data (events, stats, flags, experiments) should live in its own database,
|
|
273
|
+
**separate from the host app's main DB**. This keeps analytics writes from competing with
|
|
274
|
+
product data, lets you point multiple apps at one shared analytics store, and lets you
|
|
275
|
+
scale each independently.
|
|
276
|
+
|
|
277
|
+
Use `createUmetricsConnect()` to build a dedicated adapter in one line:
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
import { createUmetricsConnect } from 'hazo_umetrics';
|
|
281
|
+
|
|
282
|
+
// Reads HAZO_UMETRICS_DATABASE_URL + HAZO_UMETRICS_DATABASE_API_KEY from env.
|
|
283
|
+
// Falls back to ./umetrics.sqlite when type=sqlite.
|
|
284
|
+
export const getUmetricsAdapter = createUmetricsConnect;
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Then inject it into every route factory:
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
const handlers = createStatHandlers({ getAdapter: createUmetricsConnect });
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Env vars
|
|
294
|
+
|
|
295
|
+
| Variable | Required | Description |
|
|
296
|
+
|---|---|---|
|
|
297
|
+
| `HAZO_UMETRICS_DATABASE_URL` | PostgREST only | Base URL of the umetrics PostgREST server |
|
|
298
|
+
| `HAZO_UMETRICS_DATABASE_API_KEY` | PostgREST only | Bearer token for the umetrics PostgREST server |
|
|
299
|
+
| `HAZO_UMETRICS_DATABASE_TYPE` | No | `postgrest` (default) or `sqlite` |
|
|
300
|
+
| `HAZO_UMETRICS_DATABASE_PATH` | SQLite only | Path to the SQLite file (default: `./umetrics.sqlite`) |
|
|
301
|
+
|
|
302
|
+
These are independent of the host app's `POSTGREST_URL` / `POSTGREST_API_KEY` — the
|
|
303
|
+
analytics DB can be a completely different PostgREST instance (or a local SQLite file for dev).
|
|
143
304
|
|
|
144
305
|
## Config
|
|
145
306
|
|
package/SETUP_CHECKLIST.md
CHANGED
|
@@ -17,6 +17,30 @@ npm install hazo_core hazo_connect hazo_auth hazo_secure hazo_audit hazo_api haz
|
|
|
17
17
|
> `hazo_dataviz` is required when you render `MetricsPanel`/`StatTrend` — its `LineChart`
|
|
18
18
|
> draws the trend chart (moved out of `hazo_ui` in the 4.0.0 chart migration).
|
|
19
19
|
|
|
20
|
+
## ALTER TABLE for 1.4.0 (existing deployments only)
|
|
21
|
+
|
|
22
|
+
If you are upgrading an **existing** deployment from a version before 1.4.0, run these statements against your umetrics database before upgrading the package:
|
|
23
|
+
|
|
24
|
+
```sql
|
|
25
|
+
-- PostgreSQL:
|
|
26
|
+
ALTER TABLE hazo_umetrics_action_def ADD COLUMN IF NOT EXISTS datapoint_schema JSONB NOT NULL DEFAULT '[]';
|
|
27
|
+
|
|
28
|
+
-- SQLite (does not support IF NOT EXISTS on ALTER TABLE — skip if column already exists):
|
|
29
|
+
ALTER TABLE hazo_umetrics_action_def ADD COLUMN datapoint_schema TEXT NOT NULL DEFAULT '[]';
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Fresh installations (using `db_setup_sqlite.sql` / `db_setup_postgres.sql` from 1.4.0+) already include this column — no ALTER TABLE needed.
|
|
33
|
+
|
|
34
|
+
**Optional — journey graph (hazo_canvas peer dep):**
|
|
35
|
+
|
|
36
|
+
`JourneyPanel` renders an interactive dagre LR graph when `hazo_canvas` is installed. Without it, the panel falls back to a plain ordered step list. Install only if you use `JourneyPanel`:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install hazo_canvas@^1.9.1
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
20
44
|
## 2. Run DB migrations
|
|
21
45
|
|
|
22
46
|
**SQLite:**
|
|
@@ -33,7 +57,24 @@ db.close();
|
|
|
33
57
|
|
|
34
58
|
**PostgreSQL:** Run `node_modules/hazo_umetrics/db_setup_postgres.sql` against your database.
|
|
35
59
|
|
|
36
|
-
## 3. Set env vars for
|
|
60
|
+
## 3. Set env vars for the umetrics database
|
|
61
|
+
|
|
62
|
+
`createUmetricsConnect()` reads these variables to connect to the dedicated umetrics DB:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# PostgREST mode (production / staging)
|
|
66
|
+
HAZO_UMETRICS_DATABASE_URL=https://your-umetrics-postgrest.example.com
|
|
67
|
+
HAZO_UMETRICS_DATABASE_API_KEY=<bearer-token>
|
|
68
|
+
|
|
69
|
+
# SQLite mode (local dev — omit DATABASE_URL to fall back to ./umetrics.sqlite)
|
|
70
|
+
# HAZO_UMETRICS_DATABASE_TYPE=sqlite
|
|
71
|
+
# HAZO_UMETRICS_DATABASE_PATH=./umetrics.sqlite
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
> Run `db_setup_postgres.sql` (or `db_setup_sqlite.sql`) against this **umetrics DB**, not
|
|
75
|
+
> the host app's main database.
|
|
76
|
+
|
|
77
|
+
## 4. Set env vars for cookie signing
|
|
37
78
|
|
|
38
79
|
```bash
|
|
39
80
|
# Generate a 32-byte key: node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
|
|
@@ -41,11 +82,11 @@ HAZO_UMETRICS_COOKIE_KEY_CURRENT=v1
|
|
|
41
82
|
HAZO_UMETRICS_COOKIE_KEY_v1=<base64-encoded 32-byte key>
|
|
42
83
|
```
|
|
43
84
|
|
|
44
|
-
##
|
|
85
|
+
## 5. Add config file (optional)
|
|
45
86
|
|
|
46
87
|
Copy `node_modules/hazo_umetrics/config/hazo_umetrics_config.ini.sample` to your app's config directory as `hazo_umetrics_config.ini` and fill in `[ga4]` when ready for M1.
|
|
47
88
|
|
|
48
|
-
##
|
|
89
|
+
## 6. Mount API routes (Next.js)
|
|
49
90
|
|
|
50
91
|
```ts
|
|
51
92
|
// app/api/hazo_umetrics/stats/route.ts
|
|
@@ -58,7 +99,7 @@ export async function GET(req: Request) { return handlers.getStat(req); }
|
|
|
58
99
|
export async function POST(req: Request) { return handlers.recordStat(req); }
|
|
59
100
|
```
|
|
60
101
|
|
|
61
|
-
##
|
|
102
|
+
## 7. Wrap your app in HazoMetricsProvider (client)
|
|
62
103
|
|
|
63
104
|
```tsx
|
|
64
105
|
// app/layout.tsx
|
|
@@ -73,7 +114,7 @@ export default function RootLayout({ children }) {
|
|
|
73
114
|
}
|
|
74
115
|
```
|
|
75
116
|
|
|
76
|
-
##
|
|
117
|
+
## 8. Configure Tailwind (if you use hazo_umetrics UI components)
|
|
77
118
|
|
|
78
119
|
`MetricsPanel` uses shadcn token utilities (`bg-background`, `text-muted-foreground`, `border`, etc.) from `hazo_ui`. Without the token definitions the dialog panel will render transparent. In your `globals.css`:
|
|
79
120
|
|
|
@@ -112,7 +153,7 @@ export default function RootLayout({ children }) {
|
|
|
112
153
|
|
|
113
154
|
(Adjust `@import` and `@source` depth to match your project's distance from `node_modules`.)
|
|
114
155
|
|
|
115
|
-
##
|
|
156
|
+
## 9. Smoke test
|
|
116
157
|
|
|
117
158
|
```ts
|
|
118
159
|
import { recordStat, getLatestStat } from 'hazo_umetrics';
|
|
@@ -8,14 +8,25 @@
|
|
|
8
8
|
app_id = my_app
|
|
9
9
|
|
|
10
10
|
[database]
|
|
11
|
-
;
|
|
12
|
-
;
|
|
11
|
+
; Dedicated hazo_umetrics database — separate from the host app's main DB.
|
|
12
|
+
; Use createUmetricsConnect() from hazo_umetrics to wire this adapter.
|
|
13
|
+
;
|
|
14
|
+
; type: postgrest (default) | sqlite
|
|
15
|
+
; Env-var override: HAZO_UMETRICS_DATABASE_TYPE
|
|
13
16
|
; type = postgrest
|
|
17
|
+
;
|
|
18
|
+
; PostgREST mode (recommended for production):
|
|
19
|
+
; base_url — the PostgREST server base URL
|
|
20
|
+
; Env-var override: HAZO_UMETRICS_DATABASE_URL
|
|
14
21
|
; base_url = http://your-postgrest-host:4444
|
|
15
|
-
;
|
|
22
|
+
; api_key — bearer token (env only, never store in INI)
|
|
23
|
+
; Set: HAZO_UMETRICS_DATABASE_API_KEY=<your-token>
|
|
24
|
+
;
|
|
25
|
+
; SQLite mode (local development without a Postgres instance):
|
|
26
|
+
; database_path — path to the SQLite file (default: ./umetrics.sqlite)
|
|
27
|
+
; Env-var override: HAZO_UMETRICS_DATABASE_PATH
|
|
16
28
|
; type = sqlite
|
|
17
|
-
;
|
|
18
|
-
; database_path = ./umetrics_test.sqlite
|
|
29
|
+
; database_path = ./umetrics.sqlite
|
|
19
30
|
|
|
20
31
|
[env]
|
|
21
32
|
; Uncomment to hard-code the environment name (overrides HAZO_ENV / NODE_ENV).
|
package/dist/api/index.d.ts
CHANGED
|
@@ -106,6 +106,13 @@ export declare function createActionHandlers(options: ApiFactoryOptions): {
|
|
|
106
106
|
* Emits an audit entry 'action.catalog.update'.
|
|
107
107
|
*/
|
|
108
108
|
updateAction(req: Request): Promise<Response>;
|
|
109
|
+
/**
|
|
110
|
+
* POST /...
|
|
111
|
+
* Body: { app_id, action_keys, patch?, add_related?, remove_related? }
|
|
112
|
+
* Bulk-updates multiple action defs and/or their links. Requires metrics.manage.
|
|
113
|
+
* Emits a single audit entry 'action.catalog.bulk_update' per call.
|
|
114
|
+
*/
|
|
115
|
+
bulkUpdateActions(req: Request): Promise<Response>;
|
|
109
116
|
};
|
|
110
117
|
export declare function createActivityHandlers(options: ApiFactoryOptions): {
|
|
111
118
|
/**
|
|
@@ -145,5 +152,15 @@ export declare function createBehaviorHandlers(options: ApiFactoryOptions): {
|
|
|
145
152
|
* Returns events bucketed by day. Requires metrics.view.
|
|
146
153
|
*/
|
|
147
154
|
getEventsOverTime(req: Request): Promise<Response>;
|
|
155
|
+
/**
|
|
156
|
+
* GET /...?app_id=<id>&action_key=<key>[&since=<iso>][&until=<iso>][&buckets=<n>][&top_n=<n>]
|
|
157
|
+
* Returns datapoint dimension stats for an action. Requires metrics.view.
|
|
158
|
+
*/
|
|
159
|
+
getDatapoints(req: Request): Promise<Response>;
|
|
160
|
+
/**
|
|
161
|
+
* GET /...?app_id=<id>[&user_id=<id>][&session_id=<id>][&since=<iso>]
|
|
162
|
+
* Returns user journey sessions and aggregated graph. Requires metrics.view.
|
|
163
|
+
*/
|
|
164
|
+
getJourney(req: Request): Promise<Response>;
|
|
148
165
|
};
|
|
149
166
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/api/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"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"}
|
package/dist/api/index.js
CHANGED
|
@@ -8,8 +8,8 @@ import { createCrudService } from 'hazo_connect/server';
|
|
|
8
8
|
import { recordStat as _recordStat, getLatestStat as _getLatestStat, getStatSeries as _getStatSeries, } from '../server/stats.js';
|
|
9
9
|
import { resolveVariant } from '../server/flags.js';
|
|
10
10
|
import { getActivitySummary as _getActivitySummary, getActivityTrend as _getActivityTrend, } from '../server/activity.js';
|
|
11
|
-
import { ensureActionDef as _ensureActionDef, listActions as _listActions, getActionTree as _getActionTree, updateActionDef as _updateActionDef, getLinks as _getLinks, addLink as _addLink, removeLink as _removeLink, } from '../server/actions.js';
|
|
12
|
-
import { topActions as _topActions, firstSessionActions as _firstSessionActions, postReloginActions as _postReloginActions, actionsBeforeGoal as _actionsBeforeGoal, topErrors as _topErrors, tabDwell as _tabDwell, frequentActionsReturning as _frequentActionsReturning, eventsOverTime as _eventsOverTime, } from '../server/behavior.js';
|
|
11
|
+
import { ensureActionDef as _ensureActionDef, listActions as _listActions, getActionTree as _getActionTree, updateActionDef as _updateActionDef, updateActionDefBulk as _updateActionDefBulk, applyLinksBulk as _applyLinksBulk, getLinks as _getLinks, addLink as _addLink, removeLink as _removeLink, } from '../server/actions.js';
|
|
12
|
+
import { topActions as _topActions, firstSessionActions as _firstSessionActions, postReloginActions as _postReloginActions, actionsBeforeGoal as _actionsBeforeGoal, topErrors as _topErrors, tabDwell as _tabDwell, frequentActionsReturning as _frequentActionsReturning, eventsOverTime as _eventsOverTime, datapointStats as _datapointStats, userJourney as _userJourney, } from '../server/behavior.js';
|
|
13
13
|
// ---------------------------------------------------------------------------
|
|
14
14
|
// Default auth — dynamically imports hazo_auth/server-lib to avoid the
|
|
15
15
|
// server-only guard firing at module-evaluation time (e.g. in test runners).
|
|
@@ -516,6 +516,67 @@ export function createActionHandlers(options) {
|
|
|
516
516
|
});
|
|
517
517
|
return jsonOk({ action: updated });
|
|
518
518
|
},
|
|
519
|
+
/**
|
|
520
|
+
* POST /...
|
|
521
|
+
* Body: { app_id, action_keys, patch?, add_related?, remove_related? }
|
|
522
|
+
* Bulk-updates multiple action defs and/or their links. Requires metrics.manage.
|
|
523
|
+
* Emits a single audit entry 'action.catalog.bulk_update' per call.
|
|
524
|
+
*/
|
|
525
|
+
async bulkUpdateActions(req) {
|
|
526
|
+
let body;
|
|
527
|
+
try {
|
|
528
|
+
body = (await req.json());
|
|
529
|
+
}
|
|
530
|
+
catch {
|
|
531
|
+
return jsonError('BAD_REQUEST', 'Invalid JSON body', 400);
|
|
532
|
+
}
|
|
533
|
+
const { app_id, action_keys, patch, add_related, remove_related } = body;
|
|
534
|
+
if (!app_id) {
|
|
535
|
+
return jsonError('BAD_REQUEST', 'app_id is required', 400);
|
|
536
|
+
}
|
|
537
|
+
if (!Array.isArray(action_keys) || action_keys.length === 0) {
|
|
538
|
+
return jsonError('BAD_REQUEST', 'action_keys must be a non-empty array', 400);
|
|
539
|
+
}
|
|
540
|
+
const gate = await gateAuth(req, {
|
|
541
|
+
required_permissions: ['metrics.manage'],
|
|
542
|
+
app_id,
|
|
543
|
+
getAuth,
|
|
544
|
+
});
|
|
545
|
+
if (!gate.ok)
|
|
546
|
+
return gate.response;
|
|
547
|
+
const adapter = await options.getAdapter();
|
|
548
|
+
const keys = action_keys;
|
|
549
|
+
let updated = [];
|
|
550
|
+
let missing = [];
|
|
551
|
+
let linksAdded = 0;
|
|
552
|
+
let linksRemoved = 0;
|
|
553
|
+
if (patch && Object.keys(patch).length > 0) {
|
|
554
|
+
const result = await _updateActionDefBulk(adapter, {
|
|
555
|
+
app_id,
|
|
556
|
+
action_keys: keys,
|
|
557
|
+
patch: patch,
|
|
558
|
+
});
|
|
559
|
+
updated = result.updated;
|
|
560
|
+
missing = result.missing;
|
|
561
|
+
}
|
|
562
|
+
if ((add_related && add_related.length > 0) || (remove_related && remove_related.length > 0)) {
|
|
563
|
+
const result = await _applyLinksBulk(adapter, {
|
|
564
|
+
app_id,
|
|
565
|
+
action_keys: keys,
|
|
566
|
+
add_related,
|
|
567
|
+
remove_related,
|
|
568
|
+
});
|
|
569
|
+
linksAdded = result.added;
|
|
570
|
+
linksRemoved = result.removed;
|
|
571
|
+
}
|
|
572
|
+
await options.onAudit?.({
|
|
573
|
+
action: 'action.catalog.bulk_update',
|
|
574
|
+
actor_id: gate.userId,
|
|
575
|
+
app_id,
|
|
576
|
+
details: { action_keys: keys, patch, add_related, remove_related },
|
|
577
|
+
});
|
|
578
|
+
return jsonOk({ updated, missing, links: { added: linksAdded, removed: linksRemoved } });
|
|
579
|
+
},
|
|
519
580
|
};
|
|
520
581
|
}
|
|
521
582
|
// ---------------------------------------------------------------------------
|
|
@@ -744,5 +805,68 @@ export function createBehaviorHandlers(options) {
|
|
|
744
805
|
const data = await _eventsOverTime(adapter, { app_id, since, userIds, limit: 10000, catalogMap, includeArchived, keyEventsOnly });
|
|
745
806
|
return jsonOk({ data });
|
|
746
807
|
},
|
|
808
|
+
/**
|
|
809
|
+
* GET /...?app_id=<id>&action_key=<key>[&since=<iso>][&until=<iso>][&buckets=<n>][&top_n=<n>]
|
|
810
|
+
* Returns datapoint dimension stats for an action. Requires metrics.view.
|
|
811
|
+
*/
|
|
812
|
+
async getDatapoints(req) {
|
|
813
|
+
const url = new URL(req.url);
|
|
814
|
+
const app_id = url.searchParams.get('app_id') ?? '';
|
|
815
|
+
const action_key = url.searchParams.get('action_key') ?? '';
|
|
816
|
+
const since = url.searchParams.get('since') ?? undefined;
|
|
817
|
+
const until = url.searchParams.get('until') ?? undefined;
|
|
818
|
+
const bucketsParam = url.searchParams.get('buckets');
|
|
819
|
+
const buckets = bucketsParam != null ? parseInt(bucketsParam, 10) : undefined;
|
|
820
|
+
const topNParam = url.searchParams.get('top_n');
|
|
821
|
+
const topN = topNParam != null ? parseInt(topNParam, 10) : undefined;
|
|
822
|
+
const gate = await gateAuth(req, {
|
|
823
|
+
required_permissions: ['metrics.view'],
|
|
824
|
+
app_id: app_id || undefined,
|
|
825
|
+
getAuth,
|
|
826
|
+
});
|
|
827
|
+
if (!gate.ok)
|
|
828
|
+
return gate.response;
|
|
829
|
+
if (!app_id || !action_key) {
|
|
830
|
+
return jsonError('BAD_REQUEST', 'app_id and action_key are required', 400);
|
|
831
|
+
}
|
|
832
|
+
const adapter = await options.getAdapter();
|
|
833
|
+
const catalog = await _listActions(adapter, { app_id });
|
|
834
|
+
const matchingAction = catalog.find((a) => a.action_key === action_key);
|
|
835
|
+
const result = await _datapointStats(adapter, {
|
|
836
|
+
app_id,
|
|
837
|
+
action_key,
|
|
838
|
+
since,
|
|
839
|
+
until,
|
|
840
|
+
buckets,
|
|
841
|
+
topN,
|
|
842
|
+
schema: matchingAction?.datapoint_schema,
|
|
843
|
+
});
|
|
844
|
+
return jsonOk(result);
|
|
845
|
+
},
|
|
846
|
+
/**
|
|
847
|
+
* GET /...?app_id=<id>[&user_id=<id>][&session_id=<id>][&since=<iso>]
|
|
848
|
+
* Returns user journey sessions and aggregated graph. Requires metrics.view.
|
|
849
|
+
*/
|
|
850
|
+
async getJourney(req) {
|
|
851
|
+
const url = new URL(req.url);
|
|
852
|
+
const app_id = url.searchParams.get('app_id') ?? '';
|
|
853
|
+
const user_id = url.searchParams.get('user_id') ?? undefined;
|
|
854
|
+
const session_id = url.searchParams.get('session_id') ?? undefined;
|
|
855
|
+
const since = url.searchParams.get('since') ?? undefined;
|
|
856
|
+
const gate = await gateAuth(req, {
|
|
857
|
+
required_permissions: ['metrics.view'],
|
|
858
|
+
app_id: app_id || undefined,
|
|
859
|
+
getAuth,
|
|
860
|
+
});
|
|
861
|
+
if (!gate.ok)
|
|
862
|
+
return gate.response;
|
|
863
|
+
if (!app_id)
|
|
864
|
+
return jsonError('BAD_REQUEST', 'app_id is required', 400);
|
|
865
|
+
const adapter = await options.getAdapter();
|
|
866
|
+
const catalog = await _listActions(adapter, { app_id });
|
|
867
|
+
const catalogMap = new Map(catalog.map((a) => [a.action_key, { label: a.label, datapoint_schema: a.datapoint_schema }]));
|
|
868
|
+
const result = await _userJourney(adapter, { app_id, user_id, session_id, since, catalogMap });
|
|
869
|
+
return jsonOk(result);
|
|
870
|
+
},
|
|
747
871
|
};
|
|
748
872
|
}
|
package/dist/lib/index.d.ts
CHANGED
package/dist/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/index.ts"],"names":[],"mappings":"AACA,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/index.ts"],"names":[],"mappings":"AACA,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC"}
|
package/dist/lib/index.js
CHANGED
package/dist/server/actions.d.ts
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
import type { HazoConnectAdapter } from 'hazo_connect/server';
|
|
2
2
|
import type { ActionDef, ActionDefPatch, ActionNode, ActionLink } from './types.js';
|
|
3
|
+
type ActionDefRow = {
|
|
4
|
+
action_key: string;
|
|
5
|
+
app_id: string;
|
|
6
|
+
scope_id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
description: string;
|
|
9
|
+
parent_key: string | null;
|
|
10
|
+
url: string | null;
|
|
11
|
+
is_key_event: number | boolean;
|
|
12
|
+
status: string;
|
|
13
|
+
datapoint_schema: string;
|
|
14
|
+
created_at: string;
|
|
15
|
+
updated_at: string;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
};
|
|
18
|
+
export declare function applyPatch(_existing: ActionDef, patch: ActionDefPatch): Partial<ActionDefRow>;
|
|
3
19
|
/**
|
|
4
20
|
* Insert-if-absent a draft def row. No-op after first sight (seen-set cached).
|
|
5
21
|
* Called by the ingestion layer on every `action.*` event.
|
|
@@ -63,4 +79,32 @@ export declare function removeLink(adapter: HazoConnectAdapter, params: {
|
|
|
63
79
|
action_key: string;
|
|
64
80
|
related_key: string;
|
|
65
81
|
}): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Updates mutable fields across multiple action defs in one call.
|
|
84
|
+
* Returns lists of updated keys and missing (not found) keys.
|
|
85
|
+
*/
|
|
86
|
+
export declare function updateActionDefBulk(adapter: HazoConnectAdapter, params: {
|
|
87
|
+
app_id: string;
|
|
88
|
+
action_keys: string[];
|
|
89
|
+
patch: ActionDefPatch;
|
|
90
|
+
}): Promise<{
|
|
91
|
+
updated: string[];
|
|
92
|
+
missing: string[];
|
|
93
|
+
}>;
|
|
94
|
+
/**
|
|
95
|
+
* Applies link additions and removals across multiple action keys (Cartesian product).
|
|
96
|
+
* For each action_key × each add_related key: calls addLink (idempotent, self-link guarded).
|
|
97
|
+
* For each action_key × each remove_related key: calls removeLink.
|
|
98
|
+
* Returns counts of added (non-null addLink results) and removed (all removeLink calls).
|
|
99
|
+
*/
|
|
100
|
+
export declare function applyLinksBulk(adapter: HazoConnectAdapter, params: {
|
|
101
|
+
app_id: string;
|
|
102
|
+
action_keys: string[];
|
|
103
|
+
add_related?: string[];
|
|
104
|
+
remove_related?: string[];
|
|
105
|
+
}): Promise<{
|
|
106
|
+
added: number;
|
|
107
|
+
removed: number;
|
|
108
|
+
}>;
|
|
109
|
+
export {};
|
|
66
110
|
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/server/actions.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/server/actions.ts"],"names":[],"mappings":"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"}
|