@betterportal/config-manager 10.1.32 → 10.1.33

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 (51) hide show
  1. package/lib/.bsb/clients/service-betterportal-config-manager.d.ts +1 -1
  2. package/lib/.bsb/clients/service-betterportal-config-manager.js +1 -1
  3. package/lib/bp-contracts/org.betterportal.config-manager.json +2761 -0
  4. package/lib/plugins/service-betterportal-config-manager/adminApi.d.ts +199 -1
  5. package/lib/plugins/service-betterportal-config-manager/adminApi.d.ts.map +1 -1
  6. package/lib/plugins/service-betterportal-config-manager/adminApi.js +56 -7
  7. package/lib/plugins/service-betterportal-config-manager/adminApi.js.map +1 -1
  8. package/lib/plugins/service-betterportal-config-manager/bootstrapEndpoint.js +4 -4
  9. package/lib/plugins/service-betterportal-config-manager/bootstrapEndpoint.js.map +1 -1
  10. package/lib/plugins/service-betterportal-config-manager/bp-routes/auth/route.impl.js +1 -1
  11. package/lib/plugins/service-betterportal-config-manager/bp-routes/auth/route.impl.js.map +1 -1
  12. package/lib/plugins/service-betterportal-config-manager/bp-routes/config/route.impl.js +1 -1
  13. package/lib/plugins/service-betterportal-config-manager/bp-routes/config/route.impl.js.map +1 -1
  14. package/lib/plugins/service-betterportal-config-manager/bp-routes/fragments/route.impl.js +1 -1
  15. package/lib/plugins/service-betterportal-config-manager/bp-routes/fragments/route.impl.js.map +1 -1
  16. package/lib/plugins/service-betterportal-config-manager/bp-routes/menu/route.impl.js +1 -1
  17. package/lib/plugins/service-betterportal-config-manager/bp-routes/menu/route.impl.js.map +1 -1
  18. package/lib/plugins/service-betterportal-config-manager/bp-routes/preview/route.impl.js +1 -1
  19. package/lib/plugins/service-betterportal-config-manager/bp-routes/preview/route.impl.js.map +1 -1
  20. package/lib/plugins/service-betterportal-config-manager/bp-routes/routes/route.impl.js +1 -1
  21. package/lib/plugins/service-betterportal-config-manager/bp-routes/routes/route.impl.js.map +1 -1
  22. package/lib/plugins/service-betterportal-config-manager/bp-routes/services/_theme.bootstrap1/GET.js +1 -1
  23. package/lib/plugins/service-betterportal-config-manager/bp-routes/services/_theme.bootstrap1/GET.js.map +1 -1
  24. package/lib/plugins/service-betterportal-config-manager/bp-routes/services/route.impl.js +1 -1
  25. package/lib/plugins/service-betterportal-config-manager/bp-routes/services/route.impl.js.map +1 -1
  26. package/lib/plugins/service-betterportal-config-manager/bp-routes/settings/route.impl.js +1 -1
  27. package/lib/plugins/service-betterportal-config-manager/bp-routes/settings/route.impl.js.map +1 -1
  28. package/lib/plugins/service-betterportal-config-manager/bp-routes/tenants/route.impl.js +2 -2
  29. package/lib/plugins/service-betterportal-config-manager/bp-routes/tenants/route.impl.js.map +1 -1
  30. package/lib/plugins/service-betterportal-config-manager/index.d.ts.map +1 -1
  31. package/lib/plugins/service-betterportal-config-manager/index.js +2 -1
  32. package/lib/plugins/service-betterportal-config-manager/index.js.map +1 -1
  33. package/lib/plugins/service-betterportal-config-manager/setupTokens.js +1 -1
  34. package/lib/plugins/service-betterportal-config-manager/setupTokens.js.map +1 -1
  35. package/lib/plugins/service-betterportal-config-manager/storage/core.d.ts +5 -0
  36. package/lib/plugins/service-betterportal-config-manager/storage/core.d.ts.map +1 -1
  37. package/lib/plugins/service-betterportal-config-manager/storage/core.js +115 -3
  38. package/lib/plugins/service-betterportal-config-manager/storage/core.js.map +1 -1
  39. package/lib/plugins/service-betterportal-config-manager/storage/file.d.ts.map +1 -1
  40. package/lib/plugins/service-betterportal-config-manager/storage/file.js +3 -3
  41. package/lib/plugins/service-betterportal-config-manager/storage/file.js.map +1 -1
  42. package/lib/plugins/service-betterportal-config-manager/storage/postgres.d.ts.map +1 -1
  43. package/lib/plugins/service-betterportal-config-manager/storage/postgres.js +3 -3
  44. package/lib/plugins/service-betterportal-config-manager/storage/postgres.js.map +1 -1
  45. package/lib/plugins/service-betterportal-config-manager/syncApi.d.ts +3 -1
  46. package/lib/plugins/service-betterportal-config-manager/syncApi.d.ts.map +1 -1
  47. package/lib/plugins/service-betterportal-config-manager/syncApi.js +43 -1
  48. package/lib/plugins/service-betterportal-config-manager/syncApi.js.map +1 -1
  49. package/lib/schemas/service-betterportal-config-manager.json +1 -1
  50. package/lib/schemas/service-betterportal-config-manager.plugin.json +1 -1
  51. package/package.json +15 -5
@@ -0,0 +1,2761 @@
1
+ {
2
+ "manifest": {
3
+ "protocolVersion": 1,
4
+ "pluginId": "org.betterportal.config-manager",
5
+ "title": "BetterPortal Config Manager",
6
+ "description": "Admin-facing BetterPortal service for discovering and managing service config surfaces.",
7
+ "version": "10.1.33",
8
+ "category": "service",
9
+ "deploymentModes": [
10
+ "self-hosted"
11
+ ],
12
+ "capabilities": [
13
+ "view.json",
14
+ "view.metadata",
15
+ "theme.bootstrap1",
16
+ "view.html",
17
+ "theme.embedded"
18
+ ],
19
+ "supportedThemes": [
20
+ "bootstrap1",
21
+ "embedded"
22
+ ],
23
+ "supportedRenderModes": [
24
+ "page"
25
+ ],
26
+ "views": [
27
+ {
28
+ "viewId": "auth.index",
29
+ "title": "Permission Manager",
30
+ "description": "Define role -> permission grants per app. Services advertise per-view permission requirements via their manifest.",
31
+ "path": "/auth",
32
+ "methods": [
33
+ "GET"
34
+ ],
35
+ "paramsSchema": {},
36
+ "querySchema": {
37
+ "anyvaliVersion": "1.0",
38
+ "schemaVersion": "1.1",
39
+ "root": {
40
+ "kind": "object",
41
+ "properties": {
42
+ "appId": {
43
+ "kind": "optional",
44
+ "inner": {
45
+ "kind": "string",
46
+ "minLength": 1
47
+ }
48
+ }
49
+ },
50
+ "required": [],
51
+ "unknownKeys": "strip"
52
+ },
53
+ "definitions": {},
54
+ "extensions": {}
55
+ },
56
+ "headersSchema": {
57
+ "anyvaliVersion": "1.0",
58
+ "schemaVersion": "1.1",
59
+ "root": {
60
+ "kind": "object",
61
+ "properties": {},
62
+ "required": [],
63
+ "unknownKeys": "strip"
64
+ },
65
+ "definitions": {},
66
+ "extensions": {}
67
+ },
68
+ "bodySchema": {
69
+ "anyvaliVersion": "1.0",
70
+ "schemaVersion": "1.1",
71
+ "root": {
72
+ "kind": "object",
73
+ "properties": {},
74
+ "required": [],
75
+ "unknownKeys": "strip"
76
+ },
77
+ "definitions": {},
78
+ "extensions": {}
79
+ },
80
+ "jsonResponseSchema": {
81
+ "anyvaliVersion": "1.0",
82
+ "schemaVersion": "1.1",
83
+ "root": {
84
+ "kind": "object",
85
+ "properties": {
86
+ "title": {
87
+ "kind": "string",
88
+ "minLength": 1
89
+ },
90
+ "apps": {
91
+ "kind": "array",
92
+ "items": {
93
+ "kind": "object",
94
+ "properties": {
95
+ "id": {
96
+ "kind": "string",
97
+ "minLength": 1
98
+ },
99
+ "tenantId": {
100
+ "kind": "string",
101
+ "minLength": 1
102
+ },
103
+ "title": {
104
+ "kind": "string",
105
+ "minLength": 1
106
+ }
107
+ },
108
+ "required": [
109
+ "id",
110
+ "tenantId",
111
+ "title"
112
+ ],
113
+ "unknownKeys": "strip"
114
+ },
115
+ "default": []
116
+ },
117
+ "selectedAppId": {
118
+ "kind": "optional",
119
+ "inner": {
120
+ "kind": "string"
121
+ }
122
+ },
123
+ "selectedTenantId": {
124
+ "kind": "optional",
125
+ "inner": {
126
+ "kind": "string"
127
+ }
128
+ },
129
+ "authConfigured": {
130
+ "kind": "bool",
131
+ "default": false
132
+ },
133
+ "servicePermissions": {
134
+ "kind": "array",
135
+ "items": {
136
+ "kind": "object",
137
+ "properties": {
138
+ "serviceId": {
139
+ "kind": "string",
140
+ "minLength": 1
141
+ },
142
+ "title": {
143
+ "kind": "string",
144
+ "minLength": 1
145
+ },
146
+ "hostname": {
147
+ "kind": "string"
148
+ },
149
+ "manifestVersion": {
150
+ "kind": "optional",
151
+ "inner": {
152
+ "kind": "string"
153
+ }
154
+ },
155
+ "views": {
156
+ "kind": "array",
157
+ "items": {
158
+ "kind": "object",
159
+ "properties": {
160
+ "viewId": {
161
+ "kind": "string",
162
+ "minLength": 1
163
+ },
164
+ "path": {
165
+ "kind": "string",
166
+ "minLength": 1
167
+ },
168
+ "methods": {
169
+ "kind": "array",
170
+ "items": {
171
+ "kind": "string"
172
+ },
173
+ "default": []
174
+ },
175
+ "role": {
176
+ "kind": "optional",
177
+ "inner": {
178
+ "kind": "string"
179
+ }
180
+ },
181
+ "requiredPermissions": {
182
+ "kind": "array",
183
+ "items": {
184
+ "kind": "object",
185
+ "properties": {
186
+ "serviceId": {
187
+ "kind": "string",
188
+ "minLength": 1
189
+ },
190
+ "viewId": {
191
+ "kind": "string",
192
+ "minLength": 1
193
+ },
194
+ "permissions": {
195
+ "kind": "array",
196
+ "items": {
197
+ "kind": "string"
198
+ }
199
+ }
200
+ },
201
+ "required": [
202
+ "serviceId",
203
+ "viewId",
204
+ "permissions"
205
+ ],
206
+ "unknownKeys": "strip"
207
+ },
208
+ "default": []
209
+ }
210
+ },
211
+ "required": [
212
+ "viewId",
213
+ "path",
214
+ "methods",
215
+ "requiredPermissions"
216
+ ],
217
+ "unknownKeys": "strip"
218
+ },
219
+ "default": []
220
+ }
221
+ },
222
+ "required": [
223
+ "serviceId",
224
+ "title",
225
+ "hostname",
226
+ "views"
227
+ ],
228
+ "unknownKeys": "strip"
229
+ },
230
+ "default": []
231
+ },
232
+ "currentRoles": {
233
+ "kind": "array",
234
+ "items": {
235
+ "kind": "object",
236
+ "properties": {
237
+ "id": {
238
+ "kind": "string",
239
+ "minLength": 1
240
+ },
241
+ "title": {
242
+ "kind": "string",
243
+ "minLength": 1
244
+ },
245
+ "description": {
246
+ "kind": "optional",
247
+ "inner": {
248
+ "kind": "string"
249
+ }
250
+ },
251
+ "permissions": {
252
+ "kind": "array",
253
+ "items": {
254
+ "kind": "object",
255
+ "properties": {
256
+ "serviceId": {
257
+ "kind": "string",
258
+ "minLength": 1
259
+ },
260
+ "viewId": {
261
+ "kind": "string",
262
+ "minLength": 1
263
+ },
264
+ "permissions": {
265
+ "kind": "array",
266
+ "items": {
267
+ "kind": "enum",
268
+ "values": [
269
+ "read",
270
+ "create",
271
+ "update",
272
+ "delete"
273
+ ]
274
+ },
275
+ "minItems": 1
276
+ }
277
+ },
278
+ "required": [
279
+ "serviceId",
280
+ "viewId",
281
+ "permissions"
282
+ ],
283
+ "unknownKeys": "strip"
284
+ },
285
+ "default": []
286
+ }
287
+ },
288
+ "required": [
289
+ "id",
290
+ "title",
291
+ "permissions"
292
+ ],
293
+ "unknownKeys": "strip"
294
+ },
295
+ "default": []
296
+ },
297
+ "externalRoleSync": {
298
+ "kind": "optional",
299
+ "inner": {
300
+ "kind": "object",
301
+ "properties": {
302
+ "serviceTitle": {
303
+ "kind": "string",
304
+ "minLength": 1
305
+ },
306
+ "fragmentUrl": {
307
+ "kind": "string",
308
+ "minLength": 1
309
+ }
310
+ },
311
+ "required": [
312
+ "serviceTitle",
313
+ "fragmentUrl"
314
+ ],
315
+ "unknownKeys": "strip"
316
+ }
317
+ },
318
+ "managedRoleSync": {
319
+ "kind": "optional",
320
+ "inner": {
321
+ "kind": "object",
322
+ "properties": {
323
+ "serviceTitle": {
324
+ "kind": "string",
325
+ "minLength": 1
326
+ },
327
+ "syncUrl": {
328
+ "kind": "string",
329
+ "minLength": 1
330
+ }
331
+ },
332
+ "required": [
333
+ "serviceTitle",
334
+ "syncUrl"
335
+ ],
336
+ "unknownKeys": "strip"
337
+ }
338
+ },
339
+ "adminApiBase": {
340
+ "kind": "string",
341
+ "default": "/.well-known/bp/admin"
342
+ },
343
+ "serviceBaseUrl": {
344
+ "kind": "optional",
345
+ "inner": {
346
+ "kind": "string"
347
+ }
348
+ }
349
+ },
350
+ "required": [
351
+ "title",
352
+ "apps",
353
+ "authConfigured",
354
+ "servicePermissions",
355
+ "currentRoles",
356
+ "adminApiBase"
357
+ ],
358
+ "unknownKeys": "strip"
359
+ },
360
+ "definitions": {},
361
+ "extensions": {}
362
+ },
363
+ "metadataResponseSchema": {},
364
+ "renderable": true,
365
+ "html": {
366
+ "themeRenderers": {
367
+ "bootstrap1": {
368
+ "defaultRenderer": "default",
369
+ "renderModes": [
370
+ "page"
371
+ ],
372
+ "slots": [
373
+ "main"
374
+ ],
375
+ "renderers": [
376
+ {
377
+ "id": "default",
378
+ "title": "Default Content",
379
+ "slotId": "main",
380
+ "renderModes": [
381
+ "page",
382
+ "fragment"
383
+ ]
384
+ }
385
+ ]
386
+ }
387
+ }
388
+ },
389
+ "auth": {
390
+ "required": true,
391
+ "permissions": [
392
+ {
393
+ "serviceId": "org.betterportal.config-manager",
394
+ "viewId": "auth.index",
395
+ "permissions": [
396
+ "read",
397
+ "create",
398
+ "update",
399
+ "delete"
400
+ ]
401
+ }
402
+ ]
403
+ },
404
+ "dependencies": [],
405
+ "apiContracts": [],
406
+ "demoScenarios": [],
407
+ "cacheHints": {
408
+ "ttlSeconds": 0,
409
+ "varyBy": [
410
+ "accept",
411
+ "origin"
412
+ ]
413
+ }
414
+ },
415
+ {
416
+ "viewId": "config.index",
417
+ "title": "Config Manager",
418
+ "description": "Admin service that discovers BetterPortal service config surfaces.",
419
+ "path": "/config",
420
+ "methods": [
421
+ "GET"
422
+ ],
423
+ "paramsSchema": {},
424
+ "querySchema": {
425
+ "anyvaliVersion": "1.0",
426
+ "schemaVersion": "1.1",
427
+ "root": {
428
+ "kind": "object",
429
+ "properties": {},
430
+ "required": [],
431
+ "unknownKeys": "strip"
432
+ },
433
+ "definitions": {},
434
+ "extensions": {}
435
+ },
436
+ "headersSchema": {
437
+ "anyvaliVersion": "1.0",
438
+ "schemaVersion": "1.1",
439
+ "root": {
440
+ "kind": "object",
441
+ "properties": {},
442
+ "required": [],
443
+ "unknownKeys": "strip"
444
+ },
445
+ "definitions": {},
446
+ "extensions": {}
447
+ },
448
+ "bodySchema": {
449
+ "anyvaliVersion": "1.0",
450
+ "schemaVersion": "1.1",
451
+ "root": {
452
+ "kind": "object",
453
+ "properties": {},
454
+ "required": [],
455
+ "unknownKeys": "strip"
456
+ },
457
+ "definitions": {},
458
+ "extensions": {}
459
+ },
460
+ "jsonResponseSchema": {
461
+ "anyvaliVersion": "1.0",
462
+ "schemaVersion": "1.1",
463
+ "root": {
464
+ "kind": "object",
465
+ "properties": {
466
+ "title": {
467
+ "kind": "string",
468
+ "minLength": 1
469
+ },
470
+ "tenantId": {
471
+ "kind": "string",
472
+ "minLength": 1
473
+ },
474
+ "appId": {
475
+ "kind": "string",
476
+ "minLength": 1
477
+ },
478
+ "requestTimeoutMs": {
479
+ "kind": "int",
480
+ "min": 1
481
+ },
482
+ "services": {
483
+ "kind": "array",
484
+ "items": {
485
+ "kind": "object",
486
+ "properties": {
487
+ "serviceId": {
488
+ "kind": "string",
489
+ "minLength": 1
490
+ },
491
+ "bindingId": {
492
+ "kind": "string",
493
+ "minLength": 1
494
+ },
495
+ "endpointBaseUrl": {
496
+ "kind": "string",
497
+ "format": "url"
498
+ },
499
+ "deploymentMode": {
500
+ "kind": "string",
501
+ "minLength": 1
502
+ },
503
+ "healthUrl": {
504
+ "kind": "string",
505
+ "format": "url"
506
+ },
507
+ "schemaUrl": {
508
+ "kind": "string",
509
+ "format": "url"
510
+ },
511
+ "manifestUrl": {
512
+ "kind": "string",
513
+ "format": "url"
514
+ }
515
+ },
516
+ "required": [
517
+ "serviceId",
518
+ "bindingId",
519
+ "endpointBaseUrl",
520
+ "deploymentMode",
521
+ "healthUrl",
522
+ "schemaUrl",
523
+ "manifestUrl"
524
+ ],
525
+ "unknownKeys": "strip"
526
+ }
527
+ }
528
+ },
529
+ "required": [
530
+ "title",
531
+ "tenantId",
532
+ "appId",
533
+ "requestTimeoutMs",
534
+ "services"
535
+ ],
536
+ "unknownKeys": "strip"
537
+ },
538
+ "definitions": {},
539
+ "extensions": {}
540
+ },
541
+ "metadataResponseSchema": {},
542
+ "renderable": true,
543
+ "html": {
544
+ "themeRenderers": {
545
+ "bootstrap1": {
546
+ "defaultRenderer": "default",
547
+ "renderModes": [
548
+ "page"
549
+ ],
550
+ "slots": [
551
+ "main"
552
+ ],
553
+ "renderers": [
554
+ {
555
+ "id": "default",
556
+ "title": "Default Content",
557
+ "slotId": "main",
558
+ "renderModes": [
559
+ "page",
560
+ "fragment"
561
+ ]
562
+ }
563
+ ]
564
+ },
565
+ "embedded": {
566
+ "defaultRenderer": "default",
567
+ "renderModes": [
568
+ "page"
569
+ ],
570
+ "slots": [
571
+ "main"
572
+ ],
573
+ "renderers": [
574
+ {
575
+ "id": "default",
576
+ "title": "Default Content",
577
+ "slotId": "main",
578
+ "renderModes": [
579
+ "page",
580
+ "fragment"
581
+ ]
582
+ }
583
+ ]
584
+ }
585
+ }
586
+ },
587
+ "auth": {
588
+ "required": true,
589
+ "permissions": [
590
+ {
591
+ "serviceId": "org.betterportal.config-manager",
592
+ "viewId": "config.index",
593
+ "permissions": [
594
+ "read",
595
+ "update"
596
+ ]
597
+ }
598
+ ]
599
+ },
600
+ "dependencies": [],
601
+ "apiContracts": [],
602
+ "demoScenarios": [
603
+ {
604
+ "id": "default",
605
+ "title": "Default Config Admin",
606
+ "match": {
607
+ "query": {}
608
+ },
609
+ "response": {
610
+ "title": "Config Manager",
611
+ "tenantId": "tenant-main",
612
+ "appId": "app-main",
613
+ "requestTimeoutMs": 2000,
614
+ "services": []
615
+ }
616
+ }
617
+ ],
618
+ "cacheHints": {
619
+ "ttlSeconds": 30,
620
+ "varyBy": [
621
+ "accept",
622
+ "origin",
623
+ "referer",
624
+ ":origin",
625
+ ":referer"
626
+ ]
627
+ }
628
+ },
629
+ {
630
+ "viewId": "fragments.index",
631
+ "title": "Fragments",
632
+ "description": "Manage topbar/footer fragments per app.",
633
+ "path": "/fragments",
634
+ "methods": [
635
+ "GET"
636
+ ],
637
+ "paramsSchema": {},
638
+ "querySchema": {},
639
+ "headersSchema": {},
640
+ "bodySchema": {},
641
+ "jsonResponseSchema": {
642
+ "anyvaliVersion": "1.0",
643
+ "schemaVersion": "1.1",
644
+ "root": {
645
+ "kind": "object",
646
+ "properties": {
647
+ "title": {
648
+ "kind": "string",
649
+ "minLength": 1
650
+ },
651
+ "apps": {
652
+ "kind": "array",
653
+ "items": {
654
+ "kind": "object",
655
+ "properties": {
656
+ "id": {
657
+ "kind": "string",
658
+ "minLength": 1
659
+ },
660
+ "title": {
661
+ "kind": "string",
662
+ "minLength": 1
663
+ },
664
+ "tenantId": {
665
+ "kind": "string",
666
+ "minLength": 1
667
+ }
668
+ },
669
+ "required": [
670
+ "id",
671
+ "title",
672
+ "tenantId"
673
+ ],
674
+ "unknownKeys": "strip"
675
+ }
676
+ },
677
+ "selectedAppId": {
678
+ "kind": "optional",
679
+ "inner": {
680
+ "kind": "string"
681
+ }
682
+ },
683
+ "adminApiBase": {
684
+ "kind": "string",
685
+ "minLength": 1
686
+ },
687
+ "serviceBaseUrl": {
688
+ "kind": "string",
689
+ "minLength": 1
690
+ }
691
+ },
692
+ "required": [
693
+ "title",
694
+ "apps",
695
+ "adminApiBase",
696
+ "serviceBaseUrl"
697
+ ],
698
+ "unknownKeys": "strip"
699
+ },
700
+ "definitions": {},
701
+ "extensions": {}
702
+ },
703
+ "metadataResponseSchema": {},
704
+ "renderable": true,
705
+ "html": {
706
+ "themeRenderers": {
707
+ "bootstrap1": {
708
+ "defaultRenderer": "default",
709
+ "renderModes": [
710
+ "page"
711
+ ],
712
+ "slots": [
713
+ "main"
714
+ ],
715
+ "renderers": [
716
+ {
717
+ "id": "default",
718
+ "title": "Default Content",
719
+ "slotId": "main",
720
+ "renderModes": [
721
+ "page",
722
+ "fragment"
723
+ ]
724
+ }
725
+ ]
726
+ }
727
+ }
728
+ },
729
+ "auth": {
730
+ "required": true,
731
+ "permissions": [
732
+ {
733
+ "serviceId": "org.betterportal.config-manager",
734
+ "viewId": "fragments.index",
735
+ "permissions": [
736
+ "read",
737
+ "create",
738
+ "update",
739
+ "delete"
740
+ ]
741
+ }
742
+ ]
743
+ },
744
+ "dependencies": [],
745
+ "apiContracts": [],
746
+ "demoScenarios": [
747
+ {
748
+ "id": "default",
749
+ "title": "Default",
750
+ "response": {
751
+ "title": "Fragments",
752
+ "apps": [],
753
+ "adminApiBase": "/.well-known/bp/admin",
754
+ "serviceBaseUrl": ""
755
+ }
756
+ }
757
+ ],
758
+ "cacheHints": {
759
+ "ttlSeconds": 0,
760
+ "varyBy": [
761
+ "accept",
762
+ "origin"
763
+ ]
764
+ }
765
+ },
766
+ {
767
+ "viewId": "menu.index",
768
+ "title": "Menu Designer",
769
+ "description": "Design app navigation menu.",
770
+ "path": "/menu",
771
+ "methods": [
772
+ "GET"
773
+ ],
774
+ "paramsSchema": {},
775
+ "querySchema": {},
776
+ "headersSchema": {},
777
+ "bodySchema": {},
778
+ "jsonResponseSchema": {
779
+ "anyvaliVersion": "1.0",
780
+ "schemaVersion": "1.1",
781
+ "root": {
782
+ "kind": "object",
783
+ "properties": {
784
+ "title": {
785
+ "kind": "string",
786
+ "minLength": 1
787
+ },
788
+ "apps": {
789
+ "kind": "array",
790
+ "items": {
791
+ "kind": "object",
792
+ "properties": {
793
+ "id": {
794
+ "kind": "string",
795
+ "minLength": 1
796
+ },
797
+ "title": {
798
+ "kind": "string",
799
+ "minLength": 1
800
+ },
801
+ "tenantId": {
802
+ "kind": "string",
803
+ "minLength": 1
804
+ }
805
+ },
806
+ "required": [
807
+ "id",
808
+ "title",
809
+ "tenantId"
810
+ ],
811
+ "unknownKeys": "strip"
812
+ }
813
+ },
814
+ "selectedAppId": {
815
+ "kind": "optional",
816
+ "inner": {
817
+ "kind": "string"
818
+ }
819
+ },
820
+ "menu": {
821
+ "kind": "array",
822
+ "items": {
823
+ "kind": "object",
824
+ "properties": {
825
+ "id": {
826
+ "kind": "string",
827
+ "minLength": 1
828
+ },
829
+ "type": {
830
+ "kind": "string",
831
+ "minLength": 1
832
+ },
833
+ "title": {
834
+ "kind": "optional",
835
+ "inner": {
836
+ "kind": "string"
837
+ }
838
+ },
839
+ "routeId": {
840
+ "kind": "optional",
841
+ "inner": {
842
+ "kind": "string"
843
+ }
844
+ },
845
+ "href": {
846
+ "kind": "optional",
847
+ "inner": {
848
+ "kind": "string"
849
+ }
850
+ },
851
+ "enabled": {
852
+ "kind": "bool"
853
+ },
854
+ "defaultExpanded": {
855
+ "kind": "optional",
856
+ "inner": {
857
+ "kind": "bool"
858
+ }
859
+ }
860
+ },
861
+ "required": [
862
+ "id",
863
+ "type",
864
+ "enabled"
865
+ ],
866
+ "unknownKeys": "strip"
867
+ },
868
+ "default": []
869
+ },
870
+ "routes": {
871
+ "kind": "array",
872
+ "items": {
873
+ "kind": "object",
874
+ "properties": {
875
+ "id": {
876
+ "kind": "string",
877
+ "minLength": 1
878
+ },
879
+ "path": {
880
+ "kind": "string",
881
+ "minLength": 1
882
+ },
883
+ "title": {
884
+ "kind": "string"
885
+ }
886
+ },
887
+ "required": [
888
+ "id",
889
+ "path",
890
+ "title"
891
+ ],
892
+ "unknownKeys": "strip"
893
+ },
894
+ "default": []
895
+ },
896
+ "adminApiBase": {
897
+ "kind": "string",
898
+ "minLength": 1
899
+ },
900
+ "serviceBaseUrl": {
901
+ "kind": "string",
902
+ "minLength": 1
903
+ }
904
+ },
905
+ "required": [
906
+ "title",
907
+ "apps",
908
+ "menu",
909
+ "routes",
910
+ "adminApiBase",
911
+ "serviceBaseUrl"
912
+ ],
913
+ "unknownKeys": "strip"
914
+ },
915
+ "definitions": {},
916
+ "extensions": {}
917
+ },
918
+ "metadataResponseSchema": {},
919
+ "renderable": true,
920
+ "html": {
921
+ "themeRenderers": {
922
+ "bootstrap1": {
923
+ "defaultRenderer": "default",
924
+ "renderModes": [
925
+ "page"
926
+ ],
927
+ "slots": [
928
+ "main"
929
+ ],
930
+ "renderers": [
931
+ {
932
+ "id": "default",
933
+ "title": "Default Content",
934
+ "slotId": "main",
935
+ "renderModes": [
936
+ "page",
937
+ "fragment"
938
+ ]
939
+ }
940
+ ]
941
+ }
942
+ }
943
+ },
944
+ "auth": {
945
+ "required": true,
946
+ "permissions": [
947
+ {
948
+ "serviceId": "org.betterportal.config-manager",
949
+ "viewId": "menu.index",
950
+ "permissions": [
951
+ "read",
952
+ "create",
953
+ "update",
954
+ "delete"
955
+ ]
956
+ }
957
+ ]
958
+ },
959
+ "dependencies": [],
960
+ "apiContracts": [],
961
+ "demoScenarios": [
962
+ {
963
+ "id": "default",
964
+ "title": "Default",
965
+ "response": {
966
+ "title": "Menu Designer",
967
+ "apps": [],
968
+ "menu": [],
969
+ "routes": [],
970
+ "adminApiBase": "/.well-known/bp/admin",
971
+ "serviceBaseUrl": ""
972
+ }
973
+ }
974
+ ],
975
+ "cacheHints": {
976
+ "ttlSeconds": 0,
977
+ "varyBy": [
978
+ "accept",
979
+ "origin"
980
+ ]
981
+ }
982
+ },
983
+ {
984
+ "viewId": "preview.index",
985
+ "title": "Component Preview",
986
+ "description": "Browse and preview service views, components, and fragments.",
987
+ "path": "/preview",
988
+ "methods": [
989
+ "GET"
990
+ ],
991
+ "paramsSchema": {},
992
+ "querySchema": {},
993
+ "headersSchema": {},
994
+ "bodySchema": {},
995
+ "jsonResponseSchema": {
996
+ "anyvaliVersion": "1.0",
997
+ "schemaVersion": "1.1",
998
+ "root": {
999
+ "kind": "object",
1000
+ "properties": {
1001
+ "title": {
1002
+ "kind": "string",
1003
+ "minLength": 1
1004
+ },
1005
+ "services": {
1006
+ "kind": "array",
1007
+ "items": {
1008
+ "kind": "object",
1009
+ "properties": {
1010
+ "serviceId": {
1011
+ "kind": "string",
1012
+ "minLength": 1
1013
+ },
1014
+ "endpointBaseUrl": {
1015
+ "kind": "string",
1016
+ "format": "url"
1017
+ },
1018
+ "views": {
1019
+ "kind": "array",
1020
+ "items": {
1021
+ "kind": "object",
1022
+ "properties": {
1023
+ "viewId": {
1024
+ "kind": "string",
1025
+ "minLength": 1
1026
+ },
1027
+ "title": {
1028
+ "kind": "string"
1029
+ },
1030
+ "path": {
1031
+ "kind": "string",
1032
+ "minLength": 1
1033
+ },
1034
+ "themes": {
1035
+ "kind": "array",
1036
+ "items": {
1037
+ "kind": "string"
1038
+ }
1039
+ },
1040
+ "components": {
1041
+ "kind": "array",
1042
+ "items": {
1043
+ "kind": "string"
1044
+ }
1045
+ },
1046
+ "hasFragments": {
1047
+ "kind": "bool"
1048
+ },
1049
+ "demoScenarios": {
1050
+ "kind": "array",
1051
+ "items": {
1052
+ "kind": "object",
1053
+ "properties": {
1054
+ "id": {
1055
+ "kind": "string",
1056
+ "minLength": 1
1057
+ },
1058
+ "title": {
1059
+ "kind": "string"
1060
+ }
1061
+ },
1062
+ "required": [
1063
+ "id",
1064
+ "title"
1065
+ ],
1066
+ "unknownKeys": "strip"
1067
+ }
1068
+ }
1069
+ },
1070
+ "required": [
1071
+ "viewId",
1072
+ "title",
1073
+ "path",
1074
+ "themes",
1075
+ "components",
1076
+ "hasFragments",
1077
+ "demoScenarios"
1078
+ ],
1079
+ "unknownKeys": "strip"
1080
+ }
1081
+ }
1082
+ },
1083
+ "required": [
1084
+ "serviceId",
1085
+ "endpointBaseUrl",
1086
+ "views"
1087
+ ],
1088
+ "unknownKeys": "strip"
1089
+ }
1090
+ }
1091
+ },
1092
+ "required": [
1093
+ "title",
1094
+ "services"
1095
+ ],
1096
+ "unknownKeys": "strip"
1097
+ },
1098
+ "definitions": {},
1099
+ "extensions": {}
1100
+ },
1101
+ "metadataResponseSchema": {},
1102
+ "renderable": true,
1103
+ "html": {
1104
+ "themeRenderers": {
1105
+ "bootstrap1": {
1106
+ "defaultRenderer": "default",
1107
+ "renderModes": [
1108
+ "page"
1109
+ ],
1110
+ "slots": [
1111
+ "main"
1112
+ ],
1113
+ "renderers": [
1114
+ {
1115
+ "id": "default",
1116
+ "title": "Default Content",
1117
+ "slotId": "main",
1118
+ "renderModes": [
1119
+ "page",
1120
+ "fragment"
1121
+ ]
1122
+ }
1123
+ ]
1124
+ }
1125
+ }
1126
+ },
1127
+ "auth": {
1128
+ "required": true,
1129
+ "permissions": [
1130
+ {
1131
+ "serviceId": "org.betterportal.config-manager",
1132
+ "viewId": "preview.index",
1133
+ "permissions": [
1134
+ "read"
1135
+ ]
1136
+ }
1137
+ ]
1138
+ },
1139
+ "dependencies": [],
1140
+ "apiContracts": [],
1141
+ "demoScenarios": [
1142
+ {
1143
+ "id": "default",
1144
+ "title": "Default",
1145
+ "response": {
1146
+ "title": "Component Preview",
1147
+ "services": []
1148
+ }
1149
+ }
1150
+ ],
1151
+ "cacheHints": {
1152
+ "ttlSeconds": 0,
1153
+ "varyBy": [
1154
+ "accept",
1155
+ "origin"
1156
+ ]
1157
+ }
1158
+ },
1159
+ {
1160
+ "viewId": "routes.index",
1161
+ "title": "Route Designer",
1162
+ "description": "Design navigation routes for apps.",
1163
+ "path": "/routes",
1164
+ "methods": [
1165
+ "GET"
1166
+ ],
1167
+ "paramsSchema": {},
1168
+ "querySchema": {},
1169
+ "headersSchema": {},
1170
+ "bodySchema": {},
1171
+ "jsonResponseSchema": {
1172
+ "anyvaliVersion": "1.0",
1173
+ "schemaVersion": "1.1",
1174
+ "root": {
1175
+ "kind": "object",
1176
+ "properties": {
1177
+ "title": {
1178
+ "kind": "string",
1179
+ "minLength": 1
1180
+ },
1181
+ "apps": {
1182
+ "kind": "array",
1183
+ "items": {
1184
+ "kind": "object",
1185
+ "properties": {
1186
+ "id": {
1187
+ "kind": "string",
1188
+ "minLength": 1
1189
+ },
1190
+ "title": {
1191
+ "kind": "string",
1192
+ "minLength": 1
1193
+ },
1194
+ "tenantId": {
1195
+ "kind": "string",
1196
+ "minLength": 1
1197
+ }
1198
+ },
1199
+ "required": [
1200
+ "id",
1201
+ "title",
1202
+ "tenantId"
1203
+ ],
1204
+ "unknownKeys": "strip"
1205
+ }
1206
+ },
1207
+ "selectedAppId": {
1208
+ "kind": "optional",
1209
+ "inner": {
1210
+ "kind": "string"
1211
+ }
1212
+ },
1213
+ "routes": {
1214
+ "kind": "array",
1215
+ "items": {
1216
+ "kind": "object",
1217
+ "properties": {
1218
+ "id": {
1219
+ "kind": "string",
1220
+ "minLength": 1
1221
+ },
1222
+ "kind": {
1223
+ "kind": "enum",
1224
+ "values": [
1225
+ "page",
1226
+ "api"
1227
+ ],
1228
+ "default": "page"
1229
+ },
1230
+ "path": {
1231
+ "kind": "string",
1232
+ "minLength": 1
1233
+ },
1234
+ "serviceId": {
1235
+ "kind": "string",
1236
+ "minLength": 1
1237
+ },
1238
+ "viewId": {
1239
+ "kind": "string",
1240
+ "minLength": 1
1241
+ },
1242
+ "targetPath": {
1243
+ "kind": "optional",
1244
+ "inner": {
1245
+ "kind": "string"
1246
+ }
1247
+ },
1248
+ "methods": {
1249
+ "kind": "array",
1250
+ "items": {
1251
+ "kind": "string"
1252
+ },
1253
+ "default": []
1254
+ },
1255
+ "query": {
1256
+ "kind": "optional",
1257
+ "inner": {
1258
+ "kind": "string"
1259
+ }
1260
+ },
1261
+ "title": {
1262
+ "kind": "optional",
1263
+ "inner": {
1264
+ "kind": "string"
1265
+ }
1266
+ },
1267
+ "renderable": {
1268
+ "kind": "bool",
1269
+ "default": true
1270
+ },
1271
+ "enabled": {
1272
+ "kind": "bool"
1273
+ }
1274
+ },
1275
+ "required": [
1276
+ "id",
1277
+ "kind",
1278
+ "path",
1279
+ "serviceId",
1280
+ "viewId",
1281
+ "methods",
1282
+ "renderable",
1283
+ "enabled"
1284
+ ],
1285
+ "unknownKeys": "strip"
1286
+ }
1287
+ },
1288
+ "availableServices": {
1289
+ "kind": "array",
1290
+ "items": {
1291
+ "kind": "object",
1292
+ "properties": {
1293
+ "id": {
1294
+ "kind": "string",
1295
+ "minLength": 1
1296
+ },
1297
+ "title": {
1298
+ "kind": "string"
1299
+ },
1300
+ "hostname": {
1301
+ "kind": "string",
1302
+ "format": "url"
1303
+ },
1304
+ "serviceId": {
1305
+ "kind": "optional",
1306
+ "inner": {
1307
+ "kind": "string"
1308
+ }
1309
+ },
1310
+ "views": {
1311
+ "kind": "array",
1312
+ "items": {
1313
+ "kind": "object",
1314
+ "properties": {
1315
+ "viewId": {
1316
+ "kind": "string",
1317
+ "minLength": 1
1318
+ },
1319
+ "title": {
1320
+ "kind": "string"
1321
+ },
1322
+ "path": {
1323
+ "kind": "string"
1324
+ },
1325
+ "methods": {
1326
+ "kind": "array",
1327
+ "items": {
1328
+ "kind": "string"
1329
+ },
1330
+ "default": []
1331
+ },
1332
+ "renderable": {
1333
+ "kind": "bool",
1334
+ "default": true
1335
+ },
1336
+ "dependencies": {
1337
+ "kind": "array",
1338
+ "items": {
1339
+ "kind": "string"
1340
+ },
1341
+ "default": []
1342
+ }
1343
+ },
1344
+ "required": [
1345
+ "viewId",
1346
+ "title",
1347
+ "path",
1348
+ "methods",
1349
+ "renderable",
1350
+ "dependencies"
1351
+ ],
1352
+ "unknownKeys": "strip"
1353
+ },
1354
+ "default": []
1355
+ }
1356
+ },
1357
+ "required": [
1358
+ "id",
1359
+ "title",
1360
+ "hostname",
1361
+ "views"
1362
+ ],
1363
+ "unknownKeys": "strip"
1364
+ },
1365
+ "default": []
1366
+ },
1367
+ "adminApiBase": {
1368
+ "kind": "string",
1369
+ "minLength": 1
1370
+ },
1371
+ "serviceBaseUrl": {
1372
+ "kind": "string",
1373
+ "minLength": 1
1374
+ }
1375
+ },
1376
+ "required": [
1377
+ "title",
1378
+ "apps",
1379
+ "routes",
1380
+ "availableServices",
1381
+ "adminApiBase",
1382
+ "serviceBaseUrl"
1383
+ ],
1384
+ "unknownKeys": "strip"
1385
+ },
1386
+ "definitions": {},
1387
+ "extensions": {}
1388
+ },
1389
+ "metadataResponseSchema": {},
1390
+ "renderable": true,
1391
+ "html": {
1392
+ "themeRenderers": {
1393
+ "bootstrap1": {
1394
+ "defaultRenderer": "default",
1395
+ "renderModes": [
1396
+ "page"
1397
+ ],
1398
+ "slots": [
1399
+ "main"
1400
+ ],
1401
+ "renderers": [
1402
+ {
1403
+ "id": "default",
1404
+ "title": "Default Content",
1405
+ "slotId": "main",
1406
+ "renderModes": [
1407
+ "page",
1408
+ "fragment"
1409
+ ]
1410
+ }
1411
+ ]
1412
+ }
1413
+ }
1414
+ },
1415
+ "auth": {
1416
+ "required": true,
1417
+ "permissions": [
1418
+ {
1419
+ "serviceId": "org.betterportal.config-manager",
1420
+ "viewId": "routes.index",
1421
+ "permissions": [
1422
+ "read",
1423
+ "create",
1424
+ "update",
1425
+ "delete"
1426
+ ]
1427
+ }
1428
+ ]
1429
+ },
1430
+ "dependencies": [],
1431
+ "apiContracts": [],
1432
+ "demoScenarios": [
1433
+ {
1434
+ "id": "default",
1435
+ "title": "Default",
1436
+ "response": {
1437
+ "title": "Route Designer",
1438
+ "apps": [],
1439
+ "routes": [],
1440
+ "availableServices": [],
1441
+ "adminApiBase": "/.well-known/bp/admin",
1442
+ "serviceBaseUrl": ""
1443
+ }
1444
+ }
1445
+ ],
1446
+ "cacheHints": {
1447
+ "ttlSeconds": 0,
1448
+ "varyBy": [
1449
+ "accept",
1450
+ "origin"
1451
+ ]
1452
+ }
1453
+ },
1454
+ {
1455
+ "viewId": "services.index",
1456
+ "title": "Service Registry",
1457
+ "description": "Manage registered service instances.",
1458
+ "path": "/services",
1459
+ "methods": [
1460
+ "GET"
1461
+ ],
1462
+ "paramsSchema": {},
1463
+ "querySchema": {},
1464
+ "headersSchema": {},
1465
+ "bodySchema": {},
1466
+ "jsonResponseSchema": {
1467
+ "anyvaliVersion": "1.0",
1468
+ "schemaVersion": "1.1",
1469
+ "root": {
1470
+ "kind": "object",
1471
+ "properties": {
1472
+ "title": {
1473
+ "kind": "string",
1474
+ "minLength": 1,
1475
+ "metadata": {
1476
+ "description": "View title for the service registry."
1477
+ }
1478
+ },
1479
+ "services": {
1480
+ "kind": "array",
1481
+ "items": {
1482
+ "kind": "object",
1483
+ "properties": {
1484
+ "id": {
1485
+ "kind": "string",
1486
+ "minLength": 1,
1487
+ "metadata": {
1488
+ "description": "Stable UUIDv7 service instance id."
1489
+ }
1490
+ },
1491
+ "hostname": {
1492
+ "kind": "string",
1493
+ "format": "url",
1494
+ "metadata": {
1495
+ "description": "Service origin used by the browser for direct HTMX requests."
1496
+ }
1497
+ },
1498
+ "serviceId": {
1499
+ "kind": "optional",
1500
+ "inner": {
1501
+ "kind": "string"
1502
+ },
1503
+ "metadata": {
1504
+ "description": "Service plugin id from the service manifest."
1505
+ }
1506
+ },
1507
+ "capabilities": {
1508
+ "kind": "array",
1509
+ "items": {
1510
+ "kind": "string"
1511
+ },
1512
+ "default": [],
1513
+ "metadata": {
1514
+ "description": "Capabilities advertised by the service manifest."
1515
+ }
1516
+ },
1517
+ "title": {
1518
+ "kind": "optional",
1519
+ "inner": {
1520
+ "kind": "string"
1521
+ },
1522
+ "metadata": {
1523
+ "description": "Human-readable service title from the manifest or registration."
1524
+ }
1525
+ },
1526
+ "description": {
1527
+ "kind": "optional",
1528
+ "inner": {
1529
+ "kind": "string"
1530
+ },
1531
+ "metadata": {
1532
+ "description": "Human-readable service description from the manifest."
1533
+ }
1534
+ },
1535
+ "createdAt": {
1536
+ "kind": "string",
1537
+ "metadata": {
1538
+ "description": "ISO timestamp when the service registration was created."
1539
+ }
1540
+ },
1541
+ "lastSeenAt": {
1542
+ "kind": "optional",
1543
+ "inner": {
1544
+ "kind": "string"
1545
+ },
1546
+ "metadata": {
1547
+ "description": "ISO timestamp when the service last checked in or synced."
1548
+ }
1549
+ },
1550
+ "enabled": {
1551
+ "kind": "bool",
1552
+ "metadata": {
1553
+ "description": "Whether this service registration is active."
1554
+ }
1555
+ },
1556
+ "scope": {
1557
+ "kind": "string",
1558
+ "minLength": 1,
1559
+ "metadata": {
1560
+ "description": "Registration scope: tenant, shared, platform, or theme."
1561
+ }
1562
+ },
1563
+ "themeId": {
1564
+ "kind": "optional",
1565
+ "inner": {
1566
+ "kind": "string",
1567
+ "minLength": 1
1568
+ },
1569
+ "metadata": {
1570
+ "description": "Theme renderer id when the service provides a theme."
1571
+ }
1572
+ },
1573
+ "tenantId": {
1574
+ "kind": "optional",
1575
+ "inner": {
1576
+ "kind": "string"
1577
+ },
1578
+ "metadata": {
1579
+ "description": "Owning tenant id for tenant-scoped service registrations."
1580
+ }
1581
+ },
1582
+ "pushBase": {
1583
+ "kind": "string",
1584
+ "minLength": 1,
1585
+ "metadata": {
1586
+ "description": "Browser-visible route base used when pushing URLs for custom service UI."
1587
+ }
1588
+ },
1589
+ "supportsCustomUi": {
1590
+ "kind": "bool",
1591
+ "default": false,
1592
+ "metadata": {
1593
+ "description": "True when the service exposes a custom configuration UI."
1594
+ }
1595
+ },
1596
+ "configManifestKnown": {
1597
+ "kind": "bool",
1598
+ "default": false,
1599
+ "metadata": {
1600
+ "description": "True once config-manager has received this service instance manifest via sync."
1601
+ }
1602
+ },
1603
+ "hasConfigurableOptions": {
1604
+ "kind": "bool",
1605
+ "default": false,
1606
+ "metadata": {
1607
+ "description": "True when the service has configurable schema fields or a custom configuration UI."
1608
+ }
1609
+ },
1610
+ "customUiPath": {
1611
+ "kind": "optional",
1612
+ "inner": {
1613
+ "kind": "string"
1614
+ },
1615
+ "metadata": {
1616
+ "description": "Service-side path for custom configuration UI, when provided."
1617
+ }
1618
+ }
1619
+ },
1620
+ "required": [
1621
+ "id",
1622
+ "hostname",
1623
+ "capabilities",
1624
+ "createdAt",
1625
+ "enabled",
1626
+ "scope",
1627
+ "pushBase",
1628
+ "supportsCustomUi",
1629
+ "configManifestKnown",
1630
+ "hasConfigurableOptions"
1631
+ ],
1632
+ "unknownKeys": "strip"
1633
+ },
1634
+ "metadata": {
1635
+ "description": "Registered service instances visible to the admin view."
1636
+ }
1637
+ },
1638
+ "tenants": {
1639
+ "kind": "array",
1640
+ "items": {
1641
+ "kind": "object",
1642
+ "properties": {
1643
+ "id": {
1644
+ "kind": "string",
1645
+ "minLength": 1,
1646
+ "metadata": {
1647
+ "description": "Stable UUIDv7 tenant id."
1648
+ }
1649
+ },
1650
+ "title": {
1651
+ "kind": "string",
1652
+ "minLength": 1,
1653
+ "metadata": {
1654
+ "description": "Human-readable tenant title."
1655
+ }
1656
+ }
1657
+ },
1658
+ "required": [
1659
+ "id",
1660
+ "title"
1661
+ ],
1662
+ "unknownKeys": "strip"
1663
+ },
1664
+ "metadata": {
1665
+ "description": "Tenants available for grouping and service registration."
1666
+ }
1667
+ },
1668
+ "selectedTenantId": {
1669
+ "kind": "optional",
1670
+ "inner": {
1671
+ "kind": "string",
1672
+ "minLength": 1
1673
+ },
1674
+ "metadata": {
1675
+ "description": "Tenant currently selected in the service registry."
1676
+ }
1677
+ },
1678
+ "sharedServiceCatalog": {
1679
+ "kind": "array",
1680
+ "items": {
1681
+ "kind": "object",
1682
+ "properties": {
1683
+ "id": {
1684
+ "kind": "string",
1685
+ "minLength": 1
1686
+ },
1687
+ "serviceId": {
1688
+ "kind": "optional",
1689
+ "inner": {
1690
+ "kind": "string",
1691
+ "minLength": 1
1692
+ }
1693
+ },
1694
+ "title": {
1695
+ "kind": "string",
1696
+ "minLength": 1
1697
+ },
1698
+ "description": {
1699
+ "kind": "optional",
1700
+ "inner": {
1701
+ "kind": "string"
1702
+ }
1703
+ },
1704
+ "baseUrl": {
1705
+ "kind": "string",
1706
+ "minLength": 1
1707
+ },
1708
+ "owner": {
1709
+ "kind": "optional",
1710
+ "inner": {
1711
+ "kind": "string"
1712
+ }
1713
+ },
1714
+ "category": {
1715
+ "kind": "optional",
1716
+ "inner": {
1717
+ "kind": "string"
1718
+ }
1719
+ },
1720
+ "tags": {
1721
+ "kind": "array",
1722
+ "items": {
1723
+ "kind": "string"
1724
+ },
1725
+ "default": []
1726
+ },
1727
+ "installed": {
1728
+ "kind": "bool",
1729
+ "default": false
1730
+ },
1731
+ "enabled": {
1732
+ "kind": "bool",
1733
+ "default": true
1734
+ }
1735
+ },
1736
+ "required": [
1737
+ "id",
1738
+ "title",
1739
+ "baseUrl",
1740
+ "tags",
1741
+ "installed",
1742
+ "enabled"
1743
+ ],
1744
+ "unknownKeys": "strip"
1745
+ },
1746
+ "default": [],
1747
+ "metadata": {
1748
+ "description": "Shared service definitions from platform config."
1749
+ }
1750
+ },
1751
+ "sharedServiceActivations": {
1752
+ "kind": "array",
1753
+ "items": {
1754
+ "kind": "object",
1755
+ "properties": {
1756
+ "id": {
1757
+ "kind": "string",
1758
+ "minLength": 1
1759
+ },
1760
+ "tenantId": {
1761
+ "kind": "string",
1762
+ "minLength": 1
1763
+ },
1764
+ "appId": {
1765
+ "kind": "optional",
1766
+ "inner": {
1767
+ "kind": "string",
1768
+ "minLength": 1
1769
+ }
1770
+ },
1771
+ "sharedServiceId": {
1772
+ "kind": "string",
1773
+ "minLength": 1
1774
+ },
1775
+ "activatedAt": {
1776
+ "kind": "string",
1777
+ "minLength": 1
1778
+ },
1779
+ "enabled": {
1780
+ "kind": "bool",
1781
+ "default": true
1782
+ }
1783
+ },
1784
+ "required": [
1785
+ "id",
1786
+ "tenantId",
1787
+ "sharedServiceId",
1788
+ "activatedAt",
1789
+ "enabled"
1790
+ ],
1791
+ "unknownKeys": "strip"
1792
+ },
1793
+ "default": [],
1794
+ "metadata": {
1795
+ "description": "Tenant/app activations for shared services."
1796
+ }
1797
+ },
1798
+ "apps": {
1799
+ "kind": "array",
1800
+ "items": {
1801
+ "kind": "object",
1802
+ "properties": {
1803
+ "id": {
1804
+ "kind": "string",
1805
+ "minLength": 1,
1806
+ "metadata": {
1807
+ "description": "Stable UUIDv7 app id."
1808
+ }
1809
+ },
1810
+ "tenantId": {
1811
+ "kind": "string",
1812
+ "minLength": 1,
1813
+ "metadata": {
1814
+ "description": "Owning tenant id."
1815
+ }
1816
+ },
1817
+ "title": {
1818
+ "kind": "string",
1819
+ "minLength": 1,
1820
+ "metadata": {
1821
+ "description": "Human-readable app title."
1822
+ }
1823
+ }
1824
+ },
1825
+ "required": [
1826
+ "id",
1827
+ "tenantId",
1828
+ "title"
1829
+ ],
1830
+ "unknownKeys": "strip"
1831
+ },
1832
+ "default": [],
1833
+ "metadata": {
1834
+ "description": "Apps available in the current admin context."
1835
+ }
1836
+ },
1837
+ "tenantApps": {
1838
+ "kind": "record",
1839
+ "valueSchema": {
1840
+ "kind": "array",
1841
+ "items": {
1842
+ "kind": "object",
1843
+ "properties": {
1844
+ "id": {
1845
+ "kind": "string",
1846
+ "minLength": 1,
1847
+ "metadata": {
1848
+ "description": "Stable UUIDv7 app id."
1849
+ }
1850
+ },
1851
+ "title": {
1852
+ "kind": "string",
1853
+ "minLength": 1,
1854
+ "metadata": {
1855
+ "description": "Human-readable app title."
1856
+ }
1857
+ },
1858
+ "shellServiceId": {
1859
+ "kind": "optional",
1860
+ "inner": {
1861
+ "kind": "string",
1862
+ "minLength": 1
1863
+ },
1864
+ "metadata": {
1865
+ "description": "Shell service instance selected by the app."
1866
+ }
1867
+ }
1868
+ },
1869
+ "required": [
1870
+ "id",
1871
+ "title"
1872
+ ],
1873
+ "unknownKeys": "strip"
1874
+ }
1875
+ },
1876
+ "default": {},
1877
+ "metadata": {
1878
+ "description": "Apps keyed by tenant id for configuring tenant or theme-scoped services."
1879
+ }
1880
+ },
1881
+ "adminApiBase": {
1882
+ "kind": "string",
1883
+ "minLength": 1,
1884
+ "metadata": {
1885
+ "description": "Base path for config-manager admin API calls."
1886
+ }
1887
+ },
1888
+ "serviceBaseUrl": {
1889
+ "kind": "optional",
1890
+ "inner": {
1891
+ "kind": "string"
1892
+ },
1893
+ "metadata": {
1894
+ "description": "Config-manager service origin for browser-mediated admin requests."
1895
+ }
1896
+ }
1897
+ },
1898
+ "required": [
1899
+ "title",
1900
+ "services",
1901
+ "tenants",
1902
+ "sharedServiceCatalog",
1903
+ "sharedServiceActivations",
1904
+ "apps",
1905
+ "tenantApps",
1906
+ "adminApiBase"
1907
+ ],
1908
+ "unknownKeys": "strip"
1909
+ },
1910
+ "definitions": {},
1911
+ "extensions": {}
1912
+ },
1913
+ "metadataResponseSchema": {},
1914
+ "renderable": true,
1915
+ "html": {
1916
+ "themeRenderers": {
1917
+ "bootstrap1": {
1918
+ "defaultRenderer": "default",
1919
+ "renderModes": [
1920
+ "page"
1921
+ ],
1922
+ "slots": [
1923
+ "main"
1924
+ ],
1925
+ "renderers": [
1926
+ {
1927
+ "id": "default",
1928
+ "title": "Default Content",
1929
+ "slotId": "main",
1930
+ "renderModes": [
1931
+ "page",
1932
+ "fragment"
1933
+ ]
1934
+ }
1935
+ ]
1936
+ }
1937
+ }
1938
+ },
1939
+ "auth": {
1940
+ "required": true,
1941
+ "permissions": [
1942
+ {
1943
+ "serviceId": "org.betterportal.config-manager",
1944
+ "viewId": "services.index",
1945
+ "permissions": [
1946
+ "read"
1947
+ ]
1948
+ }
1949
+ ]
1950
+ },
1951
+ "dependencies": [],
1952
+ "apiContracts": [],
1953
+ "demoScenarios": [
1954
+ {
1955
+ "id": "default",
1956
+ "title": "Default",
1957
+ "response": {
1958
+ "title": "Service Registry",
1959
+ "services": [],
1960
+ "tenants": [],
1961
+ "sharedServiceCatalog": [],
1962
+ "sharedServiceActivations": [],
1963
+ "apps": [],
1964
+ "tenantApps": {},
1965
+ "adminApiBase": "/.well-known/bp/admin"
1966
+ }
1967
+ }
1968
+ ],
1969
+ "cacheHints": {
1970
+ "ttlSeconds": 0,
1971
+ "varyBy": [
1972
+ "accept",
1973
+ "origin"
1974
+ ]
1975
+ }
1976
+ },
1977
+ {
1978
+ "viewId": "settings.index",
1979
+ "title": "App Settings",
1980
+ "description": "Manage the current BetterPortal app through the user management API.",
1981
+ "path": "/settings",
1982
+ "methods": [
1983
+ "GET"
1984
+ ],
1985
+ "paramsSchema": {},
1986
+ "querySchema": {},
1987
+ "headersSchema": {},
1988
+ "bodySchema": {},
1989
+ "jsonResponseSchema": {
1990
+ "anyvaliVersion": "1.0",
1991
+ "schemaVersion": "1.1",
1992
+ "root": {
1993
+ "kind": "object",
1994
+ "properties": {
1995
+ "title": {
1996
+ "kind": "string",
1997
+ "minLength": 1
1998
+ },
1999
+ "tenant": {
2000
+ "kind": "object",
2001
+ "properties": {
2002
+ "id": {
2003
+ "kind": "string",
2004
+ "minLength": 1
2005
+ },
2006
+ "title": {
2007
+ "kind": "string",
2008
+ "minLength": 1
2009
+ }
2010
+ },
2011
+ "required": [
2012
+ "id",
2013
+ "title"
2014
+ ],
2015
+ "unknownKeys": "strip"
2016
+ },
2017
+ "app": {
2018
+ "kind": "object",
2019
+ "properties": {
2020
+ "id": {
2021
+ "kind": "string",
2022
+ "minLength": 1
2023
+ },
2024
+ "tenantId": {
2025
+ "kind": "string",
2026
+ "minLength": 1
2027
+ },
2028
+ "title": {
2029
+ "kind": "string",
2030
+ "minLength": 1
2031
+ },
2032
+ "hostnames": {
2033
+ "kind": "array",
2034
+ "items": {
2035
+ "kind": "string"
2036
+ },
2037
+ "default": []
2038
+ }
2039
+ },
2040
+ "required": [
2041
+ "id",
2042
+ "tenantId",
2043
+ "title",
2044
+ "hostnames"
2045
+ ],
2046
+ "unknownKeys": "strip"
2047
+ },
2048
+ "idsVisible": {
2049
+ "kind": "bool",
2050
+ "default": true
2051
+ },
2052
+ "managementDiscoveryUrl": {
2053
+ "kind": "string",
2054
+ "minLength": 1
2055
+ },
2056
+ "automationCatalogUrl": {
2057
+ "kind": "string",
2058
+ "minLength": 1
2059
+ },
2060
+ "endpoints": {
2061
+ "kind": "object",
2062
+ "properties": {
2063
+ "current": {
2064
+ "kind": "string",
2065
+ "minLength": 1
2066
+ },
2067
+ "services": {
2068
+ "kind": "string",
2069
+ "minLength": 1
2070
+ },
2071
+ "activateService": {
2072
+ "kind": "string",
2073
+ "minLength": 1
2074
+ },
2075
+ "routes": {
2076
+ "kind": "string",
2077
+ "minLength": 1
2078
+ },
2079
+ "fragments": {
2080
+ "kind": "string",
2081
+ "minLength": 1
2082
+ },
2083
+ "theme": {
2084
+ "kind": "string",
2085
+ "minLength": 1
2086
+ },
2087
+ "webhooks": {
2088
+ "kind": "string",
2089
+ "minLength": 1
2090
+ },
2091
+ "webhookEvents": {
2092
+ "kind": "string",
2093
+ "minLength": 1
2094
+ }
2095
+ },
2096
+ "required": [
2097
+ "current",
2098
+ "services",
2099
+ "activateService",
2100
+ "routes",
2101
+ "fragments",
2102
+ "theme",
2103
+ "webhooks",
2104
+ "webhookEvents"
2105
+ ],
2106
+ "unknownKeys": "strip"
2107
+ },
2108
+ "sharedServices": {
2109
+ "kind": "array",
2110
+ "items": {
2111
+ "kind": "object",
2112
+ "properties": {
2113
+ "id": {
2114
+ "kind": "string",
2115
+ "minLength": 1
2116
+ },
2117
+ "serviceId": {
2118
+ "kind": "optional",
2119
+ "inner": {
2120
+ "kind": "string",
2121
+ "minLength": 1
2122
+ }
2123
+ },
2124
+ "title": {
2125
+ "kind": "string",
2126
+ "minLength": 1
2127
+ },
2128
+ "description": {
2129
+ "kind": "optional",
2130
+ "inner": {
2131
+ "kind": "string"
2132
+ }
2133
+ },
2134
+ "baseUrl": {
2135
+ "kind": "string",
2136
+ "minLength": 1
2137
+ },
2138
+ "category": {
2139
+ "kind": "optional",
2140
+ "inner": {
2141
+ "kind": "string"
2142
+ }
2143
+ },
2144
+ "tags": {
2145
+ "kind": "array",
2146
+ "items": {
2147
+ "kind": "string"
2148
+ },
2149
+ "default": []
2150
+ },
2151
+ "enabled": {
2152
+ "kind": "bool",
2153
+ "default": true
2154
+ },
2155
+ "active": {
2156
+ "kind": "bool",
2157
+ "default": false
2158
+ }
2159
+ },
2160
+ "required": [
2161
+ "id",
2162
+ "title",
2163
+ "baseUrl",
2164
+ "tags",
2165
+ "enabled",
2166
+ "active"
2167
+ ],
2168
+ "unknownKeys": "strip"
2169
+ },
2170
+ "default": []
2171
+ },
2172
+ "routeCount": {
2173
+ "kind": "int",
2174
+ "min": 0
2175
+ },
2176
+ "fragmentCount": {
2177
+ "kind": "int",
2178
+ "min": 0
2179
+ }
2180
+ },
2181
+ "required": [
2182
+ "title",
2183
+ "tenant",
2184
+ "app",
2185
+ "idsVisible",
2186
+ "managementDiscoveryUrl",
2187
+ "automationCatalogUrl",
2188
+ "endpoints",
2189
+ "sharedServices",
2190
+ "routeCount",
2191
+ "fragmentCount"
2192
+ ],
2193
+ "unknownKeys": "strip"
2194
+ },
2195
+ "definitions": {},
2196
+ "extensions": {}
2197
+ },
2198
+ "metadataResponseSchema": {},
2199
+ "renderable": true,
2200
+ "html": {
2201
+ "themeRenderers": {
2202
+ "bootstrap1": {
2203
+ "defaultRenderer": "default",
2204
+ "renderModes": [
2205
+ "page"
2206
+ ],
2207
+ "slots": [
2208
+ "main"
2209
+ ],
2210
+ "renderers": [
2211
+ {
2212
+ "id": "default",
2213
+ "title": "Default Content",
2214
+ "slotId": "main",
2215
+ "renderModes": [
2216
+ "page",
2217
+ "fragment"
2218
+ ]
2219
+ }
2220
+ ]
2221
+ }
2222
+ }
2223
+ },
2224
+ "auth": {
2225
+ "required": true,
2226
+ "permissions": [
2227
+ {
2228
+ "serviceId": "org.betterportal.config-manager",
2229
+ "viewId": "settings.index",
2230
+ "permissions": [
2231
+ "read",
2232
+ "update"
2233
+ ]
2234
+ }
2235
+ ]
2236
+ },
2237
+ "dependencies": [
2238
+ "services.index",
2239
+ "routes.index",
2240
+ "fragments.index",
2241
+ "config.index"
2242
+ ],
2243
+ "apiContracts": [],
2244
+ "demoScenarios": [
2245
+ {
2246
+ "id": "default",
2247
+ "title": "Default",
2248
+ "response": {
2249
+ "title": "App Settings",
2250
+ "tenant": {
2251
+ "id": "tenant-id",
2252
+ "title": "Tenant"
2253
+ },
2254
+ "app": {
2255
+ "id": "app-id",
2256
+ "tenantId": "tenant-id",
2257
+ "title": "App",
2258
+ "hostnames": []
2259
+ },
2260
+ "idsVisible": true,
2261
+ "managementDiscoveryUrl": "/.well-known/bp/management",
2262
+ "automationCatalogUrl": "/.well-known/bp/automation/catalog",
2263
+ "endpoints": {
2264
+ "current": "/.well-known/bp/manage/current",
2265
+ "services": "/.well-known/bp/manage/services",
2266
+ "activateService": "/.well-known/bp/manage/services/activate",
2267
+ "routes": "/.well-known/bp/manage/routes",
2268
+ "fragments": "/.well-known/bp/manage/fragments",
2269
+ "theme": "/.well-known/bp/manage/theme",
2270
+ "webhooks": "/.well-known/bp/manage/webhooks/targets",
2271
+ "webhookEvents": "/.well-known/bp/manage/webhooks/events"
2272
+ },
2273
+ "sharedServices": [],
2274
+ "routeCount": 0,
2275
+ "fragmentCount": 0
2276
+ }
2277
+ }
2278
+ ],
2279
+ "cacheHints": {
2280
+ "ttlSeconds": 0,
2281
+ "varyBy": [
2282
+ "accept",
2283
+ "origin",
2284
+ "referer"
2285
+ ]
2286
+ }
2287
+ },
2288
+ {
2289
+ "viewId": "tenants.index",
2290
+ "title": "Tenants & Apps",
2291
+ "description": "Manage tenants and applications.",
2292
+ "path": "/tenants",
2293
+ "methods": [
2294
+ "DELETE",
2295
+ "GET",
2296
+ "POST",
2297
+ "PUT"
2298
+ ],
2299
+ "paramsSchema": {},
2300
+ "querySchema": {},
2301
+ "headersSchema": {},
2302
+ "bodySchema": {},
2303
+ "jsonResponseSchema": {
2304
+ "anyvaliVersion": "1.0",
2305
+ "schemaVersion": "1.1",
2306
+ "root": {
2307
+ "kind": "object",
2308
+ "properties": {
2309
+ "title": {
2310
+ "kind": "string",
2311
+ "minLength": 1
2312
+ },
2313
+ "tenants": {
2314
+ "kind": "array",
2315
+ "items": {
2316
+ "kind": "object",
2317
+ "properties": {
2318
+ "id": {
2319
+ "kind": "string",
2320
+ "minLength": 1
2321
+ },
2322
+ "slug": {
2323
+ "kind": "string",
2324
+ "minLength": 1
2325
+ },
2326
+ "title": {
2327
+ "kind": "string",
2328
+ "minLength": 1
2329
+ },
2330
+ "active": {
2331
+ "kind": "bool"
2332
+ },
2333
+ "serviceCount": {
2334
+ "kind": "int",
2335
+ "min": 0
2336
+ }
2337
+ },
2338
+ "required": [
2339
+ "id",
2340
+ "slug",
2341
+ "title",
2342
+ "active",
2343
+ "serviceCount"
2344
+ ],
2345
+ "unknownKeys": "strip"
2346
+ }
2347
+ },
2348
+ "apps": {
2349
+ "kind": "array",
2350
+ "items": {
2351
+ "kind": "object",
2352
+ "properties": {
2353
+ "id": {
2354
+ "kind": "string",
2355
+ "minLength": 1
2356
+ },
2357
+ "tenantId": {
2358
+ "kind": "string",
2359
+ "minLength": 1
2360
+ },
2361
+ "slug": {
2362
+ "kind": "string",
2363
+ "minLength": 1
2364
+ },
2365
+ "title": {
2366
+ "kind": "string",
2367
+ "minLength": 1
2368
+ },
2369
+ "hostnames": {
2370
+ "kind": "array",
2371
+ "items": {
2372
+ "kind": "string"
2373
+ }
2374
+ },
2375
+ "shellServiceId": {
2376
+ "kind": "optional",
2377
+ "inner": {
2378
+ "kind": "string",
2379
+ "minLength": 1
2380
+ }
2381
+ },
2382
+ "authServiceId": {
2383
+ "kind": "optional",
2384
+ "inner": {
2385
+ "kind": "string",
2386
+ "minLength": 1
2387
+ }
2388
+ },
2389
+ "roleAuthority": {
2390
+ "kind": "optional",
2391
+ "inner": {
2392
+ "kind": "enum",
2393
+ "values": [
2394
+ "provider",
2395
+ "betterportal"
2396
+ ]
2397
+ }
2398
+ },
2399
+ "routeCount": {
2400
+ "kind": "int",
2401
+ "min": 0
2402
+ }
2403
+ },
2404
+ "required": [
2405
+ "id",
2406
+ "tenantId",
2407
+ "slug",
2408
+ "title",
2409
+ "hostnames",
2410
+ "routeCount"
2411
+ ],
2412
+ "unknownKeys": "strip"
2413
+ }
2414
+ },
2415
+ "shellServices": {
2416
+ "kind": "array",
2417
+ "items": {
2418
+ "kind": "object",
2419
+ "properties": {
2420
+ "id": {
2421
+ "kind": "string",
2422
+ "minLength": 1
2423
+ },
2424
+ "tenantId": {
2425
+ "kind": "string",
2426
+ "minLength": 1
2427
+ },
2428
+ "title": {
2429
+ "kind": "string",
2430
+ "minLength": 1
2431
+ },
2432
+ "serviceId": {
2433
+ "kind": "optional",
2434
+ "inner": {
2435
+ "kind": "string"
2436
+ }
2437
+ }
2438
+ },
2439
+ "required": [
2440
+ "id",
2441
+ "tenantId",
2442
+ "title"
2443
+ ],
2444
+ "unknownKeys": "strip"
2445
+ },
2446
+ "default": []
2447
+ },
2448
+ "authServices": {
2449
+ "kind": "array",
2450
+ "items": {
2451
+ "kind": "object",
2452
+ "properties": {
2453
+ "id": {
2454
+ "kind": "string",
2455
+ "minLength": 1
2456
+ },
2457
+ "tenantId": {
2458
+ "kind": "string",
2459
+ "minLength": 1
2460
+ },
2461
+ "title": {
2462
+ "kind": "string",
2463
+ "minLength": 1
2464
+ },
2465
+ "serviceId": {
2466
+ "kind": "optional",
2467
+ "inner": {
2468
+ "kind": "string"
2469
+ }
2470
+ },
2471
+ "roleAuthorities": {
2472
+ "kind": "array",
2473
+ "items": {
2474
+ "kind": "enum",
2475
+ "values": [
2476
+ "provider",
2477
+ "betterportal"
2478
+ ]
2479
+ },
2480
+ "default": [
2481
+ "betterportal"
2482
+ ]
2483
+ }
2484
+ },
2485
+ "required": [
2486
+ "id",
2487
+ "tenantId",
2488
+ "title",
2489
+ "roleAuthorities"
2490
+ ],
2491
+ "unknownKeys": "strip"
2492
+ },
2493
+ "default": []
2494
+ },
2495
+ "adminApiBase": {
2496
+ "kind": "string",
2497
+ "minLength": 1
2498
+ },
2499
+ "tenantsPath": {
2500
+ "kind": "string",
2501
+ "minLength": 1
2502
+ },
2503
+ "serviceBaseUrl": {
2504
+ "kind": "optional",
2505
+ "inner": {
2506
+ "kind": "string"
2507
+ }
2508
+ }
2509
+ },
2510
+ "required": [
2511
+ "title",
2512
+ "tenants",
2513
+ "apps",
2514
+ "shellServices",
2515
+ "authServices",
2516
+ "adminApiBase",
2517
+ "tenantsPath"
2518
+ ],
2519
+ "unknownKeys": "strip"
2520
+ },
2521
+ "definitions": {},
2522
+ "extensions": {}
2523
+ },
2524
+ "metadataResponseSchema": {},
2525
+ "renderable": true,
2526
+ "html": {
2527
+ "themeRenderers": {
2528
+ "bootstrap1": {
2529
+ "defaultRenderer": "default",
2530
+ "renderModes": [
2531
+ "page"
2532
+ ],
2533
+ "slots": [
2534
+ "main"
2535
+ ],
2536
+ "renderers": [
2537
+ {
2538
+ "id": "default",
2539
+ "title": "Default Content",
2540
+ "slotId": "main",
2541
+ "renderModes": [
2542
+ "page",
2543
+ "fragment"
2544
+ ]
2545
+ },
2546
+ {
2547
+ "id": "default",
2548
+ "title": "Default Content",
2549
+ "slotId": "main",
2550
+ "renderModes": [
2551
+ "page",
2552
+ "fragment"
2553
+ ]
2554
+ },
2555
+ {
2556
+ "id": "default",
2557
+ "title": "Default Content",
2558
+ "slotId": "main",
2559
+ "renderModes": [
2560
+ "page",
2561
+ "fragment"
2562
+ ]
2563
+ },
2564
+ {
2565
+ "id": "default",
2566
+ "title": "Default Content",
2567
+ "slotId": "main",
2568
+ "renderModes": [
2569
+ "page",
2570
+ "fragment"
2571
+ ]
2572
+ }
2573
+ ]
2574
+ }
2575
+ }
2576
+ },
2577
+ "auth": {
2578
+ "required": true,
2579
+ "permissions": [
2580
+ {
2581
+ "serviceId": "org.betterportal.config-manager",
2582
+ "viewId": "tenants.index",
2583
+ "permissions": [
2584
+ "read",
2585
+ "create",
2586
+ "update",
2587
+ "delete"
2588
+ ]
2589
+ }
2590
+ ]
2591
+ },
2592
+ "dependencies": [],
2593
+ "apiContracts": [],
2594
+ "demoScenarios": [
2595
+ {
2596
+ "id": "default",
2597
+ "title": "Default",
2598
+ "response": {
2599
+ "title": "Tenants & Apps",
2600
+ "tenants": [],
2601
+ "apps": [],
2602
+ "shellServices": [],
2603
+ "authServices": [],
2604
+ "adminApiBase": "/.well-known/bp/admin",
2605
+ "tenantsPath": "/tenants"
2606
+ }
2607
+ }
2608
+ ],
2609
+ "cacheHints": {
2610
+ "ttlSeconds": 0,
2611
+ "varyBy": [
2612
+ "accept",
2613
+ "origin"
2614
+ ]
2615
+ }
2616
+ }
2617
+ ],
2618
+ "configSchemas": [],
2619
+ "permissions": [],
2620
+ "adminApis": [],
2621
+ "webhooks": [],
2622
+ "apiContracts": [],
2623
+ "m2mRequests": [],
2624
+ "developerResources": [],
2625
+ "cacheHints": {
2626
+ "metadataTtlSeconds": 300
2627
+ }
2628
+ },
2629
+ "routes": [
2630
+ {
2631
+ "viewId": "auth.index",
2632
+ "path": "/auth",
2633
+ "methods": [
2634
+ "GET"
2635
+ ],
2636
+ "paramNames": [],
2637
+ "themes": [
2638
+ "bootstrap1"
2639
+ ],
2640
+ "hasFragments": false,
2641
+ "fragments": [],
2642
+ "components": []
2643
+ },
2644
+ {
2645
+ "viewId": "config.index",
2646
+ "path": "/config",
2647
+ "methods": [
2648
+ "GET"
2649
+ ],
2650
+ "paramNames": [],
2651
+ "themes": [
2652
+ "bootstrap1",
2653
+ "embedded"
2654
+ ],
2655
+ "hasFragments": false,
2656
+ "fragments": [],
2657
+ "components": []
2658
+ },
2659
+ {
2660
+ "viewId": "fragments.index",
2661
+ "path": "/fragments",
2662
+ "methods": [
2663
+ "GET"
2664
+ ],
2665
+ "paramNames": [],
2666
+ "themes": [
2667
+ "bootstrap1"
2668
+ ],
2669
+ "hasFragments": false,
2670
+ "fragments": [],
2671
+ "components": []
2672
+ },
2673
+ {
2674
+ "viewId": "menu.index",
2675
+ "path": "/menu",
2676
+ "methods": [
2677
+ "GET"
2678
+ ],
2679
+ "paramNames": [],
2680
+ "themes": [
2681
+ "bootstrap1"
2682
+ ],
2683
+ "hasFragments": false,
2684
+ "fragments": [],
2685
+ "components": []
2686
+ },
2687
+ {
2688
+ "viewId": "preview.index",
2689
+ "path": "/preview",
2690
+ "methods": [
2691
+ "GET"
2692
+ ],
2693
+ "paramNames": [],
2694
+ "themes": [
2695
+ "bootstrap1"
2696
+ ],
2697
+ "hasFragments": false,
2698
+ "fragments": [],
2699
+ "components": []
2700
+ },
2701
+ {
2702
+ "viewId": "routes.index",
2703
+ "path": "/routes",
2704
+ "methods": [
2705
+ "GET"
2706
+ ],
2707
+ "paramNames": [],
2708
+ "themes": [
2709
+ "bootstrap1"
2710
+ ],
2711
+ "hasFragments": false,
2712
+ "fragments": [],
2713
+ "components": []
2714
+ },
2715
+ {
2716
+ "viewId": "services.index",
2717
+ "path": "/services",
2718
+ "methods": [
2719
+ "GET"
2720
+ ],
2721
+ "paramNames": [],
2722
+ "themes": [
2723
+ "bootstrap1"
2724
+ ],
2725
+ "hasFragments": false,
2726
+ "fragments": [],
2727
+ "components": []
2728
+ },
2729
+ {
2730
+ "viewId": "settings.index",
2731
+ "path": "/settings",
2732
+ "methods": [
2733
+ "GET"
2734
+ ],
2735
+ "paramNames": [],
2736
+ "themes": [
2737
+ "bootstrap1"
2738
+ ],
2739
+ "hasFragments": false,
2740
+ "fragments": [],
2741
+ "components": []
2742
+ },
2743
+ {
2744
+ "viewId": "tenants.index",
2745
+ "path": "/tenants",
2746
+ "methods": [
2747
+ "DELETE",
2748
+ "GET",
2749
+ "POST",
2750
+ "PUT"
2751
+ ],
2752
+ "paramNames": [],
2753
+ "themes": [
2754
+ "bootstrap1"
2755
+ ],
2756
+ "hasFragments": false,
2757
+ "fragments": [],
2758
+ "components": []
2759
+ }
2760
+ ]
2761
+ }