@aifabrix/builder 2.50.0 → 2.51.1
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.
- package/.cursor/plans/Done/157.1-security-quality-violations-by-type.csv +374 -0
- package/.cursor/rules/assistant-driven-integration-build.mdc +40 -0
- package/integration/hubspot-test/create-hubspot.js +1 -16
- package/jest.isolated-projects.js +77 -1
- package/jest.projects.js +5 -426
- package/lib/api/assistants.api.js +67 -0
- package/lib/api/datasources-extended.api.js +6 -6
- package/lib/api/evidence-authoring-helpers.js +267 -0
- package/lib/api/evidence-authoring.api.js +337 -0
- package/lib/api/evidence-kinds.api.js +128 -0
- package/lib/api/evidence.api.js +57 -1
- package/lib/api/index.js +24 -7
- package/lib/api/pipeline.api.js +47 -3
- package/lib/api/records-bulk.api.js +28 -3
- package/lib/api/resource-types.api.js +4 -4
- package/lib/api/roles.api.js +121 -0
- package/lib/api/types/evidence-kinds.types.js +42 -0
- package/lib/api/types/evidence.types.js +156 -8
- package/lib/api/types/roles.types.js +36 -0
- package/lib/api/work.api.js +283 -0
- package/lib/app/certification-verify-rows.js +1 -1
- package/lib/app/run-deploy-job.js +108 -0
- package/lib/app/run-helpers.js +10 -3
- package/lib/app/run.js +8 -0
- package/lib/app/show.js +2 -2
- package/lib/certification/merge-certification-from-artifact.js +1 -1
- package/lib/channels/add-channel.js +54 -23
- package/lib/channels/approval-guides/chatgpt.js +8 -7
- package/lib/channels/approval-guides/microsoft-copilot.js +7 -8
- package/lib/channels/channel-artifact-generator.js +16 -3
- package/lib/channels/channel-credential.js +3 -1
- package/lib/channels/channel-probe-evidence.js +79 -0
- package/lib/channels/channel-probe.js +265 -13
- package/lib/channels/channel-runtime-resolver.js +120 -29
- package/lib/channels/channel-status-display.js +44 -0
- package/lib/channels/channel-targets.js +7 -0
- package/lib/channels/chatgpt-runtime-contract.js +29 -0
- package/lib/channels/microsoft-copilot-package.js +280 -0
- package/lib/channels/runtime-tool-catalog.js +165 -0
- package/lib/cli/index.js +6 -0
- package/lib/cli/setup-app.js +26 -5
- package/lib/cli/setup-dev.js +23 -7
- package/lib/cli/setup-external-system-help.js +8 -2
- package/lib/cli/setup-external-system.js +12 -0
- package/lib/cli/setup-utility-help-after.js +12 -0
- package/lib/cli/setup-utility-validate.js +41 -2
- package/lib/commands/app-test.js +2 -14
- package/lib/commands/datasource-load-export-cli.js +6 -1
- package/lib/commands/deploy-gate-failure-details.js +23 -0
- package/lib/commands/deploy-gate-orchestrator.js +64 -18
- package/lib/commands/dev-cli-handlers.js +6 -3
- package/lib/commands/dev-down.js +2 -6
- package/lib/commands/dev-init.js +7 -109
- package/lib/commands/dev-refresh.js +197 -0
- package/lib/commands/evidence-kind.js +478 -0
- package/lib/commands/governance-command-action.js +4 -2
- package/lib/commands/governance-generate-external.js +56 -21
- package/lib/commands/lifecycle-external.js +10 -4
- package/lib/commands/repair-datasource-apply.js +10 -1
- package/lib/commands/repair-datasource-run.js +4 -2
- package/lib/commands/repair-datasource-test-payload.js +80 -19
- package/lib/commands/repair-datasource-webhooks-sync-bridge.js +42 -3
- package/lib/commands/repair-internal.js +9 -1
- package/lib/commands/repair-openapi-export.js +1 -1
- package/lib/commands/repair-openapi-sync.js +43 -18
- package/lib/commands/resource-type.js +101 -18
- package/lib/commands/role-assistant.js +313 -0
- package/lib/commands/role.js +452 -0
- package/lib/commands/setup.js +1 -1
- package/lib/commands/upload-data-sync-finalize.js +5 -4
- package/lib/commands/upload-sidecar-followups.js +144 -47
- package/lib/commands/upload.js +43 -6
- package/lib/commands/validate-json.js +230 -0
- package/lib/commands/verify-governance-combined-external.js +73 -9
- package/lib/commands/verify-governance-db.js +80 -25
- package/lib/commands/verify-governance-external.js +29 -5
- package/lib/commands/verify-operations-step-plan.js +78 -40
- package/lib/commands/wizard-core-helpers.js +7 -3
- package/lib/commands/wizard-core.js +78 -9
- package/lib/core/audit-logger.js +1 -1
- package/lib/core/secrets-load.js +1 -3
- package/lib/datasource/bulk-loader-run-batches.js +4 -2
- package/lib/datasource/bulk-loader-service.js +5 -1
- package/lib/datasource/capability/relate-operations.js +1 -1
- package/lib/datasource/datasource-validate-summary.js +2 -2
- package/lib/datasource/validate.js +13 -6
- package/lib/external-system/deploy-helpers.js +35 -1
- package/lib/external-system/deploy.js +23 -10
- package/lib/external-system/download-helpers.js +111 -2
- package/lib/external-system/download-role-assistant.js +55 -0
- package/lib/external-system/download.js +45 -26
- package/lib/external-system/test-helpers.js +1 -1
- package/lib/external-system/test.js +39 -3
- package/lib/generator/builders.js +3 -0
- package/lib/generator/helpers.js +13 -5
- package/lib/generator/split-variables.js +9 -3
- package/lib/generator/wizard.js +51 -4
- package/lib/infrastructure/helpers-docker-check.js +6 -0
- package/lib/infrastructure/helpers.js +1 -1
- package/lib/lifecycle/access-control-abac.js +121 -0
- package/lib/lifecycle/lifecycle-governance-options.js +4 -1
- package/lib/lifecycle/product-model.js +3 -2
- package/lib/lifecycle/report-display.js +14 -2
- package/lib/programmatic/auth-config.js +3 -2
- package/lib/programmatic/bearer-auth.js +1 -1
- package/lib/programmatic/capability-registry.js +20 -1
- package/lib/programmatic/command-options.js +1 -0
- package/lib/programmatic/enterprise-mcp-client.js +18 -2
- package/lib/programmatic/index.js +4 -0
- package/lib/programmatic/manifest-patch-section.js +48 -9
- package/lib/programmatic/manifest-section-registry-data.js +3 -2
- package/lib/programmatic/manifest-section-registry.js +18 -1
- package/lib/programmatic/openapi-apply-result-schemas.js +44 -0
- package/lib/programmatic/openapi-component-schemas.js +16 -1
- package/lib/programmatic/openapi-description-enricher.js +3 -1
- package/lib/programmatic/openapi-descriptions.js +55 -5
- package/lib/programmatic/openapi-evidence-schemas.js +161 -0
- package/lib/programmatic/openapi-manifest-schemas.js +6 -2
- package/lib/programmatic/openapi-operation-bindings.js +99 -0
- package/lib/programmatic/openapi-request-schemas.js +36 -1
- package/lib/programmatic/openapi-result-schemas.js +29 -12
- package/lib/programmatic/openapi-schema-descriptions-certify.js +5 -1
- package/lib/programmatic/openapi-schema-descriptions-core.js +6 -3
- package/lib/programmatic/openapi-schema-descriptions-evidence.js +156 -0
- package/lib/programmatic/openapi-schema-descriptions-manifest.js +4 -3
- package/lib/programmatic/openapi-schema-descriptions-operations.js +70 -0
- package/lib/programmatic/openapi-schema-helpers.js +16 -1
- package/lib/programmatic/openapi-spec.js +48 -29
- package/lib/programmatic/orchestration-openapi-meta.js +5 -0
- package/lib/programmatic/request-timeout.js +3 -0
- package/lib/programmatic/route-handler-map.js +89 -2
- package/lib/programmatic/run-certify.js +15 -2
- package/lib/programmatic/run-deploy.js +74 -0
- package/lib/programmatic/run-evidence-authoring.js +80 -0
- package/lib/programmatic/run-protection.js +124 -0
- package/lib/programmatic/run-repository-emcp.js +11 -3
- package/lib/programmatic/run-template-workspace.js +42 -2
- package/lib/programmatic/workspace-context.js +6 -0
- package/lib/protection/auth-context.js +48 -6
- package/lib/protection/paths.js +22 -0
- package/lib/protection/run-protection-create-helpers.js +22 -1
- package/lib/protection/run-protection-create.js +1 -1
- package/lib/protection/sync-after-upload.js +1 -1
- package/lib/resolvers/evidence-kind-file.js +230 -0
- package/lib/resolvers/resource-type-file.js +36 -1
- package/lib/resolvers/role-file.js +227 -0
- package/lib/role-assistant/evidence-sync.js +450 -0
- package/lib/role-assistant/github-workflow.js +96 -0
- package/lib/role-assistant/knowledge-sync.js +465 -0
- package/lib/role-assistant/settings.js +126 -0
- package/lib/role-assistant/test-cases-evaluate.js +170 -0
- package/lib/role-assistant/test-cases-honesty.js +184 -0
- package/lib/role-assistant/test-cases.js +364 -0
- package/lib/role-assistant/test-runner-workhub-answers.js +203 -0
- package/lib/role-assistant/test-runner-workhub.js +385 -0
- package/lib/role-assistant/test-runner.js +500 -0
- package/lib/schema/application-schema.json +36 -2
- package/lib/schema/deployment-rules.yaml +1 -0
- package/lib/schema/external-datasource.schema.json +121 -4
- package/lib/schema/external-system.schema.json +20 -6
- package/lib/schema/infra.parameter.yaml +45 -1
- package/lib/schema/role-assistant-settings.schema.json +108 -0
- package/lib/schema/type/credential-field-registry.json +19 -3
- package/lib/utils/api.js +52 -21
- package/lib/utils/app-path-resolve.js +72 -24
- package/lib/utils/app-register-config.js +4 -3
- package/lib/utils/authentication-shape.js +3 -1
- package/lib/utils/cli-sync-options.js +59 -3
- package/lib/utils/cli-utils.js +11 -3
- package/lib/utils/deployment-validation.js +28 -3
- package/lib/utils/dev-ca-install.js +5 -6
- package/lib/utils/dev-config.js +2 -2
- package/lib/utils/dev-list-sort.js +145 -0
- package/lib/utils/dev-platform-tls.js +0 -63
- package/lib/utils/docker-build.js +46 -27
- package/lib/utils/docker-daemon-tls-ca.js +1 -1
- package/lib/utils/docker-exec.js +91 -6
- package/lib/utils/docker-run-ephemeral.js +55 -0
- package/lib/utils/enterprise-knowledge-paths.js +29 -12
- package/lib/utils/env-copy-keycloak.js +196 -0
- package/lib/utils/env-copy.js +35 -4
- package/lib/utils/error-formatters/error-parser.js +0 -3
- package/lib/utils/external-env-template.js +1 -1
- package/lib/utils/external-system-readiness-compact-blocks.js +28 -1
- package/lib/utils/external-system-readiness-compact-display.js +3 -0
- package/lib/utils/health-check-request.js +2 -3
- package/lib/utils/help-builder.js +4 -0
- package/lib/utils/image-name.js +22 -4
- package/lib/utils/logger.js +37 -4
- package/lib/utils/manifest-source-emit.js +1 -1
- package/lib/utils/paths.js +98 -26
- package/lib/utils/pipeline-upload-auth-retry.js +19 -3
- package/lib/utils/postgres-platform-bootstrap.js +24 -17
- package/lib/utils/postgres-wipe.js +5 -2
- package/lib/utils/remote-dev-auth.js +39 -4
- package/lib/utils/resolve-docker-image-ref.js +36 -6
- package/lib/utils/role-assistant-paths.js +98 -0
- package/lib/utils/schema-loader.js +41 -0
- package/lib/utils/schema-resolver.js +36 -4
- package/lib/utils/token-manager.js +47 -22
- package/lib/utils/upload-sync-options.js +17 -3
- package/lib/utils/url-declarative-resolve-load-doc.js +38 -1
- package/lib/validation/external-manifest-validator.js +31 -8
- package/lib/validation/openapi-contract-surface-validator.js +4 -0
- package/lib/validation/validate-external-file.js +8 -1
- package/lib/validation/validator.js +6 -5
- package/package.json +35 -12
- package/scripts/export-builder-api-evidence.js +3 -3
- package/scripts/lib/plan-actor.js +2 -2
- package/scripts/lib/plan-meta.js +1 -1
- package/scripts/lib/plan-parse.js +1 -1
- package/scripts/lib/plan-prevalidate-gates.js +12 -1
- package/scripts/lib/plan-run-report.js +13 -2
- package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +10 -10
- package/templates/applications/dataplane/application.yaml +47 -17
- package/templates/applications/dataplane/env.template +28 -9
- package/templates/applications/dataplane/rbac.yaml +78 -2
- package/templates/applications/miso-controller/application.yaml +10 -1
- package/templates/applications/miso-controller/env.template +13 -8
- package/templates/applications/miso-controller/rbac.yaml +72 -0
- package/templates/channels/chatgpt/install.template.md.hbs +42 -24
- package/templates/channels/chatgpt/integration/README.md +10 -7
- package/templates/channels/chatgpt/integration/application.json +2 -2
- package/templates/channels/chatgpt/integration/chatgpt-system.json +3 -3
- package/templates/channels/chatgpt/integration/env.template +1 -1
- package/templates/channels/chatgpt/manifest.template.json.hbs +36 -5
- package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +28 -0
- package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +22 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +32 -22
- package/templates/channels/microsoft-copilot/integration/README.md +9 -7
- package/templates/channels/microsoft-copilot/integration/application.json +2 -2
- package/templates/channels/microsoft-copilot/integration/env.template +1 -1
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +7 -6
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +34 -6
- package/templates/channels/slack/integration/slack-system.json +60 -2
- package/templates/python/requirements.txt +1 -1
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI schema descriptions — Evidence authoring (162.0).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Request/result models for BTA Evidence APIs
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
/** @type {Record<string, Object>} */
|
|
12
|
+
const EVIDENCE_SCHEMA_DESCRIPTIONS = {
|
|
13
|
+
EvidenceUploadRow: {
|
|
14
|
+
_schema: 'One Evidence candidate row proposed for upload.',
|
|
15
|
+
key: 'Stable Evidence key when known.',
|
|
16
|
+
resourceType: 'Catalog resource type key this Evidence applies to.',
|
|
17
|
+
roleKey: 'Role Assistant key; must match the selected Role Assistant.',
|
|
18
|
+
kindKey: 'Evidence kind key from live metadata.',
|
|
19
|
+
kindVersion: 'Evidence kind version from live metadata.',
|
|
20
|
+
title: 'Short Evidence title.',
|
|
21
|
+
description: 'Optional longer description.',
|
|
22
|
+
when: 'Condition describing when this Evidence applies.',
|
|
23
|
+
expectedBehavior: 'Required expected behavior text.',
|
|
24
|
+
aspect: 'Optional Evidence aspect label.',
|
|
25
|
+
order: 'Optional display or priority order.',
|
|
26
|
+
status: 'Lifecycle status; upload persists as candidate.'
|
|
27
|
+
},
|
|
28
|
+
EvidenceUploadRequest: {
|
|
29
|
+
_schema: 'Upload one or many Evidence candidates for technical certification.',
|
|
30
|
+
roleKey: 'Selected Role Assistant key for authoring scope.',
|
|
31
|
+
rows: 'Evidence candidate rows to load, validate, and certify.',
|
|
32
|
+
comment: 'Optional certification comment applied to valid rows.'
|
|
33
|
+
},
|
|
34
|
+
EvidenceActivateRequest: {
|
|
35
|
+
_schema: 'Activate human-approved certified Evidence candidates.',
|
|
36
|
+
evidenceIds: 'Evidence ids or keys approved for activation.'
|
|
37
|
+
},
|
|
38
|
+
EvidenceKindSummary: {
|
|
39
|
+
_schema: 'Evidence kind available for authoring.',
|
|
40
|
+
key: 'Evidence kind key.',
|
|
41
|
+
version: 'Evidence kind version.',
|
|
42
|
+
displayName: 'Human-readable kind name.',
|
|
43
|
+
purpose: 'Kind purpose summary when present.'
|
|
44
|
+
},
|
|
45
|
+
EvidenceResourceTypeSummary: {
|
|
46
|
+
_schema: 'Resource type available for Evidence scoping.',
|
|
47
|
+
key: 'Resource type catalog key.',
|
|
48
|
+
displayName: 'Human-readable resource type name.',
|
|
49
|
+
category: 'Resource type category when present.'
|
|
50
|
+
},
|
|
51
|
+
EvidenceAuthoringConstraints: {
|
|
52
|
+
_schema: 'Certification and activation constraints for authoring.',
|
|
53
|
+
certification: 'Technical certification prerequisites.',
|
|
54
|
+
activation: 'Human-gate activation prerequisites.'
|
|
55
|
+
},
|
|
56
|
+
EvidenceAuthoringMetadataData: {
|
|
57
|
+
_schema: 'Authoritative Evidence authoring structure for a Role Assistant.',
|
|
58
|
+
roleKey: 'Selected Role Assistant key.',
|
|
59
|
+
evidenceKinds: 'Live Evidence kinds and versions.',
|
|
60
|
+
aspects: 'Distinct aspects already used by this Role Assistant.',
|
|
61
|
+
resourceTypes: 'Catalog resource types available for scoping.',
|
|
62
|
+
assistantCapabilities: 'Capability keys from the Role Assistant.',
|
|
63
|
+
writableFields: 'Fields the authoring API accepts on upload rows.',
|
|
64
|
+
requiredFields: 'Fields required on every upload row.',
|
|
65
|
+
constraints: 'Certification and activation constraints.'
|
|
66
|
+
},
|
|
67
|
+
EvidenceRowProjection: {
|
|
68
|
+
_schema: 'Evidence row projection returned by download/upload/activate.',
|
|
69
|
+
id: 'Dataplane Evidence id.',
|
|
70
|
+
key: 'Stable Evidence key when present.',
|
|
71
|
+
resourceType: 'Resource type key.',
|
|
72
|
+
roleKey: 'Role Assistant key.',
|
|
73
|
+
kindKey: 'Evidence kind key.',
|
|
74
|
+
kindVersion: 'Evidence kind version.',
|
|
75
|
+
title: 'Evidence title.',
|
|
76
|
+
description: 'Optional description.',
|
|
77
|
+
when: 'When condition text.',
|
|
78
|
+
expectedBehavior: 'Expected behavior text.',
|
|
79
|
+
aspect: 'Aspect label when present.',
|
|
80
|
+
order: 'Order value.',
|
|
81
|
+
status: 'Lifecycle status.',
|
|
82
|
+
fingerprint: 'Content fingerprint when present.'
|
|
83
|
+
},
|
|
84
|
+
EvidenceDownloadData: {
|
|
85
|
+
_schema: 'Existing Evidence for the selected Role Assistant.',
|
|
86
|
+
roleKey: 'Selected Role Assistant key.',
|
|
87
|
+
count: 'Number of Evidence rows returned.',
|
|
88
|
+
data: 'Evidence rows matching the download filters.'
|
|
89
|
+
},
|
|
90
|
+
EvidenceUploadItemOutcome: {
|
|
91
|
+
_schema: 'Per-row upload, validation, or certification outcome.',
|
|
92
|
+
rowIndex: 'Zero-based index in the upload rows array.',
|
|
93
|
+
evidenceId: 'Resolved Evidence id when available.',
|
|
94
|
+
evidenceRef: 'Evidence reference used for lifecycle calls.',
|
|
95
|
+
status: 'Outcome status label.',
|
|
96
|
+
message: 'Human-readable outcome message.',
|
|
97
|
+
issues: 'Validation or certification issues for the row.'
|
|
98
|
+
},
|
|
99
|
+
EvidenceUploadData: {
|
|
100
|
+
_schema: 'Upload result after load, validate, and certify (never activate).',
|
|
101
|
+
roleKey: 'Selected Role Assistant key.',
|
|
102
|
+
inserted: 'Rows inserted by bulk load.',
|
|
103
|
+
updated: 'Rows updated by bulk load.',
|
|
104
|
+
accepted: 'Rows accepted after technical certification.',
|
|
105
|
+
rejected: 'Rows rejected by validation or certification.',
|
|
106
|
+
warnings: 'Non-fatal row warnings.',
|
|
107
|
+
certified: 'Rows that completed technical certification.',
|
|
108
|
+
readyToActivate: 'True when at least one certified inactive row is ready.'
|
|
109
|
+
},
|
|
110
|
+
EvidenceActivateItemOutcome: {
|
|
111
|
+
_schema: 'Per-id activation outcome.',
|
|
112
|
+
evidenceId: 'Requested Evidence id or key.',
|
|
113
|
+
result: 'Activated Evidence projection when successful.',
|
|
114
|
+
error: 'Error message when activation failed.',
|
|
115
|
+
status: 'HTTP or API status code when activation failed.'
|
|
116
|
+
},
|
|
117
|
+
EvidenceActivateData: {
|
|
118
|
+
_schema: 'Activation result for one or many Evidence ids.',
|
|
119
|
+
requested: 'Number of unique Evidence ids requested.',
|
|
120
|
+
activated: 'Successfully activated Evidence outcomes.',
|
|
121
|
+
failed: 'Failed activation outcomes.',
|
|
122
|
+
success: 'True when every requested id activated.'
|
|
123
|
+
},
|
|
124
|
+
EvidenceAuthoringMetadataResponse: {
|
|
125
|
+
_schema: '200 response envelope for getEvidenceMetadata.',
|
|
126
|
+
success: 'Always true for successful builder-api JSON responses.',
|
|
127
|
+
data: 'Typed payload; see EvidenceAuthoringMetadataData.',
|
|
128
|
+
correlationId: 'UUID correlating logs for this request.',
|
|
129
|
+
requestId: 'Optional per-request UUID when emitted by the server.'
|
|
130
|
+
},
|
|
131
|
+
EvidenceDownloadResponse: {
|
|
132
|
+
_schema: '200 response envelope for downloadEvidence.',
|
|
133
|
+
success: 'Always true for successful builder-api JSON responses.',
|
|
134
|
+
data: 'Typed payload; see EvidenceDownloadData.',
|
|
135
|
+
correlationId: 'UUID correlating logs for this request.',
|
|
136
|
+
requestId: 'Optional per-request UUID when emitted by the server.'
|
|
137
|
+
},
|
|
138
|
+
EvidenceUploadResponse: {
|
|
139
|
+
_schema: '200 response envelope for uploadEvidenceCandidates.',
|
|
140
|
+
success: 'Always true for successful builder-api JSON responses.',
|
|
141
|
+
data: 'Typed payload; see EvidenceUploadData.',
|
|
142
|
+
correlationId: 'UUID correlating logs for this request.',
|
|
143
|
+
requestId: 'Optional per-request UUID when emitted by the server.'
|
|
144
|
+
},
|
|
145
|
+
EvidenceActivateResponse: {
|
|
146
|
+
_schema: '200 response envelope for activateEvidenceCandidates.',
|
|
147
|
+
success: 'Always true for successful builder-api JSON responses.',
|
|
148
|
+
data: 'Typed payload; see EvidenceActivateData.',
|
|
149
|
+
correlationId: 'UUID correlating logs for this request.',
|
|
150
|
+
requestId: 'Optional per-request UUID when emitted by the server.'
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
module.exports = {
|
|
155
|
+
EVIDENCE_SCHEMA_DESCRIPTIONS
|
|
156
|
+
};
|
|
@@ -37,11 +37,12 @@ const MANIFEST_SCHEMA_DESCRIPTIONS = {
|
|
|
37
37
|
assumptions: 'Assumptions recorded during quality scoring.'
|
|
38
38
|
},
|
|
39
39
|
ManifestPatchSectionRequest: {
|
|
40
|
-
_schema: 'Governed patch body;
|
|
40
|
+
_schema: 'Governed patch body; intent required. sectionReadToken optional (auto re-read when omitted).',
|
|
41
41
|
intent: 'Why this patch is made — audit and repair hints.',
|
|
42
42
|
patch: 'Section-scoped merge or replace payload.',
|
|
43
43
|
mode: 'Merge into existing section value or replace entirely.',
|
|
44
|
-
sectionReadToken:
|
|
44
|
+
sectionReadToken:
|
|
45
|
+
'Optional token from prior GET. When omitted, server re-reads before write. Stale token returns 409.',
|
|
45
46
|
dryRun: 'Validate patch without writing files.'
|
|
46
47
|
},
|
|
47
48
|
ManifestRepairRequest: {
|
|
@@ -68,7 +69,7 @@ const MANIFEST_SCHEMA_DESCRIPTIONS = {
|
|
|
68
69
|
},
|
|
69
70
|
repairHooks: 'Suggested repair hook names after patch.',
|
|
70
71
|
recommendedNextActions: 'Agent-facing next steps (validate, repair, ask user).',
|
|
71
|
-
sectionReadToken: 'Opaque token
|
|
72
|
+
sectionReadToken: 'Opaque token for optimistic concurrency on PATCH; optional when PATCH auto-refreshes.',
|
|
72
73
|
quality: 'Deterministic quality score and blocking issues.'
|
|
73
74
|
},
|
|
74
75
|
ManifestPatchResultData: {
|
|
@@ -73,6 +73,36 @@ const OPERATIONS_SCHEMA_DESCRIPTIONS = {
|
|
|
73
73
|
force: 'When true, upload even when validation reports non-blocking issues.',
|
|
74
74
|
probe: 'When true, perform connectivity probe before upload.'
|
|
75
75
|
},
|
|
76
|
+
DeployRequest: {
|
|
77
|
+
_schema: 'Optional flags for controller Deploy (CLI aifabrix deploy parity).',
|
|
78
|
+
gate: 'Optional pre-promote gates (comma-separated: operations, trust, governance, full).',
|
|
79
|
+
subjectEmail: 'Subject email for governance gate when gate includes governance or full.',
|
|
80
|
+
probe: 'When true, run dataplane probe checks after deploy.',
|
|
81
|
+
sync: 'When true, force full datasource data sync after deploy.',
|
|
82
|
+
verbose: 'When true, expand deploy summary output.'
|
|
83
|
+
},
|
|
84
|
+
ProtectionUploadRequest: {
|
|
85
|
+
_schema: 'Optional flags for protection upload (CLI protection upload parity).',
|
|
86
|
+
dryRun: 'When true, validate only; do not upload or sync.',
|
|
87
|
+
sync: 'When true, force full datasource data sync after upload.',
|
|
88
|
+
verbose: 'When true, emit verbose protection logs.'
|
|
89
|
+
},
|
|
90
|
+
ProtectionCreateRequest: {
|
|
91
|
+
_schema: 'Optional flags for protection create (CLI protection create parity).',
|
|
92
|
+
type: 'Preset type (for example country-sales).',
|
|
93
|
+
dimensionKey: 'Dimension catalog key when not inferred from type.',
|
|
94
|
+
field: 'Metadata field used by preset value templates.',
|
|
95
|
+
fkName: 'FK binding name in expressions.',
|
|
96
|
+
protectionKey: 'metadata.key override.',
|
|
97
|
+
displayName: 'metadata.displayName override.',
|
|
98
|
+
ruleKey: 'Rule key inside spec.rules[0].',
|
|
99
|
+
principalExpression: 'Group principal expression override.',
|
|
100
|
+
valueExpression: 'Grant valueExpression override.',
|
|
101
|
+
dryRun: 'When true, print scaffold without writing the file.',
|
|
102
|
+
force: 'When true, overwrite an existing local protection manifest.',
|
|
103
|
+
verbose: 'When true, emit verbose probe logs.',
|
|
104
|
+
disabled: 'When true, set spec.enabled to false.'
|
|
105
|
+
},
|
|
76
106
|
TestRequest: {
|
|
77
107
|
_schema: 'Optional test ladder options; runType may also be passed as query param.',
|
|
78
108
|
runType: 'Test stage: unit, integration (default), or e2e.',
|
|
@@ -267,6 +297,46 @@ const OPERATIONS_SCHEMA_DESCRIPTIONS = {
|
|
|
267
297
|
correlationId: 'UUID correlating logs for this request.',
|
|
268
298
|
requestId: 'Optional per-request UUID when emitted by the server.'
|
|
269
299
|
},
|
|
300
|
+
DeployResultData: {
|
|
301
|
+
_schema: 'Controller deploy outcome summary.',
|
|
302
|
+
deployed: 'True when controller deploy completed without gate failure.',
|
|
303
|
+
deploymentId: 'Controller deployment id when returned.',
|
|
304
|
+
environment: 'Target environment key.',
|
|
305
|
+
systemKey: 'Deployed integration system key.'
|
|
306
|
+
},
|
|
307
|
+
DeployResultResponse: {
|
|
308
|
+
_schema: '200 response envelope for runDeploySystem.',
|
|
309
|
+
success: 'Always true for successful builder-api JSON responses.',
|
|
310
|
+
data: 'Typed payload; see DeployResultData.',
|
|
311
|
+
correlationId: 'UUID correlating logs for this request.',
|
|
312
|
+
requestId: 'Optional per-request UUID when emitted by the server.'
|
|
313
|
+
},
|
|
314
|
+
ProtectionUploadData: {
|
|
315
|
+
_schema: 'Protection upload outcome.',
|
|
316
|
+
datasourceKey: 'Datasource key whose protection manifest was uploaded.',
|
|
317
|
+
uploaded: 'True when the manifest was published (false on dryRun).',
|
|
318
|
+
dryRun: 'True when validate-only dry run was requested.'
|
|
319
|
+
},
|
|
320
|
+
ProtectionUploadResponse: {
|
|
321
|
+
_schema: '200 response envelope for runProtectionUpload.',
|
|
322
|
+
success: 'Always true for successful builder-api JSON responses.',
|
|
323
|
+
data: 'Typed payload; see ProtectionUploadData.',
|
|
324
|
+
correlationId: 'UUID correlating logs for this request.',
|
|
325
|
+
requestId: 'Optional per-request UUID when emitted by the server.'
|
|
326
|
+
},
|
|
327
|
+
ProtectionCreateData: {
|
|
328
|
+
_schema: 'Protection create outcome.',
|
|
329
|
+
datasourceKey: 'Datasource key for the scaffolded protection manifest.',
|
|
330
|
+
created: 'True when the local manifest was written (false on dryRun).',
|
|
331
|
+
dryRun: 'True when scaffold was not written to disk.'
|
|
332
|
+
},
|
|
333
|
+
ProtectionCreateResponse: {
|
|
334
|
+
_schema: '200 response envelope for runProtectionCreate.',
|
|
335
|
+
success: 'Always true for successful builder-api JSON responses.',
|
|
336
|
+
data: 'Typed payload; see ProtectionCreateData.',
|
|
337
|
+
correlationId: 'UUID correlating logs for this request.',
|
|
338
|
+
requestId: 'Optional per-request UUID when emitted by the server.'
|
|
339
|
+
},
|
|
270
340
|
TestResultResponse: {
|
|
271
341
|
_schema: '200 response envelope for runTest.',
|
|
272
342
|
success: 'Always true for successful builder-api JSON responses.',
|
|
@@ -41,7 +41,15 @@ function stringArraySchema() {
|
|
|
41
41
|
* @returns {Object}
|
|
42
42
|
*/
|
|
43
43
|
function buildSuccessEnvelopeSchema(dataSchemaName) {
|
|
44
|
-
|
|
44
|
+
const dataExamples = {
|
|
45
|
+
HealthData: { status: 'ok' },
|
|
46
|
+
ReadyData: { status: 'ready', dataplaneUrl: 'http://localhost:3601' },
|
|
47
|
+
ListSystemsData: { systems: [] },
|
|
48
|
+
EmptyResultData: {},
|
|
49
|
+
WorkspaceStatusData: { status: 'ready' },
|
|
50
|
+
RepositoryStatusData: { status: 'ready' }
|
|
51
|
+
};
|
|
52
|
+
const schema = frozenObject(
|
|
45
53
|
{
|
|
46
54
|
success: { type: 'boolean', enum: [true] },
|
|
47
55
|
data: schemaRef(dataSchemaName),
|
|
@@ -50,6 +58,13 @@ function buildSuccessEnvelopeSchema(dataSchemaName) {
|
|
|
50
58
|
},
|
|
51
59
|
['success', 'data', 'correlationId']
|
|
52
60
|
);
|
|
61
|
+
schema.example = {
|
|
62
|
+
success: true,
|
|
63
|
+
data: dataExamples[dataSchemaName] || {},
|
|
64
|
+
correlationId: '00000000-0000-4000-8000-000000000001',
|
|
65
|
+
requestId: '00000000-0000-4000-8000-000000000002'
|
|
66
|
+
};
|
|
67
|
+
return schema;
|
|
53
68
|
}
|
|
54
69
|
|
|
55
70
|
/**
|
|
@@ -47,7 +47,7 @@ function problemResponseContent(description) {
|
|
|
47
47
|
description,
|
|
48
48
|
content: {
|
|
49
49
|
'application/problem+json': {
|
|
50
|
-
schema: { $ref: '#/components/schemas/
|
|
50
|
+
schema: { $ref: '#/components/schemas/ProblemDetail' }
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
};
|
|
@@ -83,6 +83,7 @@ function requiresBearerAuth(handlerId) {
|
|
|
83
83
|
function applyOperationDurationHints(capability, operation) {
|
|
84
84
|
const durationByHandler = {
|
|
85
85
|
runUpload: Number(process.env.MAX_UPLOAD_TIMEOUT_MS || 300000),
|
|
86
|
+
runDeploySystem: Number(process.env.MAX_DEPLOY_TIMEOUT_MS || 300000),
|
|
86
87
|
runTest: Number(process.env.MAX_TEST_E2E_TIMEOUT_MS || 120000),
|
|
87
88
|
runCertifyPillar: Number(process.env.MAX_CERTIFY_TIMEOUT_MS || 120000)
|
|
88
89
|
};
|
|
@@ -133,6 +134,49 @@ function buildOperationObject(capability) {
|
|
|
133
134
|
return operation;
|
|
134
135
|
}
|
|
135
136
|
|
|
137
|
+
/**
|
|
138
|
+
* @returns {Object[]}
|
|
139
|
+
*/
|
|
140
|
+
function buildOpenApiTags() {
|
|
141
|
+
return [
|
|
142
|
+
{ name: 'workspace', description: 'Per-user integration workspaces (list, create, manifest, status, diff).' },
|
|
143
|
+
{ name: 'build', description: 'Wizard generation and manifest repair.' },
|
|
144
|
+
{ name: 'manifest', description: 'Governed section get/patch/repair for LLM and MCP workflows.' },
|
|
145
|
+
{ name: 'validate', description: 'Local AJV validation and preview-upload (no Dataplane mutation).' },
|
|
146
|
+
{ name: 'test', description: 'Unit, integration, and e2e test ladder.' },
|
|
147
|
+
{ name: 'certify', description: 'Verify operations/trust/governance and lifecycle certification.' },
|
|
148
|
+
{ name: 'apply', description: 'Dev Dataplane upload (requires external-system:publish).' },
|
|
149
|
+
{ name: 'template', description: 'Enterprise MCP template.materializeWorkspace and workspace reset.' },
|
|
150
|
+
{ name: 'repository', description: 'Enterprise MCP repository.sync, createReview, status, dispatchPipeline.' },
|
|
151
|
+
{ name: 'infra', description: 'Liveness and readiness probes (no authentication).' },
|
|
152
|
+
{
|
|
153
|
+
name: 'evidence',
|
|
154
|
+
description:
|
|
155
|
+
'BTA-facing Evidence authoring: metadata, download, upload (validate+certify), and human-gated activate.'
|
|
156
|
+
}
|
|
157
|
+
];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* @returns {Object}
|
|
162
|
+
*/
|
|
163
|
+
function buildOpenApiInfo() {
|
|
164
|
+
return {
|
|
165
|
+
title: 'AI Fabrix Builder API',
|
|
166
|
+
version: '1.0.0',
|
|
167
|
+
description:
|
|
168
|
+
'Workspace orchestration for external-system dev publish. Repository and template operations delegate to Enterprise MCP (154.1). Successful JSON responses use `{ success, data, correlationId, requestId? }` with `application/json`. Errors use RFC 7807 Problem Details (`application/problem+json`) aligned with miso-controller and dataplane.',
|
|
169
|
+
'x-aifabrix': {
|
|
170
|
+
redocUrl: '/api/docs',
|
|
171
|
+
contractTier: 'public',
|
|
172
|
+
mcpGenerationReady: true,
|
|
173
|
+
rbacPreset: 'platform',
|
|
174
|
+
datasourceSplitMode: 'per-tag',
|
|
175
|
+
orchestrationDatasourceTags: listOrchestrationDatasourceTags()
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
136
180
|
/**
|
|
137
181
|
* @param {Object} [options]
|
|
138
182
|
* @param {string} [options.publicBaseUrl]
|
|
@@ -148,39 +192,14 @@ function buildOpenApiSpec(options = {}) {
|
|
|
148
192
|
if (!paths[pathKey]) {
|
|
149
193
|
paths[pathKey] = {};
|
|
150
194
|
}
|
|
151
|
-
|
|
152
|
-
paths[pathKey][method] = buildOperationObject(capability);
|
|
195
|
+
paths[pathKey][capability.method.toLowerCase()] = buildOperationObject(capability);
|
|
153
196
|
}
|
|
154
197
|
|
|
155
198
|
return {
|
|
156
199
|
openapi: '3.0.3',
|
|
157
|
-
info:
|
|
158
|
-
title: 'AI Fabrix Builder API',
|
|
159
|
-
version: '1.0.0',
|
|
160
|
-
description:
|
|
161
|
-
'Workspace orchestration for external-system dev publish. Repository and template operations delegate to Enterprise MCP (154.1). Successful JSON responses use `{ success, data, correlationId, requestId? }` with `application/json`. Errors use RFC 7807 Problem Details (`application/problem+json`) aligned with miso-controller and dataplane.',
|
|
162
|
-
'x-aifabrix': {
|
|
163
|
-
redocUrl: '/api/docs',
|
|
164
|
-
contractTier: 'public',
|
|
165
|
-
mcpGenerationReady: true,
|
|
166
|
-
rbacPreset: 'platform',
|
|
167
|
-
datasourceSplitMode: 'per-tag',
|
|
168
|
-
orchestrationDatasourceTags: listOrchestrationDatasourceTags()
|
|
169
|
-
}
|
|
170
|
-
},
|
|
200
|
+
info: buildOpenApiInfo(),
|
|
171
201
|
servers: [{ url: serverUrl, description: 'Builder API public base URL' }],
|
|
172
|
-
tags:
|
|
173
|
-
{ name: 'workspace', description: 'Per-user integration workspaces (list, create, manifest, status, diff).' },
|
|
174
|
-
{ name: 'build', description: 'Wizard generation and manifest repair.' },
|
|
175
|
-
{ name: 'manifest', description: 'Governed section get/patch/repair for LLM and MCP workflows.' },
|
|
176
|
-
{ name: 'validate', description: 'Local AJV validation and preview-upload (no Dataplane mutation).' },
|
|
177
|
-
{ name: 'test', description: 'Unit, integration, and e2e test ladder.' },
|
|
178
|
-
{ name: 'certify', description: 'Verify operations/trust/governance and lifecycle certification.' },
|
|
179
|
-
{ name: 'apply', description: 'Dev Dataplane upload (requires external-system:publish).' },
|
|
180
|
-
{ name: 'template', description: 'Enterprise MCP template.materializeWorkspace and workspace reset.' },
|
|
181
|
-
{ name: 'repository', description: 'Enterprise MCP repository.sync, createReview, status, dispatchPipeline.' },
|
|
182
|
-
{ name: 'infra', description: 'Liveness and readiness probes (no authentication).' }
|
|
183
|
-
],
|
|
202
|
+
tags: buildOpenApiTags(),
|
|
184
203
|
components: {
|
|
185
204
|
securitySchemes: {
|
|
186
205
|
bearerAuth: {
|
|
@@ -66,6 +66,11 @@ const ORCHESTRATION_TAG_CATALOG = Object.freeze({
|
|
|
66
66
|
resourceType: 'channel',
|
|
67
67
|
permissionClass: 'infra',
|
|
68
68
|
displayName: 'Infrastructure'
|
|
69
|
+
},
|
|
70
|
+
evidence: {
|
|
71
|
+
resourceType: 'role-evidence',
|
|
72
|
+
permissionClass: 'evidence',
|
|
73
|
+
displayName: 'Evidence'
|
|
69
74
|
}
|
|
70
75
|
});
|
|
71
76
|
|
|
@@ -16,6 +16,9 @@ function getTimeoutMsForHandler(handlerId) {
|
|
|
16
16
|
if (handlerId === 'runUpload') {
|
|
17
17
|
return Number(process.env.MAX_UPLOAD_TIMEOUT_MS || 300000);
|
|
18
18
|
}
|
|
19
|
+
if (handlerId === 'runDeploySystem') {
|
|
20
|
+
return Number(process.env.MAX_DEPLOY_TIMEOUT_MS || 300000);
|
|
21
|
+
}
|
|
19
22
|
if (handlerId === 'runTest') {
|
|
20
23
|
return Number(process.env.MAX_TEST_E2E_TIMEOUT_MS || 120000);
|
|
21
24
|
}
|
|
@@ -14,6 +14,8 @@ const { runWizard } = require('./run-wizard');
|
|
|
14
14
|
const { runRepair } = require('./run-repair');
|
|
15
15
|
const { runValidate } = require('./run-validate');
|
|
16
16
|
const { runPreviewUpload, runUpload } = require('./run-upload');
|
|
17
|
+
const { runDeploySystem } = require('./run-deploy');
|
|
18
|
+
const { runProtectionUpload, runProtectionCreate } = require('./run-protection');
|
|
17
19
|
const { runTest } = require('./run-test');
|
|
18
20
|
const { runCertifyPillar } = require('./run-certify');
|
|
19
21
|
const { getLifecycleReport } = require('./run-lifecycle');
|
|
@@ -32,6 +34,12 @@ const {
|
|
|
32
34
|
const { getManifestSection, listManifestSections } = require('./manifest-get-section');
|
|
33
35
|
const { patchManifestSection } = require('./manifest-patch-section');
|
|
34
36
|
const { runManifestRepair } = require('./manifest-repair');
|
|
37
|
+
const {
|
|
38
|
+
getEvidenceMetadata,
|
|
39
|
+
downloadEvidence,
|
|
40
|
+
uploadEvidenceCandidates,
|
|
41
|
+
activateEvidenceCandidates
|
|
42
|
+
} = require('./run-evidence-authoring');
|
|
35
43
|
|
|
36
44
|
/** @type {Record<string, Function>} */
|
|
37
45
|
const HANDLER_MAP = {
|
|
@@ -108,6 +116,36 @@ const HANDLER_MAP = {
|
|
|
108
116
|
probe: body.probe === true,
|
|
109
117
|
minimal: true
|
|
110
118
|
}),
|
|
119
|
+
runDeploySystem: (params, auth, body) =>
|
|
120
|
+
runDeploySystem(buildContext(auth, params.systemKey), {
|
|
121
|
+
gate: body.gate,
|
|
122
|
+
subjectEmail: body.subjectEmail,
|
|
123
|
+
probe: body.probe === true,
|
|
124
|
+
sync: body.sync === true,
|
|
125
|
+
verbose: body.verbose === true
|
|
126
|
+
}),
|
|
127
|
+
runProtectionUpload: (params, auth, body) =>
|
|
128
|
+
runProtectionUpload(buildContext(auth, params.systemKey), params.datasourceKey, {
|
|
129
|
+
dryRun: body.dryRun === true,
|
|
130
|
+
sync: body.sync === true,
|
|
131
|
+
verbose: body.verbose === true
|
|
132
|
+
}),
|
|
133
|
+
runProtectionCreate: (params, auth, body) =>
|
|
134
|
+
runProtectionCreate(buildContext(auth, params.systemKey), params.datasourceKey, {
|
|
135
|
+
type: body.type,
|
|
136
|
+
dimensionKey: body.dimensionKey,
|
|
137
|
+
field: body.field,
|
|
138
|
+
fkName: body.fkName,
|
|
139
|
+
protectionKey: body.protectionKey,
|
|
140
|
+
displayName: body.displayName,
|
|
141
|
+
ruleKey: body.ruleKey,
|
|
142
|
+
principalExpression: body.principalExpression,
|
|
143
|
+
valueExpression: body.valueExpression,
|
|
144
|
+
dryRun: body.dryRun === true,
|
|
145
|
+
force: body.force === true,
|
|
146
|
+
verbose: body.verbose === true,
|
|
147
|
+
disabled: body.disabled === true
|
|
148
|
+
}),
|
|
111
149
|
runTest: (params, auth, body, query) =>
|
|
112
150
|
runTest(buildContext(auth, params.systemKey), {
|
|
113
151
|
runType: body.runType || query.runType || 'integration',
|
|
@@ -117,7 +155,10 @@ const HANDLER_MAP = {
|
|
|
117
155
|
runCertifyPillar(buildContext(auth, params.systemKey), params.pillar, {
|
|
118
156
|
noPublish: body.noPublish === true,
|
|
119
157
|
pack: body.pack,
|
|
120
|
-
body: body.lifecycleBody
|
|
158
|
+
body: body.lifecycleBody,
|
|
159
|
+
subjectEmails: _certifySubjectEmails(body),
|
|
160
|
+
subjectUserIds: _stringList(body.subjectUserIds),
|
|
161
|
+
certificationProfile: body.certificationProfile
|
|
121
162
|
}),
|
|
122
163
|
getLifecycleReport: (params, auth, _body, query) =>
|
|
123
164
|
getLifecycleReport(buildContext(auth, params.systemKey), {
|
|
@@ -137,7 +178,53 @@ const HANDLER_MAP = {
|
|
|
137
178
|
runRepositoryDispatchPipeline: (params, auth, body) =>
|
|
138
179
|
runRepositoryDispatchPipeline(buildContext(auth, params.systemKey), body),
|
|
139
180
|
health: () => ({ status: 'ok' }),
|
|
140
|
-
ready: () => ({ status: 'ready', dataplaneUrl: process.env.DATAPLANE_URL || null })
|
|
181
|
+
ready: () => ({ status: 'ready', dataplaneUrl: process.env.DATAPLANE_URL || null }),
|
|
182
|
+
getEvidenceMetadata: (params, auth) =>
|
|
183
|
+
getEvidenceMetadata(buildContext(auth, '_evidence'), params.roleKey),
|
|
184
|
+
downloadEvidence: (params, auth, _body, query) =>
|
|
185
|
+
downloadEvidence(buildContext(auth, '_evidence'), {
|
|
186
|
+
roleKey: params.roleKey,
|
|
187
|
+
resourceType: query.resourceType,
|
|
188
|
+
status: query.status,
|
|
189
|
+
kindKey: query.kindKey,
|
|
190
|
+
aspect: query.aspect,
|
|
191
|
+
search: query.search,
|
|
192
|
+
genericOnly: query.genericOnly === 'true',
|
|
193
|
+
limit: query.limit,
|
|
194
|
+
offset: query.offset
|
|
195
|
+
}),
|
|
196
|
+
uploadEvidenceCandidates: (params, auth, body) =>
|
|
197
|
+
uploadEvidenceCandidates(buildContext(auth, '_evidence'), {
|
|
198
|
+
...(body && typeof body === 'object' ? body : {}),
|
|
199
|
+
roleKey: (body && body.roleKey) || params.roleKey
|
|
200
|
+
}),
|
|
201
|
+
activateEvidenceCandidates: (_params, auth, body) =>
|
|
202
|
+
activateEvidenceCandidates(buildContext(auth, '_evidence'), body)
|
|
141
203
|
};
|
|
142
204
|
|
|
205
|
+
/**
|
|
206
|
+
* @param {unknown} value
|
|
207
|
+
* @returns {string[]}
|
|
208
|
+
*/
|
|
209
|
+
function _stringList(value) {
|
|
210
|
+
if (!Array.isArray(value)) {
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
return value.map(item => String(item || '').trim()).filter(Boolean);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Normalize subject emails from CertifyRequest (singular or list).
|
|
218
|
+
* @param {Object} body
|
|
219
|
+
* @returns {string[]}
|
|
220
|
+
*/
|
|
221
|
+
function _certifySubjectEmails(body) {
|
|
222
|
+
const fromList = _stringList(body && body.subjectEmails);
|
|
223
|
+
const single = body && body.subjectEmail ? String(body.subjectEmail).trim() : '';
|
|
224
|
+
if (single && !fromList.includes(single)) {
|
|
225
|
+
return [single, ...fromList];
|
|
226
|
+
}
|
|
227
|
+
return fromList;
|
|
228
|
+
}
|
|
229
|
+
|
|
143
230
|
module.exports = { HANDLER_MAP };
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
const { runVerifyOperationsForExternalSystem } = require('../commands/verify-operations-external');
|
|
12
12
|
const { runVerifyTrustForExternalSystem } = require('../commands/verify-trust-external');
|
|
13
13
|
const { runVerifyGovernanceForExternalSystem } = require('../commands/verify-governance-external');
|
|
14
|
+
const { runVerifyGovernanceCombined } = require('../commands/verify-governance-combined-external');
|
|
14
15
|
const { runSystemLifecycle } = require('../api/lifecycle.api');
|
|
15
16
|
const { runWithWorkspaceContext } = require('./workspace-context');
|
|
16
17
|
const { mergeProgrammaticOptions } = require('./command-options');
|
|
@@ -45,7 +46,7 @@ async function runCertifyPillar(ctx, pillar, options = {}) {
|
|
|
45
46
|
} else if (pillar === 'trust') {
|
|
46
47
|
result = await runVerifyTrustForExternalSystem(ctx.systemKey, merged);
|
|
47
48
|
} else if (pillar === 'governance') {
|
|
48
|
-
result = await
|
|
49
|
+
result = await runGovernanceCertify(ctx.systemKey, merged);
|
|
49
50
|
} else {
|
|
50
51
|
result = await runSystemLifecycle(merged.dataplaneUrl, merged.authConfig, ctx.systemKey, options.body || {});
|
|
51
52
|
}
|
|
@@ -54,4 +55,16 @@ async function runCertifyPillar(ctx, pillar, options = {}) {
|
|
|
54
55
|
});
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Governance certify: generate packs (subjects required) then verify, unless pack override.
|
|
60
|
+
* @param {string} systemKey
|
|
61
|
+
* @param {Object} options
|
|
62
|
+
*/
|
|
63
|
+
async function runGovernanceCertify(systemKey, options) {
|
|
64
|
+
if (options.pack) {
|
|
65
|
+
return runVerifyGovernanceForExternalSystem(systemKey, options);
|
|
66
|
+
}
|
|
67
|
+
return runVerifyGovernanceCombined(systemKey, options);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = { runCertifyPillar, runGovernanceCertify, PILLARS };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmatic deploy wrapper — CLI deploy parity for builder-api.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview runDeploySystem for POST /systems/:systemKey/deploy
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const { deployExternalSystem } = require('../external-system/deploy');
|
|
12
|
+
const { runWithWorkspaceContext } = require('./workspace-context');
|
|
13
|
+
const { mergeProgrammaticOptions } = require('./command-options');
|
|
14
|
+
const { touchWorkspaceMeta } = require('./workspace-meta');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {unknown} gate
|
|
18
|
+
* @returns {string|undefined}
|
|
19
|
+
*/
|
|
20
|
+
function normalizeGate(gate) {
|
|
21
|
+
if (gate === null || gate === undefined || gate === '') {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
if (typeof gate === 'string') {
|
|
25
|
+
return gate.trim() || undefined;
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Map gateFailure / deploy errors to Problem Details status codes.
|
|
32
|
+
* @param {Error & { gateFailure?: boolean, statusCode?: number }} err
|
|
33
|
+
*/
|
|
34
|
+
function attachDeployStatus(err) {
|
|
35
|
+
if (err && err.gateFailure === true && !err.statusCode) {
|
|
36
|
+
err.statusCode = 422;
|
|
37
|
+
}
|
|
38
|
+
return err;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {import('./workspace-context').WorkspaceContext} ctx
|
|
43
|
+
* @param {Object} [options]
|
|
44
|
+
* @param {string} [options.gate] - Same as CLI --gate (operations,trust,governance,full)
|
|
45
|
+
* @param {string} [options.subjectEmail]
|
|
46
|
+
* @param {boolean} [options.probe]
|
|
47
|
+
* @param {boolean} [options.sync]
|
|
48
|
+
* @param {boolean} [options.verbose]
|
|
49
|
+
* @returns {Promise<Object>}
|
|
50
|
+
*/
|
|
51
|
+
async function runDeploySystem(ctx, options = {}) {
|
|
52
|
+
const merged = mergeProgrammaticOptions(ctx, {
|
|
53
|
+
...options,
|
|
54
|
+
gate: normalizeGate(options.gate),
|
|
55
|
+
subjectEmail: options.subjectEmail,
|
|
56
|
+
probe: options.probe === true,
|
|
57
|
+
sync: options.sync === true,
|
|
58
|
+
verbose: options.verbose === true
|
|
59
|
+
});
|
|
60
|
+
return runWithWorkspaceContext(ctx, async() => {
|
|
61
|
+
try {
|
|
62
|
+
const result = await deployExternalSystem(ctx.systemKey, merged);
|
|
63
|
+
touchWorkspaceMeta(ctx, { lastOperation: 'deploy' });
|
|
64
|
+
return result && typeof result === 'object' ? result : { deployed: true };
|
|
65
|
+
} catch (err) {
|
|
66
|
+
throw attachDeployStatus(err);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = {
|
|
72
|
+
runDeploySystem,
|
|
73
|
+
normalizeGate
|
|
74
|
+
};
|