@voyant-travel/reporting 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,15 +14,28 @@
14
14
  "QuerySourceInput": {
15
15
  "type": "object",
16
16
  "required": ["source"],
17
- "properties": { "source": { "type": "string", "minLength": 1, "maxLength": 10000 } },
17
+ "properties": {
18
+ "source": {
19
+ "type": "string",
20
+ "minLength": 1,
21
+ "maxLength": 10000
22
+ }
23
+ },
18
24
  "additionalProperties": false
19
25
  },
20
26
  "QueryPreviewInput": {
21
27
  "type": "object",
22
28
  "required": ["query"],
23
29
  "properties": {
24
- "query": { "type": "object", "additionalProperties": true },
25
- "parameters": { "type": "object", "additionalProperties": true, "default": {} }
30
+ "query": {
31
+ "type": "object",
32
+ "additionalProperties": true
33
+ },
34
+ "parameters": {
35
+ "type": "object",
36
+ "additionalProperties": true,
37
+ "default": {}
38
+ }
26
39
  },
27
40
  "additionalProperties": false
28
41
  },
@@ -30,11 +43,26 @@
30
43
  "type": "object",
31
44
  "required": ["name"],
32
45
  "properties": {
33
- "name": { "type": "string", "minLength": 1, "maxLength": 160 },
34
- "description": { "type": ["string", "null"], "maxLength": 2000 },
35
- "sourceTemplateId": { "type": ["string", "null"] },
36
- "sourceTemplateVersion": { "type": ["integer", "null"], "minimum": 1 },
37
- "draft": { "type": "object", "additionalProperties": true }
46
+ "name": {
47
+ "type": "string",
48
+ "minLength": 1,
49
+ "maxLength": 160
50
+ },
51
+ "description": {
52
+ "type": ["string", "null"],
53
+ "maxLength": 2000
54
+ },
55
+ "sourceTemplateId": {
56
+ "type": ["string", "null"]
57
+ },
58
+ "sourceTemplateVersion": {
59
+ "type": ["integer", "null"],
60
+ "minimum": 1
61
+ },
62
+ "draft": {
63
+ "type": "object",
64
+ "additionalProperties": true
65
+ }
38
66
  },
39
67
  "additionalProperties": false
40
68
  },
@@ -42,10 +70,23 @@
42
70
  "type": "object",
43
71
  "required": ["revision"],
44
72
  "properties": {
45
- "revision": { "type": "integer", "minimum": 1 },
46
- "name": { "type": "string", "minLength": 1, "maxLength": 160 },
47
- "description": { "type": ["string", "null"], "maxLength": 2000 },
48
- "draft": { "type": "object", "additionalProperties": true }
73
+ "revision": {
74
+ "type": "integer",
75
+ "minimum": 1
76
+ },
77
+ "name": {
78
+ "type": "string",
79
+ "minLength": 1,
80
+ "maxLength": 160
81
+ },
82
+ "description": {
83
+ "type": ["string", "null"],
84
+ "maxLength": 2000
85
+ },
86
+ "draft": {
87
+ "type": "object",
88
+ "additionalProperties": true
89
+ }
49
90
  },
50
91
  "additionalProperties": false
51
92
  },
@@ -53,22 +94,19 @@
53
94
  "type": "object",
54
95
  "required": ["name"],
55
96
  "properties": {
56
- "name": { "type": "string", "minLength": 1, "maxLength": 160 },
57
- "description": { "type": ["string", "null"], "maxLength": 2000 },
58
- "version": { "type": "integer", "minimum": 1 }
59
- },
60
- "additionalProperties": false
61
- },
62
- "PublishReportInput": {
63
- "type": "object",
64
- "required": ["expectedRevision"],
65
- "properties": { "expectedRevision": { "type": "integer", "minimum": 1 } },
66
- "additionalProperties": false
67
- },
68
- "RunReportInput": {
69
- "type": "object",
70
- "properties": {
71
- "parameters": { "type": "object", "additionalProperties": true, "default": {} }
97
+ "name": {
98
+ "type": "string",
99
+ "minLength": 1,
100
+ "maxLength": 160
101
+ },
102
+ "description": {
103
+ "type": ["string", "null"],
104
+ "maxLength": 2000
105
+ },
106
+ "version": {
107
+ "type": "integer",
108
+ "minimum": 1
109
+ }
72
110
  },
73
111
  "additionalProperties": false
74
112
  },
@@ -76,9 +114,18 @@
76
114
  "type": "object",
77
115
  "required": ["error"],
78
116
  "properties": {
79
- "error": { "type": "string" },
80
- "message": { "type": "string" },
81
- "missingScopes": { "type": "array", "items": { "type": "string" } }
117
+ "error": {
118
+ "type": "string"
119
+ },
120
+ "message": {
121
+ "type": "string"
122
+ },
123
+ "missingScopes": {
124
+ "type": "array",
125
+ "items": {
126
+ "type": "string"
127
+ }
128
+ }
82
129
  },
83
130
  "additionalProperties": true
84
131
  }
@@ -88,14 +135,20 @@
88
135
  "description": "Reporting API response",
89
136
  "content": {
90
137
  "application/json": {
91
- "schema": { "$ref": "#/components/schemas/ReportingResponse" }
138
+ "schema": {
139
+ "$ref": "#/components/schemas/ReportingResponse"
140
+ }
92
141
  }
93
142
  }
94
143
  },
95
144
  "ErrorResponse": {
96
145
  "description": "Reporting API error",
97
146
  "content": {
98
- "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
147
+ "application/json": {
148
+ "schema": {
149
+ "$ref": "#/components/schemas/Error"
150
+ }
151
+ }
99
152
  }
100
153
  }
101
154
  }
@@ -108,8 +161,12 @@
108
161
  "description": "Requires reports:read.",
109
162
  "tags": ["Reporting"],
110
163
  "responses": {
111
- "200": { "$ref": "#/components/responses/ReportingResponse" },
112
- "403": { "$ref": "#/components/responses/ErrorResponse" }
164
+ "200": {
165
+ "$ref": "#/components/responses/ReportingResponse"
166
+ },
167
+ "403": {
168
+ "$ref": "#/components/responses/ErrorResponse"
169
+ }
113
170
  }
114
171
  }
115
172
  },
@@ -122,13 +179,23 @@
122
179
  "requestBody": {
123
180
  "required": true,
124
181
  "content": {
125
- "application/json": { "schema": { "$ref": "#/components/schemas/QuerySourceInput" } }
182
+ "application/json": {
183
+ "schema": {
184
+ "$ref": "#/components/schemas/QuerySourceInput"
185
+ }
186
+ }
126
187
  }
127
188
  },
128
189
  "responses": {
129
- "200": { "$ref": "#/components/responses/ReportingResponse" },
130
- "400": { "$ref": "#/components/responses/ErrorResponse" },
131
- "403": { "$ref": "#/components/responses/ErrorResponse" }
190
+ "200": {
191
+ "$ref": "#/components/responses/ReportingResponse"
192
+ },
193
+ "400": {
194
+ "$ref": "#/components/responses/ErrorResponse"
195
+ },
196
+ "403": {
197
+ "$ref": "#/components/responses/ErrorResponse"
198
+ }
132
199
  }
133
200
  }
134
201
  },
@@ -141,13 +208,23 @@
141
208
  "requestBody": {
142
209
  "required": true,
143
210
  "content": {
144
- "application/json": { "schema": { "$ref": "#/components/schemas/QueryPreviewInput" } }
211
+ "application/json": {
212
+ "schema": {
213
+ "$ref": "#/components/schemas/QueryPreviewInput"
214
+ }
215
+ }
145
216
  }
146
217
  },
147
218
  "responses": {
148
- "200": { "$ref": "#/components/responses/ReportingResponse" },
149
- "400": { "$ref": "#/components/responses/ErrorResponse" },
150
- "403": { "$ref": "#/components/responses/ErrorResponse" }
219
+ "200": {
220
+ "$ref": "#/components/responses/ReportingResponse"
221
+ },
222
+ "400": {
223
+ "$ref": "#/components/responses/ErrorResponse"
224
+ },
225
+ "403": {
226
+ "$ref": "#/components/responses/ErrorResponse"
227
+ }
151
228
  }
152
229
  }
153
230
  },
@@ -161,18 +238,33 @@
161
238
  {
162
239
  "name": "limit",
163
240
  "in": "query",
164
- "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 }
241
+ "schema": {
242
+ "type": "integer",
243
+ "minimum": 1,
244
+ "maximum": 100,
245
+ "default": 25
246
+ }
165
247
  },
166
248
  {
167
249
  "name": "offset",
168
250
  "in": "query",
169
- "schema": { "type": "integer", "minimum": 0, "default": 0 }
251
+ "schema": {
252
+ "type": "integer",
253
+ "minimum": 0,
254
+ "default": 0
255
+ }
170
256
  }
171
257
  ],
172
258
  "responses": {
173
- "200": { "$ref": "#/components/responses/ReportingResponse" },
174
- "400": { "$ref": "#/components/responses/ErrorResponse" },
175
- "403": { "$ref": "#/components/responses/ErrorResponse" }
259
+ "200": {
260
+ "$ref": "#/components/responses/ReportingResponse"
261
+ },
262
+ "400": {
263
+ "$ref": "#/components/responses/ErrorResponse"
264
+ },
265
+ "403": {
266
+ "$ref": "#/components/responses/ErrorResponse"
267
+ }
176
268
  }
177
269
  },
178
270
  "post": {
@@ -183,19 +275,36 @@
183
275
  "requestBody": {
184
276
  "required": true,
185
277
  "content": {
186
- "application/json": { "schema": { "$ref": "#/components/schemas/CreateReportInput" } }
278
+ "application/json": {
279
+ "schema": {
280
+ "$ref": "#/components/schemas/CreateReportInput"
281
+ }
282
+ }
187
283
  }
188
284
  },
189
285
  "responses": {
190
- "201": { "$ref": "#/components/responses/ReportingResponse" },
191
- "400": { "$ref": "#/components/responses/ErrorResponse" },
192
- "403": { "$ref": "#/components/responses/ErrorResponse" }
286
+ "201": {
287
+ "$ref": "#/components/responses/ReportingResponse"
288
+ },
289
+ "400": {
290
+ "$ref": "#/components/responses/ErrorResponse"
291
+ },
292
+ "403": {
293
+ "$ref": "#/components/responses/ErrorResponse"
294
+ }
193
295
  }
194
296
  }
195
297
  },
196
298
  "/v1/admin/reporting/reports/{id}": {
197
299
  "parameters": [
198
- { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }
300
+ {
301
+ "name": "id",
302
+ "in": "path",
303
+ "required": true,
304
+ "schema": {
305
+ "type": "string"
306
+ }
307
+ }
199
308
  ],
200
309
  "get": {
201
310
  "operationId": "getReport",
@@ -203,9 +312,15 @@
203
312
  "description": "Requires reports:read.",
204
313
  "tags": ["Reporting"],
205
314
  "responses": {
206
- "200": { "$ref": "#/components/responses/ReportingResponse" },
207
- "403": { "$ref": "#/components/responses/ErrorResponse" },
208
- "404": { "$ref": "#/components/responses/ErrorResponse" }
315
+ "200": {
316
+ "$ref": "#/components/responses/ReportingResponse"
317
+ },
318
+ "403": {
319
+ "$ref": "#/components/responses/ErrorResponse"
320
+ },
321
+ "404": {
322
+ "$ref": "#/components/responses/ErrorResponse"
323
+ }
209
324
  }
210
325
  },
211
326
  "patch": {
@@ -216,15 +331,29 @@
216
331
  "requestBody": {
217
332
  "required": true,
218
333
  "content": {
219
- "application/json": { "schema": { "$ref": "#/components/schemas/UpdateReportInput" } }
334
+ "application/json": {
335
+ "schema": {
336
+ "$ref": "#/components/schemas/UpdateReportInput"
337
+ }
338
+ }
220
339
  }
221
340
  },
222
341
  "responses": {
223
- "200": { "$ref": "#/components/responses/ReportingResponse" },
224
- "400": { "$ref": "#/components/responses/ErrorResponse" },
225
- "403": { "$ref": "#/components/responses/ErrorResponse" },
226
- "404": { "$ref": "#/components/responses/ErrorResponse" },
227
- "409": { "$ref": "#/components/responses/ErrorResponse" }
342
+ "200": {
343
+ "$ref": "#/components/responses/ReportingResponse"
344
+ },
345
+ "400": {
346
+ "$ref": "#/components/responses/ErrorResponse"
347
+ },
348
+ "403": {
349
+ "$ref": "#/components/responses/ErrorResponse"
350
+ },
351
+ "404": {
352
+ "$ref": "#/components/responses/ErrorResponse"
353
+ },
354
+ "409": {
355
+ "$ref": "#/components/responses/ErrorResponse"
356
+ }
228
357
  }
229
358
  },
230
359
  "delete": {
@@ -233,98 +362,123 @@
233
362
  "description": "Requires reports:write.",
234
363
  "tags": ["Reporting"],
235
364
  "responses": {
236
- "200": { "$ref": "#/components/responses/ReportingResponse" },
237
- "403": { "$ref": "#/components/responses/ErrorResponse" },
238
- "404": { "$ref": "#/components/responses/ErrorResponse" },
239
- "409": { "$ref": "#/components/responses/ErrorResponse" }
365
+ "200": {
366
+ "$ref": "#/components/responses/ReportingResponse"
367
+ },
368
+ "403": {
369
+ "$ref": "#/components/responses/ErrorResponse"
370
+ },
371
+ "404": {
372
+ "$ref": "#/components/responses/ErrorResponse"
373
+ },
374
+ "409": {
375
+ "$ref": "#/components/responses/ErrorResponse"
376
+ }
240
377
  }
241
378
  }
242
379
  },
243
- "/v1/admin/reporting/templates/{id}/instantiate": {
380
+ "/v1/admin/reporting/reports/{id}/export": {
244
381
  "parameters": [
245
- { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }
382
+ {
383
+ "name": "id",
384
+ "in": "path",
385
+ "required": true,
386
+ "schema": {
387
+ "type": "string"
388
+ }
389
+ }
246
390
  ],
247
- "post": {
248
- "operationId": "instantiateReportTemplate",
249
- "summary": "Create an editable report from an available page template",
250
- "description": "Requires reports:write.",
391
+ "get": {
392
+ "operationId": "exportReport",
393
+ "summary": "Export a report as CSV, XLSX, or PDF",
394
+ "description": "Requires reports:export. Re-runs every widget server-side (honoring the saved period) and streams the file.",
251
395
  "tags": ["Reporting"],
252
- "requestBody": {
253
- "required": true,
254
- "content": {
255
- "application/json": {
256
- "schema": { "$ref": "#/components/schemas/InstantiateTemplateInput" }
396
+ "parameters": [
397
+ {
398
+ "name": "format",
399
+ "in": "query",
400
+ "required": false,
401
+ "schema": {
402
+ "type": "string",
403
+ "enum": ["csv", "xlsx", "pdf"],
404
+ "default": "csv"
257
405
  }
258
406
  }
259
- },
407
+ ],
260
408
  "responses": {
261
- "201": { "$ref": "#/components/responses/ReportingResponse" },
262
- "400": { "$ref": "#/components/responses/ErrorResponse" },
263
- "403": { "$ref": "#/components/responses/ErrorResponse" },
264
- "404": { "$ref": "#/components/responses/ErrorResponse" }
409
+ "200": {
410
+ "description": "The exported report file.",
411
+ "content": {
412
+ "text/csv": {
413
+ "schema": {
414
+ "type": "string"
415
+ }
416
+ },
417
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {
418
+ "schema": {
419
+ "type": "string",
420
+ "format": "binary"
421
+ }
422
+ },
423
+ "application/pdf": {
424
+ "schema": {
425
+ "type": "string",
426
+ "format": "binary"
427
+ }
428
+ }
429
+ }
430
+ },
431
+ "400": {
432
+ "$ref": "#/components/responses/ErrorResponse"
433
+ },
434
+ "403": {
435
+ "$ref": "#/components/responses/ErrorResponse"
436
+ },
437
+ "404": {
438
+ "$ref": "#/components/responses/ErrorResponse"
439
+ }
265
440
  }
266
441
  }
267
442
  },
268
- "/v1/admin/reporting/reports/{id}/versions": {
443
+ "/v1/admin/reporting/templates/{id}/instantiate": {
269
444
  "parameters": [
270
- { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }
271
- ],
272
- "post": {
273
- "operationId": "publishReportVersion",
274
- "summary": "Publish an immutable report snapshot",
275
- "description": "Requires reports:write and the current draft revision.",
276
- "tags": ["Reporting"],
277
- "requestBody": {
445
+ {
446
+ "name": "id",
447
+ "in": "path",
278
448
  "required": true,
279
- "content": {
280
- "application/json": { "schema": { "$ref": "#/components/schemas/PublishReportInput" } }
449
+ "schema": {
450
+ "type": "string"
281
451
  }
282
- },
283
- "responses": {
284
- "201": { "$ref": "#/components/responses/ReportingResponse" },
285
- "400": { "$ref": "#/components/responses/ErrorResponse" },
286
- "403": { "$ref": "#/components/responses/ErrorResponse" },
287
- "404": { "$ref": "#/components/responses/ErrorResponse" },
288
- "409": { "$ref": "#/components/responses/ErrorResponse" }
289
452
  }
290
- }
291
- },
292
- "/v1/admin/reporting/versions/{id}/runs": {
293
- "parameters": [
294
- { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }
295
453
  ],
296
454
  "post": {
297
- "operationId": "runReportVersion",
298
- "summary": "Execute an immutable report version",
299
- "description": "Requires reports:export and every source dataset scope used by the version.",
455
+ "operationId": "instantiateReportTemplate",
456
+ "summary": "Create an editable report from an available page template",
457
+ "description": "Requires reports:write.",
300
458
  "tags": ["Reporting"],
301
459
  "requestBody": {
302
460
  "required": true,
303
461
  "content": {
304
- "application/json": { "schema": { "$ref": "#/components/schemas/RunReportInput" } }
462
+ "application/json": {
463
+ "schema": {
464
+ "$ref": "#/components/schemas/InstantiateTemplateInput"
465
+ }
466
+ }
305
467
  }
306
468
  },
307
469
  "responses": {
308
- "201": { "$ref": "#/components/responses/ReportingResponse" },
309
- "400": { "$ref": "#/components/responses/ErrorResponse" },
310
- "403": { "$ref": "#/components/responses/ErrorResponse" },
311
- "404": { "$ref": "#/components/responses/ErrorResponse" }
312
- }
313
- }
314
- },
315
- "/v1/admin/reporting/runs/{id}": {
316
- "parameters": [
317
- { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }
318
- ],
319
- "get": {
320
- "operationId": "getReportRun",
321
- "summary": "Get persisted report results",
322
- "description": "Requires reports:export and every source dataset scope recorded on the run.",
323
- "tags": ["Reporting"],
324
- "responses": {
325
- "200": { "$ref": "#/components/responses/ReportingResponse" },
326
- "403": { "$ref": "#/components/responses/ErrorResponse" },
327
- "404": { "$ref": "#/components/responses/ErrorResponse" }
470
+ "201": {
471
+ "$ref": "#/components/responses/ReportingResponse"
472
+ },
473
+ "400": {
474
+ "$ref": "#/components/responses/ErrorResponse"
475
+ },
476
+ "403": {
477
+ "$ref": "#/components/responses/ErrorResponse"
478
+ },
479
+ "404": {
480
+ "$ref": "#/components/responses/ErrorResponse"
481
+ }
328
482
  }
329
483
  }
330
484
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyant-travel/reporting",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "Composable, domain-neutral reporting registry and persisted report lifecycle for Voyant.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -45,12 +45,14 @@
45
45
  "dependencies": {
46
46
  "@hono/zod-openapi": "^1.4.0",
47
47
  "drizzle-orm": "^0.45.2",
48
+ "exceljs": "^4.4.0",
48
49
  "hono": "^4.12.27",
50
+ "pdf-lib": "^1.17.1",
49
51
  "zod": "^4.4.3",
50
52
  "@voyant-travel/core": "^0.130.0",
53
+ "@voyant-travel/db": "^0.117.1",
51
54
  "@voyant-travel/hono": "^0.131.2",
52
- "@voyant-travel/db": "^0.117.0",
53
- "@voyant-travel/reporting-contracts": "^0.2.1",
55
+ "@voyant-travel/reporting-contracts": "^0.3.0",
54
56
  "@voyant-travel/types": "^0.109.8"
55
57
  },
56
58
  "devDependencies": {