@happyvertical/smrt-reports 0.55.6 → 0.55.8
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 +34 -0
- package/README.md +16 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +995 -4
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +444 -14
- package/dist/recipes.d.ts +28 -0
- package/dist/recipes.d.ts.map +1 -0
- package/dist/refresh.d.ts +3 -0
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +1 -1
- package/dist/refresh.js.map +1 -1
- package/dist/runtime-compiler.d.ts +142 -0
- package/dist/runtime-compiler.d.ts.map +1 -0
- package/dist/runtime-report.d.ts +105 -0
- package/dist/runtime-report.d.ts.map +1 -0
- package/dist/runtime-spec.d.ts +126 -0
- package/dist/runtime-spec.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +328 -19
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +26 -13
- package/dist/state.js.map +1 -1
- package/package.json +8 -7
package/dist/smrt-knowledge.json
CHANGED
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
"sensitiveFieldsExcluded": true,
|
|
4
4
|
"generatedAt": "1970-01-01T00:00:00.000Z",
|
|
5
5
|
"packageName": "@happyvertical/smrt-reports",
|
|
6
|
-
"packageVersion": "0.55.
|
|
6
|
+
"packageVersion": "0.55.8",
|
|
7
7
|
"sourceManifestPath": "dist/manifest.json",
|
|
8
8
|
"agentDocPath": "AGENTS.md",
|
|
9
9
|
"sourceHashes": {
|
|
10
|
-
"manifest": "
|
|
11
|
-
"packageJson": "
|
|
12
|
-
"agents": "
|
|
10
|
+
"manifest": "a2a5f00350221badf07f1eb61209bdb933208f81f4ccac683894978062a2fcee",
|
|
11
|
+
"packageJson": "05c9160b383ecae2b8dcafeb3a0b05701d2e0f1524809a1308c062968a6a178b",
|
|
12
|
+
"agents": "b7d07b1b9812cdc09f3e34f086f1ec33dc9d8ca53eb6dd070e91bd4783642956",
|
|
13
|
+
"moduleDoc:agents/runtime-reports.md": "183dade71aa7947ae5964ad21c6a94fab0b7826298dc42709379fa229928df59"
|
|
13
14
|
},
|
|
14
15
|
"exports": [
|
|
15
16
|
".",
|
|
@@ -28,6 +29,7 @@
|
|
|
28
29
|
"@happyvertical/smrt-types": "workspace:*",
|
|
29
30
|
"@happyvertical/smrt-tenancy": "workspace:*",
|
|
30
31
|
"@happyvertical/sql": "catalog:",
|
|
32
|
+
"@happyvertical/smrt-scanner": "workspace:*",
|
|
31
33
|
"@happyvertical/smrt-vitest": "workspace:*",
|
|
32
34
|
"@types/node": "24.13.6",
|
|
33
35
|
"typescript": "6.0.3",
|
|
@@ -37,6 +39,7 @@
|
|
|
37
39
|
"smrtDependencies": [
|
|
38
40
|
"@happyvertical/smrt-core",
|
|
39
41
|
"@happyvertical/smrt-jobs",
|
|
42
|
+
"@happyvertical/smrt-scanner",
|
|
40
43
|
"@happyvertical/smrt-tenancy",
|
|
41
44
|
"@happyvertical/smrt-types",
|
|
42
45
|
"@happyvertical/smrt-vitest"
|
|
@@ -141,6 +144,181 @@
|
|
|
141
144
|
"tags": [],
|
|
142
145
|
"risks": []
|
|
143
146
|
},
|
|
147
|
+
{
|
|
148
|
+
"name": "RuntimeReport",
|
|
149
|
+
"qualifiedName": "@happyvertical/smrt-reports:RuntimeReport",
|
|
150
|
+
"displayLabelField": "title",
|
|
151
|
+
"collection": "runtimereports",
|
|
152
|
+
"tableName": "runtime_reports",
|
|
153
|
+
"packageName": "@happyvertical/smrt-reports",
|
|
154
|
+
"extends": "SmrtObject",
|
|
155
|
+
"fields": [
|
|
156
|
+
{
|
|
157
|
+
"name": "tenantId",
|
|
158
|
+
"type": "text",
|
|
159
|
+
"required": true,
|
|
160
|
+
"columnType": "UUID"
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"name": "title",
|
|
164
|
+
"type": "text",
|
|
165
|
+
"required": false,
|
|
166
|
+
"columnType": "TEXT"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"name": "description",
|
|
170
|
+
"type": "text",
|
|
171
|
+
"required": false,
|
|
172
|
+
"columnType": "TEXT"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"name": "sourceId",
|
|
176
|
+
"type": "text",
|
|
177
|
+
"required": false,
|
|
178
|
+
"columnType": "TEXT"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"name": "spec",
|
|
182
|
+
"type": "text",
|
|
183
|
+
"required": true,
|
|
184
|
+
"columnType": "TEXT"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"name": "specHash",
|
|
188
|
+
"type": "text",
|
|
189
|
+
"required": false,
|
|
190
|
+
"columnType": "TEXT"
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"name": "status",
|
|
194
|
+
"type": "text",
|
|
195
|
+
"required": true,
|
|
196
|
+
"columnType": "TEXT"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"name": "createdByUserId",
|
|
200
|
+
"type": "text",
|
|
201
|
+
"required": false,
|
|
202
|
+
"columnType": "TEXT"
|
|
203
|
+
}
|
|
204
|
+
],
|
|
205
|
+
"relationships": [],
|
|
206
|
+
"methods": [
|
|
207
|
+
"getSpec",
|
|
208
|
+
"setSpec"
|
|
209
|
+
],
|
|
210
|
+
"methodSignatures": [
|
|
211
|
+
{
|
|
212
|
+
"name": "getSpec",
|
|
213
|
+
"returns": "RuntimeReportSpec"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"name": "setSpec",
|
|
217
|
+
"params": [
|
|
218
|
+
"spec: RuntimeReportSpec"
|
|
219
|
+
],
|
|
220
|
+
"returns": "void"
|
|
221
|
+
}
|
|
222
|
+
],
|
|
223
|
+
"tenant": {
|
|
224
|
+
"scoped": true,
|
|
225
|
+
"mode": "required",
|
|
226
|
+
"field": "tenantId"
|
|
227
|
+
},
|
|
228
|
+
"conflictColumns": [
|
|
229
|
+
"tenant_id",
|
|
230
|
+
"slug",
|
|
231
|
+
"context"
|
|
232
|
+
],
|
|
233
|
+
"surfaces": [
|
|
234
|
+
{
|
|
235
|
+
"kind": "api",
|
|
236
|
+
"name": "runtimereports.list",
|
|
237
|
+
"operation": "list",
|
|
238
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport",
|
|
239
|
+
"path": "/runtimereports",
|
|
240
|
+
"method": "GET"
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"kind": "api",
|
|
244
|
+
"name": "runtimereports.get",
|
|
245
|
+
"operation": "get",
|
|
246
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport",
|
|
247
|
+
"path": "/runtimereports/[id]",
|
|
248
|
+
"method": "GET"
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
"kind": "api",
|
|
252
|
+
"name": "runtimereports.create",
|
|
253
|
+
"operation": "create",
|
|
254
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport",
|
|
255
|
+
"path": "/runtimereports",
|
|
256
|
+
"method": "POST"
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"kind": "cli",
|
|
260
|
+
"name": "runtimereport_list",
|
|
261
|
+
"operation": "list",
|
|
262
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport"
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"kind": "cli",
|
|
266
|
+
"name": "runtimereport_get",
|
|
267
|
+
"operation": "get",
|
|
268
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport"
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"kind": "mcp",
|
|
272
|
+
"name": "runtimereport_list",
|
|
273
|
+
"operation": "list",
|
|
274
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport"
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"kind": "mcp",
|
|
278
|
+
"name": "runtimereport_get",
|
|
279
|
+
"operation": "get",
|
|
280
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport"
|
|
281
|
+
}
|
|
282
|
+
],
|
|
283
|
+
"withheldSurfaces": [
|
|
284
|
+
{
|
|
285
|
+
"kind": "api",
|
|
286
|
+
"operation": "getSpec",
|
|
287
|
+
"code": "not-included",
|
|
288
|
+
"reason": "not listed in api.include",
|
|
289
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport"
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"kind": "api",
|
|
293
|
+
"operation": "setSpec",
|
|
294
|
+
"code": "not-included",
|
|
295
|
+
"reason": "not listed in api.include",
|
|
296
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport"
|
|
297
|
+
}
|
|
298
|
+
],
|
|
299
|
+
"relationshipFeatures": [
|
|
300
|
+
"uuidColumns"
|
|
301
|
+
],
|
|
302
|
+
"tags": [],
|
|
303
|
+
"risks": []
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
"name": "RuntimeReportCollection",
|
|
307
|
+
"qualifiedName": "@happyvertical/smrt-reports:RuntimeReportCollection",
|
|
308
|
+
"collection": "runtimereports",
|
|
309
|
+
"tableName": "runtime_reports",
|
|
310
|
+
"packageName": "@happyvertical/smrt-reports",
|
|
311
|
+
"extends": "SmrtCollection",
|
|
312
|
+
"fields": [],
|
|
313
|
+
"relationships": [],
|
|
314
|
+
"methods": [],
|
|
315
|
+
"surfaces": [],
|
|
316
|
+
"relationshipFeatures": [
|
|
317
|
+
"uuidColumns"
|
|
318
|
+
],
|
|
319
|
+
"tags": [],
|
|
320
|
+
"risks": []
|
|
321
|
+
},
|
|
144
322
|
{
|
|
145
323
|
"name": "SmrtReportRefreshTask",
|
|
146
324
|
"qualifiedName": "@happyvertical/smrt-reports:SmrtReportRefreshTask",
|
|
@@ -238,6 +416,7 @@
|
|
|
238
416
|
"name": "SmrtPrincipalReportRefreshTask",
|
|
239
417
|
"qualifiedName": "@happyvertical/smrt-reports:SmrtPrincipalReportRefreshTask",
|
|
240
418
|
"collection": "smrtprincipalreportrefreshtasks",
|
|
419
|
+
"description": "Worker target whose authority requirement cannot be downgraded by job args.",
|
|
241
420
|
"tableName": "_smrt_principal_report_refresh_tasks",
|
|
242
421
|
"packageName": "@happyvertical/smrt-reports",
|
|
243
422
|
"extends": "SmrtReportRefreshTask",
|
|
@@ -351,25 +530,29 @@
|
|
|
351
530
|
"name": "status",
|
|
352
531
|
"type": "text",
|
|
353
532
|
"required": true,
|
|
354
|
-
"columnType": "TEXT"
|
|
533
|
+
"columnType": "TEXT",
|
|
534
|
+
"description": "Whether the refresh is running, finished, failed or was skipped."
|
|
355
535
|
},
|
|
356
536
|
{
|
|
357
537
|
"name": "startedAt",
|
|
358
538
|
"type": "datetime",
|
|
359
539
|
"required": true,
|
|
360
|
-
"columnType": "TIMESTAMP"
|
|
540
|
+
"columnType": "TIMESTAMP",
|
|
541
|
+
"description": "When the refresh began."
|
|
361
542
|
},
|
|
362
543
|
{
|
|
363
544
|
"name": "completedAt",
|
|
364
545
|
"type": "datetime",
|
|
365
546
|
"required": false,
|
|
366
|
-
"columnType": "TIMESTAMP"
|
|
547
|
+
"columnType": "TIMESTAMP",
|
|
548
|
+
"description": "When the refresh finished. Empty while it is still running."
|
|
367
549
|
},
|
|
368
550
|
{
|
|
369
551
|
"name": "rowCount",
|
|
370
552
|
"type": "integer",
|
|
371
553
|
"required": true,
|
|
372
|
-
"columnType": "INTEGER"
|
|
554
|
+
"columnType": "INTEGER",
|
|
555
|
+
"description": "How many rows the report held after the refresh."
|
|
373
556
|
},
|
|
374
557
|
{
|
|
375
558
|
"name": "changedGroupCount",
|
|
@@ -393,7 +576,8 @@
|
|
|
393
576
|
"name": "error",
|
|
394
577
|
"type": "text",
|
|
395
578
|
"required": false,
|
|
396
|
-
"columnType": "TEXT"
|
|
579
|
+
"columnType": "TEXT",
|
|
580
|
+
"description": "Why the refresh failed. Empty when it worked."
|
|
397
581
|
},
|
|
398
582
|
{
|
|
399
583
|
"name": "metadata",
|
|
@@ -681,7 +865,8 @@
|
|
|
681
865
|
"name": "cron",
|
|
682
866
|
"type": "text",
|
|
683
867
|
"required": true,
|
|
684
|
-
"columnType": "TEXT"
|
|
868
|
+
"columnType": "TEXT",
|
|
869
|
+
"description": "When the report refreshes, as a cron schedule such as 0 6 * * * for 6 am daily."
|
|
685
870
|
},
|
|
686
871
|
{
|
|
687
872
|
"name": "trigger",
|
|
@@ -693,43 +878,50 @@
|
|
|
693
878
|
"name": "mode",
|
|
694
879
|
"type": "text",
|
|
695
880
|
"required": true,
|
|
696
|
-
"columnType": "TEXT"
|
|
881
|
+
"columnType": "TEXT",
|
|
882
|
+
"description": "Rebuild recomputes the whole report. Incremental updates only what changed."
|
|
697
883
|
},
|
|
698
884
|
{
|
|
699
885
|
"name": "enabled",
|
|
700
886
|
"type": "boolean",
|
|
701
887
|
"required": true,
|
|
702
|
-
"columnType": "BOOLEAN"
|
|
888
|
+
"columnType": "BOOLEAN",
|
|
889
|
+
"description": "Turn off to stop refreshing without deleting the schedule."
|
|
703
890
|
},
|
|
704
891
|
{
|
|
705
892
|
"name": "status",
|
|
706
893
|
"type": "text",
|
|
707
894
|
"required": true,
|
|
708
|
-
"columnType": "TEXT"
|
|
895
|
+
"columnType": "TEXT",
|
|
896
|
+
"description": "Whether the schedule is active, paused, disabled or in error."
|
|
709
897
|
},
|
|
710
898
|
{
|
|
711
899
|
"name": "nextRun",
|
|
712
900
|
"type": "datetime",
|
|
713
901
|
"required": false,
|
|
714
|
-
"columnType": "TIMESTAMP"
|
|
902
|
+
"columnType": "TIMESTAMP",
|
|
903
|
+
"description": "When the report is next due to refresh."
|
|
715
904
|
},
|
|
716
905
|
{
|
|
717
906
|
"name": "lastRun",
|
|
718
907
|
"type": "datetime",
|
|
719
908
|
"required": false,
|
|
720
|
-
"columnType": "TIMESTAMP"
|
|
909
|
+
"columnType": "TIMESTAMP",
|
|
910
|
+
"description": "When the report last started a scheduled refresh."
|
|
721
911
|
},
|
|
722
912
|
{
|
|
723
913
|
"name": "lastStatus",
|
|
724
914
|
"type": "text",
|
|
725
915
|
"required": false,
|
|
726
|
-
"columnType": "TEXT"
|
|
916
|
+
"columnType": "TEXT",
|
|
917
|
+
"description": "Whether the last scheduled refresh worked or failed."
|
|
727
918
|
},
|
|
728
919
|
{
|
|
729
920
|
"name": "lastError",
|
|
730
921
|
"type": "text",
|
|
731
922
|
"required": false,
|
|
732
|
-
"columnType": "TEXT"
|
|
923
|
+
"columnType": "TEXT",
|
|
924
|
+
"description": "Why the last scheduled refresh failed. Empty when it worked."
|
|
733
925
|
},
|
|
734
926
|
{
|
|
735
927
|
"name": "runCount",
|
|
@@ -832,6 +1024,54 @@
|
|
|
832
1024
|
}
|
|
833
1025
|
],
|
|
834
1026
|
"surfaces": [
|
|
1027
|
+
{
|
|
1028
|
+
"kind": "api",
|
|
1029
|
+
"name": "runtimereports.list",
|
|
1030
|
+
"operation": "list",
|
|
1031
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport",
|
|
1032
|
+
"path": "/runtimereports",
|
|
1033
|
+
"method": "GET"
|
|
1034
|
+
},
|
|
1035
|
+
{
|
|
1036
|
+
"kind": "api",
|
|
1037
|
+
"name": "runtimereports.get",
|
|
1038
|
+
"operation": "get",
|
|
1039
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport",
|
|
1040
|
+
"path": "/runtimereports/[id]",
|
|
1041
|
+
"method": "GET"
|
|
1042
|
+
},
|
|
1043
|
+
{
|
|
1044
|
+
"kind": "api",
|
|
1045
|
+
"name": "runtimereports.create",
|
|
1046
|
+
"operation": "create",
|
|
1047
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport",
|
|
1048
|
+
"path": "/runtimereports",
|
|
1049
|
+
"method": "POST"
|
|
1050
|
+
},
|
|
1051
|
+
{
|
|
1052
|
+
"kind": "cli",
|
|
1053
|
+
"name": "runtimereport_list",
|
|
1054
|
+
"operation": "list",
|
|
1055
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport"
|
|
1056
|
+
},
|
|
1057
|
+
{
|
|
1058
|
+
"kind": "cli",
|
|
1059
|
+
"name": "runtimereport_get",
|
|
1060
|
+
"operation": "get",
|
|
1061
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport"
|
|
1062
|
+
},
|
|
1063
|
+
{
|
|
1064
|
+
"kind": "mcp",
|
|
1065
|
+
"name": "runtimereport_list",
|
|
1066
|
+
"operation": "list",
|
|
1067
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport"
|
|
1068
|
+
},
|
|
1069
|
+
{
|
|
1070
|
+
"kind": "mcp",
|
|
1071
|
+
"name": "runtimereport_get",
|
|
1072
|
+
"operation": "get",
|
|
1073
|
+
"objectName": "@happyvertical/smrt-reports:RuntimeReport"
|
|
1074
|
+
},
|
|
835
1075
|
{
|
|
836
1076
|
"kind": "cli",
|
|
837
1077
|
"name": "smrtreportrefreshtask_list",
|
|
@@ -912,7 +1152,76 @@
|
|
|
912
1152
|
"junctionCollections": 0,
|
|
913
1153
|
"hierarchicalObjects": 0,
|
|
914
1154
|
"polymorphicAssociations": 0,
|
|
915
|
-
"uuidColumns":
|
|
1155
|
+
"uuidColumns": 24
|
|
916
1156
|
},
|
|
917
|
-
"agentDoc": "# @happyvertical/smrt-reports\n\nMaterialized aggregate report models for SMRT.\n\n## Key Pieces\n\n| Module | Purpose |\n| --- | --- |\n| `SmrtReport` | Abstract report row base with `refreshedAt`, `isStale()`, and manual `refresh()` |\n| decorators | `@report`, grouping decorators, time buckets, and aggregate measure decorators |\n| compiler | Pure `ReportDefinition -> AggregateSpec` compiler and ObjectRegistry adapter |\n| aggregate | Compatibility re-export of the SDK aggregate query builder |\n| refresh | Rebuild and incremental refresh engine with run tracking, watermarks, locks, and tenant scoping |\n| state | Internal `_smrt_report_*` system models for runs, watermarks, locks, schedules, and refresh tasks |\n| scheduler | Cron schedule runner, durable refresh job enqueueing, and `onChange` interceptor registration |\n| adapter | Transport-neutral report descriptor, canonical materialized-row reads, and stable `id` row identity |\n| lifecycle | Tenant-safe freshness, run, lock, failure, and manual refresh preview/apply surfaces |\n| views | Policy-revalidated saved views, snapshot-bound exports, bounded job handoff, and artifact metadata validation |\n\n## Adapter contract\n\n- `buildReportAdapterDescriptor()` returns deterministic, serializable metadata\n for a report surface: a stable resource id, typed persisted report columns,\n the canonical `DataQuerySchema`, and UI-neutral DataTable hints. It must not\n import `smrt-ui` or expose a report-domain class to the consumer.\n- `queryReportMaterializedRows()` owns only the bounded read slice for rows that\n are already materialized. It supports projection, offset/limit paging,\n validated filters, deterministic multi-sort with an `id` tie-breaker, exact\n totals, and dimension facets. At source-query compilation,\n dimension and bucket filters compile to `WHERE`, aggregate-measure filters\n compile to `HAVING`, and mixed `OR`/`NOT` filter scopes fail closed.\n- `id` is the only row identity. It must be a non-empty persisted string and is\n never replaced by a display index or page position.\n- The descriptor is an exposure boundary. Sensitive/secret fields, fields with\n `readPermission`, and transient, system, or non-column fields fail closed and\n do not become public columns when no principal is available.\n- `tenantScoped`/`tenantField` reflect actual registered tenant metadata. A\n `tenantScope` option only contributes to the stable resource id; it is not\n authorization. Pass the same `adapter` options to\n `queryReportMaterializedRows()` that were used to build the selected\n descriptor, so results and background tasks retain that stable resource id.\n The default query path resolves the registered collection via `ObjectRegistry`,\n so normal collection tenancy interceptors apply. An injected collection is\n application-owned and must preserve the same boundary.\n- `refresh` is a declaration, not execution. It describes configured mode,\n triggers, positive-TTL stale-read behavior, and a permissioned/audited action\n with preview/apply phases. The adapter remains read-only, while\n `getReportLifecycle()` provides an explicit, tenant-safe lifecycle snapshot\n and `previewReportRefresh()` / `applyReportRefresh()` delegate authorization,\n audit, and queueing through an application action host. Only a registered\n `SmrtReportCollection` may synchronously refresh stale reads, when its TTL is\n positive and the report is not manual.\n- `views` accepts no authority. Persisted views must be normalized again through\n the current descriptor before restoring them, so changed column policy or a\n changed report definition fails closed. Treat unversioned persisted layouts as\n legacy v0 and migrate them to v1 before normalization; unknown versions must\n fail rather than being inferred. Export snapshots retain the canonical\n query fingerprint, projection, sort, as-of/freshness state, exact row count,\n and the fixed principal/tenant/report-definition/field-policy inheritance\n contract. A snapshot needs an application-host-issued opaque binding and an\n explicit offset-page read plan: workers advance it from offset zero instead\n of reusing a visible page. Preview, apply, worker, and artifact-serving\n boundaries must call the validators, including the host's immutable-snapshot\n assertion; application hosts own authorization, audit records, durable\n storage, download tokens, and queue execution.\n\n## Conventions\n\n- Report cache tables are normal `@smrt()` tables. Runtime refresh must not create schema.\n- Store report metadata under field `_meta.__report`; scanner and runtime decorators must stay aligned.\n- Keep SQL generation portable. Use the SDK `buildAggregate()`/`bucketExpr()` helpers for time buckets and `$N` placeholders.\n- Do not add a local aggregate SQL builder here; the implementation lives in `@happyvertical/sql`.\n- Refresh runtime tables are schema-managed. Runtime refresh must fail clearly when `_smrt_report_runs`, `_smrt_report_watermarks`, or `_smrt_report_locks` have not been migrated.\n- Incremental refresh requires a source watermark column (default `updatedAt`) and soft-delete column (default `deletedAt`); it recomputes affected groups and deletes empty report groups instead of applying aggregate deltas.\n- Raw aggregate refreshes must explicitly filter `tenant_id`; the tenancy interceptor only protects normal collection reads.\n- Scheduled/on-change refreshes enqueue `SmrtReportRefreshTask.run()` through `@happyvertical/smrt-jobs`; do not add a separate report queue.\n- `SmrtReportCollection` is a framework collection base (core's `SMRT_COLLECTION_BASE_NAMES`): a report collection never owns its model's table, even when an app manifest attributes the two to different packages. `pnpm test:postgres` runs the `*.optional.test.ts` lane (#3110).\n"
|
|
1157
|
+
"agentDoc": "# @happyvertical/smrt-reports\n\nMaterialized aggregate report models for SMRT.\n\n## Key Pieces\n\n| Module | Purpose |\n| --- | --- |\n| `SmrtReport` | Abstract report row base with `refreshedAt`, `isStale()`, and manual `refresh()` |\n| decorators | `@report`, grouping decorators, time buckets, and aggregate measure decorators |\n| compiler | Pure `ReportDefinition -> AggregateSpec` compiler and ObjectRegistry adapter |\n| aggregate | Compatibility re-export of the SDK aggregate query builder |\n| refresh | Rebuild and incremental refresh engine with run tracking, watermarks, locks, and tenant scoping |\n| state | Internal `_smrt_report_*` system models for runs, watermarks, locks, schedules, and refresh tasks |\n| scheduler | Cron schedule runner, durable refresh job enqueueing, and `onChange` interceptor registration |\n| adapter | Transport-neutral report descriptor, canonical materialized-row reads, and stable `id` row identity |\n| lifecycle | Tenant-safe freshness, run, lock, failure, and manual refresh preview/apply surfaces |\n| views | Policy-revalidated saved views, snapshot-bound exports, bounded job handoff, and artifact metadata validation |\n| runtime reports | Declarative `RuntimeReportSpec` stored as data (`RuntimeReport`), compiled per principal with field-policy, RBAC and tenant checks; see [agents/runtime-reports.md](agents/runtime-reports.md) |\n\n## Adapter contract\n\n- `buildReportAdapterDescriptor()` returns deterministic, serializable metadata\n for a report surface: a stable resource id, typed persisted report columns,\n the canonical `DataQuerySchema`, and UI-neutral DataTable hints. It must not\n import `smrt-ui` or expose a report-domain class to the consumer.\n- `queryReportMaterializedRows()` owns only the bounded read slice for rows that\n are already materialized. It supports projection, offset/limit paging,\n validated filters, deterministic multi-sort with an `id` tie-breaker, exact\n totals, and dimension facets. At source-query compilation,\n dimension and bucket filters compile to `WHERE`, aggregate-measure filters\n compile to `HAVING`, and mixed `OR`/`NOT` filter scopes fail closed.\n- `id` is the only row identity. It must be a non-empty persisted string and is\n never replaced by a display index or page position.\n- The descriptor is an exposure boundary. Sensitive/secret fields, fields with\n `readPermission`, and transient, system, or non-column fields fail closed and\n do not become public columns when no principal is available.\n- `tenantScoped`/`tenantField` reflect actual registered tenant metadata. A\n `tenantScope` option only contributes to the stable resource id; it is not\n authorization. Pass the same `adapter` options to\n `queryReportMaterializedRows()` that were used to build the selected\n descriptor, so results and background tasks retain that stable resource id.\n The default query path resolves the registered collection via `ObjectRegistry`,\n so normal collection tenancy interceptors apply. An injected collection is\n application-owned and must preserve the same boundary.\n- `refresh` is a declaration, not execution. It describes configured mode,\n triggers, positive-TTL stale-read behavior, and a permissioned/audited action\n with preview/apply phases. The adapter remains read-only, while\n `getReportLifecycle()` provides an explicit, tenant-safe lifecycle snapshot\n and `previewReportRefresh()` / `applyReportRefresh()` delegate authorization,\n audit, and queueing through an application action host. Only a registered\n `SmrtReportCollection` may synchronously refresh stale reads, when its TTL is\n positive and the report is not manual.\n- `views` accepts no authority. Persisted views must be normalized again through\n the current descriptor before restoring them, so changed column policy or a\n changed report definition fails closed. Treat unversioned persisted layouts as\n legacy v0 and migrate them to v1 before normalization; unknown versions must\n fail rather than being inferred. Export snapshots retain the canonical\n query fingerprint, projection, sort, as-of/freshness state, exact row count,\n and the fixed principal/tenant/report-definition/field-policy inheritance\n contract. A snapshot needs an application-host-issued opaque binding and an\n explicit offset-page read plan: workers advance it from offset zero instead\n of reusing a visible page. Preview, apply, worker, and artifact-serving\n boundaries must call the validators, including the host's immutable-snapshot\n assertion; application hosts own authorization, audit records, durable\n storage, download tokens, and queue execution.\n\n## Runtime reports (#3711)\n\nA runtime report is data, not code: `parseRuntimeReportSpec()` accepts a closed\ngrammar (no SQL, expressions, joins, tables, or tenants), and\n`compileRuntimeReportSpec()` resolves it against a server-owned source\nallow-list, the ObjectRegistry field policy, the live principal's permissions,\nand an explicit fail-closed tenant predicate. Stored `RuntimeReport` specs are\nre-compiled for the running principal on every run, and result rows are never\npersisted. Assistant tools are in `@happyvertical/smrt-chat`. The full\ncontract, authority model, and deferred work are in\n[agents/runtime-reports.md](agents/runtime-reports.md).\n\n## Recipes (#3719)\n\n`src/recipes.ts` declares `reports.materialized` (`MaterializedReportsRecipe`),\nemitted into the built `manifest.json` and `smrt-knowledge.json` `recipes`. It\nbrings only the internal refresh bookkeeping tables (runs, watermarks, locks,\nschedules, refresh tasks); an app's own `@report` classes are not listed because\nthey belong to the app. Those tables have no REST or MCP surface, so the recipe\nhas no `nav`. It declares `runtime: 'server'` (SQL aggregation, jobs) and no\n`surfaces`: this package ships no Svelte components, and declaring one that does\nnot exist is a scan-time lie. Do not add a surface until a real export exists.\n\nUser-facing help is `src/materialized.recipe.md` (#3591). It explains how the\nassistant reads declared reports (`data.discover`/`data.inspect` and\n`reports.query`/`reports.refresh` from `@happyvertical/smrt-agents`) and how\nruntime reports (`reports.runtime.*` in `@happyvertical/smrt-chat`) differ: live,\nnever stored, saved only after a person confirms. Keep that split accurate when\neither tool set changes. `{field:...}` references need a `@field({ description })`\non `state.ts` so the glossary can explain them. `src/__tests__/recipes.test.ts`\nruns the real scan, manifest and generation passes in memory and renders the help.\nSee [core recipes](../core/agents/recipes.md).\n\n## Conventions\n\n- Report cache tables are normal `@smrt()` tables. Runtime refresh must not create schema.\n- Store report metadata under field `_meta.__report`; scanner and runtime decorators must stay aligned.\n- Keep SQL generation portable. Use the SDK `buildAggregate()`/`bucketExpr()` helpers for time buckets and `$N` placeholders.\n- Do not add a local aggregate SQL builder here; the implementation lives in `@happyvertical/sql`.\n- Refresh runtime tables are schema-managed. Runtime refresh must fail clearly when `_smrt_report_runs`, `_smrt_report_watermarks`, or `_smrt_report_locks` have not been migrated.\n- Incremental refresh requires a source watermark column (default `updatedAt`) and soft-delete column (default `deletedAt`); it recomputes affected groups and deletes empty report groups instead of applying aggregate deltas.\n- Raw aggregate refreshes must explicitly filter `tenant_id`; the tenancy interceptor only protects normal collection reads.\n- Scheduled/on-change refreshes enqueue `SmrtReportRefreshTask.run()` through `@happyvertical/smrt-jobs`; do not add a separate report queue.\n- `SmrtReportCollection` is a framework collection base (core's `SMRT_COLLECTION_BASE_NAMES`): a report collection never owns its model's table, even when an app manifest attributes the two to different packages. `pnpm test:postgres` runs the `*.optional.test.ts` lane (#3110).\n",
|
|
1158
|
+
"moduleDocs": [
|
|
1159
|
+
{
|
|
1160
|
+
"path": "agents/runtime-reports.md",
|
|
1161
|
+
"module": "runtime-reports",
|
|
1162
|
+
"content": "# Runtime reports (#3711)\n\nReports the assistant (or any caller) defines at runtime from a user request.\nA report is a **declarative spec stored as data**; there is no codegen, no new\ntable per report, and no SQL, expression, join or raw-identifier syntax in the\ngrammar. Declared (`@report`) reports are unchanged and remain the way to get a\n**materialized** report.\n\n## Files\n\n| File | Role |\n| --- | --- |\n| `src/runtime-spec.ts` | `RuntimeReportSpec` grammar, strict parser, limits, stable hash |\n| `src/runtime-compiler.ts` | `compileRuntimeReportSpec()`, `describeRuntimeReportSource()`, `runRuntimeReport()` |\n| `src/runtime-report.ts` | `RuntimeReport` model (`runtime_reports`), `saveRuntimeReport()`, list/get/archive, `runStoredRuntimeReport()` |\n\nAssistant tools live in `@happyvertical/smrt-chat` (`createRuntimeReportTools()`,\n`src/runtime-report-tools.ts`).\n\n## Spec\n\n`version: 1`, `title`, optional `description`, `source` (a server-owned source\nid), `dimensions[]` (`field`, `as?`, `bucket?`), `measures[]` (`fn`: `count`,\n`countDistinct`, `sum`, `avg`, `min`, `max`; `field?`; `as?`), `filters[]`\n(AND-ed; ops `eq ne gt gte lt lte in notIn contains isNull isNotNull`),\n`having[]` (measure alias, numeric compare), `sort[]`, `limit` (1-1000, default\n100) and a `chart` hint (`table|bar|line|pie|stat`, `x`, `y[]`). Unknown keys\nat any level are rejected. Bounds (entries, string length, `in` list size,\nalias charset, reserved words) are in `RUNTIME_REPORT_LIMITS`.\n\nThe parser normalizes defaults and derives aliases, so equal specs hash equally\n(`runtimeReportSpecHash`). The hash is what a human confirmation binds to.\n\n## Authority model\n\nA spec carries **no authority**. Everything is decided at compile time from\ninputs the caller cannot supply through the spec:\n\n- **Sources.** `RuntimeReportCompileContext.sources` is a server allow-list of\n `{ id, className, collection }`. The spec names an id; unknown and\n not-offered answer identically (`unknown_source`). `authorizeSource` is the\n host's RBAC hook (the chat tools call `run.assertOperation(collection,\n 'read')`) and runs before any field is enumerated. A host should also narrow\n `sources` to those the principal may read before compiling (the chat tools do),\n because `authorizeSource` only runs for an id that is in the list: otherwise\n an RBAC refusal for a configured id and `unknown_source` for an absent one are\n different answers, and a caller can enumerate the configured source ids. `collection` is the\n permission-catalog collection **slug** (the `<collection>` of\n `<collection>.read`, for example `runtimereports`), or the registered model\n class, which resolves to that slug through the catalog's own helper. It is\n never a class name string: `Invoice` derives `Invoice.read`, which no\n catalog contains, so every read is denied and the source is silently not\n offered.\n- **Field policy.** Names are resolved from the ObjectRegistry, never from the\n spec. Not nameable: `sensitive` / `sensitivity: sensitive|secret` fields,\n `readPermission` fields unless `context.permissions` holds that permission,\n `transient`, `json`/relationship fields, `_`-prefixed internals and the tenant\n column. A hidden field is reported exactly like an absent one\n (`unknown_field`), so the compiler is not an existence oracle.\n- **Types.** `sum`/`avg` need numeric fields, `min`/`max` numeric or datetime,\n `bucket` needs datetime, `contains` needs text, id fields accept only UUIDs\n and equality-style ops. Values are coerced to the field type, then bound.\n- **Tenancy.** Raw aggregates bypass collection interceptors, so the compiler\n adds the tenant predicate itself (same column resolution as refresh).\n Tenant-scoped source with no tenant in scope reads only NULL-tenant rows;\n there is no cross-tenant option and `withSystemContext()`/super-admin bypass\n are deliberately not honored. Sources without a tenant column are global by\n definition. `deletedAt` and STI-child discriminators are applied when the\n source has them.\n- **SQL safety.** The plan is an `AggregateSpec` executed by the SDK\n `buildAggregate()`: identifiers are registry-derived and re-validated by the\n builder, values are `$N` parameters, and output aliases are prefixed `r_`\n inside the SQL so an alias can never shadow a source column.\n- **Re-validation.** A stored report is re-parsed (hash-checked) and\n re-compiled against the **running** principal on every run, so policy changes\n apply immediately and a viewer without a permission cannot run a report saved\n by someone who had it.\n- **Stored-report storage.** The tenancy interceptor filters by the AMBIENT\n tenant, while compilation uses the principal's tenant. The chat tools bind the\n two: they enter the principal's tenant context for `list`/`get`/`save` (as the\n data-surface guard does), refuse when an ambient tenant disagrees with the\n principal, require a tenant for any stored-report use, and pass the principal\n tenant as an explicit owner filter (`getRuntimeReport`/`listRuntimeReports`\n accept `tenantId`) that still holds under a system context.\n\n## Storage and surface\n\n`RuntimeReport` is `@TenantScoped({ mode: 'required' })` with `spec` (normalized\nJSON text), `specHash`, denormalized `title`/`description`/`sourceId`,\n`status` (`active|archived`) and `createdByUserId`. `validateBeforeSave()` parses\nwhatever was written and re-derives every denormalized column, so columns\ncannot disagree with the spec. `getSpec()` throws if the JSON no longer matches\n`specHash` (out-of-band edit). Adopting apps need a `db:migrate` for the new\n`runtime_reports` table; runtime never creates schema.\n\n**Invariant: no row is inserted, and no spec/title/source/description/author is\nchanged, except through the confirmed save.** It is enforced in the model layer,\nnot by which surfaces exist. `validateBeforeSave()` refuses (`confirmation_required`,\n403) every insert, and every update that changes those columns, unless the\ninstance carries a confirmation proof. The proof is a symbol-keyed constructor\noption plus a module-private `WeakMap`; only `saveRuntimeReport()` can mint it,\nand only when `confirmedSpecHash` equals the compiled plan's hash (the value\nhanded to the application's `RuntimeReportConfirmationHost`). It is single use\nand tied to that exact spec hash. A REST body, a manifest tool call or\n`new RuntimeReport({...}).save()` cannot carry it, so it is refused whatever\nsurface delivered it. A reused id on an insert is refused the same way, so it\ncannot overwrite a stored spec. Archiving or unarchiving (a `status` change with\nthe stored columns untouched) is allowed for an authorised writer.\n\n**Exposed operations** (these decide the permission catalog and RLS grants):\n\n| Surface | Operations |\n| --- | --- |\n| REST (`api`) | `list`, `get`, `create` |\n| CLI | `list`, `get` |\n| MCP | `list`, `get` |\n\nThe permission catalog therefore holds exactly `<collection>.read` and\n`<collection>.create` for `RuntimeReport` (the collection slug is\n`runtimereports`). `update` and `delete` exist on no surface, so they are not in\nthe catalog, not grantable to a role and not nameable in a persona's\n`allowedTools`. REST `create` exists only so the catalog knows the operation the\nconfirmed save performs (`assertOperation(RuntimeReport, 'create')`); its body is\nalways refused by the invariant above. The generic manifest tool dispatcher in\n`@happyvertical/smrt-chat` additionally never offers or runs a write operation on\n`RuntimeReport` (`isRuntimeReportWriteOperation`), so the assistant persists a\nreport only through `reports.runtime.define` (apply).\n\n**Result rows are never persisted.** A result computed for one principal must\nnot be served to another, so the table stores definitions only.\n\n## Why not materialize\n\nDeclared reports materialize into a build-time `@smrt()` table and refresh\nthrough the lock/watermark engine. Runtime schema creation is forbidden here, so\na runtime spec runs as a bounded live aggregate on the same `AggregateSpec`\ncompile target instead. Promoting a proven runtime spec to a declared,\nmaterialized `@report` (codegen plus a migration) is a maintainer decision and\nis tracked as a follow-up.\n\n## Money\n\nMoney fields are integer minor units; `sum`/`min`/`max` keep the integer type and\nthe source field's `format` hint is carried onto the result column. Integer\nresults beyond the JavaScript safe range throw `invalid_result` rather than\nlosing precision. `avg` is decimal.\n\n## Assistant flow (`@happyvertical/smrt-chat`)\n\n`reports.runtime.sources` (field catalogue for the principal) ->\n`reports.runtime.define` `phase: 'preview'` (validate, compile, bounded sample;\nnothing stored) -> a human confirms -> `phase: 'apply'` with the previewed\n`specHash` -> `reports.runtime.list` / `reports.runtime.run`. `apply` needs an\napplication-owned `RuntimeReportConfirmationHost.confirmSave()` that resolves\nonly after a person approved that exact spec; without a host the tools are\npropose-only, and a model-supplied `confirmed` flag is ignored. Offer the tools\nvia the persona conversation `extraTools` seam; they use the same fail-closed\n`allowedTools` gates, and `RuntimeReportError.status` (422/403/500) lets\n`classifyToolError` return repairable spec problems to the model.\n\n## Not done (needs #3708 or a design call)\n\n- A `reports.runtime` recipe for `RuntimeReport` itself. `reports.materialized`\n (see `AGENTS.md`) covers declared reports only and its help points at the\n `reports.runtime.*` tools; `RuntimeReport` has no recipe of its own yet.\n- A browser UI for the confirmation host and for rendering the chart hint.\n- Archive/rename tools, scheduling a runtime report, exporting its rows.\n"
|
|
1163
|
+
}
|
|
1164
|
+
],
|
|
1165
|
+
"recipes": [
|
|
1166
|
+
{
|
|
1167
|
+
"id": "reports.materialized",
|
|
1168
|
+
"className": "MaterializedReportsRecipe",
|
|
1169
|
+
"label": "Reports",
|
|
1170
|
+
"summary": "Keep totals and trends ready to read, refreshed on a schedule and open to the assistant.",
|
|
1171
|
+
"synonyms": [
|
|
1172
|
+
"reports",
|
|
1173
|
+
"totals",
|
|
1174
|
+
"summaries",
|
|
1175
|
+
"rollups",
|
|
1176
|
+
"kpis",
|
|
1177
|
+
"trends",
|
|
1178
|
+
"dashboards"
|
|
1179
|
+
],
|
|
1180
|
+
"models": [
|
|
1181
|
+
"@happyvertical/smrt-reports:SmrtReportRun",
|
|
1182
|
+
"@happyvertical/smrt-reports:SmrtReportWatermark",
|
|
1183
|
+
"@happyvertical/smrt-reports:SmrtReportLock",
|
|
1184
|
+
"@happyvertical/smrt-reports:SmrtReportSchedule",
|
|
1185
|
+
"@happyvertical/smrt-reports:SmrtReportRefreshTask",
|
|
1186
|
+
"@happyvertical/smrt-reports:SmrtPrincipalReportRefreshTask"
|
|
1187
|
+
],
|
|
1188
|
+
"nav": [],
|
|
1189
|
+
"requires": [],
|
|
1190
|
+
"help": {
|
|
1191
|
+
"markdown": "## Overview\n\nReports keep totals and trends, such as revenue by month or signups by week,\nworked out ahead of time so they open instantly. Someone on your team sets up\neach report once. This feature then records when each report was last\nrefreshed, how that went, and when it runs next.\n\nReports are calculated on your server, never in the browser, so this feature\nneeds your app's database.\n\n## Tasks\n\n### Ask the assistant about a report\n\n1. Ask in plain words, for example \"what was revenue last month?\".\n2. The assistant looks up the reports your account may see\n (`data.discover`, `data.inspect`), then reads rows with `reports.query`.\n It only ever sees the columns and the customer data you are allowed to see.\n3. If the numbers look old, ask how fresh the report is. The answer says when\n it was last refreshed.\n4. Ask the assistant to refresh a stale report. It previews the refresh with\n `reports.refresh` and your app decides who may apply it.\n\nThe assistant offers these tools only when your app has switched them on.\n\n### Ask a question no report covers\n\n1. Describe what you want to see, for example \"orders by status this quarter\".\n2. The assistant checks what it may report on (`reports.runtime.sources`) and\n shows a preview of the report it would save (`reports.runtime.define`).\n3. Nothing is saved until you confirm that exact report.\n4. Open it again later with `reports.runtime.list` and `reports.runtime.run`.\n\nThese reports are worked out live each time and their rows are never stored.\nThey are not refreshed in the background. A report that people open every day\nis worth asking your team to set up as a refreshed report instead.\n\n### Keep a report fresh\n\n1. Ask your team how the report refreshes: by hand, on a schedule, after the\n data changes, or when it goes out of date.\n2. A scheduled report repeats on its **{field:SmrtReportSchedule.cron}**, either\n rebuilding everything or updating only what changed, per its\n **{field:SmrtReportSchedule.mode}**.\n3. Turn **{field:SmrtReportSchedule.enabled}** off to pause a schedule without\n losing it.\n4. **{field:SmrtReportSchedule.nextRun}** shows when it is next due.\n\n### Check that a refresh worked\n\n1. Look at the latest run for the report. **{field:SmrtReportRun.status}**\n says whether it is running, finished, failed or skipped.\n2. **{field:SmrtReportRun.completedAt}** and **{field:SmrtReportRun.rowCount}**\n show when it finished and how many rows it holds.\n3. If it failed, **{field:SmrtReportRun.error}** says why.\n",
|
|
1192
|
+
"fieldRefs": [
|
|
1193
|
+
"SmrtReportRun.completedAt",
|
|
1194
|
+
"SmrtReportRun.error",
|
|
1195
|
+
"SmrtReportRun.rowCount",
|
|
1196
|
+
"SmrtReportRun.status",
|
|
1197
|
+
"SmrtReportSchedule.cron",
|
|
1198
|
+
"SmrtReportSchedule.enabled",
|
|
1199
|
+
"SmrtReportSchedule.mode",
|
|
1200
|
+
"SmrtReportSchedule.nextRun"
|
|
1201
|
+
]
|
|
1202
|
+
},
|
|
1203
|
+
"runtime": "server",
|
|
1204
|
+
"demo": {
|
|
1205
|
+
"mode": "server",
|
|
1206
|
+
"reasons": [
|
|
1207
|
+
"The recipe declares runtime \"server\".",
|
|
1208
|
+
"Needs a server because its package does not build for a browser: node:crypto/events; @happyvertical/sql root: the sync query builders it needs (validateColumnName, buildWhere, buildAggregate, bucketExpr, tableExists) have no browser-safe SDK entry; and its package depends on @happyvertical/smrt-jobs, @happyvertical/smrt-tenancy, which do not build for a browser (#3615, #3624, #3625, #3627)."
|
|
1209
|
+
]
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
],
|
|
1213
|
+
"browser": {
|
|
1214
|
+
"status": "server-only",
|
|
1215
|
+
"issues": [
|
|
1216
|
+
"#3615",
|
|
1217
|
+
"#3624",
|
|
1218
|
+
"#3625",
|
|
1219
|
+
"#3627"
|
|
1220
|
+
],
|
|
1221
|
+
"reason": "node:crypto/events; @happyvertical/sql root: the sync query builders it needs (validateColumnName, buildWhere, buildAggregate, bucketExpr, tableExists) have no browser-safe SDK entry",
|
|
1222
|
+
"via": [
|
|
1223
|
+
"@happyvertical/smrt-jobs",
|
|
1224
|
+
"@happyvertical/smrt-tenancy"
|
|
1225
|
+
]
|
|
1226
|
+
}
|
|
918
1227
|
}
|
package/dist/state.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,cAAc,EACd,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE1E,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AACrD,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AACjE,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AACvD,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AAEvE,eAAO,MAAM,qBAAqB,iFAIxB,CAAC;AAEX,eAAO,MAAM,uBAAuB,mEAG1B,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAC3E,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAE9E,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAE7E;AAED,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,iBAAiB,EACrB,MAAM,GAAE,SAAS,MAAM,EAA0B,GAChD,OAAO,CAAC,IAAI,CAAC,CAUf;AAYD,qBAKa,aAAc,SAAQ,UAAU;IAE3C,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAG/B,QAAQ,EAAE,MAAM,CAAY;IAG5B,WAAW,EAAE,MAAM,CAAM;IAGzB,WAAW,EAAE,MAAM,CAAM;IAGzB,IAAI,EAAE,iBAAiB,CAAa;IAGpC,OAAO,EAAE,oBAAoB,CAAY;
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
package/dist/state.js
CHANGED
|
@@ -83,19 +83,23 @@ __decorateClass([field({
|
|
|
83
83
|
})], SmrtReportRun.prototype, "trigger", 2);
|
|
84
84
|
__decorateClass([field({
|
|
85
85
|
type: "text",
|
|
86
|
-
required: true
|
|
86
|
+
required: true,
|
|
87
|
+
description: "Whether the refresh is running, finished, failed or was skipped."
|
|
87
88
|
})], SmrtReportRun.prototype, "status", 2);
|
|
88
89
|
__decorateClass([field({
|
|
89
90
|
type: "datetime",
|
|
90
|
-
required: true
|
|
91
|
+
required: true,
|
|
92
|
+
description: "When the refresh began."
|
|
91
93
|
})], SmrtReportRun.prototype, "startedAt", 2);
|
|
92
94
|
__decorateClass([field({
|
|
93
95
|
type: "datetime",
|
|
94
|
-
nullable: true
|
|
96
|
+
nullable: true,
|
|
97
|
+
description: "When the refresh finished. Empty while it is still running."
|
|
95
98
|
})], SmrtReportRun.prototype, "completedAt", 2);
|
|
96
99
|
__decorateClass([field({
|
|
97
100
|
type: "integer",
|
|
98
|
-
required: true
|
|
101
|
+
required: true,
|
|
102
|
+
description: "How many rows the report held after the refresh."
|
|
99
103
|
})], SmrtReportRun.prototype, "rowCount", 2);
|
|
100
104
|
__decorateClass([field({
|
|
101
105
|
type: "integer",
|
|
@@ -111,7 +115,8 @@ __decorateClass([field({
|
|
|
111
115
|
})], SmrtReportRun.prototype, "watermarkAfter", 2);
|
|
112
116
|
__decorateClass([field({
|
|
113
117
|
type: "text",
|
|
114
|
-
nullable: true
|
|
118
|
+
nullable: true,
|
|
119
|
+
description: "Why the refresh failed. Empty when it worked."
|
|
115
120
|
})], SmrtReportRun.prototype, "error", 2);
|
|
116
121
|
__decorateClass([field({ type: "json" })], SmrtReportRun.prototype, "metadata", 2);
|
|
117
122
|
SmrtReportRun = __decorateClass([TenantScoped({ mode: "optional" }), smrt({
|
|
@@ -246,7 +251,8 @@ __decorateClass([field({
|
|
|
246
251
|
})], SmrtReportSchedule.prototype, "reportClass", 2);
|
|
247
252
|
__decorateClass([field({
|
|
248
253
|
type: "text",
|
|
249
|
-
required: true
|
|
254
|
+
required: true,
|
|
255
|
+
description: "When the report refreshes, as a cron schedule such as 0 6 * * * for 6 am daily."
|
|
250
256
|
})], SmrtReportSchedule.prototype, "cron", 2);
|
|
251
257
|
__decorateClass([field({
|
|
252
258
|
type: "text",
|
|
@@ -254,31 +260,38 @@ __decorateClass([field({
|
|
|
254
260
|
})], SmrtReportSchedule.prototype, "trigger", 2);
|
|
255
261
|
__decorateClass([field({
|
|
256
262
|
type: "text",
|
|
257
|
-
required: true
|
|
263
|
+
required: true,
|
|
264
|
+
description: "Rebuild recomputes the whole report. Incremental updates only what changed."
|
|
258
265
|
})], SmrtReportSchedule.prototype, "mode", 2);
|
|
259
266
|
__decorateClass([field({
|
|
260
267
|
type: "boolean",
|
|
261
|
-
required: true
|
|
268
|
+
required: true,
|
|
269
|
+
description: "Turn off to stop refreshing without deleting the schedule."
|
|
262
270
|
})], SmrtReportSchedule.prototype, "enabled", 2);
|
|
263
271
|
__decorateClass([field({
|
|
264
272
|
type: "text",
|
|
265
|
-
required: true
|
|
273
|
+
required: true,
|
|
274
|
+
description: "Whether the schedule is active, paused, disabled or in error."
|
|
266
275
|
})], SmrtReportSchedule.prototype, "status", 2);
|
|
267
276
|
__decorateClass([field({
|
|
268
277
|
type: "datetime",
|
|
269
|
-
nullable: true
|
|
278
|
+
nullable: true,
|
|
279
|
+
description: "When the report is next due to refresh."
|
|
270
280
|
})], SmrtReportSchedule.prototype, "nextRun", 2);
|
|
271
281
|
__decorateClass([field({
|
|
272
282
|
type: "datetime",
|
|
273
|
-
nullable: true
|
|
283
|
+
nullable: true,
|
|
284
|
+
description: "When the report last started a scheduled refresh."
|
|
274
285
|
})], SmrtReportSchedule.prototype, "lastRun", 2);
|
|
275
286
|
__decorateClass([field({
|
|
276
287
|
type: "text",
|
|
277
|
-
nullable: true
|
|
288
|
+
nullable: true,
|
|
289
|
+
description: "Whether the last scheduled refresh worked or failed."
|
|
278
290
|
})], SmrtReportSchedule.prototype, "lastStatus", 2);
|
|
279
291
|
__decorateClass([field({
|
|
280
292
|
type: "text",
|
|
281
|
-
nullable: true
|
|
293
|
+
nullable: true,
|
|
294
|
+
description: "Why the last scheduled refresh failed. Empty when it worked."
|
|
282
295
|
})], SmrtReportSchedule.prototype, "lastError", 2);
|
|
283
296
|
__decorateClass([field({
|
|
284
297
|
type: "integer",
|