@happyvertical/smrt-reports 0.42.6 → 0.42.7
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 +33 -0
- package/README.md +120 -0
- package/dist/index.d.ts +483 -4
- package/dist/index.js +908 -5
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/refresh.js +2 -2
- package/dist/scheduler.js +1 -1
- package/dist/smrt-knowledge.json +7 -5
- package/package.json +6 -5
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,11 @@ import { AggregateTimeBucketUnit } from '@happyvertical/sql';
|
|
|
6
6
|
import { bucketExpr } from '@happyvertical/sql';
|
|
7
7
|
import { buildAggregate } from '@happyvertical/sql';
|
|
8
8
|
import { DatabaseInterface } from '@happyvertical/sql';
|
|
9
|
+
import { DataQueryFieldDescriptor } from '@happyvertical/smrt-types';
|
|
10
|
+
import { DataQueryFilter } from '@happyvertical/smrt-types';
|
|
11
|
+
import { DataQueryRequest } from '@happyvertical/smrt-types';
|
|
12
|
+
import { DataQueryResult } from '@happyvertical/smrt-types';
|
|
13
|
+
import { DataQuerySchema } from '@happyvertical/smrt-types';
|
|
9
14
|
import { EventEmitter } from 'node:events';
|
|
10
15
|
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
11
16
|
import { SmrtJob } from '@happyvertical/smrt-jobs';
|
|
@@ -28,6 +33,22 @@ export { AggregateSelectExpr }
|
|
|
28
33
|
|
|
29
34
|
export { AggregateSpec }
|
|
30
35
|
|
|
36
|
+
export declare interface AppliedReportRefresh {
|
|
37
|
+
phase: 'apply';
|
|
38
|
+
job: ReportRefreshJobHandle;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Queue a manual refresh only after the action host authorizes and audits it. */
|
|
42
|
+
export declare function applyReportRefresh(reportCtor: ReportCtor, options: ApplyReportRefreshOptions): Promise<AppliedReportRefresh>;
|
|
43
|
+
|
|
44
|
+
export declare interface ApplyReportRefreshOptions extends PreviewReportRefreshOptions {
|
|
45
|
+
queue?: string;
|
|
46
|
+
priority?: number;
|
|
47
|
+
timeout?: number;
|
|
48
|
+
maxAttempts?: number;
|
|
49
|
+
tenantJobCap?: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
31
52
|
export declare function assertReportTablesReady(db: DatabaseInterface, tables?: readonly string[]): Promise<void>;
|
|
32
53
|
|
|
33
54
|
export declare const avg: (column?: string, options?: {
|
|
@@ -38,8 +59,18 @@ export { bucketExpr }
|
|
|
38
59
|
|
|
39
60
|
export { buildAggregate }
|
|
40
61
|
|
|
62
|
+
export declare function buildReportAdapterDescriptor(reportCtor: new (...args: any[]) => SmrtObject, options?: ReportAdapterOptions): Promise<ReportAdapterDescriptor>;
|
|
63
|
+
|
|
41
64
|
export declare function buildReportDefinition(reportCtor: new (...args: any[]) => SmrtObject): Promise<ReportDefinition>;
|
|
42
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Bind a materialized report row to its declared source dimensions. This is a
|
|
68
|
+
* query handoff, not an executor: an authenticated source adapter must apply
|
|
69
|
+
* the inherited principal, tenant, definition, and field policy before it
|
|
70
|
+
* reads source records.
|
|
71
|
+
*/
|
|
72
|
+
export declare function buildReportDrilldownQuery(reportCtor: new (...args: any[]) => SmrtObject, row: Readonly<Record<string, unknown>>, options?: ReportAdapterOptions): Promise<ReportDrilldownQuery>;
|
|
73
|
+
|
|
43
74
|
export declare function compileReportDefinition(definition: ReportDefinition): AggregateSpec;
|
|
44
75
|
|
|
45
76
|
export declare function compileReportSpec(reportCtor: new (...args: any[]) => SmrtObject): Promise<AggregateSpec>;
|
|
@@ -59,7 +90,7 @@ export declare const day: (sourceColumn: string) => PropertyDecorator;
|
|
|
59
90
|
export declare function enqueueReportRefresh(options: EnqueueReportRefreshOptions): Promise<SmrtJob>;
|
|
60
91
|
|
|
61
92
|
export declare interface EnqueueReportRefreshOptions extends ReportRefreshJobArgs {
|
|
62
|
-
report?:
|
|
93
|
+
report?: ReportCtor_3;
|
|
63
94
|
reportClass: string;
|
|
64
95
|
db: DatabaseInterface;
|
|
65
96
|
queue?: string;
|
|
@@ -73,7 +104,7 @@ export declare function ensureReportRefreshSchedules(options: EnsureReportSchedu
|
|
|
73
104
|
|
|
74
105
|
export declare interface EnsureReportSchedulesOptions {
|
|
75
106
|
db: DatabaseInterface;
|
|
76
|
-
reports:
|
|
107
|
+
reports: ReportCtor_3[];
|
|
77
108
|
tenantIds?: string[];
|
|
78
109
|
queue?: string;
|
|
79
110
|
priority?: number;
|
|
@@ -82,6 +113,13 @@ export declare interface EnsureReportSchedulesOptions {
|
|
|
82
113
|
|
|
83
114
|
export declare function getReportGroupingColumns(definition: Pick<ReportDefinition, 'fields'>): string[];
|
|
84
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Read only the ambient tenant's report state. The caller cannot supply a
|
|
118
|
+
* tenant selector, which prevents lifecycle lookup from becoming a tenant
|
|
119
|
+
* enumeration surface.
|
|
120
|
+
*/
|
|
121
|
+
export declare function getReportLifecycle(reportCtor: ReportCtor, options: ReportLifecycleOptions): Promise<ReportLifecycleSnapshot>;
|
|
122
|
+
|
|
85
123
|
export declare function getRuntimeReportOptions(ctor: Function): ReportOptions | undefined;
|
|
86
124
|
|
|
87
125
|
export declare function groupBy(sourceColumn?: string): PropertyDecorator;
|
|
@@ -100,9 +138,32 @@ export declare const minute: (sourceColumn: string) => PropertyDecorator;
|
|
|
100
138
|
|
|
101
139
|
export declare const month: (sourceColumn: string) => PropertyDecorator;
|
|
102
140
|
|
|
141
|
+
/** Preview only declares a separately authorized and audited refresh request. */
|
|
142
|
+
export declare function previewReportRefresh(reportCtor: ReportCtor, options: PreviewReportRefreshOptions): Promise<ReportRefreshPreview>;
|
|
143
|
+
|
|
144
|
+
export declare interface PreviewReportRefreshOptions extends ReportLifecycleOptions {
|
|
145
|
+
host: ReportRefreshActionHost;
|
|
146
|
+
mode?: ReportRefreshMode;
|
|
147
|
+
/**
|
|
148
|
+
* Pass `descriptor.refresh.action` when the adapter declares a custom
|
|
149
|
+
* refresh permission, so the displayed and enforced action stay aligned.
|
|
150
|
+
*/
|
|
151
|
+
refreshAction?: Pick<ReportRefreshActionDescriptor, 'requiredPermission'>;
|
|
152
|
+
}
|
|
153
|
+
|
|
103
154
|
export declare const quarter: (sourceColumn: string) => PropertyDecorator;
|
|
104
155
|
|
|
105
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Execute bounded materialized report reads through the canonical query
|
|
158
|
+
* envelope. Every predicate is an adapter-declared field/operator pair; the
|
|
159
|
+
* collection converts it to parameterized SQL and applies tenant interceptors
|
|
160
|
+
* to list, count, and facet reads alike.
|
|
161
|
+
*/
|
|
162
|
+
export declare function queryReportMaterializedRows(reportCtor: new (...args: any[]) => SmrtObject, input: unknown, options: ReportBackgroundQueryOptions): Promise<ReportBackgroundQueryResult>;
|
|
163
|
+
|
|
164
|
+
export declare function queryReportMaterializedRows(reportCtor: new (...args: any[]) => SmrtObject, input: unknown, options?: ReportQueryOptions): Promise<ReportDataQueryResult>;
|
|
165
|
+
|
|
166
|
+
export declare function refreshReport(reportCtor: ReportCtor_2, options?: ReportRefreshOptions): Promise<ReportRefreshResult>;
|
|
106
167
|
|
|
107
168
|
export declare function registerReportRefreshInterceptor(options: ReportRefreshInterceptorOptions): () => boolean;
|
|
108
169
|
|
|
@@ -122,6 +183,36 @@ export declare const REPORT_SCHEDULES_TABLE = "_smrt_report_schedules";
|
|
|
122
183
|
|
|
123
184
|
export declare const REPORT_WATERMARKS_TABLE = "_smrt_report_watermarks";
|
|
124
185
|
|
|
186
|
+
/**
|
|
187
|
+
* The report-owned, transport-neutral descriptor. Consumers can map `schema`
|
|
188
|
+
* to the canonical data-query runtime and `columns` to their presentation
|
|
189
|
+
* contract without importing smrt-ui or a report domain class.
|
|
190
|
+
*/
|
|
191
|
+
export declare interface ReportAdapterDescriptor {
|
|
192
|
+
version: 1;
|
|
193
|
+
resourceId: string;
|
|
194
|
+
reportClassName: string;
|
|
195
|
+
sourceClassName: string;
|
|
196
|
+
tenantScoped: boolean;
|
|
197
|
+
tenantField?: string;
|
|
198
|
+
identityField: 'id';
|
|
199
|
+
columns: ReportColumnDescriptor[];
|
|
200
|
+
schema: DataQuerySchema;
|
|
201
|
+
queryExecution: ReportQueryExecutionDescriptor;
|
|
202
|
+
dataTable: ReportDataTableDescriptor;
|
|
203
|
+
drilldown: ReportDrilldownDescriptor;
|
|
204
|
+
refresh: ReportRefreshDescriptor;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export declare interface ReportAdapterOptions {
|
|
208
|
+
/** Scope used only to make a stable resource id; it is not authority. */
|
|
209
|
+
tenantScope?: 'current' | 'global' | 'tenant';
|
|
210
|
+
/** Permission that a lifecycle action host must require before refresh. */
|
|
211
|
+
refreshPermission?: string;
|
|
212
|
+
/** Consumer-owned presentational preferences; they never affect query rows. */
|
|
213
|
+
dataTable?: ReportDataTablePresentationOptions;
|
|
214
|
+
}
|
|
215
|
+
|
|
125
216
|
export declare interface ReportAggregateFieldMetadata {
|
|
126
217
|
kind: 'aggregate';
|
|
127
218
|
fn: ReportAggregateFn;
|
|
@@ -131,16 +222,170 @@ export declare interface ReportAggregateFieldMetadata {
|
|
|
131
222
|
|
|
132
223
|
export declare type ReportAggregateFn = AggregateFunction;
|
|
133
224
|
|
|
225
|
+
/** Background execution is possible only through an application-owned queue host. */
|
|
226
|
+
export declare interface ReportBackgroundQueryOptions extends ReportQueryCommonOptions {
|
|
227
|
+
execution: 'background';
|
|
228
|
+
enqueueBackgroundQuery(task: ReportBackgroundQueryTask): Promise<{
|
|
229
|
+
taskId: string;
|
|
230
|
+
}>;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/** Queuing a background query returns a handle, never rows from another scope. */
|
|
234
|
+
export declare interface ReportBackgroundQueryResult {
|
|
235
|
+
version: 1;
|
|
236
|
+
execution: 'background';
|
|
237
|
+
status: 'queued';
|
|
238
|
+
taskId: string;
|
|
239
|
+
queryFingerprint: string;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* The exact bounded request a background host may persist. Tenant, principal,
|
|
244
|
+
* collection, database, and display state deliberately remain with that host.
|
|
245
|
+
*/
|
|
246
|
+
export declare interface ReportBackgroundQueryTask {
|
|
247
|
+
version: 1;
|
|
248
|
+
execution: 'background';
|
|
249
|
+
resourceId: string;
|
|
250
|
+
reportClassName: string;
|
|
251
|
+
request: DataQueryRequest;
|
|
252
|
+
inherits: Array<'principal' | 'tenant' | 'report-definition' | 'field-policy'>;
|
|
253
|
+
}
|
|
254
|
+
|
|
134
255
|
export declare interface ReportBucketFieldMetadata {
|
|
135
256
|
kind: 'bucket';
|
|
136
257
|
unit: ReportTimeBucketUnit;
|
|
137
258
|
sourceColumn: string;
|
|
138
259
|
}
|
|
139
260
|
|
|
261
|
+
export declare type ReportColumnCapability = 'read' | 'project' | 'filter' | 'sort' | 'facet' | 'group' | 'aggregate';
|
|
262
|
+
|
|
263
|
+
export declare interface ReportColumnDescriptor extends DataQueryFieldDescriptor {
|
|
264
|
+
/** Stable output column id (never a property path). */
|
|
265
|
+
id: string;
|
|
266
|
+
fieldName: string;
|
|
267
|
+
label: string;
|
|
268
|
+
kind: ReportColumnKind;
|
|
269
|
+
filterScope: ReportFilterScope;
|
|
270
|
+
/** Capabilities available from this adapter revision. */
|
|
271
|
+
capabilities: ReportColumnCapability[];
|
|
272
|
+
format?: string;
|
|
273
|
+
sensitivity?: ReportColumnSensitivity;
|
|
274
|
+
sourceColumn?: string;
|
|
275
|
+
bucket?: ReportTimeBucketUnit;
|
|
276
|
+
aggregate?: ReportAggregateFn;
|
|
277
|
+
distinct?: boolean;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export declare type ReportColumnKind = 'identity' | 'group' | 'bucket' | 'aggregate';
|
|
281
|
+
|
|
282
|
+
/** Presentation and policy metadata understood by the report adapter. */
|
|
283
|
+
export declare type ReportColumnSensitivity = 'public' | 'personal' | 'sensitive' | 'secret';
|
|
284
|
+
|
|
140
285
|
declare type ReportCtor = new (...args: any[]) => SmrtObject;
|
|
141
286
|
|
|
142
287
|
declare type ReportCtor_2 = new (...args: any[]) => SmrtObject;
|
|
143
288
|
|
|
289
|
+
declare type ReportCtor_3 = new (...args: any[]) => SmrtObject;
|
|
290
|
+
|
|
291
|
+
export declare interface ReportDataQueryResult extends DataQueryResult {
|
|
292
|
+
/** Delivery intent only; the adapter never mutates a visible surface. */
|
|
293
|
+
execution: 'visible' | 'silent';
|
|
294
|
+
reportLifecycle?: ReportMaterializedReadLifecycle;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export declare interface ReportDataTableColumn {
|
|
298
|
+
id: string;
|
|
299
|
+
label: string;
|
|
300
|
+
accessor: string;
|
|
301
|
+
sortable: boolean;
|
|
302
|
+
searchable: false;
|
|
303
|
+
filterable: boolean;
|
|
304
|
+
/** Group ancestry for consumers with multi-level table headers. */
|
|
305
|
+
headerPath: ReportDataTableHeaderPathSegment[];
|
|
306
|
+
/** Consumer-side display instruction; materialized rows remain raw. */
|
|
307
|
+
valueFormat: ReportDataTableValueFormat;
|
|
308
|
+
/** The default alignment for the formatted display value. */
|
|
309
|
+
align: 'left' | 'right';
|
|
310
|
+
/** Generic semantic role for status/action columns introduced by later slices. */
|
|
311
|
+
role: ReportDataTableColumnRole;
|
|
312
|
+
responsive: ReportDataTableColumnResponsive;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/** Per-column presentation overrides owned by the consuming report surface. */
|
|
316
|
+
export declare interface ReportDataTableColumnOverride {
|
|
317
|
+
label?: string;
|
|
318
|
+
headerPath?: readonly ReportDataTableHeaderPathSegment[];
|
|
319
|
+
valueFormat?: ReportDataTableValueFormat;
|
|
320
|
+
align?: 'left' | 'right';
|
|
321
|
+
role?: ReportDataTableColumnRole;
|
|
322
|
+
responsive?: ReportDataTableColumnResponsive;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/** Responsive metadata that maps directly to a consumer's table contract. */
|
|
326
|
+
export declare interface ReportDataTableColumnResponsive {
|
|
327
|
+
/** Higher values make a column more important during responsive collapse. */
|
|
328
|
+
priority?: number;
|
|
329
|
+
/** Keep key dimensions reachable during responsive collapse. */
|
|
330
|
+
keepVisible?: boolean;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export declare type ReportDataTableColumnRole = 'data' | 'status' | 'action';
|
|
334
|
+
|
|
335
|
+
export declare interface ReportDataTableDescriptor {
|
|
336
|
+
rowKey: 'id';
|
|
337
|
+
manualPagination: true;
|
|
338
|
+
manualSorting: true;
|
|
339
|
+
enableFiltering: true;
|
|
340
|
+
enableSearch: false;
|
|
341
|
+
columns: ReportDataTableColumn[];
|
|
342
|
+
structuralRows: ReportDataTableStructuralRow[];
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/** Structural DataTable view hints; deliberately not a smrt-ui dependency. */
|
|
346
|
+
export declare interface ReportDataTableHeaderPathSegment {
|
|
347
|
+
/** Stable group identity within a header level. */
|
|
348
|
+
id: string;
|
|
349
|
+
/** Human-readable grouped-header label. */
|
|
350
|
+
label: string;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export declare interface ReportDataTablePresentationOptions {
|
|
354
|
+
/** Overrides are keyed by stable adapter column id, not display labels. */
|
|
355
|
+
columns?: Readonly<Record<string, ReportDataTableColumnOverride>>;
|
|
356
|
+
/** Summary/subtotal rows remain structural rather than materialized data rows. */
|
|
357
|
+
structuralRows?: readonly ReportDataTableStructuralRowInput[];
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Structural rows are intentionally separate from materialized data rows.
|
|
362
|
+
* Consumers pass them to their DataTable's structural-row slot/prop, never its
|
|
363
|
+
* selectable data collection.
|
|
364
|
+
*/
|
|
365
|
+
export declare interface ReportDataTableStructuralRow extends ReportDataTableStructuralRowInput {
|
|
366
|
+
selection: 'excluded';
|
|
367
|
+
actions: 'excluded';
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/** Input supplied by a report consumer that computes a summary or subtotal. */
|
|
371
|
+
export declare interface ReportDataTableStructuralRowInput {
|
|
372
|
+
id: string;
|
|
373
|
+
kind: ReportDataTableStructuralRowKind;
|
|
374
|
+
label: string;
|
|
375
|
+
/** Raw values keyed by the adapter's stable column id. */
|
|
376
|
+
values?: Readonly<Record<string, unknown>>;
|
|
377
|
+
/** Column that renders this row's accessible row header. */
|
|
378
|
+
labelColumnId?: string;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
export declare type ReportDataTableStructuralRowKind = 'summary' | 'subtotal' | 'aggregate' | 'footer';
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* A rendering instruction for a raw materialized value. Formatting is never
|
|
385
|
+
* applied to a query row, so sorting, export, and agent consumers retain it.
|
|
386
|
+
*/
|
|
387
|
+
export declare type ReportDataTableValueFormat = 'text' | 'date' | 'datetime' | 'percentage' | 'count' | 'money' | 'number';
|
|
388
|
+
|
|
144
389
|
export declare interface ReportDefinition {
|
|
145
390
|
reportClassName: string;
|
|
146
391
|
sourceClassName: string;
|
|
@@ -151,6 +396,46 @@ export declare interface ReportDefinition {
|
|
|
151
396
|
refresh?: ReportRefreshConfig;
|
|
152
397
|
}
|
|
153
398
|
|
|
399
|
+
export declare interface ReportDrilldownConstraint {
|
|
400
|
+
id: string;
|
|
401
|
+
sourceColumn: string;
|
|
402
|
+
kind: 'group' | 'bucket';
|
|
403
|
+
value: unknown;
|
|
404
|
+
bucket?: ReportTimeBucketUnit;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Declarative source-query handoff for a report row. No client can supply a
|
|
409
|
+
* principal, tenant, report definition, or arbitrary source field here.
|
|
410
|
+
*/
|
|
411
|
+
export declare interface ReportDrilldownDescriptor {
|
|
412
|
+
id: 'drilldown';
|
|
413
|
+
sourceClassName: string;
|
|
414
|
+
fields: ReportDrilldownFieldDescriptor[];
|
|
415
|
+
inherits: Array<'principal' | 'tenant' | 'report-definition' | 'field-policy'>;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/** One row value that can safely constrain a source-record drilldown. */
|
|
419
|
+
export declare interface ReportDrilldownFieldDescriptor {
|
|
420
|
+
/** Stable report column id; never a display label. */
|
|
421
|
+
id: string;
|
|
422
|
+
/** Declared source field/column chosen by report metadata, not caller input. */
|
|
423
|
+
sourceColumn: string;
|
|
424
|
+
kind: 'group' | 'bucket';
|
|
425
|
+
/** A bucket stays declarative so the source adapter preserves report timezone semantics. */
|
|
426
|
+
bucket?: ReportTimeBucketUnit;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/** A server adapter uses this authority-free handoff to execute a source drilldown. */
|
|
430
|
+
export declare interface ReportDrilldownQuery {
|
|
431
|
+
version: 1;
|
|
432
|
+
resourceId: string;
|
|
433
|
+
reportClassName: string;
|
|
434
|
+
sourceClassName: string;
|
|
435
|
+
constraints: ReportDrilldownConstraint[];
|
|
436
|
+
inherits: Array<'principal' | 'tenant' | 'report-definition' | 'field-policy'>;
|
|
437
|
+
}
|
|
438
|
+
|
|
154
439
|
export declare interface ReportFieldDefinition {
|
|
155
440
|
fieldName: string;
|
|
156
441
|
columnName?: string;
|
|
@@ -160,11 +445,74 @@ export declare interface ReportFieldDefinition {
|
|
|
160
445
|
|
|
161
446
|
export declare type ReportFieldMetadata = ReportGroupFieldMetadata | ReportBucketFieldMetadata | ReportAggregateFieldMetadata;
|
|
162
447
|
|
|
448
|
+
/**
|
|
449
|
+
* Source-query clause a field belongs to. The materialized read executor
|
|
450
|
+
* applies both kinds through its tenant-scoped collection, but consumers use
|
|
451
|
+
* this declaration to keep dimensions/periods (WHERE) distinct from measures
|
|
452
|
+
* (HAVING) when constructing drilldowns, saved views, or a live query.
|
|
453
|
+
*/
|
|
454
|
+
export declare type ReportFilterScope = 'where' | 'having';
|
|
455
|
+
|
|
163
456
|
export declare interface ReportGroupFieldMetadata {
|
|
164
457
|
kind: 'group';
|
|
165
458
|
sourceColumn?: string;
|
|
166
459
|
}
|
|
167
460
|
|
|
461
|
+
export declare interface ReportLifecycleOptions {
|
|
462
|
+
db: DatabaseInterface;
|
|
463
|
+
/** Test seam; production callers use the current clock. */
|
|
464
|
+
now?: Date;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
export declare interface ReportLifecycleRun {
|
|
468
|
+
id: string;
|
|
469
|
+
status: 'running' | 'success' | 'failed' | 'skipped';
|
|
470
|
+
mode: ReportRefreshMode;
|
|
471
|
+
trigger: ReportRefreshTrigger;
|
|
472
|
+
startedAt?: string;
|
|
473
|
+
completedAt?: string;
|
|
474
|
+
rowCount: number;
|
|
475
|
+
changedGroupCount: number;
|
|
476
|
+
/** A failed run is safe to retry through the separately permissioned action. */
|
|
477
|
+
mayRetry: boolean;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Transport-neutral report lifecycle state. It deliberately never includes a
|
|
482
|
+
* lock owner, a raw failure message, or tenant fanout identifiers.
|
|
483
|
+
*/
|
|
484
|
+
export declare interface ReportLifecycleSnapshot {
|
|
485
|
+
version: 1;
|
|
486
|
+
state: ReportLifecycleState;
|
|
487
|
+
asOf?: string;
|
|
488
|
+
refreshedAt?: string;
|
|
489
|
+
/** Whether existing materialized rows can remain visible while work changes state. */
|
|
490
|
+
hasUsableRows: boolean;
|
|
491
|
+
mode: ReportRefreshMode;
|
|
492
|
+
run?: ReportLifecycleRun;
|
|
493
|
+
/** A stable, redacted failure signal; raw executor errors stay server-side. */
|
|
494
|
+
failure?: {
|
|
495
|
+
code: 'refresh_failed';
|
|
496
|
+
retryable: true;
|
|
497
|
+
};
|
|
498
|
+
lock: {
|
|
499
|
+
held: boolean;
|
|
500
|
+
expiresAt?: string;
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
export declare type ReportLifecycleState = 'current' | 'stale' | 'refreshing' | 'lock-skipped' | 'failed';
|
|
505
|
+
|
|
506
|
+
/** Lifecycle context attached only when a caller explicitly opts in. */
|
|
507
|
+
export declare interface ReportMaterializedReadLifecycle {
|
|
508
|
+
snapshot: ReportLifecycleSnapshot;
|
|
509
|
+
/** Whether this collection read appears to have completed a TTL refresh. */
|
|
510
|
+
read: 'current' | 'stale' | 'refresh-triggered';
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/** Read the already-materialized primary key; never use a display/page index. */
|
|
514
|
+
export declare function reportMaterializedRowKey(row: Record<string, unknown>): string;
|
|
515
|
+
|
|
168
516
|
export declare interface ReportOptions {
|
|
169
517
|
source: ReportSource;
|
|
170
518
|
where?: WhereClause;
|
|
@@ -172,6 +520,82 @@ export declare interface ReportOptions {
|
|
|
172
520
|
refresh?: ReportRefreshConfig;
|
|
173
521
|
}
|
|
174
522
|
|
|
523
|
+
declare interface ReportQueryCommonOptions {
|
|
524
|
+
/** Injected collection seam for tests and application-owned adapters. */
|
|
525
|
+
collection?: {
|
|
526
|
+
list(options: Record<string, unknown>): Promise<Array<Record<string, unknown>>>;
|
|
527
|
+
count(options?: Record<string, unknown>): Promise<number>;
|
|
528
|
+
facets?(options: Record<string, unknown>): Promise<Array<{
|
|
529
|
+
field: string;
|
|
530
|
+
values: Array<{
|
|
531
|
+
value: string | number | boolean | null;
|
|
532
|
+
count: number;
|
|
533
|
+
}>;
|
|
534
|
+
}>>;
|
|
535
|
+
};
|
|
536
|
+
db?: DatabaseInterface;
|
|
537
|
+
/**
|
|
538
|
+
* Opt in to a tenant-safe lifecycle snapshot alongside this materialized
|
|
539
|
+
* read. It never makes a generic read mutate.
|
|
540
|
+
*/
|
|
541
|
+
lifecycle?: Omit<ReportLifecycleOptions, 'db'>;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
export declare interface ReportQueryExecutionDescriptor {
|
|
545
|
+
modes: ReportQueryExecutionMode[];
|
|
546
|
+
/** The caller may apply the returned rows to an already-authorized surface. */
|
|
547
|
+
visible: {
|
|
548
|
+
delivery: 'result';
|
|
549
|
+
};
|
|
550
|
+
/** A host queues the authority-free task and returns no materialized rows yet. */
|
|
551
|
+
background: {
|
|
552
|
+
delivery: 'queued';
|
|
553
|
+
requiresHost: true;
|
|
554
|
+
};
|
|
555
|
+
/** The caller receives rows but the adapter makes no visible-surface change. */
|
|
556
|
+
silent: {
|
|
557
|
+
delivery: 'result';
|
|
558
|
+
mutatesVisibleSurface: false;
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Delivery choices for the same bounded report query. They never add
|
|
564
|
+
* authority: a host owns visible state and background-job execution.
|
|
565
|
+
*/
|
|
566
|
+
export declare type ReportQueryExecutionMode = 'visible' | 'background' | 'silent';
|
|
567
|
+
|
|
568
|
+
/** Visible is the default; silent has identical data authority but no UI intent. */
|
|
569
|
+
export declare interface ReportQueryOptions extends ReportQueryCommonOptions {
|
|
570
|
+
execution?: 'visible' | 'silent';
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
export declare interface ReportRefreshActionContext {
|
|
574
|
+
phase: 'preview' | 'apply';
|
|
575
|
+
reportClassName: string;
|
|
576
|
+
/** The action always applies to the caller's already-bound tenant scope. */
|
|
577
|
+
tenantScope: 'ambient';
|
|
578
|
+
mode: ReportRefreshMode;
|
|
579
|
+
requiredPermission: string;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/** A report-wide lifecycle action, never a mutation performed by this adapter. */
|
|
583
|
+
export declare interface ReportRefreshActionDescriptor {
|
|
584
|
+
id: 'refresh';
|
|
585
|
+
label: 'Refresh report';
|
|
586
|
+
scope: 'surface';
|
|
587
|
+
phases: Array<'preview' | 'apply'>;
|
|
588
|
+
requiresPermission: true;
|
|
589
|
+
requiredPermission: string;
|
|
590
|
+
auditRequired: true;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/** Authority and audit stay with the application action host, not reports. */
|
|
594
|
+
export declare interface ReportRefreshActionHost {
|
|
595
|
+
authorize(context: ReportRefreshActionContext): Promise<void> | void;
|
|
596
|
+
audit(context: ReportRefreshActionContext): Promise<void> | void;
|
|
597
|
+
}
|
|
598
|
+
|
|
175
599
|
export declare interface ReportRefreshConfig {
|
|
176
600
|
mode?: ReportRefreshMode;
|
|
177
601
|
schedule?: string;
|
|
@@ -190,9 +614,23 @@ export declare interface ReportRefreshConfig {
|
|
|
190
614
|
tenantFanout?: boolean;
|
|
191
615
|
}
|
|
192
616
|
|
|
617
|
+
export declare interface ReportRefreshDescriptor {
|
|
618
|
+
mode: 'rebuild' | 'incremental';
|
|
619
|
+
/**
|
|
620
|
+
* Whether the report configuration lets a registered SmrtReportCollection
|
|
621
|
+
* synchronously refresh a stale read. Generic collection reads stay
|
|
622
|
+
* read-only and report unknown freshness until the lifecycle adapter runs.
|
|
623
|
+
*/
|
|
624
|
+
mayRefreshOnRead: boolean;
|
|
625
|
+
ttlMs?: number;
|
|
626
|
+
triggers: Array<'manual' | 'schedule' | 'change' | 'ttl' | 'job'>;
|
|
627
|
+
/** Declared only; the lifecycle adapter owns authorization, audit, and run state. */
|
|
628
|
+
action: ReportRefreshActionDescriptor;
|
|
629
|
+
}
|
|
630
|
+
|
|
193
631
|
export declare interface ReportRefreshInterceptorOptions {
|
|
194
632
|
db: DatabaseInterface;
|
|
195
|
-
reports:
|
|
633
|
+
reports: ReportCtor_3[];
|
|
196
634
|
enqueue?: boolean;
|
|
197
635
|
queue?: string;
|
|
198
636
|
priority?: number;
|
|
@@ -213,6 +651,15 @@ export declare interface ReportRefreshJobArgs {
|
|
|
213
651
|
_scheduleId?: string;
|
|
214
652
|
}
|
|
215
653
|
|
|
654
|
+
export declare interface ReportRefreshJobHandle {
|
|
655
|
+
jobId: string;
|
|
656
|
+
status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
657
|
+
attempts: number;
|
|
658
|
+
maxAttempts: number;
|
|
659
|
+
/** Bounded polling guidance; this API does not create a second queue. */
|
|
660
|
+
pollAfterMs: number;
|
|
661
|
+
}
|
|
662
|
+
|
|
216
663
|
export declare type ReportRefreshMode = 'rebuild' | 'incremental';
|
|
217
664
|
|
|
218
665
|
export declare interface ReportRefreshOptions {
|
|
@@ -229,6 +676,27 @@ export declare interface ReportRefreshOptions {
|
|
|
229
676
|
changedRows?: Record<string, unknown>[];
|
|
230
677
|
}
|
|
231
678
|
|
|
679
|
+
export declare interface ReportRefreshOutcome {
|
|
680
|
+
state: 'current' | 'lock-skipped' | 'partial';
|
|
681
|
+
rowCount: number;
|
|
682
|
+
changedGroupCount: number;
|
|
683
|
+
completedScopes: number;
|
|
684
|
+
lockSkippedScopes: number;
|
|
685
|
+
mode: ReportRefreshMode;
|
|
686
|
+
refreshedAt: string;
|
|
687
|
+
runId?: string;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/** Normalize executor results without exposing the tenant identifiers in a fanout. */
|
|
691
|
+
export declare function reportRefreshOutcome(result: ReportRefreshResult): ReportRefreshOutcome;
|
|
692
|
+
|
|
693
|
+
export declare interface ReportRefreshPreview {
|
|
694
|
+
phase: 'preview';
|
|
695
|
+
lifecycle: ReportLifecycleSnapshot;
|
|
696
|
+
action: ReportRefreshActionContext;
|
|
697
|
+
execution: 'background';
|
|
698
|
+
}
|
|
699
|
+
|
|
232
700
|
export declare interface ReportRefreshResult {
|
|
233
701
|
rowCount: number;
|
|
234
702
|
refreshedAt: Date;
|
|
@@ -396,6 +864,17 @@ export declare class SmrtReportWatermarkCollection extends SmrtCollection<SmrtRe
|
|
|
396
864
|
static readonly _itemClass: typeof SmrtReportWatermark;
|
|
397
865
|
}
|
|
398
866
|
|
|
867
|
+
/**
|
|
868
|
+
* Split the declared filter language by report semantics for consumers that
|
|
869
|
+
* construct a live source query. Mixed AND expressions are represented as two
|
|
870
|
+
* independent clauses; mixed OR/NOT expressions are rejected because moving
|
|
871
|
+
* either half across WHERE/HAVING would change their meaning.
|
|
872
|
+
*/
|
|
873
|
+
export declare function splitReportFilterScopes(descriptor: ReportAdapterDescriptor, filter: DataQueryFilter | undefined): {
|
|
874
|
+
where?: DataQueryFilter;
|
|
875
|
+
having?: DataQueryFilter;
|
|
876
|
+
};
|
|
877
|
+
|
|
399
878
|
export declare const sum: (column?: string, options?: {
|
|
400
879
|
distinct?: boolean;
|
|
401
880
|
}) => PropertyDecorator;
|