@happyvertical/smrt-reports 0.55.24 → 0.56.1

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.
Files changed (91) hide show
  1. package/AGENTS.md +26 -3
  2. package/README.md +11 -2
  3. package/dist/index.d.ts +4 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +476 -109
  6. package/dist/index.js.map +1 -1
  7. package/dist/manifest.json +174 -5
  8. package/dist/materialized-host.d.ts +72 -0
  9. package/dist/materialized-host.d.ts.map +1 -0
  10. package/dist/playground.d.ts +2 -0
  11. package/dist/playground.d.ts.map +1 -0
  12. package/dist/playground.js +154 -0
  13. package/dist/playground.js.map +1 -0
  14. package/dist/recipes.d.ts +55 -0
  15. package/dist/recipes.d.ts.map +1 -1
  16. package/dist/runtime-report.d.ts +9 -0
  17. package/dist/runtime-report.d.ts.map +1 -1
  18. package/dist/runtime-server.d.ts +77 -0
  19. package/dist/runtime-server.d.ts.map +1 -0
  20. package/dist/runtime-spec.d.ts +2 -1
  21. package/dist/runtime-spec.d.ts.map +1 -1
  22. package/dist/smrt-knowledge.json +203 -11
  23. package/dist/state.js +1 -1
  24. package/dist/state.js.map +1 -1
  25. package/dist/svelte/MaterializedReportTable.svelte +104 -0
  26. package/dist/svelte/MaterializedReportTable.svelte.d.ts +14 -0
  27. package/dist/svelte/MaterializedReportTable.svelte.d.ts.map +1 -0
  28. package/dist/svelte/ReportConfirmation.svelte +99 -0
  29. package/dist/svelte/ReportConfirmation.svelte.d.ts +15 -0
  30. package/dist/svelte/ReportConfirmation.svelte.d.ts.map +1 -0
  31. package/dist/svelte/ReportDetail.svelte +69 -0
  32. package/dist/svelte/ReportDetail.svelte.d.ts +11 -0
  33. package/dist/svelte/ReportDetail.svelte.d.ts.map +1 -0
  34. package/dist/svelte/ReportPicker.svelte +73 -0
  35. package/dist/svelte/ReportPicker.svelte.d.ts +16 -0
  36. package/dist/svelte/ReportPicker.svelte.d.ts.map +1 -0
  37. package/dist/svelte/ReportResult.svelte +69 -0
  38. package/dist/svelte/ReportResult.svelte.d.ts +10 -0
  39. package/dist/svelte/ReportResult.svelte.d.ts.map +1 -0
  40. package/dist/svelte/RuntimeReportChartWidget.svelte +20 -0
  41. package/dist/svelte/RuntimeReportChartWidget.svelte.d.ts +11 -0
  42. package/dist/svelte/RuntimeReportChartWidget.svelte.d.ts.map +1 -0
  43. package/dist/svelte/RuntimeReportDetailRoute.svelte +67 -0
  44. package/dist/svelte/RuntimeReportDetailRoute.svelte.d.ts +21 -0
  45. package/dist/svelte/RuntimeReportDetailRoute.svelte.d.ts.map +1 -0
  46. package/dist/svelte/RuntimeReportToolResult.svelte +26 -0
  47. package/dist/svelte/RuntimeReportToolResult.svelte.d.ts +8 -0
  48. package/dist/svelte/RuntimeReportToolResult.svelte.d.ts.map +1 -0
  49. package/dist/svelte/RuntimeReportWidgetOptions.svelte +58 -0
  50. package/dist/svelte/RuntimeReportWidgetOptions.svelte.d.ts +14 -0
  51. package/dist/svelte/RuntimeReportWidgetOptions.svelte.d.ts.map +1 -0
  52. package/dist/svelte/RuntimeReportsRoute.svelte +67 -0
  53. package/dist/svelte/RuntimeReportsRoute.svelte.d.ts +19 -0
  54. package/dist/svelte/RuntimeReportsRoute.svelte.d.ts.map +1 -0
  55. package/dist/svelte/SavedReports.svelte +114 -0
  56. package/dist/svelte/SavedReports.svelte.d.ts +11 -0
  57. package/dist/svelte/SavedReports.svelte.d.ts.map +1 -0
  58. package/dist/svelte/browser-client.d.ts +10 -0
  59. package/dist/svelte/browser-client.d.ts.map +1 -0
  60. package/dist/svelte/browser-client.js +16 -0
  61. package/dist/svelte/client.d.ts +15 -0
  62. package/dist/svelte/client.d.ts.map +1 -0
  63. package/dist/svelte/client.js +179 -0
  64. package/dist/svelte/index.d.ts +17 -0
  65. package/dist/svelte/index.d.ts.map +1 -0
  66. package/dist/svelte/index.js +14 -0
  67. package/dist/svelte/materialized.d.ts +19 -0
  68. package/dist/svelte/materialized.d.ts.map +1 -0
  69. package/dist/svelte/materialized.js +1 -0
  70. package/dist/svelte/messages.d.ts +72 -0
  71. package/dist/svelte/messages.d.ts.map +1 -0
  72. package/dist/svelte/messages.js +72 -0
  73. package/dist/svelte/playground.d.ts +132 -0
  74. package/dist/svelte/playground.d.ts.map +1 -0
  75. package/dist/svelte/playground.js +62 -0
  76. package/dist/svelte/preview-data.d.ts +7 -0
  77. package/dist/svelte/preview-data.d.ts.map +1 -0
  78. package/dist/svelte/preview-data.js +59 -0
  79. package/dist/svelte/result.d.ts +8 -0
  80. package/dist/svelte/result.d.ts.map +1 -0
  81. package/dist/svelte/result.js +99 -0
  82. package/dist/svelte/spec.d.ts +5 -0
  83. package/dist/svelte/spec.d.ts.map +1 -0
  84. package/dist/svelte/spec.js +282 -0
  85. package/dist/svelte/tool-result.d.ts +11 -0
  86. package/dist/svelte/tool-result.d.ts.map +1 -0
  87. package/dist/svelte/tool-result.js +19 -0
  88. package/dist/svelte/types.d.ts +38 -0
  89. package/dist/svelte/types.d.ts.map +1 -0
  90. package/dist/svelte/types.js +1 -0
  91. package/package.json +36 -12
@@ -2,7 +2,7 @@
2
2
  "version": "1.0.0",
3
3
  "timestamp": 0,
4
4
  "packageName": "@happyvertical/smrt-reports",
5
- "packageVersion": "0.55.24",
5
+ "packageVersion": "0.56.1",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-reports:SmrtReport": {
8
8
  "name": "smrtreport",
@@ -189,6 +189,31 @@
189
189
  }
190
190
  },
191
191
  "methods": {
192
+ "run": {
193
+ "name": "run",
194
+ "async": true,
195
+ "parameters": [],
196
+ "returnType": "Promise<RuntimeReportResult>",
197
+ "isStatic": false,
198
+ "isPublic": true
199
+ },
200
+ "archive": {
201
+ "name": "archive",
202
+ "async": true,
203
+ "parameters": [
204
+ {
205
+ "name": "options",
206
+ "type": "object",
207
+ "optional": false,
208
+ "memberTypes": [
209
+ "boolean"
210
+ ]
211
+ }
212
+ ],
213
+ "returnType": "Promise<object>",
214
+ "isStatic": false,
215
+ "isPublic": true
216
+ },
192
217
  "getSpec": {
193
218
  "name": "getSpec",
194
219
  "async": false,
@@ -214,23 +239,69 @@
214
239
  },
215
240
  "decoratorConfig": {
216
241
  "tableName": "runtime_reports",
242
+ "indexes": [
243
+ {
244
+ "name": "idx_runtime_reports_confirm",
245
+ "columns": [
246
+ "tenantId",
247
+ "createdByUserId",
248
+ "specHash",
249
+ "status"
250
+ ]
251
+ }
252
+ ],
253
+ "operationPermissions": {
254
+ "run": {
255
+ "action": "read"
256
+ },
257
+ "archive": {
258
+ "action": "create",
259
+ "databaseActions": [
260
+ "SELECT",
261
+ "UPDATE"
262
+ ]
263
+ }
264
+ },
217
265
  "api": {
218
266
  "include": [
219
267
  "list",
220
268
  "get",
221
- "create"
222
- ]
269
+ "create",
270
+ "run",
271
+ "archive"
272
+ ],
273
+ "principalContext": true,
274
+ "routes": {
275
+ "run": {
276
+ "method": "POST",
277
+ "scope": "item",
278
+ "effect": "read",
279
+ "idempotent": true,
280
+ "openWorld": false
281
+ },
282
+ "archive": {
283
+ "method": "POST",
284
+ "scope": "item",
285
+ "effect": "write",
286
+ "idempotent": true,
287
+ "openWorld": false
288
+ }
289
+ }
223
290
  },
224
291
  "mcp": {
225
292
  "include": [
226
293
  "list",
227
- "get"
294
+ "get",
295
+ "run",
296
+ "archive"
228
297
  ]
229
298
  },
230
299
  "cli": {
231
300
  "include": [
232
301
  "list",
233
- "get"
302
+ "get",
303
+ "run",
304
+ "archive"
234
305
  ]
235
306
  },
236
307
  "tenantScoped": {
@@ -339,6 +410,15 @@
339
410
  ],
340
411
  "unique": true
341
412
  },
413
+ {
414
+ "name": "idx_runtime_reports_confirm",
415
+ "columns": [
416
+ "tenant_id",
417
+ "created_by_user_id",
418
+ "spec_hash",
419
+ "status"
420
+ ]
421
+ },
342
422
  {
343
423
  "name": "runtime_reports_tenant_id_created_at_idx",
344
424
  "columns": [
@@ -448,6 +528,15 @@
448
528
  ],
449
529
  "unique": true
450
530
  },
531
+ {
532
+ "name": "idx_runtime_reports_confirm",
533
+ "columns": [
534
+ "tenant_id",
535
+ "created_by_user_id",
536
+ "spec_hash",
537
+ "status"
538
+ ]
539
+ },
451
540
  {
452
541
  "name": "runtime_reports_tenant_id_created_at_idx",
453
542
  "columns": [
@@ -2620,6 +2709,86 @@
2620
2709
  "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)."
2621
2710
  ]
2622
2711
  }
2712
+ },
2713
+ {
2714
+ "id": "reports.runtime",
2715
+ "className": "RuntimeReportsRecipe",
2716
+ "label": "Reports",
2717
+ "summary": "Ask for a report, approve it, and share its live totals with your team.",
2718
+ "synonyms": [],
2719
+ "models": [
2720
+ "@happyvertical/smrt-reports:RuntimeReport"
2721
+ ],
2722
+ "nav": [
2723
+ {
2724
+ "label": "Reports",
2725
+ "model": "@happyvertical/smrt-reports:RuntimeReport",
2726
+ "icon": "fileText"
2727
+ }
2728
+ ],
2729
+ "requires": [],
2730
+ "help": {
2731
+ "markdown": "# Reports\n\nAsk the assistant for a total, comparison, or trend. Review the proposed report\nand approve it to save it. Your saved reports are shared with your team; each\nperson sees results using their own access to the underlying information.\n\nReports run fresh when opened. You can archive a report to hide it from the\nactive list and restore it later. Creating and restoring reports needs report\nwriting access. Reports need a connected server and are unavailable in offline\npreviews. Scheduling, renaming, and exporting reports are not available yet.\n",
2732
+ "fieldRefs": []
2733
+ },
2734
+ "surfaces": [
2735
+ {
2736
+ "kind": "route",
2737
+ "path": "/reports",
2738
+ "export": "@happyvertical/smrt-reports/svelte#RuntimeReportsRoute",
2739
+ "label": "Reports"
2740
+ },
2741
+ {
2742
+ "kind": "route",
2743
+ "path": "/reports/:id",
2744
+ "export": "@happyvertical/smrt-reports/svelte#RuntimeReportDetailRoute",
2745
+ "label": "Report detail"
2746
+ },
2747
+ {
2748
+ "kind": "widget",
2749
+ "type": "runtime-report-chart",
2750
+ "export": "@happyvertical/smrt-reports/svelte#RuntimeReportChartWidget",
2751
+ "label": "Report chart",
2752
+ "description": "Chart a measure from a saved report.",
2753
+ "icon": "chart",
2754
+ "optionsEditor": "@happyvertical/smrt-reports/svelte#RuntimeReportWidgetOptions",
2755
+ "options": [
2756
+ {
2757
+ "key": "reportId",
2758
+ "type": "text",
2759
+ "label": "Report",
2760
+ "required": true
2761
+ },
2762
+ {
2763
+ "key": "measure",
2764
+ "type": "identifier",
2765
+ "label": "Measure",
2766
+ "required": true
2767
+ },
2768
+ {
2769
+ "key": "dimension",
2770
+ "type": "identifier",
2771
+ "label": "Dimension"
2772
+ }
2773
+ ],
2774
+ "data": {
2775
+ "load": "@happyvertical/smrt-reports#loadRuntimeReportChart",
2776
+ "models": [
2777
+ "@happyvertical/smrt-reports:RuntimeReport"
2778
+ ]
2779
+ },
2780
+ "defaultSpan": 2,
2781
+ "maxSpan": 4
2782
+ }
2783
+ ],
2784
+ "runtime": "server",
2785
+ "demo": {
2786
+ "mode": "server",
2787
+ "reasons": [
2788
+ "The recipe declares runtime \"server\".",
2789
+ "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)."
2790
+ ]
2791
+ }
2623
2792
  }
2624
2793
  ],
2625
2794
  "smrtDependencies": [
@@ -0,0 +1,72 @@
1
+ import type { ReportAdapterDescriptor, ReportDataQueryResult } from './adapter.js';
2
+ /** Verified request context supplied by an application route, never the browser. */
3
+ export interface MaterializedReportHostContext {
4
+ userId: string;
5
+ tenantId: string;
6
+ permissions: readonly string[];
7
+ }
8
+ /** The only browser-controlled selections accepted by a materialized-report host. */
9
+ export interface MaterializedReportCellRequest {
10
+ id: string;
11
+ columnId: string;
12
+ }
13
+ /** A host-normalized monetary value; values stay in integer minor units. */
14
+ export interface MaterializedReportDrilldownValues {
15
+ valueMinor?: number | null;
16
+ taxableMinor?: number | null;
17
+ taxMinor?: number | null;
18
+ }
19
+ /** One user-visible record contributing to a materialized report cell. */
20
+ export interface MaterializedReportDrilldownContributor {
21
+ id: string;
22
+ source: string;
23
+ identity: string;
24
+ date?: string | null;
25
+ party?: string | null;
26
+ values: MaterializedReportDrilldownValues;
27
+ }
28
+ /** A host-declared warning that keeps incomplete or divergent evidence visible. */
29
+ export interface MaterializedReportDrilldownWarning {
30
+ code: string;
31
+ kind: 'incomplete' | 'drift';
32
+ message: string;
33
+ }
34
+ /**
35
+ * Domain-neutral presentation returned by a materialized-report host.
36
+ *
37
+ * The route serializes this value unchanged. Hosts normalize their own source
38
+ * facts here so generic browser surfaces neither import nor infer report domains.
39
+ */
40
+ export interface MaterializedReportDrilldownPresentation {
41
+ version: 1;
42
+ selectedMeasure: {
43
+ id: string;
44
+ label: string;
45
+ };
46
+ currency: string;
47
+ contributors: readonly MaterializedReportDrilldownContributor[];
48
+ complete: boolean;
49
+ warnings: readonly MaterializedReportDrilldownWarning[];
50
+ }
51
+ /**
52
+ * Application-owned bridge for one declared materialized report.
53
+ *
54
+ * Registrations are server-only and bind tenant/principal from the route
55
+ * context. Hosts must re-read the selected row before resolving a cell.
56
+ */
57
+ export interface MaterializedReportHost<Drilldown = unknown> {
58
+ id: string;
59
+ /** Registered collection and model used by the route's normal read gate. */
60
+ collection: string;
61
+ className: string;
62
+ /** The report host fails closed unless this published permission is present. */
63
+ readPermission: string;
64
+ /** Closed visible columns that may request a source drilldown. */
65
+ drilldownColumnIds: readonly string[];
66
+ descriptor(context: MaterializedReportHostContext): Promise<ReportAdapterDescriptor>;
67
+ query(context: MaterializedReportHostContext, request: unknown): Promise<ReportDataQueryResult>;
68
+ drilldown(context: MaterializedReportHostContext, request: MaterializedReportCellRequest): Promise<Drilldown>;
69
+ }
70
+ export declare function assertMaterializedReportRead(host: MaterializedReportHost, context: MaterializedReportHostContext): void;
71
+ export declare function findMaterializedReportHost(hosts: readonly MaterializedReportHost[], id: string): MaterializedReportHost | undefined;
72
+ //# sourceMappingURL=materialized-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"materialized-host.d.ts","sourceRoot":"","sources":["../src/materialized-host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,qBAAqB,EACtB,MAAM,cAAc,CAAC;AAEtB,oFAAoF;AACpF,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED,qFAAqF;AACrF,MAAM,WAAW,6BAA6B;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,4EAA4E;AAC5E,MAAM,WAAW,iCAAiC;IAChD,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,0EAA0E;AAC1E,MAAM,WAAW,sCAAsC;IACrD,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,iCAAiC,CAAC;CAC3C;AAED,mFAAmF;AACnF,MAAM,WAAW,kCAAkC;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,uCAAuC;IACtD,OAAO,EAAE,CAAC,CAAC;IACX,eAAe,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,SAAS,sCAAsC,EAAE,CAAC;IAChE,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,SAAS,kCAAkC,EAAE,CAAC;CACzD;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB,CAAC,SAAS,GAAG,OAAO;IACzD,EAAE,EAAE,MAAM,CAAC;IACX,4EAA4E;IAC5E,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,cAAc,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,UAAU,CACR,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACpC,KAAK,CACH,OAAO,EAAE,6BAA6B,EACtC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAClC,SAAS,CACP,OAAO,EAAE,6BAA6B,EACtC,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,SAAS,CAAC,CAAC;CACvB;AAED,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,sBAAsB,EAC5B,OAAO,EAAE,6BAA6B,GACrC,IAAI,CAQN;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,SAAS,sBAAsB,EAAE,EACxC,EAAE,EAAE,MAAM,GACT,sBAAsB,GAAG,SAAS,CAEpC"}
@@ -0,0 +1,2 @@
1
+ export { default } from './svelte/playground.js';
2
+ //# sourceMappingURL=playground.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playground.d.ts","sourceRoot":"","sources":["../src/playground.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,154 @@
1
+ //#region src/svelte/preview-data.ts
2
+ var spec = {
3
+ version: 1,
4
+ title: "Sales by region",
5
+ source: "sales",
6
+ dimensions: [{
7
+ field: "region",
8
+ as: "region"
9
+ }],
10
+ measures: [{
11
+ fn: "sum",
12
+ field: "amount",
13
+ as: "total"
14
+ }],
15
+ filters: [],
16
+ having: [],
17
+ sort: [],
18
+ limit: 100,
19
+ chart: {
20
+ type: "bar",
21
+ x: "region",
22
+ y: ["total"]
23
+ }
24
+ };
25
+ var result = {
26
+ version: 1,
27
+ specHash: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
28
+ title: spec.title,
29
+ columns: [{
30
+ id: "region",
31
+ label: "Region",
32
+ role: "dimension",
33
+ type: "string"
34
+ }, {
35
+ id: "total",
36
+ label: "Total",
37
+ role: "measure",
38
+ type: "integer",
39
+ format: "money"
40
+ }],
41
+ rows: [{
42
+ region: "West",
43
+ total: 12345
44
+ }],
45
+ rowCount: 1,
46
+ truncated: false,
47
+ ranAt: "2026-10-13T12:00:00Z",
48
+ chart: spec.chart
49
+ };
50
+ var saved = {
51
+ id: "report-1",
52
+ title: spec.title,
53
+ sourceId: "sales",
54
+ createdByUserId: "alice",
55
+ status: "active",
56
+ spec,
57
+ canArchive: true
58
+ };
59
+ var proposal = {
60
+ status: "awaiting_confirmation",
61
+ specHash: result.specHash,
62
+ spec,
63
+ preview: result,
64
+ sourceLabel: "Sales",
65
+ confirmPath: "/api/_reports/runtime/confirm"
66
+ };
67
+ function client(overrides = {}) {
68
+ return {
69
+ list: async () => [saved],
70
+ get: async () => saved,
71
+ run: async () => result,
72
+ archive: async () => {},
73
+ confirm: async () => saved,
74
+ ...overrides
75
+ };
76
+ }
77
+ //#endregion
78
+ //#region src/svelte/playground.ts
79
+ var playground_default = {
80
+ packageName: "@happyvertical/smrt-reports",
81
+ displayName: "Reports",
82
+ description: "Saved runtime reports and live results.",
83
+ entries: [
84
+ {
85
+ id: "saved-reports",
86
+ title: "Saved reports",
87
+ description: "Shared reports, author filter, and archive controls.",
88
+ loadComponent: () => import("./svelte/SavedReports.svelte").then((m) => m.default),
89
+ props: { client: client() },
90
+ order: 1
91
+ },
92
+ {
93
+ id: "report-detail",
94
+ title: "Report detail",
95
+ description: "Money values with chart and table views.",
96
+ loadComponent: () => import("./svelte/ReportDetail.svelte").then((m) => m.default),
97
+ props: {
98
+ id: saved.id,
99
+ client: client(),
100
+ locale: "en-US"
101
+ },
102
+ order: 2
103
+ },
104
+ {
105
+ id: "report-confirmation",
106
+ title: "Report confirmation",
107
+ description: "Review a bounded proposal before saving.",
108
+ loadComponent: () => import("./svelte/ReportConfirmation.svelte").then((m) => m.default),
109
+ props: {
110
+ proposal,
111
+ confirm: async () => saved
112
+ },
113
+ order: 3
114
+ },
115
+ {
116
+ id: "report-picker",
117
+ title: "Report picker",
118
+ description: "Choose a saved report and its measure.",
119
+ loadComponent: () => import("./svelte/ReportPicker.svelte").then((m) => m.default),
120
+ props: {
121
+ client: client(),
122
+ reportId: saved.id,
123
+ measure: "total",
124
+ dimension: "region",
125
+ onchange: () => {}
126
+ },
127
+ order: 4
128
+ },
129
+ {
130
+ id: "reports-unavailable",
131
+ title: "Reports unavailable",
132
+ description: "Static hosts do not make server requests.",
133
+ loadComponent: () => import("./svelte/RuntimeReportsRoute.svelte").then((m) => m.default),
134
+ props: { serverAvailable: false },
135
+ order: 5
136
+ },
137
+ {
138
+ id: "report-empty",
139
+ title: "Empty report",
140
+ description: "A valid report with no matching rows.",
141
+ loadComponent: () => import("./svelte/ReportResult.svelte").then((m) => m.default),
142
+ props: { result: {
143
+ ...result,
144
+ rows: [],
145
+ rowCount: 0
146
+ } },
147
+ order: 6
148
+ }
149
+ ]
150
+ };
151
+ //#endregion
152
+ export { playground_default as default };
153
+
154
+ //# sourceMappingURL=playground.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playground.js","names":[],"sources":["../src/svelte/preview-data.ts","../src/svelte/playground.ts"],"sourcesContent":["import type {\n RuntimeReportProposal,\n RuntimeReportResult,\n RuntimeReportSpec,\n RuntimeReportsClient,\n SavedRuntimeReport,\n} from './types.js';\n\nexport const spec: RuntimeReportSpec = {\n version: 1,\n title: 'Sales by region',\n source: 'sales',\n dimensions: [{ field: 'region', as: 'region' }],\n measures: [{ fn: 'sum', field: 'amount', as: 'total' }],\n filters: [],\n having: [],\n sort: [],\n limit: 100,\n chart: { type: 'bar', x: 'region', y: ['total'] },\n};\nexport const result: RuntimeReportResult = {\n version: 1,\n specHash: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',\n title: spec.title,\n columns: [\n { id: 'region', label: 'Region', role: 'dimension', type: 'string' },\n {\n id: 'total',\n label: 'Total',\n role: 'measure',\n type: 'integer',\n format: 'money',\n },\n ],\n rows: [{ region: 'West', total: 12345 }],\n rowCount: 1,\n truncated: false,\n ranAt: '2026-10-13T12:00:00Z',\n chart: spec.chart,\n};\nexport const saved: SavedRuntimeReport = {\n id: 'report-1',\n title: spec.title,\n sourceId: 'sales',\n createdByUserId: 'alice',\n status: 'active',\n spec,\n canArchive: true,\n};\nexport const proposal: RuntimeReportProposal = {\n status: 'awaiting_confirmation',\n specHash: result.specHash,\n spec,\n preview: result,\n sourceLabel: 'Sales',\n confirmPath: '/api/_reports/runtime/confirm',\n};\nexport function client(\n overrides: Partial<RuntimeReportsClient> = {},\n): RuntimeReportsClient {\n return {\n list: async () => [saved],\n get: async () => saved,\n run: async () => result,\n archive: async () => {},\n confirm: async () => saved,\n ...overrides,\n };\n}\n","import { client, proposal, result, saved } from './preview-data.js';\n\nexport default {\n packageName: '@happyvertical/smrt-reports',\n displayName: 'Reports',\n description: 'Saved runtime reports and live results.',\n entries: [\n {\n id: 'saved-reports',\n title: 'Saved reports',\n description: 'Shared reports, author filter, and archive controls.',\n loadComponent: () =>\n import('./SavedReports.svelte').then((m) => m.default),\n props: { client: client() },\n order: 1,\n },\n {\n id: 'report-detail',\n title: 'Report detail',\n description: 'Money values with chart and table views.',\n loadComponent: () =>\n import('./ReportDetail.svelte').then((m) => m.default),\n props: { id: saved.id, client: client(), locale: 'en-US' },\n order: 2,\n },\n {\n id: 'report-confirmation',\n title: 'Report confirmation',\n description: 'Review a bounded proposal before saving.',\n loadComponent: () =>\n import('./ReportConfirmation.svelte').then((m) => m.default),\n props: { proposal, confirm: async () => saved },\n order: 3,\n },\n {\n id: 'report-picker',\n title: 'Report picker',\n description: 'Choose a saved report and its measure.',\n loadComponent: () =>\n import('./ReportPicker.svelte').then((m) => m.default),\n props: {\n client: client(),\n reportId: saved.id,\n measure: 'total',\n dimension: 'region',\n onchange: () => {},\n },\n order: 4,\n },\n {\n id: 'reports-unavailable',\n title: 'Reports unavailable',\n description: 'Static hosts do not make server requests.',\n loadComponent: () =>\n import('./RuntimeReportsRoute.svelte').then((m) => m.default),\n props: { serverAvailable: false },\n order: 5,\n },\n {\n id: 'report-empty',\n title: 'Empty report',\n description: 'A valid report with no matching rows.',\n loadComponent: () =>\n import('./ReportResult.svelte').then((m) => m.default),\n props: { result: { ...result, rows: [], rowCount: 0 } },\n order: 6,\n },\n ],\n};\n"],"mappings":";AAQO,IAAM,OAA0B;CACrC,SAAS;CACT,OAAO;CACP,QAAQ;CACR,YAAY,CAAC;EAAE,OAAO;EAAU,IAAI;CAAS,CAAC;CAC9C,UAAU,CAAC;EAAE,IAAI;EAAO,OAAO;EAAU,IAAI;CAAQ,CAAC;CACtD,SAAS,CAAC;CACV,QAAQ,CAAC;CACT,MAAM,CAAC;CACP,OAAO;CACP,OAAO;EAAE,MAAM;EAAO,GAAG;EAAU,GAAG,CAAC,OAAO;CAAE;AAClD;AACO,IAAM,SAA8B;CACzC,SAAS;CACT,UAAU;CACV,OAAO,KAAK;CACZ,SAAS,CACP;EAAE,IAAI;EAAU,OAAO;EAAU,MAAM;EAAa,MAAM;CAAS,GACnE;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,MAAM;EACN,QAAQ;CACV,CACF;CACA,MAAM,CAAC;EAAE,QAAQ;EAAQ,OAAO;CAAM,CAAC;CACvC,UAAU;CACV,WAAW;CACX,OAAO;CACP,OAAO,KAAK;AACd;AACO,IAAM,QAA4B;CACvC,IAAI;CACJ,OAAO,KAAK;CACZ,UAAU;CACV,iBAAiB;CACjB,QAAQ;CACR;CACA,YAAY;AACd;AACO,IAAM,WAAkC;CAC7C,QAAQ;CACR,UAAU,OAAO;CACjB;CACA,SAAS;CACT,aAAa;CACb,aAAa;AACf;AACO,SAAS,OACd,YAA2C,CAAC,GACtB;CACtB,OAAO;EACL,MAAM,YAAY,CAAC,KAAK;EACxB,KAAK,YAAY;EACjB,KAAK,YAAY;EACjB,SAAS,YAAY,CAAC;EACtB,SAAS,YAAY;EACrB,GAAG;CACL;AACF;;;AClEA,IAAA,qBAAe;CACb,aAAa;CACb,aAAa;CACb,aAAa;CACb,SAAS;EACP;GACE,IAAI;GACJ,OAAO;GACP,aAAa;GACb,qBACE,OAAO,+BAAuB,CAAE,MAAM,MAAM,EAAE,OAAO;GACvD,OAAO,EAAE,QAAQ,OAAO,EAAE;GAC1B,OAAO;EACT;EACA;GACE,IAAI;GACJ,OAAO;GACP,aAAa;GACb,qBACE,OAAO,+BAAuB,CAAE,MAAM,MAAM,EAAE,OAAO;GACvD,OAAO;IAAE,IAAI,MAAM;IAAI,QAAQ,OAAO;IAAG,QAAQ;GAAQ;GACzD,OAAO;EACT;EACA;GACE,IAAI;GACJ,OAAO;GACP,aAAa;GACb,qBACE,OAAO,qCAA6B,CAAE,MAAM,MAAM,EAAE,OAAO;GAC7D,OAAO;IAAE;IAAU,SAAS,YAAY;GAAM;GAC9C,OAAO;EACT;EACA;GACE,IAAI;GACJ,OAAO;GACP,aAAa;GACb,qBACE,OAAO,+BAAuB,CAAE,MAAM,MAAM,EAAE,OAAO;GACvD,OAAO;IACL,QAAQ,OAAO;IACf,UAAU,MAAM;IAChB,SAAS;IACT,WAAW;IACX,gBAAgB,CAAC;GACnB;GACA,OAAO;EACT;EACA;GACE,IAAI;GACJ,OAAO;GACP,aAAa;GACb,qBACE,OAAO,sCAA8B,CAAE,MAAM,MAAM,EAAE,OAAO;GAC9D,OAAO,EAAE,iBAAiB,MAAM;GAChC,OAAO;EACT;EACA;GACE,IAAI;GACJ,OAAO;GACP,aAAa;GACb,qBACE,OAAO,+BAAuB,CAAE,MAAM,MAAM,EAAE,OAAO;GACvD,OAAO,EAAE,QAAQ;IAAE,GAAG;IAAQ,MAAM,CAAC;IAAG,UAAU;GAAE,EAAE;GACtD,OAAO;EACT;CACF;AACF"}
package/dist/recipes.d.ts CHANGED
@@ -13,6 +13,7 @@
13
13
  * @packageDocumentation
14
14
  */
15
15
  import { SmrtRecipe } from '@happyvertical/smrt-core';
16
+ import { RuntimeReport } from './runtime-report.js';
16
17
  import { SmrtPrincipalReportRefreshTask } from './scheduler.js';
17
18
  import { SmrtReportLock, SmrtReportRun, SmrtReportSchedule, SmrtReportWatermark } from './state.js';
18
19
  /** Reports: totals and trends kept ready to read, refreshed on a schedule. */
@@ -25,4 +26,58 @@ export declare class MaterializedReportsRecipe extends SmrtRecipe {
25
26
  static models: (typeof SmrtReportRun | typeof SmrtReportWatermark | typeof SmrtReportLock | typeof SmrtReportSchedule | typeof SmrtPrincipalReportRefreshTask)[];
26
27
  static runtime: "server";
27
28
  }
29
+ /** Tenant-shared reports proposed by the assistant and approved by a person. */
30
+ export declare class RuntimeReportsRecipe extends SmrtRecipe {
31
+ static id: string;
32
+ static label: string;
33
+ static summary: string;
34
+ static help: string;
35
+ static models: (typeof RuntimeReport)[];
36
+ static nav: {
37
+ label: string;
38
+ model: typeof RuntimeReport;
39
+ icon: string;
40
+ }[];
41
+ static surfaces: readonly [{
42
+ readonly kind: "route";
43
+ readonly path: "/reports";
44
+ readonly export: "@happyvertical/smrt-reports/svelte#RuntimeReportsRoute";
45
+ readonly label: "Reports";
46
+ }, {
47
+ readonly kind: "route";
48
+ readonly path: "/reports/:id";
49
+ readonly export: "@happyvertical/smrt-reports/svelte#RuntimeReportDetailRoute";
50
+ readonly label: "Report detail";
51
+ }, {
52
+ readonly kind: "widget";
53
+ readonly type: "runtime-report-chart";
54
+ readonly export: "@happyvertical/smrt-reports/svelte#RuntimeReportChartWidget";
55
+ readonly label: "Report chart";
56
+ readonly description: "Chart a measure from a saved report.";
57
+ readonly icon: "chart";
58
+ readonly optionsEditor: "@happyvertical/smrt-reports/svelte#RuntimeReportWidgetOptions";
59
+ readonly options: readonly [{
60
+ readonly key: "reportId";
61
+ readonly type: "text";
62
+ readonly label: "Report";
63
+ readonly required: true;
64
+ }, {
65
+ readonly key: "measure";
66
+ readonly type: "identifier";
67
+ readonly label: "Measure";
68
+ readonly required: true;
69
+ }, {
70
+ readonly key: "dimension";
71
+ readonly type: "identifier";
72
+ readonly label: "Dimension";
73
+ }];
74
+ readonly data: {
75
+ readonly load: "@happyvertical/smrt-reports#loadRuntimeReportChart";
76
+ readonly models: readonly ["@happyvertical/smrt-reports:RuntimeReport"];
77
+ };
78
+ readonly defaultSpan: 2;
79
+ readonly maxSpan: 4;
80
+ }];
81
+ static runtime: "server";
82
+ }
28
83
  //# sourceMappingURL=recipes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"recipes.d.ts","sourceRoot":"","sources":["../src/recipes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EACL,8BAA8B,EAE/B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,8EAA8E;AAC9E,qBAAa,yBAA0B,SAAQ,UAAU;IACvD,MAAM,CAAC,EAAE,SAA0B;IACnC,MAAM,CAAC,IAAI,SAA8B;IACzC,MAAM,CAAC,KAAK,SAAa;IACzB,MAAM,CAAC,OAAO,SAC+E;IAC7F,MAAM,CAAC,QAAQ,WAQb;IAIF,MAAM,CAAC,MAAM,oJAOX;IAGF,MAAM,CAAC,OAAO,EAAG,QAAQ,CAAU;CACpC"}
1
+ {"version":3,"file":"recipes.d.ts","sourceRoot":"","sources":["../src/recipes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,8BAA8B,EAE/B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,8EAA8E;AAC9E,qBAAa,yBAA0B,SAAQ,UAAU;IACvD,MAAM,CAAC,EAAE,SAA0B;IACnC,MAAM,CAAC,IAAI,SAA8B;IACzC,MAAM,CAAC,KAAK,SAAa;IACzB,MAAM,CAAC,OAAO,SAC+E;IAC7F,MAAM,CAAC,QAAQ,WAQb;IAIF,MAAM,CAAC,MAAM,oJAOX;IAGF,MAAM,CAAC,OAAO,EAAG,QAAQ,CAAU;CACpC;AAED,gFAAgF;AAChF,qBAAa,oBAAqB,SAAQ,UAAU;IAClD,MAAM,CAAC,EAAE,SAAqB;IAC9B,MAAM,CAAC,KAAK,SAAa;IACzB,MAAM,CAAC,OAAO,SAC8D;IAC5E,MAAM,CAAC,IAAI,SAAyB;IACpC,MAAM,CAAC,MAAM,2BAAmB;IAChC,MAAM,CAAC,GAAG;;;;QAAkE;IAC5E,MAAM,CAAC,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCJ;IACX,MAAM,CAAC,OAAO,EAAG,QAAQ,CAAU;CACpC"}
@@ -41,6 +41,15 @@ export declare class RuntimeReport extends SmrtObject {
41
41
  /** Principal that saved the report (an id string; not a foreign key). */
42
42
  createdByUserId: string;
43
43
  constructor(options?: SmrtObjectOptions);
44
+ /** Run fresh totals using the authenticated viewer's current permissions. */
45
+ run(): Promise<RuntimeReportResult>;
46
+ /** Archive or restore this definition; no report content can be changed. */
47
+ archive(options: {
48
+ archived: boolean;
49
+ }): Promise<{
50
+ id: string;
51
+ status: RuntimeReportStatus;
52
+ }>;
44
53
  /** Re-parse the stored JSON; never trust the column without validation. */
45
54
  getSpec(): RuntimeReportSpec;
46
55
  setSpec(spec: RuntimeReportSpec): void;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-report.d.ts","sourceRoot":"","sources":["../src/runtime-report.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime-report.d.ts","sourceRoot":"","sources":["../src/runtime-report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import type { DatabaseInterface } from '@happyvertical/sql';
2
+ import { type RuntimeReportCompileContext, type RuntimeReportResult, type RuntimeReportSourceDefinition } from './runtime-compiler.js';
3
+ import { type RuntimeReportSpec } from './runtime-spec.js';
4
+ /** Browser proposal; carries data, never proof or permission to write. */
5
+ export interface RuntimeReportAwaitingConfirmation {
6
+ status: 'awaiting_confirmation';
7
+ specHash: string;
8
+ spec: RuntimeReportSpec;
9
+ sourceLabel: string;
10
+ preview: RuntimeReportResult;
11
+ confirmPath: string;
12
+ }
13
+ /** Trusted session principal and its request-scoped database/transaction. */
14
+ export interface RuntimeReportPrincipal {
15
+ db: DatabaseInterface;
16
+ userId: string;
17
+ tenantId: string;
18
+ permissions: readonly string[];
19
+ }
20
+ /** A source must declare its permission-catalog slug, never a class name. */
21
+ export interface RuntimeReportServerSource extends RuntimeReportSourceDefinition {
22
+ collection: string;
23
+ }
24
+ /** Host-owned configuration; never read it from a request body. */
25
+ export interface RuntimeReportServerOptions {
26
+ sources: readonly RuntimeReportServerSource[];
27
+ /** Called after a confirmed save (including a successful retry). */
28
+ audit?: (entry: {
29
+ action: 'confirm';
30
+ userId: string;
31
+ tenantId: string;
32
+ specHash: string;
33
+ reportId: string;
34
+ reused: boolean;
35
+ }) => unknown;
36
+ }
37
+ /** Public action failure with a stable HTTP status and code. */
38
+ export declare class RuntimeReportHttpError extends Error {
39
+ readonly status: number;
40
+ readonly code: string;
41
+ constructor(status: number, code: string, message: string);
42
+ }
43
+ /** Require an authenticated tenant principal; do not honor system bypass. */
44
+ export declare function assertRuntimeReportPrincipal(context: RuntimeReportPrincipal | null | undefined, permission: string): asserts context is RuntimeReportPrincipal;
45
+ /** Narrow sources before compilation so hidden source ids cannot be probed. */
46
+ export declare function runtimeReportPrincipalCompileContext(options: RuntimeReportServerOptions, principal: RuntimeReportPrincipal): RuntimeReportCompileContext;
47
+ /**
48
+ * Mount at POST /api/_reports/runtime/confirm. Context must come from the
49
+ * verified server session, never the JSON body. The same request executor is
50
+ * used for lookup and save, preserving an enclosing RLS transaction.
51
+ */
52
+ export declare function createRuntimeReportConfirmHandler(options?: RuntimeReportServerOptions): (request: Request, context: RuntimeReportPrincipal | null | undefined) => Promise<Response>;
53
+ /** Runtime source allow-list configured in packages.reports.runtime.sources. */
54
+ export declare function getRuntimeReportServerOptions(): RuntimeReportServerOptions;
55
+ /** Obtain authority from the authenticated execution scope, never model options. */
56
+ export declare function currentRuntimeReportPrincipal(db: DatabaseInterface): RuntimeReportPrincipal;
57
+ /** Run a saved report as this viewer, without persisting result rows. */
58
+ export declare function runRuntimeReportForPrincipal(ref: string, principal: RuntimeReportPrincipal, options?: RuntimeReportServerOptions): Promise<RuntimeReportResult>;
59
+ /** Change only the saved status under the tenant writer's authority. */
60
+ export declare function archiveRuntimeReportForPrincipal(ref: string, archived: boolean, principal: RuntimeReportPrincipal): Promise<{
61
+ id: string;
62
+ status: 'active' | 'archived';
63
+ }>;
64
+ /** Recipe loader; context.reportPrincipal is supplied by the server host. */
65
+ export declare function loadRuntimeReportChart(options: Record<string, unknown>, context: {
66
+ reportPrincipal?: RuntimeReportPrincipal;
67
+ currency?: string;
68
+ }): Promise<{
69
+ points: {
70
+ label: string;
71
+ value: number;
72
+ }[];
73
+ format: 'integer' | 'decimal' | 'money';
74
+ currency?: string;
75
+ href: string;
76
+ }>;
77
+ //# sourceMappingURL=runtime-server.d.ts.map