@elevasis/core 0.37.0 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/index.d.ts +5 -1
- package/dist/index.d.ts +26 -3
- package/dist/index.js +21 -4
- package/dist/knowledge/index.d.ts +5 -1
- package/dist/organization-model/index.d.ts +26 -3
- package/dist/organization-model/index.js +21 -4
- package/dist/test-utils/index.d.ts +5 -1
- package/dist/test-utils/index.js +20 -3
- package/package.json +1 -1
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +356 -338
- package/src/_gen/__tests__/__snapshots__/system-interface-capabilities.md.snap +47 -0
- package/src/_gen/__tests__/scaffold-contracts.test.ts +47 -8
- package/src/business/acquisition/api-schemas.test.ts +13 -1
- package/src/business/acquisition/ontology-validation.ts +13 -22
- package/src/organization-model/__tests__/domains/systems.test.ts +34 -1
- package/src/organization-model/__tests__/schema.test.ts +47 -0
- package/src/organization-model/domains/systems.ts +22 -9
- package/src/organization-model/published.ts +2 -0
- package/src/platform/constants/versions.ts +1 -1
- package/src/platform/registry/__tests__/validation.test.ts +1404 -1318
- package/src/platform/registry/index.ts +90 -88
- package/src/platform/registry/types.ts +443 -425
- package/src/platform/registry/validation.ts +74 -1
- package/src/reference/_generated/contracts.md +356 -338
- package/src/reference/_generated/system-interface-capabilities.md +47 -0
- package/src/reference/glossary.md +14 -2
|
@@ -23,13 +23,15 @@ import {
|
|
|
23
23
|
computeInterfaceReadiness,
|
|
24
24
|
type SystemInterfaceReadinessIssueFamily
|
|
25
25
|
} from '../../business/acquisition/ontology-validation'
|
|
26
|
+
import { SYSTEM_INTERFACE_PROFILES } from '../../organization-model/domains/systems'
|
|
26
27
|
import type { OmTopologyNodeRef } from '../../organization-model/domains/topology'
|
|
27
28
|
import type {
|
|
28
29
|
TriggerDefinition,
|
|
29
30
|
ResourceRelationships,
|
|
30
31
|
ExternalResourceDefinition,
|
|
31
32
|
HumanCheckpointDefinition,
|
|
32
|
-
ResourceType
|
|
33
|
+
ResourceType,
|
|
34
|
+
ApiInterfaceConformanceGap
|
|
33
35
|
} from './types'
|
|
34
36
|
|
|
35
37
|
// ============================================================================
|
|
@@ -612,6 +614,77 @@ function addSystemInterfaceIssue(
|
|
|
612
614
|
})
|
|
613
615
|
}
|
|
614
616
|
|
|
617
|
+
/**
|
|
618
|
+
* Detects systems that are API-backed (have resources with non-empty ontology
|
|
619
|
+
* bindings), CAN adopt a platform-cataloged `apiInterface` readinessProfile
|
|
620
|
+
* (system path appears in `SYSTEM_INTERFACE_PROFILES`), but have not declared
|
|
621
|
+
* `apiInterface` in the Organization Model.
|
|
622
|
+
*
|
|
623
|
+
* Originally broad-by-design (flagged any system with ontology actions/writes
|
|
624
|
+
* lacking apiInterface). Tightened in @elevasis/sdk@1.30.1 after the template
|
|
625
|
+
* surfaced the unactionable-paradox case: custom systems (e.g. `sys.operations`,
|
|
626
|
+
* `sys.notifications`) have valid `ontology.actions` bindings but cannot adopt
|
|
627
|
+
* one of the closed-catalog readiness profiles, AND the documented guidance
|
|
628
|
+
* ("Custom Systems should not declare apiInterface") is incompatible with the
|
|
629
|
+
* broad heuristic. The gate now only flags systems where adoption is even
|
|
630
|
+
* possible — i.e. the system path matches a cataloged profile's `systemPath`.
|
|
631
|
+
*
|
|
632
|
+
* A system is flagged when ALL of:
|
|
633
|
+
* (a) `system.apiInterface === undefined`, AND
|
|
634
|
+
* (b) at least one resource in `organizationModel.resources` has
|
|
635
|
+
* `resource.systemPath` matching the system path AND
|
|
636
|
+
* `resource.ontology` non-empty (has `actions` and/or `writes` defined), AND
|
|
637
|
+
* (c) the system path appears as a cataloged `systemPath` in
|
|
638
|
+
* `SYSTEM_INTERFACE_PROFILES` (so adopting a profile is actually possible).
|
|
639
|
+
*
|
|
640
|
+
* Returns `[]` when `organizationModel` is undefined or no gaps are found.
|
|
641
|
+
*/
|
|
642
|
+
export function detectMissingApiInterfaceDeclarations(
|
|
643
|
+
orgName: string,
|
|
644
|
+
organizationModel: OrganizationModel | undefined
|
|
645
|
+
): ApiInterfaceConformanceGap[] {
|
|
646
|
+
if (organizationModel === undefined) return []
|
|
647
|
+
|
|
648
|
+
// Build a map of system path → resource IDs for resources with non-empty ontology.
|
|
649
|
+
const apiBoundResourcesBySystemPath = new Map<string, string[]>()
|
|
650
|
+
for (const resource of Object.values(organizationModel.resources ?? {})) {
|
|
651
|
+
const ontology = resource.ontology
|
|
652
|
+
if (ontology === undefined) continue
|
|
653
|
+
const hasOntologyBindings =
|
|
654
|
+
(ontology.actions !== undefined && ontology.actions.length > 0) ||
|
|
655
|
+
(ontology.writes !== undefined && ontology.writes.length > 0)
|
|
656
|
+
if (!hasOntologyBindings) continue
|
|
657
|
+
const existing = apiBoundResourcesBySystemPath.get(resource.systemPath)
|
|
658
|
+
if (existing) {
|
|
659
|
+
existing.push(resource.id)
|
|
660
|
+
} else {
|
|
661
|
+
apiBoundResourcesBySystemPath.set(resource.systemPath, [resource.id])
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
if (apiBoundResourcesBySystemPath.size === 0) return []
|
|
666
|
+
|
|
667
|
+
// Closed-catalog filter: a system is only a candidate for missing apiInterface
|
|
668
|
+
// if it could actually adopt one of the cataloged platform profiles.
|
|
669
|
+
const catalogedSystemPaths = new Set<string>(SYSTEM_INTERFACE_PROFILES.map((profile) => profile.systemPath))
|
|
670
|
+
|
|
671
|
+
const gaps: ApiInterfaceConformanceGap[] = []
|
|
672
|
+
|
|
673
|
+
for (const { path, system } of listAllSystems(organizationModel)) {
|
|
674
|
+
if (system.apiInterface !== undefined) continue
|
|
675
|
+
if (!catalogedSystemPaths.has(path)) continue
|
|
676
|
+
const resourceIds = apiBoundResourcesBySystemPath.get(path)
|
|
677
|
+
if (!resourceIds || resourceIds.length === 0) continue
|
|
678
|
+
gaps.push({
|
|
679
|
+
systemPath: path,
|
|
680
|
+
resourceIds,
|
|
681
|
+
message: `[${orgName}] System '${path}' has ${resourceIds.length} API-backed resource(s) (${resourceIds.join(', ')}) but no apiInterface declaration.`
|
|
682
|
+
})
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
return gaps
|
|
686
|
+
}
|
|
687
|
+
|
|
615
688
|
/**
|
|
616
689
|
* Validates every explicitly declared API System Interface by deriving
|
|
617
690
|
* readiness from its scoped resources and ontology bindings.
|