@nasebanal/cli 0.6.0 → 0.8.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.
@@ -2,7 +2,7 @@ openapi: 3.0.3
2
2
  info:
3
3
  title: NASEBANAL - Assurance API
4
4
  description: "Backend of NASEBANAL Assurance (quality assurance for APIs and web apps, under NASEBANAL Evolution). Authenticates users via Auth0 JWT and Personal Access Tokens (PAT) and integrates with the Account API. External monitoring: register URLs to be probed on an interval, then read availability reports. Test results: report the normalised result of each CI/CD job into a named project (typically one per repository), then read its runs and suites. Every response is wrapped as `{ success, data }` (or `{ success: false, error }`)."
5
- version: 1.0.0
5
+ version: 1.8.0
6
6
  contact:
7
7
  name: NASEBANAL
8
8
  url: https://www.nasebanal.com
@@ -42,13 +42,33 @@ paths:
42
42
  application/json:
43
43
  schema:
44
44
  type: object
45
+ required:
46
+ - success
47
+ - data
45
48
  properties:
46
- status:
47
- type: string
48
- example: ok
49
- timestamp:
50
- type: string
51
- format: date-time
49
+ success:
50
+ type: boolean
51
+ enum:
52
+ - true
53
+ data:
54
+ type: object
55
+ required:
56
+ - status
57
+ - timestamp
58
+ properties:
59
+ status:
60
+ type: string
61
+ example: ok
62
+ timestamp:
63
+ type: string
64
+ format: date-time
65
+ examples:
66
+ valid:
67
+ value:
68
+ success: true
69
+ data:
70
+ status: ok
71
+ timestamp: 2026-05-14T12:00:00Z
52
72
  /api/v1/me:
53
73
  get:
54
74
  tags:
@@ -598,6 +618,48 @@ paths:
598
618
  $ref: "#/components/responses/Forbidden"
599
619
  "404":
600
620
  $ref: "#/components/responses/NotFound"
621
+ patch:
622
+ tags:
623
+ - Projects
624
+ operationId: updateProject
625
+ summary: Update a project
626
+ description: Rename a project and/or change its repository or description. Send only the fields to change; an empty `repo` clears it. `retention_days` follows the plan and is not editable.
627
+ requestBody:
628
+ required: true
629
+ content:
630
+ application/json:
631
+ schema:
632
+ $ref: "#/components/schemas/ProjectUpdate"
633
+ responses:
634
+ "200":
635
+ description: Project
636
+ content:
637
+ application/json:
638
+ schema:
639
+ type: object
640
+ required:
641
+ - success
642
+ - data
643
+ properties:
644
+ success:
645
+ type: boolean
646
+ example: true
647
+ data:
648
+ $ref: "#/components/schemas/Project"
649
+ "400":
650
+ $ref: "#/components/responses/ValidationError"
651
+ "401":
652
+ $ref: "#/components/responses/Unauthorized"
653
+ "403":
654
+ $ref: "#/components/responses/Forbidden"
655
+ "404":
656
+ $ref: "#/components/responses/NotFound"
657
+ "409":
658
+ description: A project with this name already exists in the namespace (`CONFLICT`)
659
+ content:
660
+ application/json:
661
+ schema:
662
+ $ref: "#/components/schemas/Error"
601
663
  delete:
602
664
  tags:
603
665
  - Projects
@@ -691,6 +753,8 @@ paths:
691
753
  $ref: "#/components/responses/Forbidden"
692
754
  "404":
693
755
  $ref: "#/components/responses/NotFound"
756
+ "422":
757
+ $ref: "#/components/responses/ApiVersionRequired"
694
758
  /api/v1/projects/{id}/runs:
695
759
  parameters:
696
760
  - name: id
@@ -792,18 +856,36 @@ paths:
792
856
  $ref: "#/components/responses/Forbidden"
793
857
  "404":
794
858
  $ref: "#/components/responses/NotFound"
795
- /api/v1/contracts:
859
+ /api/v1/projects/{id}/runs/{runId}/suites/{suiteId}/cases:
796
860
  parameters:
861
+ - name: id
862
+ in: path
863
+ required: true
864
+ description: Project id
865
+ schema:
866
+ type: string
867
+ - name: runId
868
+ in: path
869
+ required: true
870
+ description: Run id
871
+ schema:
872
+ type: string
873
+ - name: suiteId
874
+ in: path
875
+ required: true
876
+ description: Suite id
877
+ schema:
878
+ type: string
797
879
  - $ref: "#/components/parameters/ActiveOrganization"
798
880
  get:
799
881
  tags:
800
- - Contracts
801
- operationId: listContracts
802
- summary: List contracts
803
- description: The outsourcing contracts of the active namespace, each with its deliverables, documents and SLA clause. Read-only for now.
882
+ - Projects
883
+ operationId: getSuiteCases
884
+ summary: Get the test cases of a suite
885
+ description: The per-test cases the reporter sent with the suite result (name, outcome, duration, failure message). 404 when the suite has none.
804
886
  responses:
805
887
  "200":
806
- description: Contracts
888
+ description: Cases
807
889
  content:
808
890
  application/json:
809
891
  schema:
@@ -816,36 +898,119 @@ paths:
816
898
  type: boolean
817
899
  example: true
818
900
  data:
819
- type: object
820
- properties:
821
- data:
822
- type: array
823
- items:
824
- $ref: "#/components/schemas/Contract"
825
- total:
826
- type: integer
901
+ $ref: "#/components/schemas/SuiteCases"
827
902
  "401":
828
903
  $ref: "#/components/responses/Unauthorized"
829
904
  "403":
830
905
  $ref: "#/components/responses/Forbidden"
831
- /api/v1/contracts/{id}:
906
+ "404":
907
+ $ref: "#/components/responses/NotFound"
908
+ /api/v1/projects/{id}/runs/{runId}/suites/{suiteId}/attachment:
832
909
  parameters:
833
910
  - name: id
834
911
  in: path
835
912
  required: true
836
- description: Contract id
913
+ description: Project id
914
+ schema:
915
+ type: string
916
+ - name: runId
917
+ in: path
918
+ required: true
919
+ description: Run id
920
+ schema:
921
+ type: string
922
+ - name: suiteId
923
+ in: path
924
+ required: true
925
+ description: Suite id
837
926
  schema:
838
927
  type: string
839
928
  - $ref: "#/components/parameters/ActiveOrganization"
929
+ put:
930
+ tags:
931
+ - Projects
932
+ operationId: putSuiteAttachment
933
+ summary: Attach the original report to a result
934
+ description: "Keeps the tool's own report (a file, or a folder as a zip) with the result: the body is the file as it is, `name` is the file name it is downloaded under. One per result; sending again replaces it (so does reporting the result again). Refused with 403 `ATTACHMENTS_DISABLED` until the project turns `attachments_enabled` on. Up to 20 MiB each and 200 MiB per project. The server only stores it: it is not opened, unzipped or shown."
935
+ parameters:
936
+ - name: name
937
+ in: query
938
+ required: false
939
+ description: The file name to download it as (letters, digits, `.`, `_`, `-` and spaces; anything else becomes `_`). Default `report.zip`.
940
+ schema:
941
+ type: string
942
+ maxLength: 100
943
+ requestBody:
944
+ required: true
945
+ description: The report file, or a zip of the report folder
946
+ content:
947
+ application/octet-stream:
948
+ schema:
949
+ type: string
950
+ format: binary
951
+ application/zip:
952
+ schema:
953
+ type: string
954
+ format: binary
955
+ responses:
956
+ "201":
957
+ description: Stored
958
+ content:
959
+ application/json:
960
+ schema:
961
+ type: object
962
+ required:
963
+ - success
964
+ - data
965
+ properties:
966
+ success:
967
+ type: boolean
968
+ example: true
969
+ data:
970
+ $ref: "#/components/schemas/AttachmentStored"
971
+ "400":
972
+ $ref: "#/components/responses/ValidationError"
973
+ "401":
974
+ $ref: "#/components/responses/Unauthorized"
975
+ "403":
976
+ $ref: "#/components/responses/Forbidden"
977
+ "404":
978
+ $ref: "#/components/responses/NotFound"
979
+ "409":
980
+ description: The project already holds 200 MiB of attached reports
981
+ "413":
982
+ description: Larger than 20 MiB
983
+ "503":
984
+ description: Report storage is not configured
840
985
  get:
841
986
  tags:
842
- - Contracts
843
- operationId: getContract
844
- summary: Get a contract
845
- description: One contract. A contract outside the active namespace is reported as not found.
987
+ - Projects
988
+ operationId: getSuiteAttachment
989
+ summary: Download the original report of a result
990
+ description: "The bytes that were attached, always as a download (`Content-Disposition: attachment`, `application/octet-stream`, `nosniff`). 404 when nothing is attached."
846
991
  responses:
847
992
  "200":
848
- description: Contract
993
+ description: The attached report
994
+ content:
995
+ application/octet-stream:
996
+ schema:
997
+ type: string
998
+ format: binary
999
+ "401":
1000
+ $ref: "#/components/responses/Unauthorized"
1001
+ "403":
1002
+ $ref: "#/components/responses/Forbidden"
1003
+ "404":
1004
+ $ref: "#/components/responses/NotFound"
1005
+ delete:
1006
+ tags:
1007
+ - Projects
1008
+ operationId: deleteSuiteAttachment
1009
+ summary: Remove the attached report of a result
1010
+ description: Drops the attached report; the result stays. 404 when nothing is attached.
1011
+ responses:
1012
+ "200":
1013
+ description: Removed
849
1014
  content:
850
1015
  application/json:
851
1016
  schema:
@@ -858,99 +1023,890 @@ paths:
858
1023
  type: boolean
859
1024
  example: true
860
1025
  data:
861
- $ref: "#/components/schemas/Contract"
1026
+ type: object
1027
+ properties:
1028
+ suite_id:
1029
+ type: string
1030
+ deleted:
1031
+ type: boolean
1032
+ example: true
862
1033
  "401":
863
1034
  $ref: "#/components/responses/Unauthorized"
864
1035
  "403":
865
1036
  $ref: "#/components/responses/Forbidden"
866
1037
  "404":
867
1038
  $ref: "#/components/responses/NotFound"
868
- components:
869
- securitySchemes:
870
- BearerAuth:
871
- type: http
872
- scheme: bearer
873
- bearerFormat: JWT or PAT
874
- description: Use either an Auth0 JWT token or a Personal Access Token (PAT) starting with `nbpat_`.
875
- schemas:
876
- User:
877
- type: object
878
- properties:
879
- id:
880
- type: integer
881
- auth0_sub:
882
- type: string
883
- email:
884
- type: string
885
- format: email
886
- name:
887
- type: string
888
- language:
889
- type: string
890
- enum:
891
- - ja
892
- - en
893
- plan:
894
- type: string
895
- enum:
896
- - free
897
- - pro
898
- - family
899
- - enterprise
900
- subscription_status:
901
- type: string
902
- enum:
903
- - active
904
- - canceled
905
- - past_due
906
- - trialing
907
- nullable: true
908
- subscription_expires_at:
909
- type: string
910
- format: date-time
911
- nullable: true
912
- UserResponse:
913
- type: object
914
- properties:
915
- data:
916
- $ref: "#/components/schemas/User"
917
- Error:
918
- type: object
919
- properties:
920
- error:
921
- type: object
922
- properties:
923
- code:
924
- type: string
925
- message:
926
- type: string
927
- CheckError:
928
- type: string
929
- nullable: true
930
- enum:
931
- - timeout
932
- - connection_failed
933
- - unexpected_status
934
- - keyword_not_found
935
- - null
936
- description: Why a check failed; null when it passed
937
- MonitorSettings:
938
- type: object
939
- properties:
940
- name:
1039
+ /api/v1/projects/{id}/runs/{runId}/suites/{suiteId}:
1040
+ parameters:
1041
+ - name: id
1042
+ in: path
1043
+ required: true
1044
+ description: Project id
1045
+ schema:
941
1046
  type: string
942
- maxLength: 100
943
- url:
1047
+ - name: runId
1048
+ in: path
1049
+ required: true
1050
+ description: Run id
1051
+ schema:
944
1052
  type: string
945
- format: uri
946
- maxLength: 2048
947
- method:
1053
+ - name: suiteId
1054
+ in: path
1055
+ required: true
1056
+ description: Suite id
1057
+ schema:
948
1058
  type: string
949
- enum:
950
- - GET
951
- - HEAD
952
- default: GET
953
- interval_minutes:
1059
+ - $ref: "#/components/parameters/ActiveOrganization"
1060
+ patch:
1061
+ tags:
1062
+ - Projects
1063
+ operationId: updateSuite
1064
+ summary: Correct a stored test result
1065
+ description: "Edit what a person may correct by hand: the outcome, the counts, the duration, the coverage, the name, the API version and the run's branch / commit / CI link. Kind and tool identify the result and cannot change; the name and the API version can, as long as the run does not already have a result with the same kind, name and version; metrics, failures and cases come from the report itself. A key that is present replaces the value (`null` clears it); an absent key is left alone. Answers the whole run."
1066
+ requestBody:
1067
+ required: true
1068
+ content:
1069
+ application/json:
1070
+ schema:
1071
+ $ref: "#/components/schemas/SuiteUpdate"
1072
+ responses:
1073
+ "200":
1074
+ description: The run, with its suites
1075
+ content:
1076
+ application/json:
1077
+ schema:
1078
+ type: object
1079
+ required:
1080
+ - success
1081
+ - data
1082
+ properties:
1083
+ success:
1084
+ type: boolean
1085
+ example: true
1086
+ data:
1087
+ $ref: "#/components/schemas/Run"
1088
+ "400":
1089
+ $ref: "#/components/responses/ValidationError"
1090
+ "401":
1091
+ $ref: "#/components/responses/Unauthorized"
1092
+ "403":
1093
+ $ref: "#/components/responses/Forbidden"
1094
+ "404":
1095
+ $ref: "#/components/responses/NotFound"
1096
+ "409":
1097
+ description: Changing the name or the API version would give the result the same kind, name and version as another result of the run (`CONFLICT`)
1098
+ content:
1099
+ application/json:
1100
+ schema:
1101
+ $ref: "#/components/schemas/Error"
1102
+ "422":
1103
+ $ref: "#/components/responses/ApiVersionRequired"
1104
+ delete:
1105
+ tags:
1106
+ - Projects
1107
+ operationId: deleteSuite
1108
+ summary: Delete a stored test result
1109
+ description: Deletes one suite result and its stored cases. A run left with no suite is deleted too (`run_deleted`).
1110
+ responses:
1111
+ "200":
1112
+ description: Deleted
1113
+ content:
1114
+ application/json:
1115
+ schema:
1116
+ type: object
1117
+ required:
1118
+ - success
1119
+ - data
1120
+ properties:
1121
+ success:
1122
+ type: boolean
1123
+ example: true
1124
+ data:
1125
+ type: object
1126
+ properties:
1127
+ id:
1128
+ type: string
1129
+ deleted:
1130
+ type: boolean
1131
+ run_deleted:
1132
+ type: boolean
1133
+ "401":
1134
+ $ref: "#/components/responses/Unauthorized"
1135
+ "403":
1136
+ $ref: "#/components/responses/Forbidden"
1137
+ "404":
1138
+ $ref: "#/components/responses/NotFound"
1139
+ /api/v1/projects/{id}/quality:
1140
+ parameters:
1141
+ - name: id
1142
+ in: path
1143
+ required: true
1144
+ description: Project id
1145
+ schema:
1146
+ type: string
1147
+ - $ref: "#/components/parameters/ActiveOrganization"
1148
+ get:
1149
+ tags:
1150
+ - Projects
1151
+ operationId: getProjectQuality
1152
+ summary: Get a project's quality summary
1153
+ description: "The quality summary of one of your projects, computed now, whether or not it is public: one verdict per perspective (unit, E2E, contract, security, performance, availability) and the numbers behind them. There is no weighted total. This is what the report page shows its owner."
1154
+ responses:
1155
+ "200":
1156
+ description: Quality summary
1157
+ headers:
1158
+ Access-Control-Allow-Origin:
1159
+ schema:
1160
+ type: string
1161
+ description: "*"
1162
+ content:
1163
+ application/json:
1164
+ schema:
1165
+ type: object
1166
+ required:
1167
+ - success
1168
+ - data
1169
+ properties:
1170
+ success:
1171
+ type: boolean
1172
+ example: true
1173
+ data:
1174
+ $ref: "#/components/schemas/QualityView"
1175
+ "401":
1176
+ $ref: "#/components/responses/Unauthorized"
1177
+ "404":
1178
+ $ref: "#/components/responses/NotFound"
1179
+ /api/v1/public/projects/{publicId}/summary:
1180
+ parameters:
1181
+ - name: publicId
1182
+ in: path
1183
+ required: true
1184
+ description: The public token of a project (the `public_id` it got when its owner made it public)
1185
+ schema:
1186
+ type: string
1187
+ get:
1188
+ tags:
1189
+ - Projects
1190
+ operationId: getPublicQualitySummary
1191
+ summary: Public quality summary
1192
+ description: "The quality summary of a project whose report is PUBLIC (`report_access: public`), readable without authentication (Kong Dev Portal and other pages build their own display from it). Aggregate verdicts and numbers only: never a test name, a failure message or a commit. Any other project and a token nobody has both answer 404, so a private project cannot be told from no project. Cached for 5 minutes."
1193
+ security: []
1194
+ responses:
1195
+ "200":
1196
+ description: Quality summary
1197
+ headers:
1198
+ Access-Control-Allow-Origin:
1199
+ schema:
1200
+ type: string
1201
+ description: "*"
1202
+ content:
1203
+ application/json:
1204
+ schema:
1205
+ type: object
1206
+ required:
1207
+ - success
1208
+ - data
1209
+ properties:
1210
+ success:
1211
+ type: boolean
1212
+ example: true
1213
+ data:
1214
+ $ref: "#/components/schemas/QualityView"
1215
+ "404":
1216
+ $ref: "#/components/responses/NotFound"
1217
+ /api/v1/shared/projects/{publicId}/summary:
1218
+ parameters:
1219
+ - name: publicId
1220
+ in: path
1221
+ required: true
1222
+ description: The public token of a project (public_id)
1223
+ schema:
1224
+ type: string
1225
+ get:
1226
+ tags:
1227
+ - Projects
1228
+ operationId: getSharedQualitySummary
1229
+ summary: Report summary for a signed-in visitor
1230
+ description: "The quality summary for a visitor who is SIGNED IN: any NASEBANAL account with the link may read it when the report is `login` or `public`. `hidden` and an unknown token answer 404 whoever asks (the report page uses this after a login; without credentials it is a 401)."
1231
+ responses:
1232
+ "200":
1233
+ description: Quality summary
1234
+ content:
1235
+ application/json:
1236
+ schema:
1237
+ type: object
1238
+ required:
1239
+ - success
1240
+ - data
1241
+ properties:
1242
+ success:
1243
+ type: boolean
1244
+ example: true
1245
+ data:
1246
+ $ref: "#/components/schemas/QualityView"
1247
+ "401":
1248
+ $ref: "#/components/responses/Unauthorized"
1249
+ "404":
1250
+ $ref: "#/components/responses/NotFound"
1251
+ /api/v1/public/projects/{publicId}/badge:
1252
+ parameters:
1253
+ - name: publicId
1254
+ in: path
1255
+ required: true
1256
+ description: The public token of a project (the `public_id` it got when its owner made it public)
1257
+ schema:
1258
+ type: string
1259
+ get:
1260
+ tags:
1261
+ - Projects
1262
+ operationId: getPublicQualityBadge
1263
+ summary: Public quality badge (shields.io endpoint JSON)
1264
+ description: "The JSON a shields.io endpoint badge reads (`https://img.shields.io/endpoint?url=...`), for READMEs on GitHub and GitLab. The message is how many perspectives pass out of all of them (`5/6`); the colour is red when one fails, green when all pass, yellow when some are not measured yet, light grey when nothing is. 404 when the badge is not public (`public_badge`) or the token is unknown (the two are not told apart): through shields.io that shows shields.io's own error badge, so use the SVG endpoint where nothing at all should show. `?label=` sets the left text (30 characters at most)."
1265
+ security: []
1266
+ parameters:
1267
+ - name: label
1268
+ in: query
1269
+ required: false
1270
+ schema:
1271
+ type: string
1272
+ maxLength: 30
1273
+ example: Target API
1274
+ responses:
1275
+ "200":
1276
+ description: shields.io endpoint badge
1277
+ headers:
1278
+ Access-Control-Allow-Origin:
1279
+ schema:
1280
+ type: string
1281
+ description: "*"
1282
+ content:
1283
+ application/json:
1284
+ schema:
1285
+ $ref: "#/components/schemas/ShieldsBadge"
1286
+ /api/v1/public/projects/{publicId}/badge.svg:
1287
+ parameters:
1288
+ - name: publicId
1289
+ in: path
1290
+ required: true
1291
+ description: The public token of a project (the `public_id` it got when its owner made it public)
1292
+ schema:
1293
+ type: string
1294
+ get:
1295
+ tags:
1296
+ - Projects
1297
+ operationId: getPublicQualityBadgeSvg
1298
+ summary: Public quality badge (SVG)
1299
+ description: The badge itself, in shields.io flat style, to use as an image in a README, a page or Kong Dev Portal without going through shields.io. Same content and colours as the JSON badge. When the badge is not public (or the token is unknown) it answers 200 with an empty image of zero size, so a README shows no badge and no broken-image icon.
1300
+ security: []
1301
+ parameters:
1302
+ - name: label
1303
+ in: query
1304
+ required: false
1305
+ schema:
1306
+ type: string
1307
+ maxLength: 30
1308
+ responses:
1309
+ "200":
1310
+ description: SVG image
1311
+ headers:
1312
+ Access-Control-Allow-Origin:
1313
+ schema:
1314
+ type: string
1315
+ description: "*"
1316
+ content:
1317
+ image/svg+xml:
1318
+ schema:
1319
+ type: string
1320
+ /api/v1/projects/{id}/components:
1321
+ parameters:
1322
+ - name: id
1323
+ in: path
1324
+ required: true
1325
+ description: Project id
1326
+ schema:
1327
+ type: string
1328
+ - $ref: "#/components/parameters/ActiveOrganization"
1329
+ get:
1330
+ tags:
1331
+ - Projects
1332
+ operationId: listComponents
1333
+ summary: List components
1334
+ description: "The components of a project: what its results are reported under (the front end, the back end, a service of a monorepo), each with the number of results it holds. A component exists before it has a result."
1335
+ responses:
1336
+ "200":
1337
+ description: Components
1338
+ content:
1339
+ application/json:
1340
+ schema:
1341
+ type: object
1342
+ required:
1343
+ - success
1344
+ - data
1345
+ properties:
1346
+ success:
1347
+ type: boolean
1348
+ example: true
1349
+ data:
1350
+ type: array
1351
+ items:
1352
+ $ref: "#/components/schemas/Component"
1353
+ "401":
1354
+ $ref: "#/components/responses/Unauthorized"
1355
+ "403":
1356
+ $ref: "#/components/responses/Forbidden"
1357
+ "404":
1358
+ $ref: "#/components/responses/NotFound"
1359
+ post:
1360
+ tags:
1361
+ - Projects
1362
+ operationId: createComponent
1363
+ summary: Add a component
1364
+ description: Registers a component of a project ahead of its first result. Reporting a result under a new name creates the component by itself, so this is only needed to prepare one. The name is unique in the project (case-insensitive).
1365
+ requestBody:
1366
+ required: true
1367
+ content:
1368
+ application/json:
1369
+ schema:
1370
+ $ref: "#/components/schemas/ComponentWrite"
1371
+ responses:
1372
+ "201":
1373
+ description: Created
1374
+ content:
1375
+ application/json:
1376
+ schema:
1377
+ type: object
1378
+ required:
1379
+ - success
1380
+ - data
1381
+ properties:
1382
+ success:
1383
+ type: boolean
1384
+ example: true
1385
+ data:
1386
+ $ref: "#/components/schemas/Component"
1387
+ "400":
1388
+ $ref: "#/components/responses/ValidationError"
1389
+ "401":
1390
+ $ref: "#/components/responses/Unauthorized"
1391
+ "403":
1392
+ $ref: "#/components/responses/Forbidden"
1393
+ "404":
1394
+ $ref: "#/components/responses/NotFound"
1395
+ "409":
1396
+ description: A component with this name already exists in the project (`CONFLICT`)
1397
+ content:
1398
+ application/json:
1399
+ schema:
1400
+ $ref: "#/components/schemas/Error"
1401
+ /api/v1/projects/{id}/components/{componentId}:
1402
+ parameters:
1403
+ - name: id
1404
+ in: path
1405
+ required: true
1406
+ description: Project id
1407
+ schema:
1408
+ type: string
1409
+ - $ref: "#/components/parameters/ActiveOrganization"
1410
+ - name: componentId
1411
+ in: path
1412
+ required: true
1413
+ description: Component id
1414
+ schema:
1415
+ type: string
1416
+ patch:
1417
+ tags:
1418
+ - Projects
1419
+ operationId: updateComponent
1420
+ summary: Rename a component
1421
+ description: Renames a component; its results follow, since they refer to it by id. A name another component of the project already has is refused (409).
1422
+ requestBody:
1423
+ required: true
1424
+ content:
1425
+ application/json:
1426
+ schema:
1427
+ $ref: "#/components/schemas/ComponentWrite"
1428
+ responses:
1429
+ "200":
1430
+ description: Component
1431
+ content:
1432
+ application/json:
1433
+ schema:
1434
+ type: object
1435
+ required:
1436
+ - success
1437
+ - data
1438
+ properties:
1439
+ success:
1440
+ type: boolean
1441
+ example: true
1442
+ data:
1443
+ $ref: "#/components/schemas/Component"
1444
+ "400":
1445
+ $ref: "#/components/responses/ValidationError"
1446
+ "401":
1447
+ $ref: "#/components/responses/Unauthorized"
1448
+ "403":
1449
+ $ref: "#/components/responses/Forbidden"
1450
+ "404":
1451
+ $ref: "#/components/responses/NotFound"
1452
+ "409":
1453
+ description: Another component of the project already has this name (`CONFLICT`)
1454
+ content:
1455
+ application/json:
1456
+ schema:
1457
+ $ref: "#/components/schemas/Error"
1458
+ delete:
1459
+ tags:
1460
+ - Projects
1461
+ operationId: deleteComponent
1462
+ summary: Delete a component
1463
+ description: "Removes the component from every result it belongs to. A result that belongs to no other component is **deleted** (with its stored cases) and so is a run left empty; a result that also belongs to other components stays. Refused (409, nothing deleted) when taking the component off would make a result identical to another one of the same run, kind and version. This cannot be undone; ask the person first. Monitors tied to the component are never deleted: they stay, no longer tied to it."
1464
+ responses:
1465
+ "200":
1466
+ description: Deleted
1467
+ content:
1468
+ application/json:
1469
+ schema:
1470
+ type: object
1471
+ required:
1472
+ - success
1473
+ - data
1474
+ properties:
1475
+ success:
1476
+ type: boolean
1477
+ example: true
1478
+ data:
1479
+ type: object
1480
+ properties:
1481
+ id:
1482
+ type: string
1483
+ deleted:
1484
+ type: boolean
1485
+ results_deleted:
1486
+ type: integer
1487
+ results_detached:
1488
+ type: integer
1489
+ description: Results that also belong to other components, which stay (only this component is taken off them)
1490
+ monitors_detached:
1491
+ type: integer
1492
+ description: Monitors that were tied to it. They stay, untied.
1493
+ runs_deleted:
1494
+ type: integer
1495
+ "401":
1496
+ $ref: "#/components/responses/Unauthorized"
1497
+ "403":
1498
+ $ref: "#/components/responses/Forbidden"
1499
+ "404":
1500
+ $ref: "#/components/responses/NotFound"
1501
+ "409":
1502
+ description: Taking the component off a result would make it identical to another result of the run (`CONFLICT`)
1503
+ content:
1504
+ application/json:
1505
+ schema:
1506
+ $ref: "#/components/schemas/Error"
1507
+ /api/v1/projects/{id}/components/{componentId}/merge:
1508
+ parameters:
1509
+ - name: id
1510
+ in: path
1511
+ required: true
1512
+ description: Project id
1513
+ schema:
1514
+ type: string
1515
+ - name: componentId
1516
+ in: path
1517
+ required: true
1518
+ description: Id of the component that is merged away
1519
+ schema:
1520
+ type: string
1521
+ - $ref: "#/components/parameters/ActiveOrganization"
1522
+ post:
1523
+ tags:
1524
+ - Projects
1525
+ operationId: mergeComponent
1526
+ summary: Merge a component into another
1527
+ description: Replaces the component by another one of the same project in every result it belongs to, then deletes it. Refused (409, nothing moved) when a result would then be identical to another one of the same run, kind and version. This cannot be undone; ask the person first. Monitors tied to the component are tied to the other one instead.
1528
+ requestBody:
1529
+ required: true
1530
+ content:
1531
+ application/json:
1532
+ schema:
1533
+ $ref: "#/components/schemas/ComponentMerge"
1534
+ responses:
1535
+ "200":
1536
+ description: Merged
1537
+ content:
1538
+ application/json:
1539
+ schema:
1540
+ type: object
1541
+ required:
1542
+ - success
1543
+ - data
1544
+ properties:
1545
+ success:
1546
+ type: boolean
1547
+ example: true
1548
+ data:
1549
+ type: object
1550
+ properties:
1551
+ id:
1552
+ type: string
1553
+ description: The receiving component
1554
+ merged_id:
1555
+ type: string
1556
+ description: The component that was merged away and deleted
1557
+ results_moved:
1558
+ type: integer
1559
+ "400":
1560
+ $ref: "#/components/responses/ValidationError"
1561
+ "401":
1562
+ $ref: "#/components/responses/Unauthorized"
1563
+ "403":
1564
+ $ref: "#/components/responses/Forbidden"
1565
+ "404":
1566
+ $ref: "#/components/responses/NotFound"
1567
+ "409":
1568
+ description: A result would become identical to another one of the same run, kind and API version (`CONFLICT`)
1569
+ content:
1570
+ application/json:
1571
+ schema:
1572
+ $ref: "#/components/schemas/Error"
1573
+ /api/v1/contracts:
1574
+ parameters:
1575
+ - $ref: "#/components/parameters/ActiveOrganization"
1576
+ get:
1577
+ tags:
1578
+ - Contracts
1579
+ operationId: listContracts
1580
+ summary: List contracts
1581
+ description: The outsourcing contracts of the active namespace, each with its deliverables, documents and SLA clause.
1582
+ responses:
1583
+ "200":
1584
+ description: Contracts
1585
+ content:
1586
+ application/json:
1587
+ schema:
1588
+ type: object
1589
+ required:
1590
+ - success
1591
+ - data
1592
+ properties:
1593
+ success:
1594
+ type: boolean
1595
+ example: true
1596
+ data:
1597
+ type: object
1598
+ properties:
1599
+ data:
1600
+ type: array
1601
+ items:
1602
+ $ref: "#/components/schemas/Contract"
1603
+ total:
1604
+ type: integer
1605
+ "401":
1606
+ $ref: "#/components/responses/Unauthorized"
1607
+ "403":
1608
+ $ref: "#/components/responses/Forbidden"
1609
+ post:
1610
+ tags:
1611
+ - Contracts
1612
+ operationId: createContract
1613
+ summary: Create a contract
1614
+ description: Create a contract with its deliverables, documents and optional SLA clause in the active namespace. Projects and the related contract must belong to the same namespace.
1615
+ requestBody:
1616
+ required: true
1617
+ content:
1618
+ application/json:
1619
+ schema:
1620
+ $ref: "#/components/schemas/ContractInput"
1621
+ responses:
1622
+ "201":
1623
+ description: Contract created
1624
+ content:
1625
+ application/json:
1626
+ schema:
1627
+ type: object
1628
+ required:
1629
+ - success
1630
+ - data
1631
+ properties:
1632
+ success:
1633
+ type: boolean
1634
+ example: true
1635
+ data:
1636
+ $ref: "#/components/schemas/Contract"
1637
+ "400":
1638
+ $ref: "#/components/responses/ValidationError"
1639
+ "401":
1640
+ $ref: "#/components/responses/Unauthorized"
1641
+ "403":
1642
+ $ref: "#/components/responses/Forbidden"
1643
+ "404":
1644
+ $ref: "#/components/responses/NotFound"
1645
+ "409":
1646
+ description: The per-namespace contract limit is reached (`LIMIT_REACHED`)
1647
+ content:
1648
+ application/json:
1649
+ schema:
1650
+ $ref: "#/components/schemas/Error"
1651
+ /api/v1/contracts/{id}:
1652
+ parameters:
1653
+ - name: id
1654
+ in: path
1655
+ required: true
1656
+ description: Contract id
1657
+ schema:
1658
+ type: string
1659
+ - $ref: "#/components/parameters/ActiveOrganization"
1660
+ get:
1661
+ tags:
1662
+ - Contracts
1663
+ operationId: getContract
1664
+ summary: Get a contract
1665
+ description: One contract. A contract outside the active namespace is reported as not found.
1666
+ responses:
1667
+ "200":
1668
+ description: Contract
1669
+ content:
1670
+ application/json:
1671
+ schema:
1672
+ type: object
1673
+ required:
1674
+ - success
1675
+ - data
1676
+ properties:
1677
+ success:
1678
+ type: boolean
1679
+ example: true
1680
+ data:
1681
+ $ref: "#/components/schemas/Contract"
1682
+ "401":
1683
+ $ref: "#/components/responses/Unauthorized"
1684
+ "403":
1685
+ $ref: "#/components/responses/Forbidden"
1686
+ "404":
1687
+ $ref: "#/components/responses/NotFound"
1688
+ put:
1689
+ tags:
1690
+ - Contracts
1691
+ operationId: updateContract
1692
+ summary: Replace a contract
1693
+ description: Replaces the whole contract, deliverables and documents included (the body is the full document, not a patch). A deliverable keeps its id, and so its record, only when its `id` from an earlier read is sent back; any other id is ignored and a new one issued.
1694
+ requestBody:
1695
+ required: true
1696
+ content:
1697
+ application/json:
1698
+ schema:
1699
+ $ref: "#/components/schemas/ContractInput"
1700
+ responses:
1701
+ "200":
1702
+ description: Contract
1703
+ content:
1704
+ application/json:
1705
+ schema:
1706
+ type: object
1707
+ required:
1708
+ - success
1709
+ - data
1710
+ properties:
1711
+ success:
1712
+ type: boolean
1713
+ example: true
1714
+ data:
1715
+ $ref: "#/components/schemas/Contract"
1716
+ "400":
1717
+ $ref: "#/components/responses/ValidationError"
1718
+ "401":
1719
+ $ref: "#/components/responses/Unauthorized"
1720
+ "403":
1721
+ $ref: "#/components/responses/Forbidden"
1722
+ "404":
1723
+ $ref: "#/components/responses/NotFound"
1724
+ delete:
1725
+ tags:
1726
+ - Contracts
1727
+ operationId: deleteContract
1728
+ summary: Delete a contract
1729
+ description: Also deletes its deliverables and documents. Contracts that pointed at it keep existing, unlinked.
1730
+ responses:
1731
+ "200":
1732
+ description: Deleted
1733
+ content:
1734
+ application/json:
1735
+ schema:
1736
+ type: object
1737
+ required:
1738
+ - success
1739
+ - data
1740
+ properties:
1741
+ success:
1742
+ type: boolean
1743
+ example: true
1744
+ data:
1745
+ type: object
1746
+ properties:
1747
+ id:
1748
+ type: string
1749
+ deleted:
1750
+ type: boolean
1751
+ "401":
1752
+ $ref: "#/components/responses/Unauthorized"
1753
+ "403":
1754
+ $ref: "#/components/responses/Forbidden"
1755
+ "404":
1756
+ $ref: "#/components/responses/NotFound"
1757
+ /api/v1/public/projects/{publicId}/report:
1758
+ parameters:
1759
+ - name: publicId
1760
+ in: path
1761
+ required: true
1762
+ schema:
1763
+ type: string
1764
+ description: The public token of a project (public_id)
1765
+ get:
1766
+ tags:
1767
+ - Projects
1768
+ operationId: getPublicQualityReport
1769
+ summary: Dashboard report of a public project
1770
+ description: "The dashboard data of a project whose report is PUBLIC (`report_access: public`), readable without authentication: the same runs and monitoring the owner's Charts screen draws, with everything that identifies something removed (no commit, branch, CI URL, test name, failure text or monitored URL). Any other project and an unknown token answer 404. Cached for 10 minutes."
1771
+ responses:
1772
+ "200":
1773
+ description: Dashboard report
1774
+ content:
1775
+ application/json:
1776
+ schema:
1777
+ type: object
1778
+ required:
1779
+ - success
1780
+ - data
1781
+ properties:
1782
+ success:
1783
+ type: boolean
1784
+ example: true
1785
+ data:
1786
+ $ref: "#/components/schemas/QualityReport"
1787
+ "404":
1788
+ $ref: "#/components/responses/NotFound"
1789
+ /api/v1/shared/projects/{publicId}/report:
1790
+ parameters:
1791
+ - name: publicId
1792
+ in: path
1793
+ required: true
1794
+ schema:
1795
+ type: string
1796
+ description: The public token of a project (public_id)
1797
+ get:
1798
+ tags:
1799
+ - Projects
1800
+ operationId: getSharedQualityReport
1801
+ summary: Dashboard report for a signed-in visitor
1802
+ description: The same dashboard data for a SIGNED-IN visitor when `report_access` is `login` or `public`. `hidden` and an unknown token answer 404; without credentials it is a 401.
1803
+ responses:
1804
+ "200":
1805
+ description: Dashboard report
1806
+ content:
1807
+ application/json:
1808
+ schema:
1809
+ type: object
1810
+ required:
1811
+ - success
1812
+ - data
1813
+ properties:
1814
+ success:
1815
+ type: boolean
1816
+ example: true
1817
+ data:
1818
+ $ref: "#/components/schemas/QualityReport"
1819
+ "401":
1820
+ $ref: "#/components/responses/Unauthorized"
1821
+ "404":
1822
+ $ref: "#/components/responses/NotFound"
1823
+ components:
1824
+ securitySchemes:
1825
+ BearerAuth:
1826
+ type: http
1827
+ scheme: bearer
1828
+ bearerFormat: JWT or PAT
1829
+ description: Use either an Auth0 JWT token or a Personal Access Token (PAT) starting with `nbpat_`.
1830
+ schemas:
1831
+ User:
1832
+ type: object
1833
+ properties:
1834
+ id:
1835
+ type: integer
1836
+ auth0_sub:
1837
+ type: string
1838
+ email:
1839
+ type: string
1840
+ format: email
1841
+ name:
1842
+ type: string
1843
+ language:
1844
+ type: string
1845
+ enum:
1846
+ - ja
1847
+ - en
1848
+ plan:
1849
+ type: string
1850
+ enum:
1851
+ - free
1852
+ - pro
1853
+ - family
1854
+ - enterprise
1855
+ subscription_status:
1856
+ type: string
1857
+ enum:
1858
+ - active
1859
+ - canceled
1860
+ - past_due
1861
+ - trialing
1862
+ nullable: true
1863
+ subscription_expires_at:
1864
+ type: string
1865
+ format: date-time
1866
+ nullable: true
1867
+ UserResponse:
1868
+ type: object
1869
+ properties:
1870
+ data:
1871
+ $ref: "#/components/schemas/User"
1872
+ Error:
1873
+ type: object
1874
+ properties:
1875
+ error:
1876
+ type: object
1877
+ properties:
1878
+ code:
1879
+ type: string
1880
+ message:
1881
+ type: string
1882
+ CheckError:
1883
+ type: string
1884
+ nullable: true
1885
+ enum:
1886
+ - timeout
1887
+ - connection_failed
1888
+ - unexpected_status
1889
+ - keyword_not_found
1890
+ - null
1891
+ description: Why a check failed; null when it passed
1892
+ MonitorSettings:
1893
+ type: object
1894
+ properties:
1895
+ name:
1896
+ type: string
1897
+ maxLength: 100
1898
+ description: Optional. Left out, the name is the host and path of the URL (`api.example.com/health`), and it then follows the URL when that changes.
1899
+ url:
1900
+ type: string
1901
+ format: uri
1902
+ maxLength: 2048
1903
+ method:
1904
+ type: string
1905
+ enum:
1906
+ - GET
1907
+ - HEAD
1908
+ default: GET
1909
+ interval_minutes:
954
1910
  type: integer
955
1911
  enum:
956
1912
  - 5
@@ -978,11 +1934,32 @@ components:
978
1934
  enabled:
979
1935
  type: boolean
980
1936
  default: true
1937
+ project_id:
1938
+ type: string
1939
+ nullable: true
1940
+ description: Project this monitor belongs to; its uptime then counts toward that project's quality gates. null = not assigned.
1941
+ api_version:
1942
+ type: string
1943
+ nullable: true
1944
+ maxLength: 32
1945
+ pattern: ^[A-Za-z0-9][A-Za-z0-9._-]*$
1946
+ description: API version this monitor checks (e.g. `v1`, `v2`), when the project serves several versions from one repository. null = not tied to a version (it counts for every version).
1947
+ description:
1948
+ type: string
1949
+ nullable: true
1950
+ maxLength: 500
1951
+ description: "Free text about the monitor: what it watches, why it exists. Up to 500 characters; an empty string clears it."
1952
+ components:
1953
+ type: array
1954
+ maxItems: 20
1955
+ description: "Names of the components of the project this monitor is about (the front end, the back end, a gateway in front of both). New names are created in the project. Needs `project_id`. Send `[]` for none: the monitor is then about the whole project and counts in every component's view. Changing `project_id` without sending this drops the old project's components. Up to 20."
1956
+ items:
1957
+ type: string
1958
+ maxLength: 100
981
1959
  MonitorCreate:
982
1960
  allOf:
983
1961
  - $ref: "#/components/schemas/MonitorSettings"
984
1962
  required:
985
- - name
986
1963
  - url
987
1964
  MonitorUpdate:
988
1965
  allOf:
@@ -1048,6 +2025,24 @@ components:
1048
2025
  nullable: true
1049
2026
  description: Owning organization; null for a personal monitor.
1050
2027
  example: null
2028
+ project_id:
2029
+ type: string
2030
+ nullable: true
2031
+ description: Project this monitor belongs to; its uptime then counts toward that project's quality gates. null = not assigned.
2032
+ api_version:
2033
+ type: string
2034
+ nullable: true
2035
+ maxLength: 32
2036
+ description: API version this monitor checks (e.g. `v1`, `v2`), when the project serves several versions from one repository. null = not tied to a version (it counts for every version).
2037
+ description:
2038
+ type: string
2039
+ nullable: true
2040
+ description: Free text; null = none.
2041
+ components:
2042
+ type: array
2043
+ description: The components this monitor is tied to; empty = about the whole project, so it counts in every component's view.
2044
+ items:
2045
+ $ref: "#/components/schemas/ComponentRef"
1051
2046
  MonitorWithUptime:
1052
2047
  allOf:
1053
2048
  - $ref: "#/components/schemas/Monitor"
@@ -1216,6 +2211,77 @@ components:
1216
2211
  maxLength: 200
1217
2212
  description: "Where the code lives, as `owner/name` (or `group/subgroup/project`, optionally prefixed by a host). Informational: several projects may share one repository, and it may be omitted."
1218
2213
  example: nasebanal/nb-target-api
2214
+ description:
2215
+ type: string
2216
+ nullable: true
2217
+ maxLength: 500
2218
+ description: A short free-text summary of what the project is. Informational; may be omitted.
2219
+ spec_id:
2220
+ type: string
2221
+ nullable: true
2222
+ maxLength: 64
2223
+ description: "The API this project assesses: the id of a spec in the API catalog (nb-specs-api). Stored as an id only; whether it exists is not checked. Optional."
2224
+ spec_environment:
2225
+ type: string
2226
+ nullable: true
2227
+ maxLength: 40
2228
+ description: Which environment of that API the project covers (production, staging, development, or any label), up to 40 characters. Needs spec_id. Optional.
2229
+ ProjectUpdate:
2230
+ type: object
2231
+ minProperties: 1
2232
+ properties:
2233
+ name:
2234
+ type: string
2235
+ maxLength: 100
2236
+ description: Unique within the namespace, ignoring case.
2237
+ repo:
2238
+ type: string
2239
+ nullable: true
2240
+ maxLength: 200
2241
+ description: "`owner/name` (or `group/subgroup/project`). An empty string clears it."
2242
+ example: nasebanal/nb-target-api
2243
+ description:
2244
+ type: string
2245
+ nullable: true
2246
+ maxLength: 500
2247
+ description: Free-text summary. An empty string clears it.
2248
+ spec_id:
2249
+ type: string
2250
+ nullable: true
2251
+ maxLength: 64
2252
+ description: The API this project assesses (a spec id of the API catalog). An empty string or null clears it, and spec_environment with it.
2253
+ spec_environment:
2254
+ type: string
2255
+ nullable: true
2256
+ maxLength: 40
2257
+ description: The environment of that API the project covers, up to 40 characters. Needs spec_id. An empty string or null clears it.
2258
+ public_badge:
2259
+ type: boolean
2260
+ description: true makes the badge readable without authentication (issues the public token the first time); false makes the badge show nothing at all. The token is kept, and this does not change report_access.
2261
+ attachments_enabled:
2262
+ type: boolean
2263
+ description: true lets reports be attached to this project's results (`PUT .../attachment`); false (the default) refuses them with 403 `ATTACHMENTS_DISABLED`. Off by default because a report can hold secrets and every member of the project's namespace can download it. Turning it off stops new attachments; what is already stored stays until it is removed.
2264
+ api_version_required_kinds:
2265
+ type: array
2266
+ items:
2267
+ type: string
2268
+ enum:
2269
+ - unit
2270
+ - e2e
2271
+ - load
2272
+ - contract
2273
+ - security
2274
+ description: "The kinds of result (`unit`, `e2e`, `load`, `contract`, `security`) that must carry an `api_version`. A result of such a kind without one is refused with 422 `API_VERSION_REQUIRED`, and so is an edit that clears its version. Use it for a project whose versions are kept apart (a branch each, or /v1 and /v2 side by side), where a forgotten label would put one version's result in every version's view. An empty list (the default) requires none. It governs only what arrives or is edited from now on: stored results are untouched."
2275
+ report_access:
2276
+ type: string
2277
+ enum:
2278
+ - hidden
2279
+ - login
2280
+ - public
2281
+ description: hidden, login or public (see the Project schema). Setting it away from hidden issues the public token the first time. Does not change public_badge.
2282
+ rotate_public_id:
2283
+ type: boolean
2284
+ description: "true replaces the public token: every old link stops working."
1219
2285
  Project:
1220
2286
  type: object
1221
2287
  required:
@@ -1236,6 +2302,48 @@ components:
1236
2302
  repo:
1237
2303
  type: string
1238
2304
  nullable: true
2305
+ description:
2306
+ type: string
2307
+ nullable: true
2308
+ description: Free-text summary a person wrote; null = none
2309
+ spec_id:
2310
+ type: string
2311
+ nullable: true
2312
+ maxLength: 64
2313
+ description: "The API this project assesses: the id of a spec in the API catalog (nb-specs-api), kept as an id only (whether it exists is not checked). null = none. Clearing it clears spec_environment too."
2314
+ spec_environment:
2315
+ type: string
2316
+ nullable: true
2317
+ maxLength: 40
2318
+ description: Which environment of that API the project covers (production, staging, development, or any label), up to 40 characters. Needs spec_id. null = not said.
2319
+ public_badge:
2320
+ type: boolean
2321
+ description: true = the badge ("5/6" and a colour) is readable without authentication by public_id; false = it shows nothing at all. Independent of report_access.
2322
+ attachments_enabled:
2323
+ type: boolean
2324
+ description: Whether reports may be attached to this project's results. false until someone who can edit the project turns it on.
2325
+ api_version_required_kinds:
2326
+ type: array
2327
+ items:
2328
+ type: string
2329
+ enum:
2330
+ - unit
2331
+ - e2e
2332
+ - load
2333
+ - contract
2334
+ - security
2335
+ description: The kinds of result that must carry an `api_version` (see the update schema). [] = none.
2336
+ report_access:
2337
+ type: string
2338
+ enum:
2339
+ - hidden
2340
+ - login
2341
+ - public
2342
+ description: "Who may read the quality report (the summary, the report page and its embed): hidden = nobody (404 whoever asks), login = anyone signed in to NASEBANAL who has the link, public = anyone with the link, no login. Independent of public_badge."
2343
+ public_id:
2344
+ type: string
2345
+ nullable: true
2346
+ description: The unguessable token of the public URLs; issued when the project is first made public and kept when it is turned off. null = never made public.
1239
2347
  retention_days:
1240
2348
  type: integer
1241
2349
  description: Runs older than this are deleted daily. Follows the reporter's plan, refreshed on every report.
@@ -1244,47 +2352,344 @@ components:
1244
2352
  format: date-time
1245
2353
  updated_at:
1246
2354
  type: string
1247
- format: date-time
1248
- ProjectWithLatestRun:
1249
- allOf:
1250
- - $ref: "#/components/schemas/Project"
1251
- - type: object
2355
+ format: date-time
2356
+ QualityGate:
2357
+ type: object
2358
+ required:
2359
+ - id
2360
+ - state
2361
+ - facts
2362
+ properties:
2363
+ id:
2364
+ type: string
2365
+ enum:
2366
+ - unit
2367
+ - e2e
2368
+ - contract
2369
+ - security
2370
+ - performance
2371
+ - availability
2372
+ state:
2373
+ type: string
2374
+ enum:
2375
+ - pass
2376
+ - fail
2377
+ - unmeasured
2378
+ description: "`unmeasured` = nothing was reported for this perspective yet"
2379
+ facts:
2380
+ type: object
2381
+ additionalProperties:
2382
+ type: number
2383
+ description: The aggregate numbers behind the verdict (passed / total tests, coverage_pct, p95_ms, error_rate_pct, high_risk / medium / low findings, uptime_pct). Only what applies to the perspective.
2384
+ QualityView:
2385
+ type: object
2386
+ required:
2387
+ - name
2388
+ - gates
2389
+ - measured
2390
+ - total
2391
+ - failing
2392
+ - computed_at
2393
+ properties:
2394
+ name:
2395
+ type: string
2396
+ environment:
2397
+ type: string
2398
+ nullable: true
2399
+ description: The environment of an API the project covers (production, staging, ...); null = not said
2400
+ gates:
2401
+ type: array
2402
+ items:
2403
+ $ref: "#/components/schemas/QualityGate"
2404
+ measured:
2405
+ type: integer
2406
+ description: How many perspectives have a verdict
2407
+ total:
2408
+ type: integer
2409
+ description: How many perspectives exist (six)
2410
+ failing:
2411
+ type: integer
2412
+ description: How many of the measured perspectives fail
2413
+ computed_at:
2414
+ type: string
2415
+ format: date-time
2416
+ ShieldsBadge:
2417
+ type: object
2418
+ description: The JSON a shields.io endpoint badge reads (https://shields.io/badges/endpoint-badge)
2419
+ required:
2420
+ - schemaVersion
2421
+ - label
2422
+ - message
2423
+ - color
2424
+ properties:
2425
+ schemaVersion:
2426
+ type: integer
2427
+ enum:
2428
+ - 1
2429
+ label:
2430
+ type: string
2431
+ message:
2432
+ type: string
2433
+ example: 5/6
2434
+ color:
2435
+ type: string
2436
+ enum:
2437
+ - brightgreen
2438
+ - yellow
2439
+ - red
2440
+ - lightgrey
2441
+ cacheSeconds:
2442
+ type: integer
2443
+ example: 300
2444
+ ProjectWithLatestRun:
2445
+ allOf:
2446
+ - $ref: "#/components/schemas/Project"
2447
+ - type: object
2448
+ properties:
2449
+ latest_run:
2450
+ allOf:
2451
+ - $ref: "#/components/schemas/Run"
2452
+ nullable: true
2453
+ SuiteTests:
2454
+ type: object
2455
+ properties:
2456
+ total:
2457
+ type: integer
2458
+ minimum: 0
2459
+ nullable: true
2460
+ passed:
2461
+ type: integer
2462
+ minimum: 0
2463
+ nullable: true
2464
+ failed:
2465
+ type: integer
2466
+ minimum: 0
2467
+ nullable: true
2468
+ skipped:
2469
+ type: integer
2470
+ minimum: 0
2471
+ nullable: true
2472
+ SuiteFailure:
2473
+ type: object
2474
+ required:
2475
+ - name
2476
+ properties:
2477
+ name:
2478
+ type: string
2479
+ maxLength: 300
2480
+ message:
2481
+ type: string
2482
+ nullable: true
2483
+ maxLength: 500
2484
+ SuiteCase:
2485
+ type: object
2486
+ required:
2487
+ - name
2488
+ - status
2489
+ properties:
2490
+ name:
2491
+ type: string
2492
+ maxLength: 300
2493
+ status:
2494
+ type: string
2495
+ enum:
2496
+ - passed
2497
+ - failed
2498
+ - skipped
2499
+ duration_ms:
2500
+ type: integer
2501
+ minimum: 0
2502
+ nullable: true
2503
+ message:
2504
+ type: string
2505
+ nullable: true
2506
+ maxLength: 2000
2507
+ description: Failure or error message, truncated by the reporter
2508
+ ComponentMerge:
2509
+ type: object
2510
+ required:
2511
+ - into
2512
+ properties:
2513
+ into:
2514
+ type: string
2515
+ description: Id of the component that receives the results. It must belong to the same project and differ from the one in the path.
2516
+ ComponentWrite:
2517
+ type: object
2518
+ required:
2519
+ - name
2520
+ properties:
2521
+ name:
2522
+ type: string
2523
+ minLength: 1
2524
+ maxLength: 100
2525
+ description: The component's name, such as `web`, `api` or `backend-provider`. Unique in the project (case-insensitive).
2526
+ ComponentRef:
2527
+ type: object
2528
+ required:
2529
+ - id
2530
+ - name
2531
+ properties:
2532
+ id:
2533
+ type: string
2534
+ name:
2535
+ type: string
2536
+ Component:
2537
+ type: object
2538
+ required:
2539
+ - id
2540
+ - name
2541
+ - results_count
2542
+ - exclusive_results_count
2543
+ - monitors_count
2544
+ properties:
2545
+ id:
2546
+ type: string
2547
+ name:
2548
+ type: string
2549
+ description: The component's name, such as `web`, `api` or `backend-provider`. Unique in the project (case-insensitive).
2550
+ results_count:
2551
+ type: integer
2552
+ minimum: 0
2553
+ description: Number of results that belong to this component (a result of several components counts for each).
2554
+ exclusive_results_count:
2555
+ type: integer
2556
+ minimum: 0
2557
+ description: "How many of those belong to no other component: the ones deleted along with it."
2558
+ monitors_count:
2559
+ type: integer
2560
+ minimum: 0
2561
+ description: How many monitors are tied to this component (they stay when it is deleted, just no longer tied).
2562
+ created_at:
2563
+ type: string
2564
+ format: date-time
2565
+ updated_at:
2566
+ type: string
2567
+ format: date-time
2568
+ SuiteUpdate:
2569
+ type: object
2570
+ description: Fields of a stored suite result that may be corrected. At least one is required.
2571
+ properties:
2572
+ name:
2573
+ type: string
2574
+ maxLength: 100
2575
+ description: Move the result to this one component (created when new); shorthand for a `components` of one. An empty string means `default`.
2576
+ components:
2577
+ type: array
2578
+ maxItems: 20
2579
+ description: Replace the components the result belongs to (created when new; an empty list means `default`). A result of the run that already has the same kind, set of components and version makes it a conflict (409).
2580
+ items:
2581
+ type: string
2582
+ maxLength: 100
2583
+ description:
2584
+ type: string
2585
+ nullable: true
2586
+ maxLength: 500
2587
+ description: Free text about the result (up to 500 characters). `null` or an empty string clears it.
2588
+ label:
2589
+ type: string
2590
+ nullable: true
2591
+ maxLength: 100
2592
+ description: Correct the label (see `Suite.label`). `null` or an empty string clears it. Refused (409) when the run already has a result with the same kind, components, API version and label.
2593
+ api_version:
2594
+ type: string
2595
+ nullable: true
2596
+ maxLength: 32
2597
+ pattern: ^[A-Za-z0-9][A-Za-z0-9._-]*$
2598
+ description: Correct the API version of this result. `null` clears it (the result then applies to every version).
2599
+ status:
2600
+ type: string
2601
+ enum:
2602
+ - passed
2603
+ - failed
2604
+ tests:
2605
+ type: object
2606
+ description: Merged with the stored counts; passed + failed + skipped must not exceed total. `null` clears all four.
2607
+ nullable: true
1252
2608
  properties:
1253
- latest_run:
1254
- allOf:
1255
- - $ref: "#/components/schemas/Run"
2609
+ total:
2610
+ type: integer
2611
+ minimum: 0
1256
2612
  nullable: true
1257
- SuiteTests:
1258
- type: object
1259
- properties:
1260
- total:
1261
- type: integer
1262
- minimum: 0
1263
- nullable: true
1264
- passed:
1265
- type: integer
1266
- minimum: 0
1267
- nullable: true
1268
- failed:
2613
+ passed:
2614
+ type: integer
2615
+ minimum: 0
2616
+ nullable: true
2617
+ failed:
2618
+ type: integer
2619
+ minimum: 0
2620
+ nullable: true
2621
+ skipped:
2622
+ type: integer
2623
+ minimum: 0
2624
+ nullable: true
2625
+ duration_ms:
1269
2626
  type: integer
1270
2627
  minimum: 0
1271
2628
  nullable: true
1272
- skipped:
1273
- type: integer
1274
- minimum: 0
2629
+ coverage:
2630
+ type: object
1275
2631
  nullable: true
1276
- SuiteFailure:
2632
+ properties:
2633
+ lines_pct:
2634
+ type: number
2635
+ minimum: 0
2636
+ maximum: 100
2637
+ nullable: true
2638
+ branches_pct:
2639
+ type: number
2640
+ minimum: 0
2641
+ maximum: 100
2642
+ nullable: true
2643
+ run:
2644
+ type: object
2645
+ description: Run-level fields, shared by every suite of the run
2646
+ properties:
2647
+ commit_sha:
2648
+ type: string
2649
+ maxLength: 64
2650
+ nullable: true
2651
+ branch:
2652
+ type: string
2653
+ maxLength: 255
2654
+ nullable: true
2655
+ ci_url:
2656
+ type: string
2657
+ maxLength: 2048
2658
+ nullable: true
2659
+ description: http(s) URL of the CI run
2660
+ provider:
2661
+ type: string
2662
+ nullable: true
2663
+ maxLength: 20
2664
+ description: The CI provider the run came from (`github` or `gitlab`; `other` for anything else), when the sender knew it. With the project's repository and the commit it lets a page link to a file in the repository.
2665
+ AttachmentStored:
1277
2666
  type: object
2667
+ description: What was stored for the result.
1278
2668
  required:
2669
+ - suite_id
1279
2670
  - name
2671
+ - size_bytes
1280
2672
  properties:
2673
+ suite_id:
2674
+ type: string
1281
2675
  name:
1282
2676
  type: string
1283
- maxLength: 300
1284
- message:
2677
+ description: The file name it is downloaded under.
2678
+ size_bytes:
2679
+ type: integer
2680
+ description: Its size in bytes.
2681
+ SuiteCases:
2682
+ type: object
2683
+ required:
2684
+ - suite_id
2685
+ - cases
2686
+ properties:
2687
+ suite_id:
1285
2688
  type: string
1286
- nullable: true
1287
- maxLength: 500
2689
+ cases:
2690
+ type: array
2691
+ items:
2692
+ $ref: "#/components/schemas/SuiteCase"
1288
2693
  Suite:
1289
2694
  type: object
1290
2695
  required:
@@ -1306,17 +2711,36 @@ components:
1306
2711
  - security
1307
2712
  tool:
1308
2713
  type: string
1309
- enum:
1310
- - vitest
1311
- - pytest
1312
- - playwright
1313
- - specmatic
1314
- - zap
1315
- - locust
2714
+ description: "The producing tool, as a label (lower-case letters, digits, `.`, `_`, `-`; up to 50), for example vitest, pytest, playwright, specmatic, zap, locust, trivy, k6. It is not a closed list: what a result means is carried by `kind` and by the normalised `metrics`, so a tool can be swapped for another that reports the same things. Converting a tool's own report into that shape is the sender's job (the nb CLI, a script). Matching is case-insensitive."
1316
2715
  example: vitest
2716
+ tool_version:
2717
+ type: string
2718
+ nullable: true
2719
+ maxLength: 50
2720
+ description: "The version of the tool that produced the report (e.g. `9.1.0`), when the sender knew it. Informational: it is not part of the result's identity, and a report sent again replaces it."
2721
+ report_path:
2722
+ type: string
2723
+ nullable: true
2724
+ maxLength: 512
2725
+ description: "Where the report file is in the repository, relative to the repository root (for example `reports/junit.xml`), when the report is committed there. Only set it for a file that is in the commit: with the run's `commit_sha` and `provider` it becomes a link to the file. Informational; a report sent again replaces it."
2726
+ attachment:
2727
+ type: object
2728
+ nullable: true
2729
+ description: The original report kept with the result (download it from `.../attachment`); null when none was attached.
2730
+ properties:
2731
+ name:
2732
+ type: string
2733
+ size_bytes:
2734
+ type: integer
1317
2735
  name:
1318
2736
  type: string
1319
- description: Tells apart several suites of one kind in a run; empty when single
2737
+ description: "A label for display: the names of the result's components, joined with `, `."
2738
+ components:
2739
+ type: array
2740
+ minItems: 1
2741
+ description: The components the result belongs to (at least one). A result may be about several, such as an end-to-end test of the front end and the back end together.
2742
+ items:
2743
+ $ref: "#/components/schemas/ComponentRef"
1320
2744
  status:
1321
2745
  type: string
1322
2746
  enum:
@@ -1348,9 +2772,27 @@ components:
1348
2772
  nullable: true
1349
2773
  items:
1350
2774
  $ref: "#/components/schemas/SuiteFailure"
2775
+ description:
2776
+ type: string
2777
+ nullable: true
2778
+ description: Free text; null = none.
2779
+ label:
2780
+ type: string
2781
+ nullable: true
2782
+ maxLength: 100
2783
+ description: "A name that tells apart results of one run, kind, components and API version, such as two scans of one tool (`baseline`, `full-scan`). null = none. It is part of the result's identity: the same combination with the same label replaces it."
2784
+ cases_count:
2785
+ type: integer
2786
+ minimum: 0
2787
+ nullable: true
2788
+ description: Number of per-test cases stored for this suite (read them with `getSuiteCases`); null when the reporter sent none
1351
2789
  updated_at:
1352
2790
  type: string
1353
2791
  format: date-time
2792
+ api_version:
2793
+ type: string
2794
+ nullable: true
2795
+ description: API version this result is for (e.g. `v1`, `v2`). null or absent = it applies to every version (unit tests usually do). Within one run a suite is identified by `kind`, `name` and `api_version`, so the results for v1 and v2 of the same kind and name sit side by side (one with no version is a third, shared one); reporting the same combination again replaces it.
1354
2796
  Run:
1355
2797
  type: object
1356
2798
  required:
@@ -1374,6 +2816,11 @@ components:
1374
2816
  ci_url:
1375
2817
  type: string
1376
2818
  nullable: true
2819
+ provider:
2820
+ type: string
2821
+ nullable: true
2822
+ maxLength: 20
2823
+ description: The CI provider the run came from (`github` or `gitlab`; `other` for anything else), when the sender knew it. With the project's repository and the commit it lets a page link to a file in the repository.
1377
2824
  started_at:
1378
2825
  type: string
1379
2826
  format: date-time
@@ -1418,6 +2865,13 @@ components:
1418
2865
  type: string
1419
2866
  maxLength: 2048
1420
2867
  description: http(s) URL of the CI run
2868
+ provider:
2869
+ type: string
2870
+ enum:
2871
+ - github
2872
+ - gitlab
2873
+ - other
2874
+ description: The CI provider the run came from (`github` or `gitlab`; `other` for anything else), when the sender knew it. With the project's repository and the commit it lets a page link to a file in the repository.
1421
2875
  started_at:
1422
2876
  type: string
1423
2877
  format: date-time
@@ -1439,18 +2893,42 @@ components:
1439
2893
  tool:
1440
2894
  type: string
1441
2895
  maxLength: 50
1442
- enum:
1443
- - vitest
1444
- - pytest
1445
- - playwright
1446
- - specmatic
1447
- - zap
1448
- - locust
1449
- description: "The producing tool. Supported per kind: unit = vitest | pytest, e2e = playwright, contract = specmatic, security = zap, load = locust. Any other tool, or a tool paired with the wrong kind, is rejected with 400. Matching is case-insensitive."
2896
+ pattern: ^[a-z0-9][a-z0-9._-]{0,49}$
2897
+ description: "The producing tool, as a label (lower-case letters, digits, `.`, `_`, `-`; up to 50), for example vitest, pytest, playwright, specmatic, zap, locust, trivy, k6. It is not a closed list: what a result means is carried by `kind` and by the normalised `metrics`, so a tool can be swapped for another that reports the same things. Converting a tool's own report into that shape is the sender's job (the nb CLI, a script). Matching is case-insensitive."
1450
2898
  example: playwright
2899
+ api_version:
2900
+ type: string
2901
+ nullable: true
2902
+ maxLength: 32
2903
+ pattern: ^[A-Za-z0-9][A-Za-z0-9._-]*$
2904
+ description: API version this result is for (e.g. `v1`, `v2`). null or absent = it applies to every version (unit tests usually do). Within one run a suite is identified by `kind`, `name` and `api_version`, so the results for v1 and v2 of the same kind and name sit side by side (one with no version is a third, shared one); reporting the same combination again replaces it.
1451
2905
  name:
1452
2906
  type: string
1453
2907
  maxLength: 100
2908
+ description: One component this result is for. Shorthand for a `components` of one; if both are sent, the result belongs to all of them. Omit both for the component `default`.
2909
+ components:
2910
+ type: array
2911
+ maxItems: 20
2912
+ description: "The components this result is for: the front end, the back end, a service. Each is created in the project when new. Up to 20. Omitted or empty (with no `name`) means `default`. A suite in a run is identified by `kind`, the set of components, `api_version` and `label`; reporting the same combination again replaces it."
2913
+ items:
2914
+ type: string
2915
+ maxLength: 100
2916
+ description:
2917
+ type: string
2918
+ maxLength: 500
2919
+ description: "Free text about the result: what it covers, why it is as it is. Up to 500 characters. Reporting the same result again without one keeps the earlier text; with one replaces it."
2920
+ label:
2921
+ type: string
2922
+ maxLength: 100
2923
+ description: A name that tells apart results that are otherwise the same (same kind, components and API version), such as two scans of one tool (`baseline`, `full-scan`). Optional; up to 100 characters. Reporting the same combination with the same label again replaces the result.
2924
+ tool_version:
2925
+ type: string
2926
+ maxLength: 50
2927
+ description: "The version of the tool that produced the report (e.g. `9.1.0`). Optional; up to 50 characters. Informational: it is not part of the result's identity."
2928
+ report_path:
2929
+ type: string
2930
+ maxLength: 512
2931
+ description: "The report file's path in the repository, relative to its root (for example `reports/junit.xml`). Optional; up to 512 characters; no `..` segments. Send it only when the file is committed at the run's `commit_sha`. Informational: it is not part of the result's identity."
1454
2932
  status:
1455
2933
  type: string
1456
2934
  enum:
@@ -1492,7 +2970,7 @@ components:
1492
2970
  maxProperties: 20
1493
2971
  additionalProperties:
1494
2972
  type: number
1495
- description: "snake_case keys, finite numbers. Conventional keys: load -> p95_ms, rps, error_rate_pct; security -> critical, high, medium, low, info; contract -> coverage_pct."
2973
+ description: "snake_case keys, finite numbers. The conventional keys are what the dashboard reads, whatever the tool: load -> p95_ms, rps, error_rate_pct; security -> critical, high, medium, low, info (findings by severity, so a scanner maps its own levels onto these); contract -> coverage_pct (share of the spec's operations exercised). Counts and coverage of unit and e2e suites travel in `tests` and `coverage`, not here."
1496
2974
  example:
1497
2975
  p95_ms: 240
1498
2976
  rps: 120.5
@@ -1502,6 +2980,12 @@ components:
1502
2980
  items:
1503
2981
  $ref: "#/components/schemas/SuiteFailure"
1504
2982
  description: The first failures only
2983
+ cases:
2984
+ type: array
2985
+ maxItems: 5000
2986
+ items:
2987
+ $ref: "#/components/schemas/SuiteCase"
2988
+ description: Every test case of a JUnit-based report (vitest, pytest, playwright, specmatic). Kept in object storage and read back with `getSuiteCases`; D1 keeps only the summary. Omit for locust and zap. A retried job replaces the earlier list.
1505
2989
  ResultAccepted:
1506
2990
  type: object
1507
2991
  required:
@@ -1592,6 +3076,119 @@ components:
1592
3076
  date:
1593
3077
  type: string
1594
3078
  format: date
3079
+ ContractDeliverableInput:
3080
+ type: object
3081
+ required:
3082
+ - name
3083
+ - due
3084
+ - amount
3085
+ properties:
3086
+ id:
3087
+ type: string
3088
+ description: Send back an existing id to keep that deliverable; omitted or unknown ids get a new one
3089
+ name:
3090
+ type: string
3091
+ maxLength: 120
3092
+ project_id:
3093
+ type: string
3094
+ nullable: true
3095
+ version:
3096
+ type: string
3097
+ nullable: true
3098
+ maxLength: 32
3099
+ pattern: ^[A-Za-z0-9._-]+$
3100
+ due:
3101
+ type: string
3102
+ format: date
3103
+ amount:
3104
+ type: integer
3105
+ minimum: 0
3106
+ maximum: 1000000000
3107
+ paid:
3108
+ type: boolean
3109
+ default: false
3110
+ ContractInput:
3111
+ type: object
3112
+ required:
3113
+ - title
3114
+ - kind
3115
+ - status
3116
+ - orderer
3117
+ - vendor
3118
+ - start
3119
+ - end
3120
+ - amount
3121
+ properties:
3122
+ title:
3123
+ type: string
3124
+ maxLength: 160
3125
+ description: Bilingual, "ja / en"
3126
+ kind:
3127
+ type: string
3128
+ enum:
3129
+ - development
3130
+ - maintenance
3131
+ status:
3132
+ type: string
3133
+ enum:
3134
+ - draft
3135
+ - active
3136
+ - completed
3137
+ orderer:
3138
+ type: string
3139
+ maxLength: 100
3140
+ vendor:
3141
+ type: string
3142
+ maxLength: 100
3143
+ start:
3144
+ type: string
3145
+ format: date
3146
+ end:
3147
+ type: string
3148
+ format: date
3149
+ description: ">= start"
3150
+ amount:
3151
+ type: integer
3152
+ minimum: 0
3153
+ maximum: 100000000000
3154
+ oas_url:
3155
+ type: string
3156
+ format: uri
3157
+ nullable: true
3158
+ description: http(s) URL of the OpenAPI document
3159
+ sla_project_id:
3160
+ type: string
3161
+ nullable: true
3162
+ sla:
3163
+ allOf:
3164
+ - $ref: "#/components/schemas/ContractSla"
3165
+ nullable: true
3166
+ description: Operations contracts only. Omit or null for none.
3167
+ related:
3168
+ type: object
3169
+ nullable: true
3170
+ description: Link to another contract of the same namespace
3171
+ required:
3172
+ - id
3173
+ - relation
3174
+ properties:
3175
+ id:
3176
+ type: string
3177
+ relation:
3178
+ type: string
3179
+ enum:
3180
+ - follows
3181
+ - change_order
3182
+ deliverables:
3183
+ type: array
3184
+ maxItems: 20
3185
+ items:
3186
+ $ref: "#/components/schemas/ContractDeliverableInput"
3187
+ documents:
3188
+ type: array
3189
+ maxItems: 20
3190
+ items:
3191
+ $ref: "#/components/schemas/ContractDocument"
1595
3192
  Contract:
1596
3193
  type: object
1597
3194
  required:
@@ -1680,6 +3277,54 @@ components:
1680
3277
  updated_at:
1681
3278
  type: string
1682
3279
  format: date-time
3280
+ QualityReport:
3281
+ type: object
3282
+ description: "The dashboard data of a public report: the project's name, environment, component names and recent runs (verdicts, counts, coverage, metrics only), and its monitors' uptime and daily states (named Monitor 1, 2, ...)."
3283
+ required:
3284
+ - project
3285
+ - monitoring
3286
+ - built_at
3287
+ properties:
3288
+ project:
3289
+ type: object
3290
+ required:
3291
+ - name
3292
+ - environment
3293
+ - components
3294
+ - runs
3295
+ properties:
3296
+ name:
3297
+ type: string
3298
+ environment:
3299
+ type: string
3300
+ nullable: true
3301
+ components:
3302
+ type: array
3303
+ items:
3304
+ type: object
3305
+ properties:
3306
+ name:
3307
+ type: string
3308
+ runs:
3309
+ type: array
3310
+ items:
3311
+ $ref: "#/components/schemas/Run"
3312
+ monitoring:
3313
+ type: object
3314
+ required:
3315
+ - monitors
3316
+ - uptime_30d
3317
+ properties:
3318
+ monitors:
3319
+ type: array
3320
+ items:
3321
+ type: object
3322
+ uptime_30d:
3323
+ type: number
3324
+ nullable: true
3325
+ built_at:
3326
+ type: string
3327
+ format: date-time
1683
3328
  responses:
1684
3329
  Unauthorized:
1685
3330
  description: Authentication required or invalid token
@@ -1713,6 +3358,17 @@ components:
1713
3358
  error:
1714
3359
  code: NOT_FOUND
1715
3360
  message: Monitor not found
3361
+ ApiVersionRequired:
3362
+ description: The project requires an `api_version` for this kind of result (`API_VERSION_REQUIRED`)
3363
+ content:
3364
+ application/json:
3365
+ schema:
3366
+ $ref: "#/components/schemas/Error"
3367
+ example:
3368
+ success: false
3369
+ error:
3370
+ code: API_VERSION_REQUIRED
3371
+ message: "This project requires an API version for contract results: send api_version (nb: --api-version, or NB_API_VERSION)"
1716
3372
  Forbidden:
1717
3373
  description: The caller does not belong to the active organization (`FORBIDDEN`)
1718
3374
  content: