storybooker 0.19.4 → 0.22.0-canary.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.
Files changed (215) hide show
  1. package/README.md +40 -18
  2. package/dist/adapters/_internal/queue.d.mts +127 -0
  3. package/dist/aws-dynamodb.d.mts +22 -0
  4. package/dist/aws-dynamodb.mjs +118 -0
  5. package/dist/aws-dynamodb.mjs.map +1 -0
  6. package/dist/aws-s3.d.mts +20 -0
  7. package/dist/aws-s3.mjs +96 -0
  8. package/dist/aws-s3.mjs.map +1 -0
  9. package/dist/azure-blob-storage.d.mts +20 -0
  10. package/dist/azure-blob-storage.mjs +126 -0
  11. package/dist/azure-blob-storage.mjs.map +1 -0
  12. package/dist/azure-cosmos-db.d.mts +23 -0
  13. package/dist/azure-cosmos-db.mjs +87 -0
  14. package/dist/azure-cosmos-db.mjs.map +1 -0
  15. package/dist/azure-data-tables.d.mts +23 -0
  16. package/dist/azure-data-tables.mjs +127 -0
  17. package/dist/azure-data-tables.mjs.map +1 -0
  18. package/dist/azure-easy-auth.d.mts +50 -0
  19. package/dist/azure-easy-auth.mjs +88 -0
  20. package/dist/azure-easy-auth.mjs.map +1 -0
  21. package/dist/azure-functions.d.mts +62 -0
  22. package/dist/azure-functions.mjs +147 -0
  23. package/dist/azure-functions.mjs.map +1 -0
  24. package/dist/fs.d.mts +37 -0
  25. package/dist/fs.mjs +240 -0
  26. package/dist/fs.mjs.map +1 -0
  27. package/dist/gcp-big-table.d.mts +23 -0
  28. package/dist/gcp-big-table.mjs +92 -0
  29. package/dist/gcp-big-table.mjs.map +1 -0
  30. package/dist/gcp-firestore.d.mts +22 -0
  31. package/dist/gcp-firestore.mjs +87 -0
  32. package/dist/gcp-firestore.mjs.map +1 -0
  33. package/dist/gcp-storage.d.mts +20 -0
  34. package/dist/gcp-storage.mjs +96 -0
  35. package/dist/gcp-storage.mjs.map +1 -0
  36. package/dist/handlers/handle-process-zip.mjs +90 -0
  37. package/dist/handlers/handle-process-zip.mjs.map +1 -0
  38. package/dist/handlers/handle-purge.d.mts +12 -0
  39. package/dist/handlers/handle-purge.mjs +36 -0
  40. package/dist/handlers/handle-purge.mjs.map +1 -0
  41. package/dist/handlers/handle-serve-storybook.mjs +94 -0
  42. package/dist/handlers/handle-serve-storybook.mjs.map +1 -0
  43. package/dist/index.d.mts +28 -0
  44. package/dist/index.mjs +62 -0
  45. package/dist/index.mjs.map +1 -0
  46. package/dist/models/builds-model.mjs +248 -0
  47. package/dist/models/builds-model.mjs.map +1 -0
  48. package/dist/models/builds-schema.d.mts +171 -0
  49. package/dist/models/builds-schema.mjs +67 -0
  50. package/dist/models/builds-schema.mjs.map +1 -0
  51. package/dist/models/projects-model.mjs +122 -0
  52. package/dist/models/projects-model.mjs.map +1 -0
  53. package/dist/models/projects-schema.d.mts +70 -0
  54. package/dist/models/projects-schema.mjs +37 -0
  55. package/dist/models/projects-schema.mjs.map +1 -0
  56. package/dist/models/tags-model.mjs +110 -0
  57. package/dist/models/tags-model.mjs.map +1 -0
  58. package/dist/models/tags-schema.d.mts +76 -0
  59. package/dist/models/tags-schema.mjs +34 -0
  60. package/dist/models/tags-schema.mjs.map +1 -0
  61. package/dist/models/~model.mjs +43 -0
  62. package/dist/models/~model.mjs.map +1 -0
  63. package/dist/models/~shared-schema.d.mts +1 -0
  64. package/dist/models/~shared-schema.mjs +20 -0
  65. package/dist/models/~shared-schema.mjs.map +1 -0
  66. package/dist/mysql.d.mts +39 -0
  67. package/dist/mysql.mjs +151 -0
  68. package/dist/mysql.mjs.map +1 -0
  69. package/dist/redis.d.mts +33 -0
  70. package/dist/redis.mjs +118 -0
  71. package/dist/redis.mjs.map +1 -0
  72. package/dist/routers/account-router.mjs +91 -0
  73. package/dist/routers/account-router.mjs.map +1 -0
  74. package/dist/routers/builds-router.mjs +347 -0
  75. package/dist/routers/builds-router.mjs.map +1 -0
  76. package/dist/routers/projects-router.mjs +236 -0
  77. package/dist/routers/projects-router.mjs.map +1 -0
  78. package/dist/routers/root-router.mjs +108 -0
  79. package/dist/routers/root-router.mjs.map +1 -0
  80. package/dist/routers/tags-router.mjs +269 -0
  81. package/dist/routers/tags-router.mjs.map +1 -0
  82. package/dist/routers/tasks-router.mjs +71 -0
  83. package/dist/routers/tasks-router.mjs.map +1 -0
  84. package/dist/urls.d.mts +47 -0
  85. package/dist/urls.mjs +208 -0
  86. package/dist/urls.mjs.map +1 -0
  87. package/dist/utils/adapter-utils.d.mts +14 -0
  88. package/dist/utils/adapter-utils.mjs +14 -0
  89. package/dist/utils/adapter-utils.mjs.map +1 -0
  90. package/dist/utils/auth.mjs +25 -0
  91. package/dist/utils/auth.mjs.map +1 -0
  92. package/dist/utils/error.d.mts +21 -0
  93. package/dist/utils/error.mjs +109 -0
  94. package/dist/utils/error.mjs.map +1 -0
  95. package/dist/utils/file-utils.mjs +16 -0
  96. package/dist/utils/file-utils.mjs.map +1 -0
  97. package/dist/utils/openapi-utils.mjs +45 -0
  98. package/dist/utils/openapi-utils.mjs.map +1 -0
  99. package/dist/utils/request.mjs +35 -0
  100. package/dist/utils/request.mjs.map +1 -0
  101. package/dist/utils/response.mjs +24 -0
  102. package/dist/utils/response.mjs.map +1 -0
  103. package/dist/utils/store.mjs +54 -0
  104. package/dist/utils/store.mjs.map +1 -0
  105. package/dist/utils/ui-utils.mjs +38 -0
  106. package/dist/utils/ui-utils.mjs.map +1 -0
  107. package/dist/utils/url-utils.d.mts +10 -0
  108. package/dist/utils/url-utils.mjs +54 -0
  109. package/dist/utils/url-utils.mjs.map +1 -0
  110. package/dist/~internal/adapter/auth.d.mts +123 -0
  111. package/dist/~internal/adapter/auth.mjs +20 -0
  112. package/dist/~internal/adapter/auth.mjs.map +1 -0
  113. package/dist/~internal/adapter/database.d.mts +240 -0
  114. package/dist/~internal/adapter/database.mjs +63 -0
  115. package/dist/~internal/adapter/database.mjs.map +1 -0
  116. package/dist/~internal/adapter/logger.d.mts +34 -0
  117. package/dist/~internal/adapter/logger.mjs +13 -0
  118. package/dist/~internal/adapter/logger.mjs.map +1 -0
  119. package/dist/~internal/adapter/storage.d.mts +208 -0
  120. package/dist/~internal/adapter/storage.mjs +63 -0
  121. package/dist/~internal/adapter/storage.mjs.map +1 -0
  122. package/dist/~internal/adapter/ui.d.mts +109 -0
  123. package/dist/~internal/adapter/ui.mjs +1 -0
  124. package/dist/~internal/adapter.d.mts +8 -0
  125. package/dist/~internal/adapter.mjs +6 -0
  126. package/dist/~internal/constants.d.mts +24 -0
  127. package/dist/~internal/constants.mjs +32 -0
  128. package/dist/~internal/constants.mjs.map +1 -0
  129. package/dist/~internal/mimes.d.mts +449 -0
  130. package/dist/~internal/mimes.mjs +454 -0
  131. package/dist/~internal/mimes.mjs.map +1 -0
  132. package/dist/~internal/router.d.mts +1651 -0
  133. package/dist/~internal/router.mjs +39 -0
  134. package/dist/~internal/router.mjs.map +1 -0
  135. package/dist/~internal/types.d.mts +77 -0
  136. package/dist/~internal/types.mjs +1 -0
  137. package/dist/~internal/utils.d.mts +4 -0
  138. package/dist/~internal/utils.mjs +5 -0
  139. package/openapi.json +3162 -0
  140. package/package.json +148 -27
  141. package/src/adapters/_internal/auth.ts +135 -0
  142. package/src/adapters/_internal/database.ts +241 -0
  143. package/src/adapters/_internal/index.ts +8 -0
  144. package/src/adapters/_internal/logger.ts +41 -0
  145. package/src/adapters/_internal/queue.ts +151 -0
  146. package/src/adapters/_internal/storage.ts +197 -0
  147. package/src/adapters/_internal/ui.ts +103 -0
  148. package/src/adapters/aws-dynamodb.ts +201 -0
  149. package/src/adapters/aws-s3.ts +160 -0
  150. package/src/adapters/azure-blob-storage.ts +223 -0
  151. package/src/adapters/azure-cosmos-db.ts +158 -0
  152. package/src/adapters/azure-data-tables.ts +223 -0
  153. package/src/adapters/azure-easy-auth.ts +174 -0
  154. package/src/adapters/azure-functions.ts +242 -0
  155. package/src/adapters/fs.ts +398 -0
  156. package/src/adapters/gcp-big-table.ts +157 -0
  157. package/src/adapters/gcp-firestore.ts +146 -0
  158. package/src/adapters/gcp-storage.ts +141 -0
  159. package/src/adapters/mysql.ts +296 -0
  160. package/src/adapters/redis.ts +242 -0
  161. package/src/handlers/handle-process-zip.ts +117 -0
  162. package/src/handlers/handle-purge.ts +65 -0
  163. package/src/handlers/handle-serve-storybook.ts +101 -0
  164. package/src/index.ts +81 -16
  165. package/src/mocks/mock-auth-service.ts +51 -0
  166. package/src/mocks/mock-store.ts +26 -0
  167. package/src/models/builds-model.ts +373 -0
  168. package/src/models/builds-schema.ts +84 -0
  169. package/src/models/projects-model.ts +177 -0
  170. package/src/models/projects-schema.ts +69 -0
  171. package/src/models/tags-model.ts +138 -0
  172. package/src/models/tags-schema.ts +45 -0
  173. package/src/models/~model.ts +79 -0
  174. package/src/models/~shared-schema.ts +14 -0
  175. package/src/routers/_app-router.ts +57 -0
  176. package/src/routers/account-router.ts +136 -0
  177. package/src/routers/builds-router.ts +464 -0
  178. package/src/routers/projects-router.ts +309 -0
  179. package/src/routers/root-router.ts +127 -0
  180. package/src/routers/tags-router.ts +339 -0
  181. package/src/routers/tasks-router.ts +75 -0
  182. package/src/types.ts +107 -0
  183. package/src/urls.ts +327 -0
  184. package/src/utils/adapter-utils.ts +26 -0
  185. package/src/utils/auth.test.ts +71 -0
  186. package/src/utils/auth.ts +39 -0
  187. package/src/utils/constants.ts +31 -0
  188. package/src/utils/date-utils.ts +10 -0
  189. package/src/utils/error.test.ts +86 -0
  190. package/src/utils/error.ts +140 -0
  191. package/src/utils/file-utils.test.ts +65 -0
  192. package/src/utils/file-utils.ts +43 -0
  193. package/src/utils/index.ts +3 -0
  194. package/src/utils/mime-utils.ts +457 -0
  195. package/src/utils/openapi-utils.ts +49 -0
  196. package/src/utils/request.ts +97 -0
  197. package/src/utils/response.ts +20 -0
  198. package/src/utils/store.ts +85 -0
  199. package/src/utils/story-utils.ts +42 -0
  200. package/src/utils/text-utils.ts +10 -0
  201. package/src/utils/ui-utils.ts +57 -0
  202. package/src/utils/url-utils.ts +113 -0
  203. package/dist/index.js +0 -554
  204. package/src/commands/create.ts +0 -263
  205. package/src/commands/purge.ts +0 -70
  206. package/src/commands/test.ts +0 -42
  207. package/src/service-schema.d.ts +0 -2023
  208. package/src/utils/auth-utils.ts +0 -31
  209. package/src/utils/pkg-utils.ts +0 -37
  210. package/src/utils/sb-build.ts +0 -55
  211. package/src/utils/sb-test.ts +0 -115
  212. package/src/utils/schema-utils.ts +0 -123
  213. package/src/utils/stream-utils.ts +0 -72
  214. package/src/utils/types.ts +0 -4
  215. package/src/utils/zip.ts +0 -77
package/openapi.json ADDED
@@ -0,0 +1,3162 @@
1
+ {
2
+ "openapi": "3.1.0",
3
+ "info": {
4
+ "title": "StoryBooker",
5
+ "version": ""
6
+ },
7
+ "components": {
8
+ "schemas": {
9
+ "ProjectID": {
10
+ "type": "string",
11
+ "description": "The ID of the project."
12
+ },
13
+ "BuildID": {
14
+ "type": "string",
15
+ "minLength": 7,
16
+ "description": "The ID of the build."
17
+ },
18
+ "Project": {
19
+ "type": "object",
20
+ "properties": {
21
+ "createdAt": {
22
+ "type": "string",
23
+ "format": "date-time",
24
+ "default": "2025-12-25T19:37:51.491Z"
25
+ },
26
+ "gitHubDefaultBranch": {
27
+ "type": "string",
28
+ "default": "main",
29
+ "description": "Default branch to use for GitHub repository"
30
+ },
31
+ "gitHubPath": {
32
+ "type": "string",
33
+ "description": "Path to the storybook project with respect to repository root."
34
+ },
35
+ "gitHubRepository": {
36
+ "type": "string",
37
+ "minLength": 1
38
+ },
39
+ "id": {
40
+ "$ref": "#/components/schemas/ProjectID"
41
+ },
42
+ "jiraDomain": {
43
+ "anyOf": [
44
+ {
45
+ "type": "string",
46
+ "format": "uri"
47
+ },
48
+ {
49
+ "type": "string",
50
+ "enum": [
51
+ ""
52
+ ]
53
+ }
54
+ ]
55
+ },
56
+ "latestBuildId": {
57
+ "anyOf": [
58
+ {
59
+ "$ref": "#/components/schemas/BuildID"
60
+ },
61
+ {
62
+ "type": "string",
63
+ "enum": [
64
+ ""
65
+ ]
66
+ }
67
+ ]
68
+ },
69
+ "name": {
70
+ "type": "string",
71
+ "description": "Name of the project."
72
+ },
73
+ "purgeBuildsAfterDays": {
74
+ "type": "number",
75
+ "minimum": 1,
76
+ "default": 30,
77
+ "description": "Days after which the builds in the project should be purged."
78
+ },
79
+ "updatedAt": {
80
+ "type": "string",
81
+ "format": "date-time",
82
+ "default": "2025-12-25T19:37:51.492Z"
83
+ }
84
+ },
85
+ "required": [
86
+ "gitHubRepository",
87
+ "id",
88
+ "name"
89
+ ],
90
+ "description": "StoryBooker project"
91
+ },
92
+ "ResponseError": {
93
+ "type": "object",
94
+ "properties": {
95
+ "errorMessage": {
96
+ "type": "string"
97
+ }
98
+ },
99
+ "required": [
100
+ "errorMessage"
101
+ ]
102
+ },
103
+ "Build": {
104
+ "type": "object",
105
+ "properties": {
106
+ "authorEmail": {
107
+ "type": "string",
108
+ "description": "Email of the author"
109
+ },
110
+ "authorName": {
111
+ "type": "string"
112
+ },
113
+ "createdAt": {
114
+ "type": "string",
115
+ "format": "date-time",
116
+ "default": "2025-12-25T19:37:51.485Z"
117
+ },
118
+ "id": {
119
+ "$ref": "#/components/schemas/BuildID"
120
+ },
121
+ "tagIds": {
122
+ "type": "string"
123
+ },
124
+ "message": {
125
+ "type": "string"
126
+ },
127
+ "updatedAt": {
128
+ "type": "string",
129
+ "format": "date-time",
130
+ "default": "2025-12-25T19:37:51.489Z"
131
+ },
132
+ "coverage": {
133
+ "type": "string",
134
+ "enum": [
135
+ "none",
136
+ "uploaded",
137
+ "processing",
138
+ "ready"
139
+ ]
140
+ },
141
+ "screenshots": {
142
+ "type": "string",
143
+ "enum": [
144
+ "none",
145
+ "uploaded",
146
+ "processing",
147
+ "ready"
148
+ ]
149
+ },
150
+ "storybook": {
151
+ "type": "string",
152
+ "enum": [
153
+ "none",
154
+ "uploaded",
155
+ "processing",
156
+ "ready"
157
+ ]
158
+ },
159
+ "testReport": {
160
+ "type": "string",
161
+ "enum": [
162
+ "none",
163
+ "uploaded",
164
+ "processing",
165
+ "ready"
166
+ ]
167
+ }
168
+ },
169
+ "required": [
170
+ "authorEmail",
171
+ "authorName",
172
+ "id",
173
+ "coverage",
174
+ "screenshots",
175
+ "storybook",
176
+ "testReport"
177
+ ],
178
+ "description": "StoryBooker Build"
179
+ },
180
+ "TagID": {
181
+ "type": "string",
182
+ "description": "The ID of the tag."
183
+ },
184
+ "Tag": {
185
+ "type": "object",
186
+ "properties": {
187
+ "buildsCount": {
188
+ "type": "number",
189
+ "default": 0
190
+ },
191
+ "createdAt": {
192
+ "type": "string",
193
+ "format": "date-time",
194
+ "default": "2025-12-25T19:37:51.492Z"
195
+ },
196
+ "id": {
197
+ "$ref": "#/components/schemas/TagID"
198
+ },
199
+ "latestBuildId": {
200
+ "anyOf": [
201
+ {
202
+ "$ref": "#/components/schemas/BuildID"
203
+ },
204
+ {
205
+ "type": "string",
206
+ "enum": [
207
+ ""
208
+ ]
209
+ }
210
+ ]
211
+ },
212
+ "type": {
213
+ "type": "string",
214
+ "enum": [
215
+ "branch",
216
+ "pr",
217
+ "jira"
218
+ ]
219
+ },
220
+ "updatedAt": {
221
+ "type": "string",
222
+ "format": "date-time",
223
+ "default": "2025-12-25T19:37:51.492Z"
224
+ },
225
+ "value": {
226
+ "type": "string",
227
+ "description": "The value of the tag."
228
+ }
229
+ },
230
+ "required": [
231
+ "id",
232
+ "type",
233
+ "value"
234
+ ],
235
+ "description": "StoryBooker Tag"
236
+ }
237
+ },
238
+ "parameters": {}
239
+ },
240
+ "paths": {
241
+ "/": {
242
+ "get": {
243
+ "summary": "Homepage",
244
+ "responses": {
245
+ "200": {
246
+ "description": "Render homepage or return a list of endpoint-urls.",
247
+ "content": {
248
+ "application/json": {
249
+ "schema": {
250
+ "type": "object",
251
+ "properties": {
252
+ "name": {
253
+ "type": "string"
254
+ },
255
+ "adapters": {
256
+ "type": "object",
257
+ "additionalProperties": {
258
+ "type": "object",
259
+ "properties": {
260
+ "name": {
261
+ "type": "string"
262
+ }
263
+ },
264
+ "required": [
265
+ "name"
266
+ ]
267
+ }
268
+ },
269
+ "config": {
270
+ "type": "object",
271
+ "additionalProperties": {}
272
+ },
273
+ "urls": {
274
+ "type": "object",
275
+ "additionalProperties": {
276
+ "type": "string"
277
+ }
278
+ }
279
+ },
280
+ "required": [
281
+ "name",
282
+ "adapters",
283
+ "config",
284
+ "urls"
285
+ ]
286
+ }
287
+ },
288
+ "text/html": {
289
+ "schema": {
290
+ "type": "string",
291
+ "example": "<!DOCTYPE html>"
292
+ }
293
+ }
294
+ }
295
+ }
296
+ }
297
+ }
298
+ },
299
+ "/health": {
300
+ "get": {
301
+ "summary": "Health check",
302
+ "responses": {
303
+ "200": {
304
+ "description": "Health check status"
305
+ }
306
+ }
307
+ }
308
+ },
309
+ "/_/{projectId}/{buildId}/{filepath{.+}}": {
310
+ "get": {
311
+ "summary": "Serve build files",
312
+ "parameters": [
313
+ {
314
+ "schema": {
315
+ "type": "string"
316
+ },
317
+ "required": true,
318
+ "name": "projectId",
319
+ "in": "path"
320
+ },
321
+ {
322
+ "schema": {
323
+ "type": "string"
324
+ },
325
+ "required": true,
326
+ "name": "buildId",
327
+ "in": "path"
328
+ },
329
+ {
330
+ "schema": {
331
+ "type": "string"
332
+ },
333
+ "required": true,
334
+ "name": "filepath",
335
+ "in": "path"
336
+ },
337
+ {
338
+ "schema": {
339
+ "type": "string"
340
+ },
341
+ "required": false,
342
+ "name": "id",
343
+ "in": "query"
344
+ },
345
+ {
346
+ "schema": {
347
+ "type": "string"
348
+ },
349
+ "required": false,
350
+ "name": "path",
351
+ "in": "query"
352
+ },
353
+ {
354
+ "schema": {
355
+ "type": "string",
356
+ "enum": [
357
+ "story"
358
+ ]
359
+ },
360
+ "required": false,
361
+ "name": "viewMode",
362
+ "in": "query"
363
+ }
364
+ ],
365
+ "responses": {
366
+ "200": {
367
+ "description": "Serving the uploaded file",
368
+ "content": {
369
+ "*/*": {
370
+ "schema": {
371
+ "type": "string"
372
+ }
373
+ }
374
+ }
375
+ }
376
+ }
377
+ }
378
+ },
379
+ "/projects": {
380
+ "get": {
381
+ "summary": "List projects",
382
+ "tags": [
383
+ "Projects"
384
+ ],
385
+ "responses": {
386
+ "200": {
387
+ "description": "A list of projects.",
388
+ "content": {
389
+ "application/json": {
390
+ "schema": {
391
+ "type": "object",
392
+ "properties": {
393
+ "projects": {
394
+ "type": "array",
395
+ "items": {
396
+ "$ref": "#/components/schemas/Project"
397
+ }
398
+ }
399
+ },
400
+ "required": [
401
+ "projects"
402
+ ]
403
+ }
404
+ },
405
+ "text/html": {
406
+ "schema": {
407
+ "type": "string",
408
+ "example": "<!DOCTYPE html>"
409
+ }
410
+ }
411
+ }
412
+ },
413
+ "400": {
414
+ "description": "Invalid request data",
415
+ "content": {
416
+ "application/json": {
417
+ "schema": {
418
+ "$ref": "#/components/schemas/ResponseError"
419
+ }
420
+ }
421
+ }
422
+ },
423
+ "401": {
424
+ "description": "Unauthenticated access",
425
+ "content": {
426
+ "application/json": {
427
+ "schema": {
428
+ "$ref": "#/components/schemas/ResponseError"
429
+ }
430
+ }
431
+ }
432
+ },
433
+ "403": {
434
+ "description": "Unauthorised access",
435
+ "content": {
436
+ "application/json": {
437
+ "schema": {
438
+ "$ref": "#/components/schemas/ResponseError"
439
+ }
440
+ }
441
+ }
442
+ },
443
+ "500": {
444
+ "description": "An unexpected server-error occurred.",
445
+ "content": {
446
+ "application/json": {
447
+ "schema": {
448
+ "$ref": "#/components/schemas/ResponseError"
449
+ }
450
+ }
451
+ }
452
+ }
453
+ }
454
+ }
455
+ },
456
+ "/projects/create": {
457
+ "get": {
458
+ "summary": "Create project - UI",
459
+ "tags": [
460
+ "Projects"
461
+ ],
462
+ "responses": {
463
+ "200": {
464
+ "description": "UI to create project",
465
+ "content": {
466
+ "text/html": {
467
+ "schema": {
468
+ "type": "string",
469
+ "example": "<!DOCTYPE html>"
470
+ }
471
+ }
472
+ }
473
+ },
474
+ "400": {
475
+ "description": "Invalid request data",
476
+ "content": {
477
+ "application/json": {
478
+ "schema": {
479
+ "$ref": "#/components/schemas/ResponseError"
480
+ }
481
+ }
482
+ }
483
+ },
484
+ "401": {
485
+ "description": "Unauthenticated access",
486
+ "content": {
487
+ "application/json": {
488
+ "schema": {
489
+ "$ref": "#/components/schemas/ResponseError"
490
+ }
491
+ }
492
+ }
493
+ },
494
+ "403": {
495
+ "description": "Unauthorised access",
496
+ "content": {
497
+ "application/json": {
498
+ "schema": {
499
+ "$ref": "#/components/schemas/ResponseError"
500
+ }
501
+ }
502
+ }
503
+ },
504
+ "500": {
505
+ "description": "An unexpected server-error occurred.",
506
+ "content": {
507
+ "application/json": {
508
+ "schema": {
509
+ "$ref": "#/components/schemas/ResponseError"
510
+ }
511
+ }
512
+ }
513
+ }
514
+ }
515
+ },
516
+ "post": {
517
+ "summary": "Create project - action",
518
+ "tags": [
519
+ "Projects"
520
+ ],
521
+ "requestBody": {
522
+ "required": true,
523
+ "content": {
524
+ "application/x-www-form-urlencoded": {
525
+ "schema": {
526
+ "type": "object",
527
+ "properties": {
528
+ "gitHubDefaultBranch": {
529
+ "type": "string",
530
+ "default": "main",
531
+ "description": "Default branch to use for GitHub repository"
532
+ },
533
+ "gitHubPath": {
534
+ "type": "string",
535
+ "description": "Path to the storybook project with respect to repository root."
536
+ },
537
+ "gitHubRepository": {
538
+ "type": "string",
539
+ "minLength": 1
540
+ },
541
+ "id": {
542
+ "$ref": "#/components/schemas/ProjectID"
543
+ },
544
+ "jiraDomain": {
545
+ "anyOf": [
546
+ {
547
+ "type": "string",
548
+ "format": "uri"
549
+ },
550
+ {
551
+ "type": "string",
552
+ "enum": [
553
+ ""
554
+ ]
555
+ }
556
+ ]
557
+ },
558
+ "name": {
559
+ "type": "string",
560
+ "description": "Name of the project."
561
+ },
562
+ "purgeBuildsAfterDays": {
563
+ "type": "number",
564
+ "minimum": 1,
565
+ "default": 30,
566
+ "description": "Days after which the builds in the project should be purged."
567
+ }
568
+ },
569
+ "required": [
570
+ "gitHubRepository",
571
+ "id",
572
+ "name"
573
+ ]
574
+ }
575
+ }
576
+ }
577
+ },
578
+ "responses": {
579
+ "201": {
580
+ "description": "Project created successfully",
581
+ "content": {
582
+ "application/json": {
583
+ "schema": {
584
+ "type": "object",
585
+ "properties": {
586
+ "project": {
587
+ "$ref": "#/components/schemas/Project"
588
+ }
589
+ },
590
+ "required": [
591
+ "project"
592
+ ]
593
+ }
594
+ }
595
+ }
596
+ },
597
+ "303": {
598
+ "description": "Redirect to project.",
599
+ "headers": {
600
+ "location": {
601
+ "description": "Location/URL to redirect.",
602
+ "schema": {
603
+ "type": "string"
604
+ },
605
+ "required": true
606
+ },
607
+ "hx-location": {
608
+ "description": "Location/URL to redirect using HTMX.",
609
+ "schema": {
610
+ "type": "string"
611
+ },
612
+ "required": false
613
+ }
614
+ }
615
+ },
616
+ "400": {
617
+ "description": "Invalid request data",
618
+ "content": {
619
+ "application/json": {
620
+ "schema": {
621
+ "$ref": "#/components/schemas/ResponseError"
622
+ }
623
+ }
624
+ }
625
+ },
626
+ "401": {
627
+ "description": "Unauthenticated access",
628
+ "content": {
629
+ "application/json": {
630
+ "schema": {
631
+ "$ref": "#/components/schemas/ResponseError"
632
+ }
633
+ }
634
+ }
635
+ },
636
+ "403": {
637
+ "description": "Unauthorised access",
638
+ "content": {
639
+ "application/json": {
640
+ "schema": {
641
+ "$ref": "#/components/schemas/ResponseError"
642
+ }
643
+ }
644
+ }
645
+ },
646
+ "409": {
647
+ "description": "Project already exists.",
648
+ "content": {
649
+ "application/json": {
650
+ "schema": {
651
+ "$ref": "#/components/schemas/ResponseError"
652
+ }
653
+ }
654
+ }
655
+ },
656
+ "415": {
657
+ "description": "Unsupported Media Type",
658
+ "content": {
659
+ "application/json": {
660
+ "schema": {
661
+ "$ref": "#/components/schemas/ResponseError"
662
+ }
663
+ }
664
+ }
665
+ },
666
+ "500": {
667
+ "description": "An unexpected server-error occurred.",
668
+ "content": {
669
+ "application/json": {
670
+ "schema": {
671
+ "$ref": "#/components/schemas/ResponseError"
672
+ }
673
+ }
674
+ }
675
+ }
676
+ }
677
+ }
678
+ },
679
+ "/projects/{projectId}": {
680
+ "get": {
681
+ "summary": "Project details",
682
+ "tags": [
683
+ "Projects"
684
+ ],
685
+ "parameters": [
686
+ {
687
+ "schema": {
688
+ "$ref": "#/components/schemas/ProjectID"
689
+ },
690
+ "required": true,
691
+ "description": "The ID of the project.",
692
+ "name": "projectId",
693
+ "in": "path"
694
+ }
695
+ ],
696
+ "responses": {
697
+ "200": {
698
+ "description": "Details of the project",
699
+ "content": {
700
+ "application/json": {
701
+ "schema": {
702
+ "type": "object",
703
+ "properties": {
704
+ "project": {
705
+ "$ref": "#/components/schemas/Project"
706
+ }
707
+ },
708
+ "required": [
709
+ "project"
710
+ ]
711
+ }
712
+ },
713
+ "text/html": {
714
+ "schema": {
715
+ "type": "string",
716
+ "example": "<!DOCTYPE html>"
717
+ }
718
+ }
719
+ }
720
+ },
721
+ "400": {
722
+ "description": "Invalid request data",
723
+ "content": {
724
+ "application/json": {
725
+ "schema": {
726
+ "$ref": "#/components/schemas/ResponseError"
727
+ }
728
+ }
729
+ }
730
+ },
731
+ "401": {
732
+ "description": "Unauthenticated access",
733
+ "content": {
734
+ "application/json": {
735
+ "schema": {
736
+ "$ref": "#/components/schemas/ResponseError"
737
+ }
738
+ }
739
+ }
740
+ },
741
+ "403": {
742
+ "description": "Unauthorised access",
743
+ "content": {
744
+ "application/json": {
745
+ "schema": {
746
+ "$ref": "#/components/schemas/ResponseError"
747
+ }
748
+ }
749
+ }
750
+ },
751
+ "404": {
752
+ "description": "Matching project not found.",
753
+ "content": {
754
+ "application/json": {
755
+ "schema": {
756
+ "$ref": "#/components/schemas/ResponseError"
757
+ }
758
+ }
759
+ }
760
+ },
761
+ "500": {
762
+ "description": "An unexpected server-error occurred.",
763
+ "content": {
764
+ "application/json": {
765
+ "schema": {
766
+ "$ref": "#/components/schemas/ResponseError"
767
+ }
768
+ }
769
+ }
770
+ }
771
+ }
772
+ }
773
+ },
774
+ "/projects/{projectId}/delete": {
775
+ "post": {
776
+ "summary": "Delete project - action",
777
+ "tags": [
778
+ "Projects"
779
+ ],
780
+ "parameters": [
781
+ {
782
+ "schema": {
783
+ "$ref": "#/components/schemas/ProjectID"
784
+ },
785
+ "required": true,
786
+ "description": "The ID of the project.",
787
+ "name": "projectId",
788
+ "in": "path"
789
+ }
790
+ ],
791
+ "responses": {
792
+ "204": {
793
+ "description": "Project deleted successfully."
794
+ },
795
+ "303": {
796
+ "description": "Redirect to projects list.",
797
+ "headers": {
798
+ "location": {
799
+ "description": "Location/URL to redirect.",
800
+ "schema": {
801
+ "type": "string"
802
+ },
803
+ "required": true
804
+ },
805
+ "hx-location": {
806
+ "description": "Location/URL to redirect using HTMX.",
807
+ "schema": {
808
+ "type": "string"
809
+ },
810
+ "required": false
811
+ }
812
+ }
813
+ },
814
+ "400": {
815
+ "description": "Invalid request data",
816
+ "content": {
817
+ "application/json": {
818
+ "schema": {
819
+ "$ref": "#/components/schemas/ResponseError"
820
+ }
821
+ }
822
+ }
823
+ },
824
+ "401": {
825
+ "description": "Unauthenticated access",
826
+ "content": {
827
+ "application/json": {
828
+ "schema": {
829
+ "$ref": "#/components/schemas/ResponseError"
830
+ }
831
+ }
832
+ }
833
+ },
834
+ "403": {
835
+ "description": "Unauthorised access",
836
+ "content": {
837
+ "application/json": {
838
+ "schema": {
839
+ "$ref": "#/components/schemas/ResponseError"
840
+ }
841
+ }
842
+ }
843
+ },
844
+ "404": {
845
+ "description": "Matching project not found.",
846
+ "content": {
847
+ "application/json": {
848
+ "schema": {
849
+ "$ref": "#/components/schemas/ResponseError"
850
+ }
851
+ }
852
+ }
853
+ },
854
+ "500": {
855
+ "description": "An unexpected server-error occurred.",
856
+ "content": {
857
+ "application/json": {
858
+ "schema": {
859
+ "$ref": "#/components/schemas/ResponseError"
860
+ }
861
+ }
862
+ }
863
+ }
864
+ }
865
+ }
866
+ },
867
+ "/projects/{projectId}/update": {
868
+ "get": {
869
+ "summary": "Update project - UI",
870
+ "tags": [
871
+ "Projects"
872
+ ],
873
+ "parameters": [
874
+ {
875
+ "schema": {
876
+ "$ref": "#/components/schemas/ProjectID"
877
+ },
878
+ "required": true,
879
+ "description": "The ID of the project.",
880
+ "name": "projectId",
881
+ "in": "path"
882
+ }
883
+ ],
884
+ "responses": {
885
+ "200": {
886
+ "description": "UI to update project",
887
+ "content": {
888
+ "text/html": {
889
+ "schema": {
890
+ "type": "string",
891
+ "example": "<!DOCTYPE html>"
892
+ }
893
+ }
894
+ }
895
+ },
896
+ "400": {
897
+ "description": "Invalid request data",
898
+ "content": {
899
+ "application/json": {
900
+ "schema": {
901
+ "$ref": "#/components/schemas/ResponseError"
902
+ }
903
+ }
904
+ }
905
+ },
906
+ "401": {
907
+ "description": "Unauthenticated access",
908
+ "content": {
909
+ "application/json": {
910
+ "schema": {
911
+ "$ref": "#/components/schemas/ResponseError"
912
+ }
913
+ }
914
+ }
915
+ },
916
+ "403": {
917
+ "description": "Unauthorised access",
918
+ "content": {
919
+ "application/json": {
920
+ "schema": {
921
+ "$ref": "#/components/schemas/ResponseError"
922
+ }
923
+ }
924
+ }
925
+ },
926
+ "404": {
927
+ "description": "Matching project not found.",
928
+ "content": {
929
+ "application/json": {
930
+ "schema": {
931
+ "$ref": "#/components/schemas/ResponseError"
932
+ }
933
+ }
934
+ }
935
+ },
936
+ "500": {
937
+ "description": "An unexpected server-error occurred.",
938
+ "content": {
939
+ "application/json": {
940
+ "schema": {
941
+ "$ref": "#/components/schemas/ResponseError"
942
+ }
943
+ }
944
+ }
945
+ }
946
+ }
947
+ },
948
+ "post": {
949
+ "summary": "Update project - action",
950
+ "tags": [
951
+ "Projects"
952
+ ],
953
+ "parameters": [
954
+ {
955
+ "schema": {
956
+ "$ref": "#/components/schemas/ProjectID"
957
+ },
958
+ "required": true,
959
+ "description": "The ID of the project.",
960
+ "name": "projectId",
961
+ "in": "path"
962
+ }
963
+ ],
964
+ "requestBody": {
965
+ "required": true,
966
+ "content": {
967
+ "application/x-www-form-urlencoded": {
968
+ "schema": {
969
+ "type": "object",
970
+ "properties": {
971
+ "gitHubPath": {
972
+ "type": "string",
973
+ "description": "Path to the storybook project with respect to repository root."
974
+ },
975
+ "gitHubRepository": {
976
+ "type": "string",
977
+ "minLength": 1
978
+ },
979
+ "jiraDomain": {
980
+ "anyOf": [
981
+ {
982
+ "type": "string",
983
+ "format": "uri"
984
+ },
985
+ {
986
+ "type": "string",
987
+ "enum": [
988
+ ""
989
+ ]
990
+ }
991
+ ]
992
+ },
993
+ "latestBuildId": {
994
+ "anyOf": [
995
+ {
996
+ "$ref": "#/components/schemas/BuildID"
997
+ },
998
+ {
999
+ "type": "string",
1000
+ "enum": [
1001
+ ""
1002
+ ]
1003
+ }
1004
+ ]
1005
+ },
1006
+ "name": {
1007
+ "type": "string",
1008
+ "description": "Name of the project."
1009
+ },
1010
+ "purgeBuildsAfterDays": {
1011
+ "type": "number",
1012
+ "minimum": 1,
1013
+ "default": 30,
1014
+ "description": "Days after which the builds in the project should be purged."
1015
+ },
1016
+ "gitHubDefaultBranch": {
1017
+ "type": "string"
1018
+ }
1019
+ }
1020
+ }
1021
+ }
1022
+ }
1023
+ },
1024
+ "responses": {
1025
+ "202": {
1026
+ "description": "Project updated successfully"
1027
+ },
1028
+ "303": {
1029
+ "description": "Redirect to project.",
1030
+ "headers": {
1031
+ "location": {
1032
+ "description": "Location/URL to redirect.",
1033
+ "schema": {
1034
+ "type": "string"
1035
+ },
1036
+ "required": true
1037
+ },
1038
+ "hx-location": {
1039
+ "description": "Location/URL to redirect using HTMX.",
1040
+ "schema": {
1041
+ "type": "string"
1042
+ },
1043
+ "required": false
1044
+ }
1045
+ }
1046
+ },
1047
+ "400": {
1048
+ "description": "Invalid request data",
1049
+ "content": {
1050
+ "application/json": {
1051
+ "schema": {
1052
+ "$ref": "#/components/schemas/ResponseError"
1053
+ }
1054
+ }
1055
+ }
1056
+ },
1057
+ "401": {
1058
+ "description": "Unauthenticated access",
1059
+ "content": {
1060
+ "application/json": {
1061
+ "schema": {
1062
+ "$ref": "#/components/schemas/ResponseError"
1063
+ }
1064
+ }
1065
+ }
1066
+ },
1067
+ "403": {
1068
+ "description": "Unauthorised access",
1069
+ "content": {
1070
+ "application/json": {
1071
+ "schema": {
1072
+ "$ref": "#/components/schemas/ResponseError"
1073
+ }
1074
+ }
1075
+ }
1076
+ },
1077
+ "404": {
1078
+ "description": "Matching project not found.",
1079
+ "content": {
1080
+ "application/json": {
1081
+ "schema": {
1082
+ "$ref": "#/components/schemas/ResponseError"
1083
+ }
1084
+ }
1085
+ }
1086
+ },
1087
+ "415": {
1088
+ "description": "Unsupported Media Type",
1089
+ "content": {
1090
+ "application/json": {
1091
+ "schema": {
1092
+ "$ref": "#/components/schemas/ResponseError"
1093
+ }
1094
+ }
1095
+ }
1096
+ },
1097
+ "500": {
1098
+ "description": "An unexpected server-error occurred.",
1099
+ "content": {
1100
+ "application/json": {
1101
+ "schema": {
1102
+ "$ref": "#/components/schemas/ResponseError"
1103
+ }
1104
+ }
1105
+ }
1106
+ }
1107
+ }
1108
+ }
1109
+ },
1110
+ "/projects/{projectId}/builds": {
1111
+ "get": {
1112
+ "summary": "List builds",
1113
+ "tags": [
1114
+ "Builds"
1115
+ ],
1116
+ "parameters": [
1117
+ {
1118
+ "schema": {
1119
+ "$ref": "#/components/schemas/ProjectID"
1120
+ },
1121
+ "required": true,
1122
+ "description": "The ID of the project.",
1123
+ "name": "projectId",
1124
+ "in": "path"
1125
+ }
1126
+ ],
1127
+ "responses": {
1128
+ "200": {
1129
+ "description": "A list of builds in the project.",
1130
+ "content": {
1131
+ "application/json": {
1132
+ "schema": {
1133
+ "type": "object",
1134
+ "properties": {
1135
+ "builds": {
1136
+ "type": "array",
1137
+ "items": {
1138
+ "$ref": "#/components/schemas/Build"
1139
+ }
1140
+ }
1141
+ },
1142
+ "required": [
1143
+ "builds"
1144
+ ]
1145
+ }
1146
+ },
1147
+ "text/html": {
1148
+ "schema": {
1149
+ "type": "string",
1150
+ "example": "<!DOCTYPE html>"
1151
+ }
1152
+ }
1153
+ }
1154
+ },
1155
+ "400": {
1156
+ "description": "Invalid request data",
1157
+ "content": {
1158
+ "application/json": {
1159
+ "schema": {
1160
+ "$ref": "#/components/schemas/ResponseError"
1161
+ }
1162
+ }
1163
+ }
1164
+ },
1165
+ "401": {
1166
+ "description": "Unauthenticated access",
1167
+ "content": {
1168
+ "application/json": {
1169
+ "schema": {
1170
+ "$ref": "#/components/schemas/ResponseError"
1171
+ }
1172
+ }
1173
+ }
1174
+ },
1175
+ "403": {
1176
+ "description": "Unauthorised access",
1177
+ "content": {
1178
+ "application/json": {
1179
+ "schema": {
1180
+ "$ref": "#/components/schemas/ResponseError"
1181
+ }
1182
+ }
1183
+ }
1184
+ },
1185
+ "500": {
1186
+ "description": "An unexpected server-error occurred.",
1187
+ "content": {
1188
+ "application/json": {
1189
+ "schema": {
1190
+ "$ref": "#/components/schemas/ResponseError"
1191
+ }
1192
+ }
1193
+ }
1194
+ }
1195
+ }
1196
+ }
1197
+ },
1198
+ "/projects/{projectId}/builds/create": {
1199
+ "get": {
1200
+ "summary": "Create build - UI",
1201
+ "tags": [
1202
+ "Builds"
1203
+ ],
1204
+ "parameters": [
1205
+ {
1206
+ "schema": {
1207
+ "$ref": "#/components/schemas/ProjectID"
1208
+ },
1209
+ "required": true,
1210
+ "description": "The ID of the project.",
1211
+ "name": "projectId",
1212
+ "in": "path"
1213
+ },
1214
+ {
1215
+ "schema": {
1216
+ "type": "string"
1217
+ },
1218
+ "required": false,
1219
+ "name": "tagId",
1220
+ "in": "query"
1221
+ }
1222
+ ],
1223
+ "responses": {
1224
+ "200": {
1225
+ "description": "UI to create build",
1226
+ "content": {
1227
+ "text/html": {
1228
+ "schema": {
1229
+ "type": "string",
1230
+ "example": "<!DOCTYPE html>"
1231
+ }
1232
+ }
1233
+ }
1234
+ },
1235
+ "400": {
1236
+ "description": "Invalid request data",
1237
+ "content": {
1238
+ "application/json": {
1239
+ "schema": {
1240
+ "$ref": "#/components/schemas/ResponseError"
1241
+ }
1242
+ }
1243
+ }
1244
+ },
1245
+ "401": {
1246
+ "description": "Unauthenticated access",
1247
+ "content": {
1248
+ "application/json": {
1249
+ "schema": {
1250
+ "$ref": "#/components/schemas/ResponseError"
1251
+ }
1252
+ }
1253
+ }
1254
+ },
1255
+ "403": {
1256
+ "description": "Unauthorised access",
1257
+ "content": {
1258
+ "application/json": {
1259
+ "schema": {
1260
+ "$ref": "#/components/schemas/ResponseError"
1261
+ }
1262
+ }
1263
+ }
1264
+ },
1265
+ "500": {
1266
+ "description": "An unexpected server-error occurred.",
1267
+ "content": {
1268
+ "application/json": {
1269
+ "schema": {
1270
+ "$ref": "#/components/schemas/ResponseError"
1271
+ }
1272
+ }
1273
+ }
1274
+ }
1275
+ }
1276
+ },
1277
+ "post": {
1278
+ "summary": "Create build - action",
1279
+ "tags": [
1280
+ "Builds"
1281
+ ],
1282
+ "parameters": [
1283
+ {
1284
+ "schema": {
1285
+ "$ref": "#/components/schemas/ProjectID"
1286
+ },
1287
+ "required": true,
1288
+ "description": "The ID of the project.",
1289
+ "name": "projectId",
1290
+ "in": "path"
1291
+ }
1292
+ ],
1293
+ "requestBody": {
1294
+ "required": true,
1295
+ "content": {
1296
+ "application/x-www-form-urlencoded": {
1297
+ "schema": {
1298
+ "type": "object",
1299
+ "properties": {
1300
+ "authorEmail": {
1301
+ "type": "string",
1302
+ "description": "Email of the author"
1303
+ },
1304
+ "authorName": {
1305
+ "type": "string"
1306
+ },
1307
+ "id": {
1308
+ "$ref": "#/components/schemas/BuildID"
1309
+ },
1310
+ "message": {
1311
+ "type": "string"
1312
+ },
1313
+ "tags": {
1314
+ "anyOf": [
1315
+ {
1316
+ "type": "array",
1317
+ "items": {
1318
+ "$ref": "#/components/schemas/TagID"
1319
+ }
1320
+ },
1321
+ {
1322
+ "$ref": "#/components/schemas/TagID"
1323
+ }
1324
+ ],
1325
+ "description": "Tag IDs associated with the build. Should be created beforehand."
1326
+ }
1327
+ },
1328
+ "required": [
1329
+ "authorEmail",
1330
+ "authorName",
1331
+ "id",
1332
+ "tags"
1333
+ ]
1334
+ }
1335
+ }
1336
+ }
1337
+ },
1338
+ "responses": {
1339
+ "201": {
1340
+ "description": "Build created successfully",
1341
+ "content": {
1342
+ "application/json": {
1343
+ "schema": {
1344
+ "type": "object",
1345
+ "properties": {
1346
+ "build": {
1347
+ "$ref": "#/components/schemas/Build"
1348
+ },
1349
+ "url": {
1350
+ "type": "string",
1351
+ "format": "uri"
1352
+ }
1353
+ },
1354
+ "required": [
1355
+ "build",
1356
+ "url"
1357
+ ]
1358
+ }
1359
+ }
1360
+ }
1361
+ },
1362
+ "303": {
1363
+ "description": "Redirect to build.",
1364
+ "headers": {
1365
+ "location": {
1366
+ "description": "Location/URL to redirect.",
1367
+ "schema": {
1368
+ "type": "string"
1369
+ },
1370
+ "required": true
1371
+ },
1372
+ "hx-location": {
1373
+ "description": "Location/URL to redirect using HTMX.",
1374
+ "schema": {
1375
+ "type": "string"
1376
+ },
1377
+ "required": false
1378
+ }
1379
+ }
1380
+ },
1381
+ "400": {
1382
+ "description": "Invalid request data",
1383
+ "content": {
1384
+ "application/json": {
1385
+ "schema": {
1386
+ "$ref": "#/components/schemas/ResponseError"
1387
+ }
1388
+ }
1389
+ }
1390
+ },
1391
+ "401": {
1392
+ "description": "Unauthenticated access",
1393
+ "content": {
1394
+ "application/json": {
1395
+ "schema": {
1396
+ "$ref": "#/components/schemas/ResponseError"
1397
+ }
1398
+ }
1399
+ }
1400
+ },
1401
+ "403": {
1402
+ "description": "Unauthorised access",
1403
+ "content": {
1404
+ "application/json": {
1405
+ "schema": {
1406
+ "$ref": "#/components/schemas/ResponseError"
1407
+ }
1408
+ }
1409
+ }
1410
+ },
1411
+ "409": {
1412
+ "description": "Build already exists.",
1413
+ "content": {
1414
+ "application/json": {
1415
+ "schema": {
1416
+ "$ref": "#/components/schemas/ResponseError"
1417
+ }
1418
+ }
1419
+ }
1420
+ },
1421
+ "415": {
1422
+ "description": "Unsupported Media Type",
1423
+ "content": {
1424
+ "application/json": {
1425
+ "schema": {
1426
+ "$ref": "#/components/schemas/ResponseError"
1427
+ }
1428
+ }
1429
+ }
1430
+ },
1431
+ "500": {
1432
+ "description": "An unexpected server-error occurred.",
1433
+ "content": {
1434
+ "application/json": {
1435
+ "schema": {
1436
+ "$ref": "#/components/schemas/ResponseError"
1437
+ }
1438
+ }
1439
+ }
1440
+ }
1441
+ }
1442
+ }
1443
+ },
1444
+ "/projects/{projectId}/builds/{buildId}": {
1445
+ "get": {
1446
+ "summary": "Build details",
1447
+ "tags": [
1448
+ "Builds"
1449
+ ],
1450
+ "parameters": [
1451
+ {
1452
+ "schema": {
1453
+ "$ref": "#/components/schemas/ProjectID"
1454
+ },
1455
+ "required": true,
1456
+ "description": "The ID of the project.",
1457
+ "name": "projectId",
1458
+ "in": "path"
1459
+ },
1460
+ {
1461
+ "schema": {
1462
+ "$ref": "#/components/schemas/BuildID"
1463
+ },
1464
+ "required": true,
1465
+ "description": "The ID of the build.",
1466
+ "name": "buildId",
1467
+ "in": "path"
1468
+ }
1469
+ ],
1470
+ "responses": {
1471
+ "200": {
1472
+ "description": "Details of the build",
1473
+ "content": {
1474
+ "application/json": {
1475
+ "schema": {
1476
+ "type": "object",
1477
+ "properties": {
1478
+ "build": {
1479
+ "$ref": "#/components/schemas/Build"
1480
+ },
1481
+ "url": {
1482
+ "type": "string",
1483
+ "format": "uri"
1484
+ }
1485
+ },
1486
+ "required": [
1487
+ "build",
1488
+ "url"
1489
+ ]
1490
+ }
1491
+ },
1492
+ "text/html": {
1493
+ "schema": {
1494
+ "type": "string",
1495
+ "example": "<!DOCTYPE html>"
1496
+ }
1497
+ }
1498
+ }
1499
+ },
1500
+ "400": {
1501
+ "description": "Invalid request data",
1502
+ "content": {
1503
+ "application/json": {
1504
+ "schema": {
1505
+ "$ref": "#/components/schemas/ResponseError"
1506
+ }
1507
+ }
1508
+ }
1509
+ },
1510
+ "401": {
1511
+ "description": "Unauthenticated access",
1512
+ "content": {
1513
+ "application/json": {
1514
+ "schema": {
1515
+ "$ref": "#/components/schemas/ResponseError"
1516
+ }
1517
+ }
1518
+ }
1519
+ },
1520
+ "403": {
1521
+ "description": "Unauthorised access",
1522
+ "content": {
1523
+ "application/json": {
1524
+ "schema": {
1525
+ "$ref": "#/components/schemas/ResponseError"
1526
+ }
1527
+ }
1528
+ }
1529
+ },
1530
+ "404": {
1531
+ "description": "Matching build not found.",
1532
+ "content": {
1533
+ "application/json": {
1534
+ "schema": {
1535
+ "$ref": "#/components/schemas/ResponseError"
1536
+ }
1537
+ }
1538
+ }
1539
+ },
1540
+ "500": {
1541
+ "description": "An unexpected server-error occurred.",
1542
+ "content": {
1543
+ "application/json": {
1544
+ "schema": {
1545
+ "$ref": "#/components/schemas/ResponseError"
1546
+ }
1547
+ }
1548
+ }
1549
+ }
1550
+ }
1551
+ }
1552
+ },
1553
+ "/projects/{projectId}/builds/{buildId}/delete": {
1554
+ "post": {
1555
+ "summary": "Delete build - action",
1556
+ "tags": [
1557
+ "Builds"
1558
+ ],
1559
+ "parameters": [
1560
+ {
1561
+ "schema": {
1562
+ "$ref": "#/components/schemas/ProjectID"
1563
+ },
1564
+ "required": true,
1565
+ "description": "The ID of the project.",
1566
+ "name": "projectId",
1567
+ "in": "path"
1568
+ },
1569
+ {
1570
+ "schema": {
1571
+ "$ref": "#/components/schemas/BuildID"
1572
+ },
1573
+ "required": true,
1574
+ "description": "The ID of the build.",
1575
+ "name": "buildId",
1576
+ "in": "path"
1577
+ }
1578
+ ],
1579
+ "responses": {
1580
+ "204": {
1581
+ "description": "Build deleted successfully."
1582
+ },
1583
+ "303": {
1584
+ "description": "Redirect to builds list.",
1585
+ "headers": {
1586
+ "location": {
1587
+ "description": "Location/URL to redirect.",
1588
+ "schema": {
1589
+ "type": "string"
1590
+ },
1591
+ "required": true
1592
+ },
1593
+ "hx-location": {
1594
+ "description": "Location/URL to redirect using HTMX.",
1595
+ "schema": {
1596
+ "type": "string"
1597
+ },
1598
+ "required": false
1599
+ }
1600
+ }
1601
+ },
1602
+ "400": {
1603
+ "description": "Invalid request data",
1604
+ "content": {
1605
+ "application/json": {
1606
+ "schema": {
1607
+ "$ref": "#/components/schemas/ResponseError"
1608
+ }
1609
+ }
1610
+ }
1611
+ },
1612
+ "401": {
1613
+ "description": "Unauthenticated access",
1614
+ "content": {
1615
+ "application/json": {
1616
+ "schema": {
1617
+ "$ref": "#/components/schemas/ResponseError"
1618
+ }
1619
+ }
1620
+ }
1621
+ },
1622
+ "403": {
1623
+ "description": "Unauthorised access",
1624
+ "content": {
1625
+ "application/json": {
1626
+ "schema": {
1627
+ "$ref": "#/components/schemas/ResponseError"
1628
+ }
1629
+ }
1630
+ }
1631
+ },
1632
+ "404": {
1633
+ "description": "Matching build not found.",
1634
+ "content": {
1635
+ "application/json": {
1636
+ "schema": {
1637
+ "$ref": "#/components/schemas/ResponseError"
1638
+ }
1639
+ }
1640
+ }
1641
+ },
1642
+ "500": {
1643
+ "description": "An unexpected server-error occurred.",
1644
+ "content": {
1645
+ "application/json": {
1646
+ "schema": {
1647
+ "$ref": "#/components/schemas/ResponseError"
1648
+ }
1649
+ }
1650
+ }
1651
+ }
1652
+ }
1653
+ }
1654
+ },
1655
+ "/projects/{projectId}/builds/{buildId}/update": {
1656
+ "post": {
1657
+ "summary": "Update build - action",
1658
+ "tags": [
1659
+ "Builds"
1660
+ ],
1661
+ "parameters": [
1662
+ {
1663
+ "schema": {
1664
+ "$ref": "#/components/schemas/ProjectID"
1665
+ },
1666
+ "required": true,
1667
+ "description": "The ID of the project.",
1668
+ "name": "projectId",
1669
+ "in": "path"
1670
+ },
1671
+ {
1672
+ "schema": {
1673
+ "$ref": "#/components/schemas/BuildID"
1674
+ },
1675
+ "required": true,
1676
+ "description": "The ID of the build.",
1677
+ "name": "buildId",
1678
+ "in": "path"
1679
+ }
1680
+ ],
1681
+ "requestBody": {
1682
+ "required": true,
1683
+ "content": {
1684
+ "application/x-www-form-urlencoded": {
1685
+ "schema": {
1686
+ "type": "object",
1687
+ "properties": {
1688
+ "authorEmail": {
1689
+ "type": "string",
1690
+ "description": "Email of the author"
1691
+ },
1692
+ "authorName": {
1693
+ "type": "string"
1694
+ },
1695
+ "tagIds": {
1696
+ "type": "string"
1697
+ },
1698
+ "message": {
1699
+ "type": "string"
1700
+ },
1701
+ "coverage": {
1702
+ "type": "string",
1703
+ "enum": [
1704
+ "none",
1705
+ "uploaded",
1706
+ "processing",
1707
+ "ready"
1708
+ ]
1709
+ },
1710
+ "screenshots": {
1711
+ "type": "string",
1712
+ "enum": [
1713
+ "none",
1714
+ "uploaded",
1715
+ "processing",
1716
+ "ready"
1717
+ ]
1718
+ },
1719
+ "storybook": {
1720
+ "type": "string",
1721
+ "enum": [
1722
+ "none",
1723
+ "uploaded",
1724
+ "processing",
1725
+ "ready"
1726
+ ]
1727
+ },
1728
+ "testReport": {
1729
+ "type": "string",
1730
+ "enum": [
1731
+ "none",
1732
+ "uploaded",
1733
+ "processing",
1734
+ "ready"
1735
+ ]
1736
+ }
1737
+ }
1738
+ }
1739
+ }
1740
+ }
1741
+ },
1742
+ "responses": {
1743
+ "202": {
1744
+ "description": "Build updated successfully"
1745
+ },
1746
+ "303": {
1747
+ "description": "Redirect to build.",
1748
+ "headers": {
1749
+ "location": {
1750
+ "description": "Location/URL to redirect.",
1751
+ "schema": {
1752
+ "type": "string"
1753
+ },
1754
+ "required": true
1755
+ },
1756
+ "hx-location": {
1757
+ "description": "Location/URL to redirect using HTMX.",
1758
+ "schema": {
1759
+ "type": "string"
1760
+ },
1761
+ "required": false
1762
+ }
1763
+ }
1764
+ },
1765
+ "400": {
1766
+ "description": "Invalid request data",
1767
+ "content": {
1768
+ "application/json": {
1769
+ "schema": {
1770
+ "$ref": "#/components/schemas/ResponseError"
1771
+ }
1772
+ }
1773
+ }
1774
+ },
1775
+ "401": {
1776
+ "description": "Unauthenticated access",
1777
+ "content": {
1778
+ "application/json": {
1779
+ "schema": {
1780
+ "$ref": "#/components/schemas/ResponseError"
1781
+ }
1782
+ }
1783
+ }
1784
+ },
1785
+ "403": {
1786
+ "description": "Unauthorised access",
1787
+ "content": {
1788
+ "application/json": {
1789
+ "schema": {
1790
+ "$ref": "#/components/schemas/ResponseError"
1791
+ }
1792
+ }
1793
+ }
1794
+ },
1795
+ "404": {
1796
+ "description": "Matching project or build not found.",
1797
+ "content": {
1798
+ "application/json": {
1799
+ "schema": {
1800
+ "$ref": "#/components/schemas/ResponseError"
1801
+ }
1802
+ }
1803
+ }
1804
+ },
1805
+ "415": {
1806
+ "description": "Unsupported Media Type",
1807
+ "content": {
1808
+ "application/json": {
1809
+ "schema": {
1810
+ "$ref": "#/components/schemas/ResponseError"
1811
+ }
1812
+ }
1813
+ }
1814
+ },
1815
+ "500": {
1816
+ "description": "An unexpected server-error occurred.",
1817
+ "content": {
1818
+ "application/json": {
1819
+ "schema": {
1820
+ "$ref": "#/components/schemas/ResponseError"
1821
+ }
1822
+ }
1823
+ }
1824
+ }
1825
+ }
1826
+ }
1827
+ },
1828
+ "/projects/{projectId}/builds/{buildId}/upload": {
1829
+ "get": {
1830
+ "summary": "Upload build - UI",
1831
+ "tags": [
1832
+ "Builds"
1833
+ ],
1834
+ "parameters": [
1835
+ {
1836
+ "schema": {
1837
+ "$ref": "#/components/schemas/ProjectID"
1838
+ },
1839
+ "required": true,
1840
+ "description": "The ID of the project.",
1841
+ "name": "projectId",
1842
+ "in": "path"
1843
+ },
1844
+ {
1845
+ "schema": {
1846
+ "$ref": "#/components/schemas/BuildID"
1847
+ },
1848
+ "required": true,
1849
+ "description": "The ID of the build.",
1850
+ "name": "buildId",
1851
+ "in": "path"
1852
+ },
1853
+ {
1854
+ "schema": {
1855
+ "type": "string",
1856
+ "enum": [
1857
+ "storybook",
1858
+ "testReport",
1859
+ "coverage",
1860
+ "screenshots"
1861
+ ],
1862
+ "default": "storybook"
1863
+ },
1864
+ "required": false,
1865
+ "name": "variant",
1866
+ "in": "query"
1867
+ }
1868
+ ],
1869
+ "responses": {
1870
+ "200": {
1871
+ "description": "UI to upload build",
1872
+ "content": {
1873
+ "text/html": {
1874
+ "schema": {
1875
+ "type": "string",
1876
+ "example": "<!DOCTYPE html>"
1877
+ }
1878
+ }
1879
+ }
1880
+ },
1881
+ "400": {
1882
+ "description": "Invalid request data",
1883
+ "content": {
1884
+ "application/json": {
1885
+ "schema": {
1886
+ "$ref": "#/components/schemas/ResponseError"
1887
+ }
1888
+ }
1889
+ }
1890
+ },
1891
+ "401": {
1892
+ "description": "Unauthenticated access",
1893
+ "content": {
1894
+ "application/json": {
1895
+ "schema": {
1896
+ "$ref": "#/components/schemas/ResponseError"
1897
+ }
1898
+ }
1899
+ }
1900
+ },
1901
+ "403": {
1902
+ "description": "Unauthorised access",
1903
+ "content": {
1904
+ "application/json": {
1905
+ "schema": {
1906
+ "$ref": "#/components/schemas/ResponseError"
1907
+ }
1908
+ }
1909
+ }
1910
+ },
1911
+ "404": {
1912
+ "description": "Matching build not found.",
1913
+ "content": {
1914
+ "application/json": {
1915
+ "schema": {
1916
+ "$ref": "#/components/schemas/ResponseError"
1917
+ }
1918
+ }
1919
+ }
1920
+ },
1921
+ "500": {
1922
+ "description": "An unexpected server-error occurred.",
1923
+ "content": {
1924
+ "application/json": {
1925
+ "schema": {
1926
+ "$ref": "#/components/schemas/ResponseError"
1927
+ }
1928
+ }
1929
+ }
1930
+ }
1931
+ }
1932
+ },
1933
+ "post": {
1934
+ "summary": "Upload build - action",
1935
+ "tags": [
1936
+ "Builds"
1937
+ ],
1938
+ "parameters": [
1939
+ {
1940
+ "schema": {
1941
+ "$ref": "#/components/schemas/ProjectID"
1942
+ },
1943
+ "required": true,
1944
+ "description": "The ID of the project.",
1945
+ "name": "projectId",
1946
+ "in": "path"
1947
+ },
1948
+ {
1949
+ "schema": {
1950
+ "$ref": "#/components/schemas/BuildID"
1951
+ },
1952
+ "required": true,
1953
+ "description": "The ID of the build.",
1954
+ "name": "buildId",
1955
+ "in": "path"
1956
+ },
1957
+ {
1958
+ "schema": {
1959
+ "type": "string",
1960
+ "enum": [
1961
+ "storybook",
1962
+ "testReport",
1963
+ "coverage",
1964
+ "screenshots"
1965
+ ],
1966
+ "default": "storybook"
1967
+ },
1968
+ "required": false,
1969
+ "name": "variant",
1970
+ "in": "query"
1971
+ }
1972
+ ],
1973
+ "requestBody": {
1974
+ "description": "Compressed zip containing files.",
1975
+ "required": true,
1976
+ "content": {
1977
+ "multipart/form-data": {
1978
+ "schema": {
1979
+ "type": "object",
1980
+ "properties": {
1981
+ "file": {
1982
+ "type": "object"
1983
+ },
1984
+ "variant": {
1985
+ "type": "string",
1986
+ "enum": [
1987
+ "storybook",
1988
+ "testReport",
1989
+ "coverage",
1990
+ "screenshots"
1991
+ ],
1992
+ "default": "storybook"
1993
+ }
1994
+ },
1995
+ "required": [
1996
+ "file"
1997
+ ]
1998
+ }
1999
+ },
2000
+ "application/zip": {
2001
+ "schema": {
2002
+ "format": "binary",
2003
+ "type": "string"
2004
+ },
2005
+ "example": "storybook.zip"
2006
+ }
2007
+ }
2008
+ },
2009
+ "responses": {
2010
+ "204": {
2011
+ "description": "File uploaded successfully"
2012
+ },
2013
+ "303": {
2014
+ "description": "Redirect to project.",
2015
+ "headers": {
2016
+ "location": {
2017
+ "description": "Location/URL to redirect.",
2018
+ "schema": {
2019
+ "type": "string"
2020
+ },
2021
+ "required": true
2022
+ },
2023
+ "hx-location": {
2024
+ "description": "Location/URL to redirect using HTMX.",
2025
+ "schema": {
2026
+ "type": "string"
2027
+ },
2028
+ "required": false
2029
+ }
2030
+ }
2031
+ },
2032
+ "400": {
2033
+ "description": "Invalid request data",
2034
+ "content": {
2035
+ "application/json": {
2036
+ "schema": {
2037
+ "$ref": "#/components/schemas/ResponseError"
2038
+ }
2039
+ }
2040
+ }
2041
+ },
2042
+ "401": {
2043
+ "description": "Unauthenticated access",
2044
+ "content": {
2045
+ "application/json": {
2046
+ "schema": {
2047
+ "$ref": "#/components/schemas/ResponseError"
2048
+ }
2049
+ }
2050
+ }
2051
+ },
2052
+ "403": {
2053
+ "description": "Unauthorised access",
2054
+ "content": {
2055
+ "application/json": {
2056
+ "schema": {
2057
+ "$ref": "#/components/schemas/ResponseError"
2058
+ }
2059
+ }
2060
+ }
2061
+ },
2062
+ "404": {
2063
+ "description": "Matching project not found.",
2064
+ "content": {
2065
+ "application/json": {
2066
+ "schema": {
2067
+ "$ref": "#/components/schemas/ResponseError"
2068
+ }
2069
+ }
2070
+ }
2071
+ },
2072
+ "415": {
2073
+ "description": "Unsupported Media Type",
2074
+ "content": {
2075
+ "application/json": {
2076
+ "schema": {
2077
+ "$ref": "#/components/schemas/ResponseError"
2078
+ }
2079
+ }
2080
+ }
2081
+ },
2082
+ "500": {
2083
+ "description": "An unexpected server-error occurred.",
2084
+ "content": {
2085
+ "application/json": {
2086
+ "schema": {
2087
+ "$ref": "#/components/schemas/ResponseError"
2088
+ }
2089
+ }
2090
+ }
2091
+ }
2092
+ }
2093
+ }
2094
+ },
2095
+ "/projects/{projectId}/tags": {
2096
+ "get": {
2097
+ "summary": "List tags",
2098
+ "tags": [
2099
+ "Tags"
2100
+ ],
2101
+ "parameters": [
2102
+ {
2103
+ "schema": {
2104
+ "$ref": "#/components/schemas/ProjectID"
2105
+ },
2106
+ "required": true,
2107
+ "description": "The ID of the project.",
2108
+ "name": "projectId",
2109
+ "in": "path"
2110
+ },
2111
+ {
2112
+ "schema": {
2113
+ "anyOf": [
2114
+ {
2115
+ "type": "string",
2116
+ "enum": [
2117
+ "branch",
2118
+ "pr",
2119
+ "jira"
2120
+ ]
2121
+ },
2122
+ {
2123
+ "type": "string",
2124
+ "enum": [
2125
+ ""
2126
+ ]
2127
+ }
2128
+ ]
2129
+ },
2130
+ "required": false,
2131
+ "name": "type",
2132
+ "in": "query"
2133
+ }
2134
+ ],
2135
+ "responses": {
2136
+ "200": {
2137
+ "description": "A list of tags in the project.",
2138
+ "content": {
2139
+ "application/json": {
2140
+ "schema": {
2141
+ "type": "object",
2142
+ "properties": {
2143
+ "tags": {
2144
+ "type": "array",
2145
+ "items": {
2146
+ "$ref": "#/components/schemas/Tag"
2147
+ }
2148
+ }
2149
+ },
2150
+ "required": [
2151
+ "tags"
2152
+ ]
2153
+ }
2154
+ },
2155
+ "text/html": {
2156
+ "schema": {
2157
+ "type": "string",
2158
+ "example": "<!DOCTYPE html>"
2159
+ }
2160
+ }
2161
+ }
2162
+ },
2163
+ "400": {
2164
+ "description": "Invalid request data",
2165
+ "content": {
2166
+ "application/json": {
2167
+ "schema": {
2168
+ "$ref": "#/components/schemas/ResponseError"
2169
+ }
2170
+ }
2171
+ }
2172
+ },
2173
+ "401": {
2174
+ "description": "Unauthenticated access",
2175
+ "content": {
2176
+ "application/json": {
2177
+ "schema": {
2178
+ "$ref": "#/components/schemas/ResponseError"
2179
+ }
2180
+ }
2181
+ }
2182
+ },
2183
+ "403": {
2184
+ "description": "Unauthorised access",
2185
+ "content": {
2186
+ "application/json": {
2187
+ "schema": {
2188
+ "$ref": "#/components/schemas/ResponseError"
2189
+ }
2190
+ }
2191
+ }
2192
+ },
2193
+ "500": {
2194
+ "description": "An unexpected server-error occurred.",
2195
+ "content": {
2196
+ "application/json": {
2197
+ "schema": {
2198
+ "$ref": "#/components/schemas/ResponseError"
2199
+ }
2200
+ }
2201
+ }
2202
+ }
2203
+ }
2204
+ }
2205
+ },
2206
+ "/projects/{projectId}/tags/create": {
2207
+ "get": {
2208
+ "summary": "Create tag - UI",
2209
+ "tags": [
2210
+ "Tags"
2211
+ ],
2212
+ "parameters": [
2213
+ {
2214
+ "schema": {
2215
+ "$ref": "#/components/schemas/ProjectID"
2216
+ },
2217
+ "required": true,
2218
+ "description": "The ID of the project.",
2219
+ "name": "projectId",
2220
+ "in": "path"
2221
+ }
2222
+ ],
2223
+ "responses": {
2224
+ "200": {
2225
+ "description": "UI to create tag",
2226
+ "content": {
2227
+ "text/html": {
2228
+ "schema": {
2229
+ "type": "string",
2230
+ "example": "<!DOCTYPE html>"
2231
+ }
2232
+ }
2233
+ }
2234
+ },
2235
+ "400": {
2236
+ "description": "Invalid request data",
2237
+ "content": {
2238
+ "application/json": {
2239
+ "schema": {
2240
+ "$ref": "#/components/schemas/ResponseError"
2241
+ }
2242
+ }
2243
+ }
2244
+ },
2245
+ "401": {
2246
+ "description": "Unauthenticated access",
2247
+ "content": {
2248
+ "application/json": {
2249
+ "schema": {
2250
+ "$ref": "#/components/schemas/ResponseError"
2251
+ }
2252
+ }
2253
+ }
2254
+ },
2255
+ "403": {
2256
+ "description": "Unauthorised access",
2257
+ "content": {
2258
+ "application/json": {
2259
+ "schema": {
2260
+ "$ref": "#/components/schemas/ResponseError"
2261
+ }
2262
+ }
2263
+ }
2264
+ },
2265
+ "500": {
2266
+ "description": "An unexpected server-error occurred.",
2267
+ "content": {
2268
+ "application/json": {
2269
+ "schema": {
2270
+ "$ref": "#/components/schemas/ResponseError"
2271
+ }
2272
+ }
2273
+ }
2274
+ }
2275
+ }
2276
+ },
2277
+ "post": {
2278
+ "summary": "Create tag - action",
2279
+ "tags": [
2280
+ "Tags"
2281
+ ],
2282
+ "parameters": [
2283
+ {
2284
+ "schema": {
2285
+ "$ref": "#/components/schemas/ProjectID"
2286
+ },
2287
+ "required": true,
2288
+ "description": "The ID of the project.",
2289
+ "name": "projectId",
2290
+ "in": "path"
2291
+ }
2292
+ ],
2293
+ "requestBody": {
2294
+ "required": true,
2295
+ "content": {
2296
+ "application/x-www-form-urlencoded": {
2297
+ "schema": {
2298
+ "type": "object",
2299
+ "properties": {
2300
+ "latestBuildId": {
2301
+ "anyOf": [
2302
+ {
2303
+ "$ref": "#/components/schemas/BuildID"
2304
+ },
2305
+ {
2306
+ "type": "string",
2307
+ "enum": [
2308
+ ""
2309
+ ]
2310
+ }
2311
+ ]
2312
+ },
2313
+ "type": {
2314
+ "type": "string",
2315
+ "enum": [
2316
+ "branch",
2317
+ "pr",
2318
+ "jira"
2319
+ ]
2320
+ },
2321
+ "value": {
2322
+ "type": "string",
2323
+ "description": "The value of the tag."
2324
+ }
2325
+ },
2326
+ "required": [
2327
+ "type",
2328
+ "value"
2329
+ ]
2330
+ }
2331
+ }
2332
+ }
2333
+ },
2334
+ "responses": {
2335
+ "201": {
2336
+ "description": "Tag created successfully",
2337
+ "content": {
2338
+ "application/json": {
2339
+ "schema": {
2340
+ "type": "object",
2341
+ "properties": {
2342
+ "tag": {
2343
+ "$ref": "#/components/schemas/Tag"
2344
+ }
2345
+ },
2346
+ "required": [
2347
+ "tag"
2348
+ ]
2349
+ }
2350
+ }
2351
+ }
2352
+ },
2353
+ "303": {
2354
+ "description": "Redirect to tag.",
2355
+ "headers": {
2356
+ "location": {
2357
+ "description": "Location/URL to redirect.",
2358
+ "schema": {
2359
+ "type": "string"
2360
+ },
2361
+ "required": true
2362
+ },
2363
+ "hx-location": {
2364
+ "description": "Location/URL to redirect using HTMX.",
2365
+ "schema": {
2366
+ "type": "string"
2367
+ },
2368
+ "required": false
2369
+ }
2370
+ }
2371
+ },
2372
+ "400": {
2373
+ "description": "Invalid request data",
2374
+ "content": {
2375
+ "application/json": {
2376
+ "schema": {
2377
+ "$ref": "#/components/schemas/ResponseError"
2378
+ }
2379
+ }
2380
+ }
2381
+ },
2382
+ "401": {
2383
+ "description": "Unauthenticated access",
2384
+ "content": {
2385
+ "application/json": {
2386
+ "schema": {
2387
+ "$ref": "#/components/schemas/ResponseError"
2388
+ }
2389
+ }
2390
+ }
2391
+ },
2392
+ "403": {
2393
+ "description": "Unauthorised access",
2394
+ "content": {
2395
+ "application/json": {
2396
+ "schema": {
2397
+ "$ref": "#/components/schemas/ResponseError"
2398
+ }
2399
+ }
2400
+ }
2401
+ },
2402
+ "409": {
2403
+ "description": "Tag already exists.",
2404
+ "content": {
2405
+ "application/json": {
2406
+ "schema": {
2407
+ "$ref": "#/components/schemas/ResponseError"
2408
+ }
2409
+ }
2410
+ }
2411
+ },
2412
+ "415": {
2413
+ "description": "Unsupported Media Type",
2414
+ "content": {
2415
+ "application/json": {
2416
+ "schema": {
2417
+ "$ref": "#/components/schemas/ResponseError"
2418
+ }
2419
+ }
2420
+ }
2421
+ },
2422
+ "500": {
2423
+ "description": "An unexpected server-error occurred.",
2424
+ "content": {
2425
+ "application/json": {
2426
+ "schema": {
2427
+ "$ref": "#/components/schemas/ResponseError"
2428
+ }
2429
+ }
2430
+ }
2431
+ }
2432
+ }
2433
+ }
2434
+ },
2435
+ "/projects/{projectId}/tags/{tagId}": {
2436
+ "get": {
2437
+ "summary": "Tag details",
2438
+ "tags": [
2439
+ "Tags"
2440
+ ],
2441
+ "parameters": [
2442
+ {
2443
+ "schema": {
2444
+ "$ref": "#/components/schemas/ProjectID"
2445
+ },
2446
+ "required": true,
2447
+ "description": "The ID of the project.",
2448
+ "name": "projectId",
2449
+ "in": "path"
2450
+ },
2451
+ {
2452
+ "schema": {
2453
+ "$ref": "#/components/schemas/TagID"
2454
+ },
2455
+ "required": true,
2456
+ "description": "The ID of the tag.",
2457
+ "name": "tagId",
2458
+ "in": "path"
2459
+ }
2460
+ ],
2461
+ "responses": {
2462
+ "200": {
2463
+ "description": "Details of the tag",
2464
+ "content": {
2465
+ "application/json": {
2466
+ "schema": {
2467
+ "type": "object",
2468
+ "properties": {
2469
+ "tag": {
2470
+ "$ref": "#/components/schemas/Tag"
2471
+ }
2472
+ },
2473
+ "required": [
2474
+ "tag"
2475
+ ]
2476
+ }
2477
+ },
2478
+ "text/html": {
2479
+ "schema": {
2480
+ "type": "string",
2481
+ "example": "<!DOCTYPE html>"
2482
+ }
2483
+ }
2484
+ }
2485
+ },
2486
+ "400": {
2487
+ "description": "Invalid request data",
2488
+ "content": {
2489
+ "application/json": {
2490
+ "schema": {
2491
+ "$ref": "#/components/schemas/ResponseError"
2492
+ }
2493
+ }
2494
+ }
2495
+ },
2496
+ "401": {
2497
+ "description": "Unauthenticated access",
2498
+ "content": {
2499
+ "application/json": {
2500
+ "schema": {
2501
+ "$ref": "#/components/schemas/ResponseError"
2502
+ }
2503
+ }
2504
+ }
2505
+ },
2506
+ "403": {
2507
+ "description": "Unauthorised access",
2508
+ "content": {
2509
+ "application/json": {
2510
+ "schema": {
2511
+ "$ref": "#/components/schemas/ResponseError"
2512
+ }
2513
+ }
2514
+ }
2515
+ },
2516
+ "404": {
2517
+ "description": "Matching tag not found.",
2518
+ "content": {
2519
+ "application/json": {
2520
+ "schema": {
2521
+ "$ref": "#/components/schemas/ResponseError"
2522
+ }
2523
+ }
2524
+ }
2525
+ },
2526
+ "500": {
2527
+ "description": "An unexpected server-error occurred.",
2528
+ "content": {
2529
+ "application/json": {
2530
+ "schema": {
2531
+ "$ref": "#/components/schemas/ResponseError"
2532
+ }
2533
+ }
2534
+ }
2535
+ }
2536
+ }
2537
+ }
2538
+ },
2539
+ "/projects/{projectId}/tags/{tagId}/delete": {
2540
+ "post": {
2541
+ "summary": "Delete tag - action",
2542
+ "tags": [
2543
+ "Tags"
2544
+ ],
2545
+ "parameters": [
2546
+ {
2547
+ "schema": {
2548
+ "$ref": "#/components/schemas/ProjectID"
2549
+ },
2550
+ "required": true,
2551
+ "description": "The ID of the project.",
2552
+ "name": "projectId",
2553
+ "in": "path"
2554
+ },
2555
+ {
2556
+ "schema": {
2557
+ "$ref": "#/components/schemas/TagID"
2558
+ },
2559
+ "required": true,
2560
+ "description": "The ID of the tag.",
2561
+ "name": "tagId",
2562
+ "in": "path"
2563
+ }
2564
+ ],
2565
+ "responses": {
2566
+ "204": {
2567
+ "description": "Tag deleted successfully."
2568
+ },
2569
+ "303": {
2570
+ "description": "Redirect to tags list.",
2571
+ "headers": {
2572
+ "location": {
2573
+ "description": "Location/URL to redirect.",
2574
+ "schema": {
2575
+ "type": "string"
2576
+ },
2577
+ "required": true
2578
+ },
2579
+ "hx-location": {
2580
+ "description": "Location/URL to redirect using HTMX.",
2581
+ "schema": {
2582
+ "type": "string"
2583
+ },
2584
+ "required": false
2585
+ }
2586
+ }
2587
+ },
2588
+ "400": {
2589
+ "description": "Invalid request data",
2590
+ "content": {
2591
+ "application/json": {
2592
+ "schema": {
2593
+ "$ref": "#/components/schemas/ResponseError"
2594
+ }
2595
+ }
2596
+ }
2597
+ },
2598
+ "401": {
2599
+ "description": "Unauthenticated access",
2600
+ "content": {
2601
+ "application/json": {
2602
+ "schema": {
2603
+ "$ref": "#/components/schemas/ResponseError"
2604
+ }
2605
+ }
2606
+ }
2607
+ },
2608
+ "403": {
2609
+ "description": "Unauthorised access",
2610
+ "content": {
2611
+ "application/json": {
2612
+ "schema": {
2613
+ "$ref": "#/components/schemas/ResponseError"
2614
+ }
2615
+ }
2616
+ }
2617
+ },
2618
+ "404": {
2619
+ "description": "Matching tag not found.",
2620
+ "content": {
2621
+ "application/json": {
2622
+ "schema": {
2623
+ "$ref": "#/components/schemas/ResponseError"
2624
+ }
2625
+ }
2626
+ }
2627
+ },
2628
+ "500": {
2629
+ "description": "An unexpected server-error occurred.",
2630
+ "content": {
2631
+ "application/json": {
2632
+ "schema": {
2633
+ "$ref": "#/components/schemas/ResponseError"
2634
+ }
2635
+ }
2636
+ }
2637
+ }
2638
+ }
2639
+ }
2640
+ },
2641
+ "/projects/{projectId}/tags/{tagId}/update": {
2642
+ "get": {
2643
+ "summary": "Update tag - UI",
2644
+ "tags": [
2645
+ "Tags"
2646
+ ],
2647
+ "parameters": [
2648
+ {
2649
+ "schema": {
2650
+ "$ref": "#/components/schemas/ProjectID"
2651
+ },
2652
+ "required": true,
2653
+ "description": "The ID of the project.",
2654
+ "name": "projectId",
2655
+ "in": "path"
2656
+ },
2657
+ {
2658
+ "schema": {
2659
+ "$ref": "#/components/schemas/TagID"
2660
+ },
2661
+ "required": true,
2662
+ "description": "The ID of the tag.",
2663
+ "name": "tagId",
2664
+ "in": "path"
2665
+ }
2666
+ ],
2667
+ "responses": {
2668
+ "200": {
2669
+ "description": "UI to upload tag",
2670
+ "content": {
2671
+ "text/html": {
2672
+ "schema": {
2673
+ "type": "string",
2674
+ "example": "<!DOCTYPE html>"
2675
+ }
2676
+ }
2677
+ }
2678
+ },
2679
+ "400": {
2680
+ "description": "Invalid request data",
2681
+ "content": {
2682
+ "application/json": {
2683
+ "schema": {
2684
+ "$ref": "#/components/schemas/ResponseError"
2685
+ }
2686
+ }
2687
+ }
2688
+ },
2689
+ "401": {
2690
+ "description": "Unauthenticated access",
2691
+ "content": {
2692
+ "application/json": {
2693
+ "schema": {
2694
+ "$ref": "#/components/schemas/ResponseError"
2695
+ }
2696
+ }
2697
+ }
2698
+ },
2699
+ "403": {
2700
+ "description": "Unauthorised access",
2701
+ "content": {
2702
+ "application/json": {
2703
+ "schema": {
2704
+ "$ref": "#/components/schemas/ResponseError"
2705
+ }
2706
+ }
2707
+ }
2708
+ },
2709
+ "404": {
2710
+ "description": "Matching tag not found.",
2711
+ "content": {
2712
+ "application/json": {
2713
+ "schema": {
2714
+ "$ref": "#/components/schemas/ResponseError"
2715
+ }
2716
+ }
2717
+ }
2718
+ },
2719
+ "500": {
2720
+ "description": "An unexpected server-error occurred.",
2721
+ "content": {
2722
+ "application/json": {
2723
+ "schema": {
2724
+ "$ref": "#/components/schemas/ResponseError"
2725
+ }
2726
+ }
2727
+ }
2728
+ }
2729
+ }
2730
+ },
2731
+ "post": {
2732
+ "summary": "Update tag - action",
2733
+ "tags": [
2734
+ "Tags"
2735
+ ],
2736
+ "parameters": [
2737
+ {
2738
+ "schema": {
2739
+ "$ref": "#/components/schemas/ProjectID"
2740
+ },
2741
+ "required": true,
2742
+ "description": "The ID of the project.",
2743
+ "name": "projectId",
2744
+ "in": "path"
2745
+ },
2746
+ {
2747
+ "schema": {
2748
+ "$ref": "#/components/schemas/TagID"
2749
+ },
2750
+ "required": true,
2751
+ "description": "The ID of the tag.",
2752
+ "name": "tagId",
2753
+ "in": "path"
2754
+ }
2755
+ ],
2756
+ "requestBody": {
2757
+ "required": true,
2758
+ "content": {
2759
+ "application/x-www-form-urlencoded": {
2760
+ "schema": {
2761
+ "type": "object",
2762
+ "properties": {
2763
+ "buildsCount": {
2764
+ "type": "number",
2765
+ "default": 0
2766
+ },
2767
+ "latestBuildId": {
2768
+ "anyOf": [
2769
+ {
2770
+ "$ref": "#/components/schemas/BuildID"
2771
+ },
2772
+ {
2773
+ "type": "string",
2774
+ "enum": [
2775
+ ""
2776
+ ]
2777
+ }
2778
+ ]
2779
+ },
2780
+ "type": {
2781
+ "type": "string",
2782
+ "enum": [
2783
+ "branch",
2784
+ "pr",
2785
+ "jira"
2786
+ ]
2787
+ },
2788
+ "value": {
2789
+ "type": "string",
2790
+ "description": "The value of the tag."
2791
+ }
2792
+ }
2793
+ }
2794
+ }
2795
+ }
2796
+ },
2797
+ "responses": {
2798
+ "202": {
2799
+ "description": "Tag updated successfully"
2800
+ },
2801
+ "303": {
2802
+ "description": "Redirect to tag.",
2803
+ "headers": {
2804
+ "location": {
2805
+ "description": "Location/URL to redirect.",
2806
+ "schema": {
2807
+ "type": "string"
2808
+ },
2809
+ "required": true
2810
+ },
2811
+ "hx-location": {
2812
+ "description": "Location/URL to redirect using HTMX.",
2813
+ "schema": {
2814
+ "type": "string"
2815
+ },
2816
+ "required": false
2817
+ }
2818
+ }
2819
+ },
2820
+ "400": {
2821
+ "description": "Invalid request data",
2822
+ "content": {
2823
+ "application/json": {
2824
+ "schema": {
2825
+ "$ref": "#/components/schemas/ResponseError"
2826
+ }
2827
+ }
2828
+ }
2829
+ },
2830
+ "401": {
2831
+ "description": "Unauthenticated access",
2832
+ "content": {
2833
+ "application/json": {
2834
+ "schema": {
2835
+ "$ref": "#/components/schemas/ResponseError"
2836
+ }
2837
+ }
2838
+ }
2839
+ },
2840
+ "403": {
2841
+ "description": "Unauthorised access",
2842
+ "content": {
2843
+ "application/json": {
2844
+ "schema": {
2845
+ "$ref": "#/components/schemas/ResponseError"
2846
+ }
2847
+ }
2848
+ }
2849
+ },
2850
+ "404": {
2851
+ "description": "Matching project or tag not found.",
2852
+ "content": {
2853
+ "application/json": {
2854
+ "schema": {
2855
+ "$ref": "#/components/schemas/ResponseError"
2856
+ }
2857
+ }
2858
+ }
2859
+ },
2860
+ "415": {
2861
+ "description": "Unsupported Media Type",
2862
+ "content": {
2863
+ "application/json": {
2864
+ "schema": {
2865
+ "$ref": "#/components/schemas/ResponseError"
2866
+ }
2867
+ }
2868
+ }
2869
+ },
2870
+ "500": {
2871
+ "description": "An unexpected server-error occurred.",
2872
+ "content": {
2873
+ "application/json": {
2874
+ "schema": {
2875
+ "$ref": "#/components/schemas/ResponseError"
2876
+ }
2877
+ }
2878
+ }
2879
+ }
2880
+ }
2881
+ }
2882
+ },
2883
+ "/tasks/purge": {
2884
+ "post": {
2885
+ "summary": "Purge outdated builds",
2886
+ "tags": [
2887
+ "Tasks"
2888
+ ],
2889
+ "parameters": [
2890
+ {
2891
+ "schema": {
2892
+ "type": "string"
2893
+ },
2894
+ "required": false,
2895
+ "name": "projectId",
2896
+ "in": "query"
2897
+ }
2898
+ ],
2899
+ "responses": {
2900
+ "204": {
2901
+ "description": "Purge complete"
2902
+ }
2903
+ }
2904
+ }
2905
+ },
2906
+ "/tasks/process-zip": {
2907
+ "post": {
2908
+ "summary": "Process uploaded zip files",
2909
+ "tags": [
2910
+ "Tasks"
2911
+ ],
2912
+ "parameters": [
2913
+ {
2914
+ "schema": {
2915
+ "type": "string"
2916
+ },
2917
+ "required": true,
2918
+ "name": "projectId",
2919
+ "in": "query"
2920
+ },
2921
+ {
2922
+ "schema": {
2923
+ "type": "string"
2924
+ },
2925
+ "required": true,
2926
+ "name": "buildId",
2927
+ "in": "query"
2928
+ },
2929
+ {
2930
+ "schema": {
2931
+ "type": "string",
2932
+ "enum": [
2933
+ "storybook",
2934
+ "testReport",
2935
+ "coverage",
2936
+ "screenshots"
2937
+ ]
2938
+ },
2939
+ "required": true,
2940
+ "name": "variant",
2941
+ "in": "query"
2942
+ }
2943
+ ],
2944
+ "responses": {
2945
+ "204": {
2946
+ "description": "Request to process zip file accepter"
2947
+ }
2948
+ }
2949
+ }
2950
+ },
2951
+ "/account": {
2952
+ "get": {
2953
+ "summary": "Account page",
2954
+ "tags": [
2955
+ "Account"
2956
+ ],
2957
+ "responses": {
2958
+ "200": {
2959
+ "description": "Render account page",
2960
+ "content": {
2961
+ "text/html": {
2962
+ "schema": {
2963
+ "type": "string",
2964
+ "example": "<!DOCTYPE html>"
2965
+ }
2966
+ }
2967
+ }
2968
+ },
2969
+ "400": {
2970
+ "description": "Invalid request data",
2971
+ "content": {
2972
+ "application/json": {
2973
+ "schema": {
2974
+ "$ref": "#/components/schemas/ResponseError"
2975
+ }
2976
+ }
2977
+ }
2978
+ },
2979
+ "401": {
2980
+ "description": "Unauthenticated access",
2981
+ "content": {
2982
+ "application/json": {
2983
+ "schema": {
2984
+ "$ref": "#/components/schemas/ResponseError"
2985
+ }
2986
+ }
2987
+ }
2988
+ },
2989
+ "403": {
2990
+ "description": "Unauthorised access",
2991
+ "content": {
2992
+ "application/json": {
2993
+ "schema": {
2994
+ "$ref": "#/components/schemas/ResponseError"
2995
+ }
2996
+ }
2997
+ }
2998
+ },
2999
+ "500": {
3000
+ "description": "An unexpected server-error occurred.",
3001
+ "content": {
3002
+ "application/json": {
3003
+ "schema": {
3004
+ "$ref": "#/components/schemas/ResponseError"
3005
+ }
3006
+ }
3007
+ }
3008
+ }
3009
+ }
3010
+ }
3011
+ },
3012
+ "/account/login": {
3013
+ "get": {
3014
+ "summary": "Login to account",
3015
+ "tags": [
3016
+ "Account"
3017
+ ],
3018
+ "parameters": [
3019
+ {
3020
+ "schema": {
3021
+ "type": "string"
3022
+ },
3023
+ "required": false,
3024
+ "name": "redirect",
3025
+ "in": "query"
3026
+ }
3027
+ ],
3028
+ "responses": {
3029
+ "302": {
3030
+ "description": "Login successful",
3031
+ "headers": {
3032
+ "location": {
3033
+ "description": "Location/URL to redirect.",
3034
+ "schema": {
3035
+ "type": "string"
3036
+ },
3037
+ "required": true
3038
+ },
3039
+ "hx-location": {
3040
+ "description": "Location/URL to redirect using HTMX.",
3041
+ "schema": {
3042
+ "type": "string"
3043
+ },
3044
+ "required": false
3045
+ }
3046
+ }
3047
+ },
3048
+ "400": {
3049
+ "description": "Invalid request data",
3050
+ "content": {
3051
+ "application/json": {
3052
+ "schema": {
3053
+ "$ref": "#/components/schemas/ResponseError"
3054
+ }
3055
+ }
3056
+ }
3057
+ },
3058
+ "401": {
3059
+ "description": "Unauthenticated access",
3060
+ "content": {
3061
+ "application/json": {
3062
+ "schema": {
3063
+ "$ref": "#/components/schemas/ResponseError"
3064
+ }
3065
+ }
3066
+ }
3067
+ },
3068
+ "403": {
3069
+ "description": "Unauthorised access",
3070
+ "content": {
3071
+ "application/json": {
3072
+ "schema": {
3073
+ "$ref": "#/components/schemas/ResponseError"
3074
+ }
3075
+ }
3076
+ }
3077
+ },
3078
+ "500": {
3079
+ "description": "An unexpected server-error occurred.",
3080
+ "content": {
3081
+ "application/json": {
3082
+ "schema": {
3083
+ "$ref": "#/components/schemas/ResponseError"
3084
+ }
3085
+ }
3086
+ }
3087
+ }
3088
+ }
3089
+ }
3090
+ },
3091
+ "/account/logout": {
3092
+ "get": {
3093
+ "summary": "Logout from account",
3094
+ "tags": [
3095
+ "Account"
3096
+ ],
3097
+ "responses": {
3098
+ "302": {
3099
+ "description": "Logout successful",
3100
+ "headers": {
3101
+ "location": {
3102
+ "description": "Location/URL to redirect.",
3103
+ "schema": {
3104
+ "type": "string"
3105
+ },
3106
+ "required": true
3107
+ },
3108
+ "hx-location": {
3109
+ "description": "Location/URL to redirect using HTMX.",
3110
+ "schema": {
3111
+ "type": "string"
3112
+ },
3113
+ "required": false
3114
+ }
3115
+ }
3116
+ },
3117
+ "400": {
3118
+ "description": "Invalid request data",
3119
+ "content": {
3120
+ "application/json": {
3121
+ "schema": {
3122
+ "$ref": "#/components/schemas/ResponseError"
3123
+ }
3124
+ }
3125
+ }
3126
+ },
3127
+ "401": {
3128
+ "description": "Unauthenticated access",
3129
+ "content": {
3130
+ "application/json": {
3131
+ "schema": {
3132
+ "$ref": "#/components/schemas/ResponseError"
3133
+ }
3134
+ }
3135
+ }
3136
+ },
3137
+ "403": {
3138
+ "description": "Unauthorised access",
3139
+ "content": {
3140
+ "application/json": {
3141
+ "schema": {
3142
+ "$ref": "#/components/schemas/ResponseError"
3143
+ }
3144
+ }
3145
+ }
3146
+ },
3147
+ "500": {
3148
+ "description": "An unexpected server-error occurred.",
3149
+ "content": {
3150
+ "application/json": {
3151
+ "schema": {
3152
+ "$ref": "#/components/schemas/ResponseError"
3153
+ }
3154
+ }
3155
+ }
3156
+ }
3157
+ }
3158
+ }
3159
+ }
3160
+ },
3161
+ "webhooks": {}
3162
+ }