@voyant-travel/reporting 0.1.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.
@@ -0,0 +1,298 @@
1
+ {
2
+ "openapi": "3.1.0",
3
+ "info": {
4
+ "title": "Voyant Reporting Admin API",
5
+ "version": "1.0.0",
6
+ "description": "Composable report catalog, drafts, immutable versions, and bounded execution."
7
+ },
8
+ "components": {
9
+ "schemas": {
10
+ "ReportingResponse": {
11
+ "type": "object",
12
+ "additionalProperties": true
13
+ },
14
+ "QuerySourceInput": {
15
+ "type": "object",
16
+ "required": ["source"],
17
+ "properties": { "source": { "type": "string", "minLength": 1, "maxLength": 10000 } },
18
+ "additionalProperties": false
19
+ },
20
+ "QueryPreviewInput": {
21
+ "type": "object",
22
+ "required": ["query"],
23
+ "properties": {
24
+ "query": { "type": "object", "additionalProperties": true },
25
+ "parameters": { "type": "object", "additionalProperties": true, "default": {} }
26
+ },
27
+ "additionalProperties": false
28
+ },
29
+ "CreateReportInput": {
30
+ "type": "object",
31
+ "required": ["name"],
32
+ "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 }
38
+ },
39
+ "additionalProperties": false
40
+ },
41
+ "UpdateReportInput": {
42
+ "type": "object",
43
+ "required": ["revision"],
44
+ "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 }
49
+ },
50
+ "additionalProperties": false
51
+ },
52
+ "InstantiateTemplateInput": {
53
+ "type": "object",
54
+ "required": ["name"],
55
+ "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": {} }
72
+ },
73
+ "additionalProperties": false
74
+ },
75
+ "Error": {
76
+ "type": "object",
77
+ "required": ["error"],
78
+ "properties": {
79
+ "error": { "type": "string" },
80
+ "message": { "type": "string" },
81
+ "missingScopes": { "type": "array", "items": { "type": "string" } }
82
+ },
83
+ "additionalProperties": true
84
+ }
85
+ },
86
+ "responses": {
87
+ "ReportingResponse": {
88
+ "description": "Reporting API response",
89
+ "content": {
90
+ "application/json": {
91
+ "schema": { "$ref": "#/components/schemas/ReportingResponse" }
92
+ }
93
+ }
94
+ },
95
+ "ErrorResponse": {
96
+ "description": "Reporting API error",
97
+ "content": {
98
+ "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
99
+ }
100
+ }
101
+ }
102
+ },
103
+ "paths": {
104
+ "/v1/admin/reporting/catalog": {
105
+ "get": {
106
+ "operationId": "getReportingCatalog",
107
+ "summary": "List available datasets, widget presets, and page templates",
108
+ "description": "Requires reports:read.",
109
+ "tags": ["Reporting"],
110
+ "responses": {
111
+ "200": { "$ref": "#/components/responses/ReportingResponse" },
112
+ "403": { "$ref": "#/components/responses/ErrorResponse" }
113
+ }
114
+ }
115
+ },
116
+ "/v1/admin/reporting/queries/parse": {
117
+ "post": {
118
+ "operationId": "parseReportingQuery",
119
+ "summary": "Parse the bounded reporting query language",
120
+ "description": "Requires reports:read. The language does not permit joins, mutations, or arbitrary code.",
121
+ "tags": ["Reporting"],
122
+ "requestBody": {
123
+ "required": true,
124
+ "content": { "application/json": { "schema": { "$ref": "#/components/schemas/QuerySourceInput" } } }
125
+ },
126
+ "responses": {
127
+ "200": { "$ref": "#/components/responses/ReportingResponse" },
128
+ "400": { "$ref": "#/components/responses/ErrorResponse" },
129
+ "403": { "$ref": "#/components/responses/ErrorResponse" }
130
+ }
131
+ }
132
+ },
133
+ "/v1/admin/reporting/queries/preview": {
134
+ "post": {
135
+ "operationId": "previewReportingQuery",
136
+ "summary": "Execute a bounded query preview",
137
+ "description": "Requires reports:read and every scope declared by the selected dataset fields.",
138
+ "tags": ["Reporting"],
139
+ "requestBody": {
140
+ "required": true,
141
+ "content": { "application/json": { "schema": { "$ref": "#/components/schemas/QueryPreviewInput" } } }
142
+ },
143
+ "responses": {
144
+ "200": { "$ref": "#/components/responses/ReportingResponse" },
145
+ "400": { "$ref": "#/components/responses/ErrorResponse" },
146
+ "403": { "$ref": "#/components/responses/ErrorResponse" }
147
+ }
148
+ }
149
+ },
150
+ "/v1/admin/reporting/reports": {
151
+ "get": {
152
+ "operationId": "listReports",
153
+ "summary": "List saved report drafts",
154
+ "description": "Requires reports:read.",
155
+ "tags": ["Reporting"],
156
+ "parameters": [
157
+ { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 } },
158
+ { "name": "offset", "in": "query", "schema": { "type": "integer", "minimum": 0, "default": 0 } }
159
+ ],
160
+ "responses": {
161
+ "200": { "$ref": "#/components/responses/ReportingResponse" },
162
+ "400": { "$ref": "#/components/responses/ErrorResponse" },
163
+ "403": { "$ref": "#/components/responses/ErrorResponse" }
164
+ }
165
+ },
166
+ "post": {
167
+ "operationId": "createReport",
168
+ "summary": "Create a report draft",
169
+ "description": "Requires reports:write.",
170
+ "tags": ["Reporting"],
171
+ "requestBody": {
172
+ "required": true,
173
+ "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateReportInput" } } }
174
+ },
175
+ "responses": {
176
+ "201": { "$ref": "#/components/responses/ReportingResponse" },
177
+ "400": { "$ref": "#/components/responses/ErrorResponse" },
178
+ "403": { "$ref": "#/components/responses/ErrorResponse" }
179
+ }
180
+ }
181
+ },
182
+ "/v1/admin/reporting/reports/{id}": {
183
+ "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
184
+ "get": {
185
+ "operationId": "getReport",
186
+ "summary": "Get a saved report draft",
187
+ "description": "Requires reports:read.",
188
+ "tags": ["Reporting"],
189
+ "responses": {
190
+ "200": { "$ref": "#/components/responses/ReportingResponse" },
191
+ "403": { "$ref": "#/components/responses/ErrorResponse" },
192
+ "404": { "$ref": "#/components/responses/ErrorResponse" }
193
+ }
194
+ },
195
+ "patch": {
196
+ "operationId": "updateReport",
197
+ "summary": "Save an optimistic-concurrency report edit",
198
+ "description": "Requires reports:write and the current draft revision.",
199
+ "tags": ["Reporting"],
200
+ "requestBody": {
201
+ "required": true,
202
+ "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateReportInput" } } }
203
+ },
204
+ "responses": {
205
+ "200": { "$ref": "#/components/responses/ReportingResponse" },
206
+ "400": { "$ref": "#/components/responses/ErrorResponse" },
207
+ "403": { "$ref": "#/components/responses/ErrorResponse" },
208
+ "404": { "$ref": "#/components/responses/ErrorResponse" },
209
+ "409": { "$ref": "#/components/responses/ErrorResponse" }
210
+ }
211
+ },
212
+ "delete": {
213
+ "operationId": "deleteReport",
214
+ "summary": "Delete a report without retained runs",
215
+ "description": "Requires reports:write.",
216
+ "tags": ["Reporting"],
217
+ "responses": {
218
+ "200": { "$ref": "#/components/responses/ReportingResponse" },
219
+ "403": { "$ref": "#/components/responses/ErrorResponse" },
220
+ "404": { "$ref": "#/components/responses/ErrorResponse" },
221
+ "409": { "$ref": "#/components/responses/ErrorResponse" }
222
+ }
223
+ }
224
+ },
225
+ "/v1/admin/reporting/templates/{id}/instantiate": {
226
+ "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
227
+ "post": {
228
+ "operationId": "instantiateReportTemplate",
229
+ "summary": "Create an editable report from an available page template",
230
+ "description": "Requires reports:write.",
231
+ "tags": ["Reporting"],
232
+ "requestBody": {
233
+ "required": true,
234
+ "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InstantiateTemplateInput" } } }
235
+ },
236
+ "responses": {
237
+ "201": { "$ref": "#/components/responses/ReportingResponse" },
238
+ "400": { "$ref": "#/components/responses/ErrorResponse" },
239
+ "403": { "$ref": "#/components/responses/ErrorResponse" },
240
+ "404": { "$ref": "#/components/responses/ErrorResponse" }
241
+ }
242
+ }
243
+ },
244
+ "/v1/admin/reporting/reports/{id}/versions": {
245
+ "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
246
+ "post": {
247
+ "operationId": "publishReportVersion",
248
+ "summary": "Publish an immutable report snapshot",
249
+ "description": "Requires reports:write and the current draft revision.",
250
+ "tags": ["Reporting"],
251
+ "requestBody": {
252
+ "required": true,
253
+ "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PublishReportInput" } } }
254
+ },
255
+ "responses": {
256
+ "201": { "$ref": "#/components/responses/ReportingResponse" },
257
+ "400": { "$ref": "#/components/responses/ErrorResponse" },
258
+ "403": { "$ref": "#/components/responses/ErrorResponse" },
259
+ "404": { "$ref": "#/components/responses/ErrorResponse" },
260
+ "409": { "$ref": "#/components/responses/ErrorResponse" }
261
+ }
262
+ }
263
+ },
264
+ "/v1/admin/reporting/versions/{id}/runs": {
265
+ "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
266
+ "post": {
267
+ "operationId": "runReportVersion",
268
+ "summary": "Execute an immutable report version",
269
+ "description": "Requires reports:export and every source dataset scope used by the version.",
270
+ "tags": ["Reporting"],
271
+ "requestBody": {
272
+ "required": true,
273
+ "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RunReportInput" } } }
274
+ },
275
+ "responses": {
276
+ "201": { "$ref": "#/components/responses/ReportingResponse" },
277
+ "400": { "$ref": "#/components/responses/ErrorResponse" },
278
+ "403": { "$ref": "#/components/responses/ErrorResponse" },
279
+ "404": { "$ref": "#/components/responses/ErrorResponse" }
280
+ }
281
+ }
282
+ },
283
+ "/v1/admin/reporting/runs/{id}": {
284
+ "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
285
+ "get": {
286
+ "operationId": "getReportRun",
287
+ "summary": "Get persisted report results",
288
+ "description": "Requires reports:export and every source dataset scope recorded on the run.",
289
+ "tags": ["Reporting"],
290
+ "responses": {
291
+ "200": { "$ref": "#/components/responses/ReportingResponse" },
292
+ "403": { "$ref": "#/components/responses/ErrorResponse" },
293
+ "404": { "$ref": "#/components/responses/ErrorResponse" }
294
+ }
295
+ }
296
+ }
297
+ }
298
+ }
package/package.json ADDED
@@ -0,0 +1,106 @@
1
+ {
2
+ "name": "@voyant-travel/reporting",
3
+ "version": "0.1.0",
4
+ "description": "Composable, domain-neutral reporting registry and persisted report lifecycle for Voyant.",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js",
11
+ "default": "./dist/index.js"
12
+ },
13
+ "./schema": {
14
+ "types": "./dist/schema.d.ts",
15
+ "import": "./dist/schema.js",
16
+ "default": "./dist/schema.js"
17
+ },
18
+ "./service": {
19
+ "types": "./dist/service.d.ts",
20
+ "import": "./dist/service.js",
21
+ "default": "./dist/service.js"
22
+ },
23
+ "./registry": {
24
+ "types": "./dist/registry.d.ts",
25
+ "import": "./dist/registry.js",
26
+ "default": "./dist/registry.js"
27
+ },
28
+ "./routes": {
29
+ "types": "./dist/routes.d.ts",
30
+ "import": "./dist/routes.js",
31
+ "default": "./dist/routes.js"
32
+ },
33
+ "./api-runtime": {
34
+ "types": "./dist/api-runtime.d.ts",
35
+ "import": "./dist/api-runtime.js",
36
+ "default": "./dist/api-runtime.js"
37
+ },
38
+ "./voyant": {
39
+ "types": "./dist/voyant.d.ts",
40
+ "import": "./dist/voyant.js",
41
+ "default": "./dist/voyant.js"
42
+ },
43
+ "./openapi/admin": "./openapi/admin/reporting.json"
44
+ },
45
+ "dependencies": {
46
+ "@hono/zod-openapi": "^1.4.0",
47
+ "drizzle-orm": "^0.45.2",
48
+ "hono": "^4.12.27",
49
+ "zod": "^4.4.3",
50
+ "@voyant-travel/core": "^0.128.0",
51
+ "@voyant-travel/reporting-contracts": "^0.1.0",
52
+ "@voyant-travel/types": "^0.109.4",
53
+ "@voyant-travel/db": "^0.114.14",
54
+ "@voyant-travel/hono": "^0.130.0"
55
+ },
56
+ "devDependencies": {
57
+ "drizzle-kit": "^0.31.10",
58
+ "typescript": "^6.0.3",
59
+ "vitest": "^4.1.9",
60
+ "@voyant-travel/voyant-typescript-config": "^0.1.0"
61
+ },
62
+ "files": [
63
+ "dist",
64
+ "openapi",
65
+ "migrations/*.sql",
66
+ "migrations/meta/_journal.json"
67
+ ],
68
+ "publishConfig": {
69
+ "access": "public"
70
+ },
71
+ "repository": {
72
+ "type": "git",
73
+ "url": "https://github.com/voyant-travel/voyant.git",
74
+ "directory": "packages/reporting"
75
+ },
76
+ "voyant": {
77
+ "schemaVersion": "voyant.package.v1",
78
+ "kind": "module",
79
+ "manifest": "./voyant",
80
+ "compatibleWith": {
81
+ "framework": ">=0.26.0",
82
+ "targets": [
83
+ "node"
84
+ ],
85
+ "modes": [
86
+ "local",
87
+ "managed-cloud",
88
+ "self-hosted"
89
+ ]
90
+ },
91
+ "schema": "./schema",
92
+ "requiresSchemas": [
93
+ "@voyant-travel/db"
94
+ ]
95
+ },
96
+ "scripts": {
97
+ "build": "tsc -p tsconfig.build.json",
98
+ "clean": "rm -rf dist tsconfig.tsbuildinfo",
99
+ "typecheck": "tsc -p tsconfig.typecheck.json",
100
+ "lint": "biome check src/ tests/",
101
+ "test": "vitest run",
102
+ "db:generate": "drizzle-kit generate --config=drizzle.migrations.config.ts --prefix=timestamp --name=reporting_baseline && node ../../scripts/migrations/guard-create-type.mjs ./migrations && node ../../scripts/migrations/ensure-extensions.mjs ./migrations"
103
+ },
104
+ "main": "./dist/index.js",
105
+ "types": "./dist/index.d.ts"
106
+ }