@mxtommy/kip 4.8.4 → 4.8.5

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 (64) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/package.json +1 -1
  3. package/plugin/history-series.service.js +637 -0
  4. package/plugin/index.js +1322 -0
  5. package/plugin/kip-series-contract.js +31 -0
  6. package/plugin/openApi.json +855 -0
  7. package/plugin/sqlite-history-storage.service.js +1124 -0
  8. package/public/assets/help-docs/ais-radar.md +261 -0
  9. package/public/assets/help-docs/dashboards.md +1 -1
  10. package/public/assets/help-docs/menu.json +17 -2
  11. package/public/{chunk-Co2wVrD6.js → chunk-0ijGpqkR.js} +1 -1
  12. package/public/{chunk-JhFkJS7i.js → chunk-6MiGh2Ts.js} +1 -1
  13. package/public/{chunk-DIl1k00y.js → chunk-7QXXQf2h.js} +1 -1
  14. package/public/{chunk-CYYBxjrc.js → chunk-B4Wxwb2y.js} +1 -1
  15. package/public/{chunk-q9NoPvcx.js → chunk-BAVmyVwG.js} +1 -1
  16. package/public/{chunk-BfiyH3nV.js → chunk-BOlUTHo6.js} +1 -1
  17. package/public/{chunk-x7L6DXVK.js → chunk-BTv5PhTr.js} +1 -1
  18. package/public/{chunk-BeM64etA.js → chunk-BZG04c3j.js} +1 -1
  19. package/public/{chunk-0z3nIRXw.js → chunk-BaGEtCmz.js} +1 -1
  20. package/public/{chunk-otzyItXL.js → chunk-Bbyk4dOu.js} +1 -1
  21. package/public/{chunk-CCfhzpE8.js → chunk-Be5KcT7R.js} +1 -1
  22. package/public/{chunk-BFpzxIIT.js → chunk-Bp1YVCJL.js} +1 -1
  23. package/public/{chunk-CLs_NL1y.js → chunk-BwYOFdBA.js} +1 -1
  24. package/public/{chunk-D-_-GUVr.js → chunk-Bx77STup.js} +1 -1
  25. package/public/{chunk-COI6IBXH.js → chunk-ByC_hFSP.js} +1 -1
  26. package/public/{chunk-CIGP2YJm.js → chunk-ByFzHU1s.js} +1 -1
  27. package/public/{chunk-CXvWM_vF.js → chunk-BzH86te1.js} +1 -1
  28. package/public/{chunk-CxPx4NZv.js → chunk-C7ax8Sqz.js} +1 -1
  29. package/public/{chunk-CoCQ3DW2.js → chunk-C89yhdsn.js} +1 -1
  30. package/public/{chunk-BTOTKeBo.js → chunk-CJhkckXA.js} +1 -1
  31. package/public/{chunk-BUguZ7cK.js → chunk-CLIWxVhS.js} +1 -1
  32. package/public/{chunk-eQ1pa34Q.js → chunk-CQtqkz1Y.js} +1 -1
  33. package/public/{chunk-BIb-xYiS.js → chunk-CRy9Da7a.js} +1 -1
  34. package/public/{chunk-Do8wqING.js → chunk-CcaPRVAZ.js} +1 -1
  35. package/public/{chunk-BjINKQ03.js → chunk-CdNfAZ0G.js} +1 -1
  36. package/public/{chunk-CLTHuhlN.js → chunk-Cj0AJQ8U.js} +1 -1
  37. package/public/{chunk-B9nVBlGj.js → chunk-CkFpNfxN.js} +1 -1
  38. package/public/{chunk-B09jfNia.js → chunk-Cn9j0-tJ.js} +1 -1
  39. package/public/{chunk-_zRMMvCu.js → chunk-Co8V0LUu.js} +1 -1
  40. package/public/{chunk-ibauGmSP.js → chunk-CteyWXZ_.js} +1 -1
  41. package/public/{chunk-C6b8CVno.js → chunk-CuPmfpgh.js} +1 -1
  42. package/public/{chunk-DmkAKXR1.js → chunk-CwGTKplC.js} +1 -1
  43. package/public/{chunk-DPnbM-aB.js → chunk-CzEDfe2A.js} +1 -1
  44. package/public/{chunk-DUEKoZhd.js → chunk-D1Yncgg5.js} +1 -1
  45. package/public/{chunk-DTN-sa1K.js → chunk-D63LEt5t.js} +1 -1
  46. package/public/{chunk-BpcNrtxJ.js → chunk-DN39qO63.js} +1 -1
  47. package/public/{chunk-szQs8fiq.js → chunk-DNbLx4NZ.js} +1 -1
  48. package/public/{chunk-D1HYfaL_.js → chunk-DRPjASjZ.js} +1 -1
  49. package/public/{chunk-CyVRpGoJ.js → chunk-Dddd8rAh.js} +1 -1
  50. package/public/{chunk-C_OZJltF.js → chunk-DiDkZnhZ.js} +1 -1
  51. package/public/{chunk-CHAFm_nM.js → chunk-DonRL_4T.js} +1 -1
  52. package/public/{chunk-BJ-wyixK.js → chunk-DufX2AHa.js} +1 -1
  53. package/public/{chunk-07zHjmg-.js → chunk-DxS7HN4G.js} +1 -1
  54. package/public/{chunk-BLEZOsfR.js → chunk-Fy40z1B2.js} +1 -1
  55. package/public/{chunk-OeQDZKFO.js → chunk-MO2v041V.js} +1 -1
  56. package/public/{chunk-BuvyF0y5.js → chunk-MakCt36b.js} +1 -1
  57. package/public/{chunk-BZx964-p.js → chunk-TdI_E-cf.js} +1 -1
  58. package/public/{chunk-B0D54iJs.js → chunk-TneLdWrI.js} +1 -1
  59. package/public/{chunk-BN7A4g6c.js → chunk-YZWhRxa9.js} +1 -1
  60. package/public/{chunk-CQMVIDcp.js → chunk-_toW-rHA.js} +1 -1
  61. package/public/{chunk-B0eE4udE.js → chunk-tbyiK3Ur.js} +1 -1
  62. package/public/{chunk-D2953Rfp.js → chunk-urAQA4U_.js} +1 -1
  63. package/public/index.html +1 -1
  64. package/public/{main-YKDNK5VZ.js → main-F7NMHHV4.js} +4 -4
@@ -0,0 +1,855 @@
1
+ {
2
+ "openapi": "3.0.0",
3
+ "info": {
4
+ "version": "1.1.0",
5
+ "title": "KIP Plugin API",
6
+ "description": "Endpoints\n- List remote displays and control remote dashboard of a given KIP instance.\n- Configure data series for widget framework historical data series and data chart widgets.",
7
+ "termsOfService": "http://signalk.org/terms/",
8
+ "license": {
9
+ "name": "Apache 2.0",
10
+ "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
11
+ }
12
+ },
13
+ "externalDocs": {
14
+ "url": "http://signalk.org/specification/",
15
+ "description": "Signal K specification."
16
+ },
17
+ "servers": [
18
+ {
19
+ "url": "/"
20
+ }
21
+ ],
22
+ "tags": [
23
+ {
24
+ "name": "Displays",
25
+ "description": "KIP remote display discovery and control."
26
+ },
27
+ {
28
+ "name": "Series",
29
+ "description": "KIP widget history series configuration."
30
+ }
31
+ ],
32
+ "components": {
33
+ "schemas": {
34
+ "DisplayInfo": {
35
+ "type": "object",
36
+ "properties": {
37
+ "displayId": {
38
+ "type": "string",
39
+ "description": "KIP instance UUID"
40
+ },
41
+ "displayName": {
42
+ "type": "string",
43
+ "nullable": true
44
+ }
45
+ },
46
+ "required": [
47
+ "displayId"
48
+ ]
49
+ },
50
+ "ScreenItem": {
51
+ "type": "object",
52
+ "properties": {
53
+ "id": {
54
+ "type": "string"
55
+ },
56
+ "name": {
57
+ "type": "string"
58
+ },
59
+ "icon": {
60
+ "type": "string"
61
+ }
62
+ },
63
+ "required": [
64
+ "id",
65
+ "name",
66
+ "icon"
67
+ ]
68
+ },
69
+ "ScreenListOrNull": {
70
+ "type": "array",
71
+ "nullable": true,
72
+ "items": {
73
+ "$ref": "#/components/schemas/ScreenItem"
74
+ }
75
+ },
76
+ "SuccessResponse": {
77
+ "type": "object",
78
+ "properties": {
79
+ "state": {
80
+ "type": "string",
81
+ "enum": [
82
+ "SUCCESS"
83
+ ]
84
+ },
85
+ "statusCode": {
86
+ "type": "integer",
87
+ "enum": [
88
+ 200
89
+ ]
90
+ }
91
+ },
92
+ "required": [
93
+ "state",
94
+ "statusCode"
95
+ ]
96
+ },
97
+ "ErrorResponse": {
98
+ "type": "object",
99
+ "properties": {
100
+ "state": {
101
+ "type": "string",
102
+ "enum": [
103
+ "FAILED"
104
+ ]
105
+ },
106
+ "statusCode": {
107
+ "type": "integer"
108
+ },
109
+ "message": {
110
+ "type": "string"
111
+ }
112
+ },
113
+ "required": [
114
+ "state",
115
+ "statusCode",
116
+ "message"
117
+ ]
118
+ },
119
+ "ActiveScreenSetRequest": {
120
+ "type": "object",
121
+ "properties": {
122
+ "screenIdx": {
123
+ "type": "integer",
124
+ "nullable": true,
125
+ "description": "Index of active screen or null to clear"
126
+ }
127
+ }
128
+ },
129
+ "AnyObjectOrNull": {
130
+ "type": "object",
131
+ "nullable": true,
132
+ "additionalProperties": true
133
+ },
134
+ "SeriesDefinitionBase": {
135
+ "type": "object",
136
+ "properties": {
137
+ "seriesId": {
138
+ "type": "string"
139
+ },
140
+ "datasetUuid": {
141
+ "type": "string"
142
+ },
143
+ "ownerWidgetUuid": {
144
+ "type": "string"
145
+ },
146
+ "ownerWidgetSelector": {
147
+ "type": "string",
148
+ "nullable": true
149
+ },
150
+ "path": {
151
+ "type": "string"
152
+ },
153
+ "context": {
154
+ "type": "string",
155
+ "nullable": true
156
+ },
157
+ "source": {
158
+ "type": "string",
159
+ "nullable": true
160
+ },
161
+ "timeScale": {
162
+ "type": "string",
163
+ "nullable": true
164
+ },
165
+ "period": {
166
+ "type": "integer",
167
+ "nullable": true
168
+ },
169
+ "retentionDurationMs": {
170
+ "type": "integer",
171
+ "nullable": true
172
+ },
173
+ "sampleTime": {
174
+ "type": "integer",
175
+ "nullable": true
176
+ },
177
+ "enabled": {
178
+ "type": "boolean",
179
+ "default": true
180
+ },
181
+ "methods": {
182
+ "type": "array",
183
+ "items": {
184
+ "type": "string",
185
+ "enum": [
186
+ "min",
187
+ "max",
188
+ "avg",
189
+ "sma",
190
+ "ema"
191
+ ]
192
+ }
193
+ },
194
+ "reconcileTs": {
195
+ "type": "integer",
196
+ "nullable": true
197
+ }
198
+ },
199
+ "required": [
200
+ "seriesId",
201
+ "datasetUuid",
202
+ "ownerWidgetUuid",
203
+ "ownerWidgetSelector",
204
+ "path",
205
+ "enabled"
206
+ ]
207
+ },
208
+ "ConcreteSeriesDefinition": {
209
+ "allOf": [
210
+ {
211
+ "$ref": "#/components/schemas/SeriesDefinitionBase"
212
+ },
213
+ {
214
+ "type": "object",
215
+ "properties": {
216
+ "expansionMode": {
217
+ "nullable": true,
218
+ "description": "Null for concrete series definitions."
219
+ },
220
+ "familyKey": {
221
+ "type": "string",
222
+ "nullable": true,
223
+ "description": "Concrete series do not use family key and should leave this null."
224
+ },
225
+ "allowedIds": {
226
+ "type": "array",
227
+ "nullable": true,
228
+ "items": {
229
+ "type": "string"
230
+ },
231
+ "description": "Concrete series do not use template filters and should leave this null."
232
+ },
233
+ "trackedDevices": {
234
+ "type": "array",
235
+ "nullable": true,
236
+ "items": {
237
+ "type": "object",
238
+ "properties": {
239
+ "id": {
240
+ "type": "string"
241
+ },
242
+ "source": {
243
+ "type": "string"
244
+ }
245
+ },
246
+ "required": [
247
+ "id",
248
+ "source"
249
+ ]
250
+ },
251
+ "description": "Concrete series do not use tracked device template filters and should leave this null."
252
+ }
253
+ }
254
+ }
255
+ ]
256
+ },
257
+ "TemplateSeriesDefinition": {
258
+ "allOf": [
259
+ {
260
+ "$ref": "#/components/schemas/SeriesDefinitionBase"
261
+ },
262
+ {
263
+ "type": "object",
264
+ "properties": {
265
+ "ownerWidgetSelector": {
266
+ "type": "string",
267
+ "enum": [
268
+ "widget-bms",
269
+ "widget-solar-charger",
270
+ "widget-charger",
271
+ "widget-inverter",
272
+ "widget-alternator",
273
+ "widget-ac"
274
+ ]
275
+ },
276
+ "expansionMode": {
277
+ "type": "string",
278
+ "enum": [
279
+ "bms-battery-tree",
280
+ "solar-tree",
281
+ "charger-tree",
282
+ "inverter-tree",
283
+ "alternator-tree",
284
+ "ac-tree"
285
+ ]
286
+ },
287
+ "familyKey": {
288
+ "type": "string",
289
+ "enum": [
290
+ "batteries",
291
+ "solar",
292
+ "chargers",
293
+ "inverters",
294
+ "alternators",
295
+ "ac"
296
+ ]
297
+ },
298
+ "allowedIds": {
299
+ "type": "array",
300
+ "nullable": true,
301
+ "items": {
302
+ "type": "string"
303
+ },
304
+ "description": "Template device IDs to include. Null or empty includes all discovered devices."
305
+ },
306
+ "trackedDevices": {
307
+ "type": "array",
308
+ "nullable": true,
309
+ "items": {
310
+ "type": "object",
311
+ "properties": {
312
+ "id": {
313
+ "type": "string"
314
+ },
315
+ "source": {
316
+ "type": "string"
317
+ }
318
+ },
319
+ "required": [
320
+ "id",
321
+ "source"
322
+ ]
323
+ },
324
+ "description": "Explicit tracked device id/source pairs to expand. When provided, template expansion skips self-tree discovery and emits one concrete series per pair and metric."
325
+ }
326
+ },
327
+ "required": [
328
+ "ownerWidgetSelector",
329
+ "expansionMode",
330
+ "familyKey"
331
+ ]
332
+ }
333
+ ]
334
+ },
335
+ "SeriesDefinition": {
336
+ "oneOf": [
337
+ {
338
+ "$ref": "#/components/schemas/ConcreteSeriesDefinition"
339
+ },
340
+ {
341
+ "$ref": "#/components/schemas/TemplateSeriesDefinition"
342
+ }
343
+ ]
344
+ },
345
+ "SeriesReconcileResult": {
346
+ "type": "object",
347
+ "properties": {
348
+ "created": {
349
+ "type": "integer"
350
+ },
351
+ "updated": {
352
+ "type": "integer"
353
+ },
354
+ "deleted": {
355
+ "type": "integer"
356
+ },
357
+ "total": {
358
+ "type": "integer"
359
+ }
360
+ },
361
+ "required": [
362
+ "created",
363
+ "updated",
364
+ "deleted",
365
+ "total"
366
+ ]
367
+ }
368
+ },
369
+ "parameters": {
370
+ "DisplayIdParam": {
371
+ "in": "path",
372
+ "required": true,
373
+ "name": "displayId",
374
+ "description": "KIP instance UUID",
375
+ "schema": {
376
+ "type": "string"
377
+ }
378
+ },
379
+ "SeriesIdParam": {
380
+ "in": "path",
381
+ "required": true,
382
+ "name": "seriesId",
383
+ "description": "Series identifier (dataset UUID)",
384
+ "schema": {
385
+ "type": "string"
386
+ }
387
+ }
388
+ },
389
+ "securitySchemes": {
390
+ "bearerAuth": {
391
+ "type": "http",
392
+ "scheme": "bearer",
393
+ "bearerFormat": "JWT"
394
+ },
395
+ "cookieAuth": {
396
+ "type": "apiKey",
397
+ "in": "cookie",
398
+ "name": "JAUTHENTICATION"
399
+ }
400
+ }
401
+ },
402
+ "security": [
403
+ {
404
+ "cookieAuth": []
405
+ },
406
+ {
407
+ "bearerAuth": []
408
+ }
409
+ ],
410
+ "paths": {
411
+ "/plugins/kip/displays": {
412
+ "get": {
413
+ "tags": [
414
+ "Displays"
415
+ ],
416
+ "summary": "List available KIP displays",
417
+ "responses": {
418
+ "200": {
419
+ "description": "List of KIP instances discovered under self.displays",
420
+ "content": {
421
+ "application/json": {
422
+ "schema": {
423
+ "type": "array",
424
+ "items": {
425
+ "$ref": "#/components/schemas/DisplayInfo"
426
+ }
427
+ }
428
+ }
429
+ }
430
+ },
431
+ "400": {
432
+ "description": "Bad request",
433
+ "content": {
434
+ "application/json": {
435
+ "schema": {
436
+ "$ref": "#/components/schemas/ErrorResponse"
437
+ }
438
+ }
439
+ }
440
+ }
441
+ }
442
+ }
443
+ },
444
+ "/plugins/kip/displays/{displayId}": {
445
+ "parameters": [
446
+ {
447
+ "$ref": "#/components/parameters/DisplayIdParam"
448
+ }
449
+ ],
450
+ "get": {
451
+ "tags": [
452
+ "Displays"
453
+ ],
454
+ "summary": "List screens for a display (self.displays.{displayId}.value.screens)",
455
+ "responses": {
456
+ "200": {
457
+ "description": "Array of screen entries (or null)",
458
+ "content": {
459
+ "application/json": {
460
+ "schema": {
461
+ "$ref": "#/components/schemas/ScreenListOrNull"
462
+ }
463
+ }
464
+ }
465
+ },
466
+ "404": {
467
+ "description": "Not found",
468
+ "content": {
469
+ "application/json": {
470
+ "schema": {
471
+ "$ref": "#/components/schemas/ErrorResponse"
472
+ }
473
+ }
474
+ }
475
+ },
476
+ "400": {
477
+ "description": "Bad request",
478
+ "content": {
479
+ "application/json": {
480
+ "schema": {
481
+ "$ref": "#/components/schemas/ErrorResponse"
482
+ }
483
+ }
484
+ }
485
+ }
486
+ }
487
+ },
488
+ "put": {
489
+ "tags": [
490
+ "Displays"
491
+ ],
492
+ "summary": "Set display entry under self.displays.{displayId}",
493
+ "requestBody": {
494
+ "required": false,
495
+ "content": {
496
+ "application/json": {
497
+ "schema": {
498
+ "$ref": "#/components/schemas/AnyObjectOrNull"
499
+ }
500
+ }
501
+ }
502
+ },
503
+ "responses": {
504
+ "200": {
505
+ "description": "Updated",
506
+ "content": {
507
+ "application/json": {
508
+ "schema": {
509
+ "$ref": "#/components/schemas/SuccessResponse"
510
+ }
511
+ }
512
+ }
513
+ },
514
+ "400": {
515
+ "description": "Bad request",
516
+ "content": {
517
+ "application/json": {
518
+ "schema": {
519
+ "$ref": "#/components/schemas/ErrorResponse"
520
+ }
521
+ }
522
+ }
523
+ }
524
+ }
525
+ }
526
+ },
527
+ "/plugins/kip/displays/{displayId}/screenIndex": {
528
+ "parameters": [
529
+ {
530
+ "$ref": "#/components/parameters/DisplayIdParam"
531
+ }
532
+ ],
533
+ "get": {
534
+ "tags": [
535
+ "Displays"
536
+ ],
537
+ "summary": "Get current screen index for display (self.displays.{displayId}.screenIndex)",
538
+ "responses": {
539
+ "200": {
540
+ "description": "Current screen index or null",
541
+ "content": {
542
+ "application/json": {
543
+ "schema": {
544
+ "type": "integer",
545
+ "nullable": true
546
+ }
547
+ }
548
+ }
549
+ },
550
+ "404": {
551
+ "description": "Not found",
552
+ "content": {
553
+ "application/json": {
554
+ "schema": {
555
+ "$ref": "#/components/schemas/ErrorResponse"
556
+ }
557
+ }
558
+ }
559
+ },
560
+ "400": {
561
+ "description": "Bad request",
562
+ "content": {
563
+ "application/json": {
564
+ "schema": {
565
+ "$ref": "#/components/schemas/ErrorResponse"
566
+ }
567
+ }
568
+ }
569
+ }
570
+ }
571
+ },
572
+ "put": {
573
+ "tags": [
574
+ "Displays"
575
+ ],
576
+ "summary": "Set current screen index for display (self.displays.{displayId}.screenIndex)",
577
+ "requestBody": {
578
+ "required": false,
579
+ "content": {
580
+ "application/json": {
581
+ "schema": {
582
+ "$ref": "#/components/schemas/ActiveScreenSetRequest"
583
+ }
584
+ }
585
+ }
586
+ },
587
+ "responses": {
588
+ "200": {
589
+ "description": "Updated",
590
+ "content": {
591
+ "application/json": {
592
+ "schema": {
593
+ "$ref": "#/components/schemas/SuccessResponse"
594
+ }
595
+ }
596
+ }
597
+ },
598
+ "400": {
599
+ "description": "Bad request",
600
+ "content": {
601
+ "application/json": {
602
+ "schema": {
603
+ "$ref": "#/components/schemas/ErrorResponse"
604
+ }
605
+ }
606
+ }
607
+ }
608
+ }
609
+ }
610
+ },
611
+ "/plugins/kip/displays/{displayId}/activeScreen": {
612
+ "parameters": [
613
+ {
614
+ "$ref": "#/components/parameters/DisplayIdParam"
615
+ }
616
+ ],
617
+ "get": {
618
+ "tags": [
619
+ "Displays"
620
+ ],
621
+ "summary": "Get requested screen change index (self.displays.{displayId}.activeScreen)",
622
+ "responses": {
623
+ "200": {
624
+ "description": "Requested screen index or null",
625
+ "content": {
626
+ "application/json": {
627
+ "schema": {
628
+ "type": "integer",
629
+ "nullable": true
630
+ }
631
+ }
632
+ }
633
+ },
634
+ "404": {
635
+ "description": "Not found",
636
+ "content": {
637
+ "application/json": {
638
+ "schema": {
639
+ "$ref": "#/components/schemas/ErrorResponse"
640
+ }
641
+ }
642
+ }
643
+ },
644
+ "400": {
645
+ "description": "Bad request",
646
+ "content": {
647
+ "application/json": {
648
+ "schema": {
649
+ "$ref": "#/components/schemas/ErrorResponse"
650
+ }
651
+ }
652
+ }
653
+ }
654
+ }
655
+ },
656
+ "put": {
657
+ "tags": [
658
+ "Displays"
659
+ ],
660
+ "summary": "Request a screen change (sets self.displays.{displayId}.activeScreen)",
661
+ "requestBody": {
662
+ "required": false,
663
+ "content": {
664
+ "application/json": {
665
+ "schema": {
666
+ "$ref": "#/components/schemas/ActiveScreenSetRequest"
667
+ }
668
+ }
669
+ }
670
+ },
671
+ "responses": {
672
+ "200": {
673
+ "description": "Updated",
674
+ "content": {
675
+ "application/json": {
676
+ "schema": {
677
+ "$ref": "#/components/schemas/SuccessResponse"
678
+ }
679
+ }
680
+ }
681
+ },
682
+ "400": {
683
+ "description": "Bad request",
684
+ "content": {
685
+ "application/json": {
686
+ "schema": {
687
+ "$ref": "#/components/schemas/ErrorResponse"
688
+ }
689
+ }
690
+ }
691
+ }
692
+ }
693
+ }
694
+ },
695
+ "/plugins/kip/series": {
696
+ "get": {
697
+ "tags": [
698
+ "Series"
699
+ ],
700
+ "summary": "List all configured history series",
701
+ "responses": {
702
+ "200": {
703
+ "description": "Current series definitions",
704
+ "content": {
705
+ "application/json": {
706
+ "schema": {
707
+ "type": "array",
708
+ "items": {
709
+ "$ref": "#/components/schemas/SeriesDefinition"
710
+ }
711
+ }
712
+ }
713
+ }
714
+ },
715
+ "400": {
716
+ "description": "Bad request",
717
+ "content": {
718
+ "application/json": {
719
+ "schema": {
720
+ "$ref": "#/components/schemas/ErrorResponse"
721
+ }
722
+ }
723
+ }
724
+ }
725
+ }
726
+ }
727
+ },
728
+ "/plugins/kip/series/{seriesId}": {
729
+ "parameters": [
730
+ {
731
+ "$ref": "#/components/parameters/SeriesIdParam"
732
+ }
733
+ ],
734
+ "put": {
735
+ "tags": [
736
+ "Series"
737
+ ],
738
+ "summary": "Create or update a series definition",
739
+ "requestBody": {
740
+ "required": true,
741
+ "content": {
742
+ "application/json": {
743
+ "schema": {
744
+ "$ref": "#/components/schemas/SeriesDefinition"
745
+ }
746
+ }
747
+ }
748
+ },
749
+ "responses": {
750
+ "200": {
751
+ "description": "Series upserted",
752
+ "content": {
753
+ "application/json": {
754
+ "schema": {
755
+ "$ref": "#/components/schemas/SeriesDefinition"
756
+ }
757
+ }
758
+ }
759
+ },
760
+ "400": {
761
+ "description": "Bad request",
762
+ "content": {
763
+ "application/json": {
764
+ "schema": {
765
+ "$ref": "#/components/schemas/ErrorResponse"
766
+ }
767
+ }
768
+ }
769
+ }
770
+ }
771
+ },
772
+ "delete": {
773
+ "tags": [
774
+ "Series"
775
+ ],
776
+ "summary": "Delete a series definition",
777
+ "responses": {
778
+ "200": {
779
+ "description": "Series removed",
780
+ "content": {
781
+ "application/json": {
782
+ "schema": {
783
+ "$ref": "#/components/schemas/SuccessResponse"
784
+ }
785
+ }
786
+ }
787
+ },
788
+ "404": {
789
+ "description": "Series not found",
790
+ "content": {
791
+ "application/json": {
792
+ "schema": {
793
+ "$ref": "#/components/schemas/ErrorResponse"
794
+ }
795
+ }
796
+ }
797
+ },
798
+ "400": {
799
+ "description": "Bad request",
800
+ "content": {
801
+ "application/json": {
802
+ "schema": {
803
+ "$ref": "#/components/schemas/ErrorResponse"
804
+ }
805
+ }
806
+ }
807
+ }
808
+ }
809
+ }
810
+ },
811
+ "/plugins/kip/series/reconcile": {
812
+ "post": {
813
+ "tags": [
814
+ "Series"
815
+ ],
816
+ "summary": "Reconcile full desired series set",
817
+ "requestBody": {
818
+ "required": true,
819
+ "content": {
820
+ "application/json": {
821
+ "schema": {
822
+ "type": "array",
823
+ "items": {
824
+ "$ref": "#/components/schemas/SeriesDefinition"
825
+ }
826
+ }
827
+ }
828
+ }
829
+ },
830
+ "responses": {
831
+ "200": {
832
+ "description": "Reconcile summary",
833
+ "content": {
834
+ "application/json": {
835
+ "schema": {
836
+ "$ref": "#/components/schemas/SeriesReconcileResult"
837
+ }
838
+ }
839
+ }
840
+ },
841
+ "400": {
842
+ "description": "Bad request",
843
+ "content": {
844
+ "application/json": {
845
+ "schema": {
846
+ "$ref": "#/components/schemas/ErrorResponse"
847
+ }
848
+ }
849
+ }
850
+ }
851
+ }
852
+ }
853
+ }
854
+ }
855
+ }