@elevasis/core 0.34.1 → 0.35.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 +74 -2
- package/dist/auth/index.js +65 -30
- package/dist/index.d.ts +60 -2
- package/dist/index.js +52 -1
- package/dist/knowledge/index.d.ts +12 -0
- package/dist/organization-model/index.d.ts +60 -2
- package/dist/organization-model/index.js +52 -1
- package/dist/test-utils/index.d.ts +12 -0
- package/dist/test-utils/index.js +51 -0
- package/package.json +1 -1
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +69 -30
- package/src/auth/multi-tenancy/index.ts +29 -26
- package/src/auth/multi-tenancy/org-id.test.ts +139 -0
- package/src/auth/multi-tenancy/org-id.ts +112 -0
- package/src/business/acquisition/api-schemas.test.ts +456 -28
- package/src/business/acquisition/ontology-validation.ts +715 -23
- package/src/execution/engine/tools/platform/storage/__tests__/storage.test.ts +997 -998
- package/src/organization-model/__tests__/domains/systems.test.ts +61 -15
- package/src/organization-model/__tests__/domains/topology.test.ts +23 -0
- package/src/organization-model/__tests__/schema.test.ts +112 -0
- package/src/organization-model/domains/systems.ts +44 -0
- package/src/organization-model/domains/topology.ts +18 -1
- package/src/organization-model/published.ts +19 -1
- package/src/organization-model/schema-refinements.ts +23 -0
- package/src/organization-model/types.ts +17 -1
- package/src/platform/constants/versions.ts +1 -1
- package/src/platform/registry/__tests__/validation.test.ts +254 -15
- package/src/platform/registry/index.ts +28 -15
- package/src/platform/registry/validation.ts +180 -2
- package/src/reference/_generated/contracts.md +44 -0
- package/src/supabase/__tests__/helpers.test.ts +92 -51
- package/src/supabase/helpers.ts +40 -20
- package/src/supabase/index.ts +52 -52
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
-
import {
|
|
3
|
-
DEFAULT_ORGANIZATION_MODEL_SYSTEMS,
|
|
4
|
-
SystemEntrySchema,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_ORGANIZATION_MODEL_SYSTEMS,
|
|
4
|
+
SystemEntrySchema,
|
|
5
|
+
SystemApiInterfaceSchema,
|
|
6
|
+
SystemInterfaceRefSchema,
|
|
7
|
+
SystemKindSchema,
|
|
8
|
+
SystemStatusSchema,
|
|
9
|
+
SystemsDomainSchema
|
|
10
|
+
} from '../../domains/systems'
|
|
9
11
|
import { resolveOrganizationModel } from '../../resolve'
|
|
10
12
|
|
|
11
13
|
const VALID_SYSTEM = {
|
|
@@ -27,7 +29,7 @@ describe('SystemEntrySchema - positive parse', () => {
|
|
|
27
29
|
}
|
|
28
30
|
})
|
|
29
31
|
|
|
30
|
-
it('accepts all optional governance references when present', () => {
|
|
32
|
+
it('accepts all optional governance references when present', () => {
|
|
31
33
|
const result = SystemEntrySchema.safeParse({
|
|
32
34
|
...VALID_SYSTEM,
|
|
33
35
|
responsibleRoleId: 'role.sales-ops',
|
|
@@ -35,8 +37,43 @@ describe('SystemEntrySchema - positive parse', () => {
|
|
|
35
37
|
drivesGoals: ['goal.pipeline-coverage']
|
|
36
38
|
})
|
|
37
39
|
|
|
38
|
-
expect(result.success).toBe(true)
|
|
39
|
-
})
|
|
40
|
+
expect(result.success).toBe(true)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('accepts a thin API System Interface marker with scoped resources', () => {
|
|
44
|
+
const result = SystemEntrySchema.safeParse({
|
|
45
|
+
...VALID_SYSTEM,
|
|
46
|
+
apiInterface: {
|
|
47
|
+
lifecycle: 'active',
|
|
48
|
+
readinessProfile: 'sales.lead-gen.api',
|
|
49
|
+
resourceIds: ['lead-gen-list-builder']
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
expect(result.success).toBe(true)
|
|
54
|
+
if (result.success) {
|
|
55
|
+
expect(result.data.apiInterface).toEqual({
|
|
56
|
+
lifecycle: 'active',
|
|
57
|
+
readinessProfile: 'sales.lead-gen.api',
|
|
58
|
+
resourceIds: ['lead-gen-list-builder']
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('represents missing and disabled System Interfaces distinctly', () => {
|
|
64
|
+
const missing = SystemEntrySchema.parse(VALID_SYSTEM)
|
|
65
|
+
const disabled = SystemEntrySchema.parse({
|
|
66
|
+
...VALID_SYSTEM,
|
|
67
|
+
apiInterface: {
|
|
68
|
+
lifecycle: 'disabled',
|
|
69
|
+
readinessProfile: 'sales.lead-gen.api'
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
expect(missing.apiInterface).toBeUndefined()
|
|
74
|
+
expect(disabled.apiInterface?.lifecycle).toBe('disabled')
|
|
75
|
+
expect(disabled.apiInterface?.resourceIds).toEqual([])
|
|
76
|
+
})
|
|
40
77
|
|
|
41
78
|
it('trims id, title, and description', () => {
|
|
42
79
|
const result = SystemEntrySchema.safeParse({
|
|
@@ -86,10 +123,19 @@ describe('SystemEntrySchema - negative parse', () => {
|
|
|
86
123
|
expect(SystemEntrySchema.safeParse({ ...VALID_SYSTEM, status: 'paused' }).success).toBe(false)
|
|
87
124
|
})
|
|
88
125
|
|
|
89
|
-
it('rejects IDs that do not match the OM model-id format', () => {
|
|
90
|
-
expect(SystemEntrySchema.safeParse({ ...VALID_SYSTEM, id: 'Sys Lead Gen' }).success).toBe(false)
|
|
91
|
-
})
|
|
92
|
-
|
|
126
|
+
it('rejects IDs that do not match the OM model-id format', () => {
|
|
127
|
+
expect(SystemEntrySchema.safeParse({ ...VALID_SYSTEM, id: 'Sys Lead Gen' }).success).toBe(false)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('rejects malformed System Interface states', () => {
|
|
131
|
+
expect(SystemApiInterfaceSchema.safeParse({ kind: 'api', lifecycle: 'active' }).success).toBe(false)
|
|
132
|
+
expect(SystemApiInterfaceSchema.safeParse({ lifecycle: 'paused' }).success).toBe(false)
|
|
133
|
+
expect(SystemApiInterfaceSchema.safeParse({ readinessProfile: 'Sales Lead Gen API' }).success).toBe(false)
|
|
134
|
+
expect(
|
|
135
|
+
SystemInterfaceRefSchema.safeParse({ systemPath: 'sales.lead-gen', interfaceKey: 'api' }).success
|
|
136
|
+
).toBe(true)
|
|
137
|
+
})
|
|
138
|
+
})
|
|
93
139
|
|
|
94
140
|
describe('SystemsDomainSchema', () => {
|
|
95
141
|
it('accepts an empty systems record', () => {
|
|
@@ -3,6 +3,8 @@ import { ZodError } from 'zod'
|
|
|
3
3
|
import {
|
|
4
4
|
OmTopologyDomainSchema,
|
|
5
5
|
OmTopologyMetadataSchema,
|
|
6
|
+
OmTopologySystemInterfaceGrantMetadataSchema,
|
|
7
|
+
OmTopologySystemInterfaceGrantSchema,
|
|
6
8
|
defineTopology,
|
|
7
9
|
defineTopologyRelationship,
|
|
8
10
|
parseTopologyNodeRef,
|
|
@@ -128,6 +130,27 @@ describe('OM topology domain', () => {
|
|
|
128
130
|
).toBe(false)
|
|
129
131
|
})
|
|
130
132
|
|
|
133
|
+
it('documents scoped System Interface topology grants', () => {
|
|
134
|
+
const grant = OmTopologySystemInterfaceGrantSchema.parse({
|
|
135
|
+
consumer: { systemPath: 'sales.lead-gen', interfaceKey: 'api' },
|
|
136
|
+
provider: { systemPath: 'sales.crm', interfaceKey: 'api' },
|
|
137
|
+
resourceIds: ['lead-gen-crm-handoff'],
|
|
138
|
+
ontologyIds: ['sales.crm:object/deal']
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
expect(grant).toEqual({
|
|
142
|
+
consumer: { systemPath: 'sales.lead-gen', interfaceKey: 'api' },
|
|
143
|
+
provider: { systemPath: 'sales.crm', interfaceKey: 'api' },
|
|
144
|
+
resourceIds: ['lead-gen-crm-handoff'],
|
|
145
|
+
ontologyIds: ['sales.crm:object/deal']
|
|
146
|
+
})
|
|
147
|
+
expect(
|
|
148
|
+
OmTopologySystemInterfaceGrantMetadataSchema.safeParse({
|
|
149
|
+
systemInterfaceGrant: grant
|
|
150
|
+
}).success
|
|
151
|
+
).toBe(true)
|
|
152
|
+
})
|
|
153
|
+
|
|
131
154
|
it('compiles typed resource objects through authoring helpers', () => {
|
|
132
155
|
const relationship = defineTopologyRelationship({
|
|
133
156
|
from: SOURCE_RESOURCE,
|
|
@@ -187,6 +187,118 @@ describe('domain metadata validation', () => {
|
|
|
187
187
|
})
|
|
188
188
|
})
|
|
189
189
|
|
|
190
|
+
describe('retired contract authoring surfaces', () => {
|
|
191
|
+
it('does not materialize absent System Contracts or Bridge Contracts for existing OMs', () => {
|
|
192
|
+
const model = OrganizationModelSchema.parse(makeMinimalModel({ dashboard: makeSystem('dashboard', '/') }))
|
|
193
|
+
|
|
194
|
+
expect((model.systems.dashboard as Record<string, unknown>).contracts).toBeUndefined()
|
|
195
|
+
expect((model as Record<string, unknown>).bridgeContracts).toBeUndefined()
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
it('rejects authored System Contracts and top-level Bridge Contracts', () => {
|
|
199
|
+
const messages = getIssueMessages({
|
|
200
|
+
...makeMinimalModel({
|
|
201
|
+
sales: { id: 'sales', order: 10, label: 'Sales', lifecycle: 'active' },
|
|
202
|
+
'sales.lead-gen': {
|
|
203
|
+
...makeSystem('sales.lead-gen', '/lead-gen/lists'),
|
|
204
|
+
contracts: [
|
|
205
|
+
{
|
|
206
|
+
id: 'retired.contract',
|
|
207
|
+
ownerSystemPath: 'sales.lead-gen',
|
|
208
|
+
provided: []
|
|
209
|
+
}
|
|
210
|
+
]
|
|
211
|
+
},
|
|
212
|
+
'sales.crm': {
|
|
213
|
+
...makeSystem('sales.crm', '/crm'),
|
|
214
|
+
contracts: [
|
|
215
|
+
{
|
|
216
|
+
id: 'retired.crm.contract',
|
|
217
|
+
ownerSystemPath: 'sales.crm',
|
|
218
|
+
provided: []
|
|
219
|
+
}
|
|
220
|
+
]
|
|
221
|
+
}
|
|
222
|
+
}),
|
|
223
|
+
bridgeContracts: [
|
|
224
|
+
{
|
|
225
|
+
id: 'retired.bridge',
|
|
226
|
+
ownerSystemPath: 'sales.lead-gen',
|
|
227
|
+
consumerSystemPath: 'sales.crm',
|
|
228
|
+
required: [],
|
|
229
|
+
provided: []
|
|
230
|
+
}
|
|
231
|
+
]
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
expect(messages.some((message) => message.includes('Unrecognized key'))).toBe(true)
|
|
235
|
+
})
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
describe('System Interface schema integration', () => {
|
|
239
|
+
it('accepts a System API Interface scoped to resources from the same System', () => {
|
|
240
|
+
const result = OrganizationModelSchema.safeParse({
|
|
241
|
+
...makeMinimalModel({
|
|
242
|
+
'sales.lead-gen': {
|
|
243
|
+
...makeSystem('sales.lead-gen', '/lead-gen/lists'),
|
|
244
|
+
apiInterface: {
|
|
245
|
+
lifecycle: 'active',
|
|
246
|
+
readinessProfile: 'sales.lead-gen.api',
|
|
247
|
+
resourceIds: ['lead-gen-list-builder']
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}),
|
|
251
|
+
resources: {
|
|
252
|
+
'lead-gen-list-builder': {
|
|
253
|
+
id: 'lead-gen-list-builder',
|
|
254
|
+
order: 10,
|
|
255
|
+
kind: 'workflow',
|
|
256
|
+
systemPath: 'sales.lead-gen',
|
|
257
|
+
status: 'active'
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
expect(result.success).toBe(true)
|
|
263
|
+
if (result.success) {
|
|
264
|
+
expect(result.data.systems['sales.lead-gen']?.apiInterface).toMatchObject({
|
|
265
|
+
lifecycle: 'active',
|
|
266
|
+
readinessProfile: 'sales.lead-gen.api',
|
|
267
|
+
resourceIds: ['lead-gen-list-builder']
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
it('rejects System Interface resource scopes that point at missing or foreign-System resources', () => {
|
|
273
|
+
const messages = getIssueMessages({
|
|
274
|
+
...makeMinimalModel({
|
|
275
|
+
'sales.lead-gen': {
|
|
276
|
+
...makeSystem('sales.lead-gen', '/lead-gen/lists'),
|
|
277
|
+
apiInterface: {
|
|
278
|
+
readinessProfile: 'sales.lead-gen.api',
|
|
279
|
+
resourceIds: ['missing-resource', 'crm-deal-sync']
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
'sales.crm': makeSystem('sales.crm', '/crm')
|
|
283
|
+
}),
|
|
284
|
+
resources: {
|
|
285
|
+
'crm-deal-sync': {
|
|
286
|
+
id: 'crm-deal-sync',
|
|
287
|
+
order: 10,
|
|
288
|
+
kind: 'workflow',
|
|
289
|
+
systemPath: 'sales.crm',
|
|
290
|
+
status: 'active'
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
expect(messages.some((message) => message.includes('scopes unknown resource "missing-resource"'))).toBe(true)
|
|
296
|
+
expect(
|
|
297
|
+
messages.some((message) => message.includes('scopes resource "crm-deal-sync" from system "sales.crm"'))
|
|
298
|
+
).toBe(true)
|
|
299
|
+
})
|
|
300
|
+
})
|
|
301
|
+
|
|
190
302
|
describe('deployment projection validation', () => {
|
|
191
303
|
it('rejects old deploy governance projections that omit referenced full-model domains', () => {
|
|
192
304
|
const messages = getIssueMessages({
|
|
@@ -61,6 +61,42 @@ export const SystemUiSchema = z.object({
|
|
|
61
61
|
order: z.number().int().optional()
|
|
62
62
|
})
|
|
63
63
|
|
|
64
|
+
export const SystemInterfaceKeySchema = ModelIdSchema
|
|
65
|
+
export const SystemInterfaceLifecycleSchema = z
|
|
66
|
+
.enum(['draft', 'active', 'disabled', 'deprecated', 'archived'])
|
|
67
|
+
.meta({ label: 'System interface lifecycle', color: 'teal' })
|
|
68
|
+
export const SystemInterfaceReadinessProfileSchema = z
|
|
69
|
+
.string()
|
|
70
|
+
.trim()
|
|
71
|
+
.min(1)
|
|
72
|
+
.max(200)
|
|
73
|
+
.regex(
|
|
74
|
+
/^[a-z0-9][a-z0-9-]*(?:\.[a-z0-9][a-z0-9-]*)*(?:\.[a-z0-9][a-z0-9-]*)?$/,
|
|
75
|
+
'Readiness profiles must use dotted lowercase identifiers (e.g. "sales.lead-gen.api")'
|
|
76
|
+
)
|
|
77
|
+
export const SystemInterfaceResourceScopeSchema = z
|
|
78
|
+
.array(ModelIdSchema)
|
|
79
|
+
.default([])
|
|
80
|
+
|
|
81
|
+
export const SystemApiInterfaceSchema = z
|
|
82
|
+
.object({
|
|
83
|
+
lifecycle: SystemInterfaceLifecycleSchema.default('active'),
|
|
84
|
+
readinessProfile: SystemInterfaceReadinessProfileSchema.optional(),
|
|
85
|
+
/**
|
|
86
|
+
* Resource ids that participate in this API interface. This scopes readiness
|
|
87
|
+
* derivation without duplicating authored required/provided contract refs.
|
|
88
|
+
*/
|
|
89
|
+
resourceIds: SystemInterfaceResourceScopeSchema.optional()
|
|
90
|
+
})
|
|
91
|
+
.strict()
|
|
92
|
+
|
|
93
|
+
export const SystemInterfaceRefSchema = z
|
|
94
|
+
.object({
|
|
95
|
+
systemPath: SystemPathSchema,
|
|
96
|
+
interfaceKey: SystemInterfaceKeySchema
|
|
97
|
+
})
|
|
98
|
+
.strict()
|
|
99
|
+
|
|
64
100
|
// ---------------------------------------------------------------------------
|
|
65
101
|
// Recursive SystemEntry schema.
|
|
66
102
|
//
|
|
@@ -102,6 +138,7 @@ export interface SystemEntry {
|
|
|
102
138
|
actions?: { actionId: string; intent: 'exposes' | 'consumes'; invocation?: unknown }[]
|
|
103
139
|
policies?: string[]
|
|
104
140
|
drivesGoals?: string[]
|
|
141
|
+
apiInterface?: z.infer<typeof SystemApiInterfaceSchema>
|
|
105
142
|
/** @deprecated Use lifecycle. Accepted for one publish cycle. */
|
|
106
143
|
status?: 'active' | 'deprecated' | 'archived'
|
|
107
144
|
path?: string
|
|
@@ -155,6 +192,8 @@ export const SystemEntrySchema: ZodType<SystemEntry> = z
|
|
|
155
192
|
.array(ModelIdSchema.meta({ ref: 'goal' }))
|
|
156
193
|
.default([])
|
|
157
194
|
.optional(),
|
|
195
|
+
/** Thin API runtime-boundary marker. Readiness is derived from scoped resources and topology. */
|
|
196
|
+
apiInterface: SystemApiInterfaceSchema.optional(),
|
|
158
197
|
/** @deprecated Use lifecycle. Accepted for one publish cycle. */
|
|
159
198
|
status: SystemStatusSchema.optional(),
|
|
160
199
|
/** @deprecated Use ui.path. Kept for one-cycle Feature compatibility. */
|
|
@@ -240,6 +279,11 @@ export type SystemLifecycle = z.infer<typeof SystemLifecycleSchema>
|
|
|
240
279
|
/** @deprecated Use SystemLifecycle. Accepted for one publish cycle. */
|
|
241
280
|
export type SystemStatus = z.infer<typeof SystemStatusSchema>
|
|
242
281
|
export type SystemLocalConfig = z.infer<typeof SystemConfigSchema>
|
|
282
|
+
export type SystemInterfaceKey = z.infer<typeof SystemInterfaceKeySchema>
|
|
283
|
+
export type SystemInterfaceLifecycle = z.infer<typeof SystemInterfaceLifecycleSchema>
|
|
284
|
+
export type SystemInterfaceReadinessProfile = z.infer<typeof SystemInterfaceReadinessProfileSchema>
|
|
285
|
+
export type SystemApiInterface = z.infer<typeof SystemApiInterfaceSchema>
|
|
286
|
+
export type SystemInterfaceRef = z.infer<typeof SystemInterfaceRefSchema>
|
|
243
287
|
// SystemEntry is declared as an explicit interface above the schema (required for
|
|
244
288
|
// recursive z.lazy() type inference). Re-export omitted — the interface IS the type.
|
|
245
289
|
export type SystemsDomain = z.infer<typeof SystemsDomainSchema>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { OntologyIdSchema, parseOntologyId } from '../ontology'
|
|
3
|
-
import { JsonValueSchema, SystemPathSchema } from './systems'
|
|
3
|
+
import { JsonValueSchema, SystemInterfaceRefSchema, SystemPathSchema } from './systems'
|
|
4
4
|
import { ModelIdSchema } from './shared'
|
|
5
5
|
import { ResourceIdSchema, type ResourceEntry } from './resources'
|
|
6
6
|
|
|
@@ -74,6 +74,21 @@ export const OmTopologyMetadataSchema = z
|
|
|
74
74
|
visit(metadata, [])
|
|
75
75
|
})
|
|
76
76
|
|
|
77
|
+
export const OmTopologySystemInterfaceGrantSchema = z
|
|
78
|
+
.object({
|
|
79
|
+
consumer: SystemInterfaceRefSchema,
|
|
80
|
+
provider: SystemInterfaceRefSchema,
|
|
81
|
+
resourceIds: z.array(ResourceIdSchema).default([]),
|
|
82
|
+
ontologyIds: z.array(OntologyIdSchema).default([])
|
|
83
|
+
})
|
|
84
|
+
.strict()
|
|
85
|
+
|
|
86
|
+
export const OmTopologySystemInterfaceGrantMetadataSchema = z
|
|
87
|
+
.object({
|
|
88
|
+
systemInterfaceGrant: OmTopologySystemInterfaceGrantSchema
|
|
89
|
+
})
|
|
90
|
+
.strict()
|
|
91
|
+
|
|
77
92
|
export const OmTopologyRelationshipSchema = z.object({
|
|
78
93
|
from: OmTopologyNodeRefSchema,
|
|
79
94
|
kind: OmTopologyRelationshipKindSchema,
|
|
@@ -99,6 +114,8 @@ export type OmTopologyNodeKind = z.infer<typeof OmTopologyNodeKindSchema>
|
|
|
99
114
|
export type OmTopologyRelationshipKind = z.infer<typeof OmTopologyRelationshipKindSchema>
|
|
100
115
|
export type OmTopologyNodeRef = z.infer<typeof OmTopologyNodeRefSchema>
|
|
101
116
|
export type OmTopologyMetadata = z.infer<typeof OmTopologyMetadataSchema>
|
|
117
|
+
export type OmTopologySystemInterfaceGrant = z.infer<typeof OmTopologySystemInterfaceGrantSchema>
|
|
118
|
+
export type OmTopologySystemInterfaceGrantMetadata = z.infer<typeof OmTopologySystemInterfaceGrantMetadataSchema>
|
|
102
119
|
export type OmTopologyRelationship = z.infer<typeof OmTopologyRelationshipSchema>
|
|
103
120
|
export type OmTopologyDomain = z.infer<typeof OmTopologyDomainSchema>
|
|
104
121
|
|
|
@@ -29,7 +29,11 @@ export {
|
|
|
29
29
|
OrganizationModelDomainMetadataSchema,
|
|
30
30
|
OrganizationModelSchema
|
|
31
31
|
} from './schema'
|
|
32
|
-
export {
|
|
32
|
+
export {
|
|
33
|
+
NodeIdPathSchema,
|
|
34
|
+
NodeIdStringSchema,
|
|
35
|
+
UiPositionSchema
|
|
36
|
+
} from './domains/systems'
|
|
33
37
|
export { LinkSchema } from './graph/link'
|
|
34
38
|
export { IconNameSchema, TechStackEntrySchema } from './domains/shared'
|
|
35
39
|
export {
|
|
@@ -113,6 +117,11 @@ export {
|
|
|
113
117
|
defineSystems,
|
|
114
118
|
SystemEntrySchema,
|
|
115
119
|
SystemIdSchema,
|
|
120
|
+
SystemInterfaceKeySchema,
|
|
121
|
+
SystemInterfaceLifecycleSchema,
|
|
122
|
+
SystemInterfaceReadinessProfileSchema,
|
|
123
|
+
SystemInterfaceRefSchema,
|
|
124
|
+
SystemApiInterfaceSchema,
|
|
116
125
|
SystemKindSchema,
|
|
117
126
|
SystemLifecycleSchema,
|
|
118
127
|
SystemPathSchema,
|
|
@@ -158,6 +167,8 @@ export {
|
|
|
158
167
|
OmTopologyNodeRefSchema,
|
|
159
168
|
OmTopologyRelationshipKindSchema,
|
|
160
169
|
OmTopologyRelationshipSchema,
|
|
170
|
+
OmTopologySystemInterfaceGrantMetadataSchema,
|
|
171
|
+
OmTopologySystemInterfaceGrantSchema,
|
|
161
172
|
parseTopologyNodeRef,
|
|
162
173
|
topologyRelationship,
|
|
163
174
|
topologyRef
|
|
@@ -291,6 +302,11 @@ export type {
|
|
|
291
302
|
OrganizationModelKeyResult,
|
|
292
303
|
OrganizationModelObjective,
|
|
293
304
|
OrganizationModelSystemEntry,
|
|
305
|
+
OrganizationModelSystemApiInterface,
|
|
306
|
+
OrganizationModelSystemInterfaceKey,
|
|
307
|
+
OrganizationModelSystemInterfaceLifecycle,
|
|
308
|
+
OrganizationModelSystemInterfaceReadinessProfile,
|
|
309
|
+
OrganizationModelSystemInterfaceRef,
|
|
294
310
|
OrganizationModelSystemId,
|
|
295
311
|
OrganizationModelSystemKind,
|
|
296
312
|
OrganizationModelSystemLifecycle,
|
|
@@ -322,6 +338,8 @@ export type {
|
|
|
322
338
|
OrganizationModelTopologyNodeRef,
|
|
323
339
|
OrganizationModelTopologyRelationship,
|
|
324
340
|
OrganizationModelTopologyRelationshipKind,
|
|
341
|
+
OrganizationModelTopologySystemInterfaceGrant,
|
|
342
|
+
OrganizationModelTopologySystemInterfaceGrantMetadata,
|
|
325
343
|
OrganizationModelWorkflowResourceEntry,
|
|
326
344
|
OrganizationModelActions,
|
|
327
345
|
OrganizationModelAction,
|
|
@@ -372,6 +372,7 @@ export function refineOrganizationModel(model: OrganizationModel, ctx: z.Refinem
|
|
|
372
372
|
)
|
|
373
373
|
}
|
|
374
374
|
})
|
|
375
|
+
|
|
375
376
|
})
|
|
376
377
|
|
|
377
378
|
Object.values(model.actions).forEach((action) => {
|
|
@@ -571,6 +572,28 @@ export function refineOrganizationModel(model: OrganizationModel, ctx: z.Refinem
|
|
|
571
572
|
}
|
|
572
573
|
})
|
|
573
574
|
|
|
575
|
+
allSystems.forEach(({ path: systemPath, schemaPath, system }) => {
|
|
576
|
+
system.apiInterface?.resourceIds?.forEach((resourceId, resourceIndex) => {
|
|
577
|
+
const resource = resourcesById.get(resourceId)
|
|
578
|
+
if (resource === undefined) {
|
|
579
|
+
addIssue(
|
|
580
|
+
ctx,
|
|
581
|
+
[...schemaPath, 'apiInterface', 'resourceIds', resourceIndex],
|
|
582
|
+
`System Interface "${systemPath}/api" scopes unknown resource "${resourceId}"`
|
|
583
|
+
)
|
|
584
|
+
return
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
if (resource.systemPath !== systemPath) {
|
|
588
|
+
addIssue(
|
|
589
|
+
ctx,
|
|
590
|
+
[...schemaPath, 'apiInterface', 'resourceIds', resourceIndex],
|
|
591
|
+
`System Interface "${systemPath}/api" scopes resource "${resourceId}" from system "${resource.systemPath}"`
|
|
592
|
+
)
|
|
593
|
+
}
|
|
594
|
+
})
|
|
595
|
+
})
|
|
596
|
+
|
|
574
597
|
function validateResourceOntologyBinding(
|
|
575
598
|
resourceId: string,
|
|
576
599
|
bindingKey: 'actions' | 'primaryAction' | 'reads' | 'writes' | 'usesCatalogs' | 'emits',
|
|
@@ -37,6 +37,11 @@ import {
|
|
|
37
37
|
} from './domains/knowledge'
|
|
38
38
|
import {
|
|
39
39
|
SystemEntrySchema,
|
|
40
|
+
SystemInterfaceKeySchema,
|
|
41
|
+
SystemInterfaceLifecycleSchema,
|
|
42
|
+
SystemInterfaceReadinessProfileSchema,
|
|
43
|
+
SystemInterfaceRefSchema,
|
|
44
|
+
SystemApiInterfaceSchema,
|
|
40
45
|
SystemConfigSchema,
|
|
41
46
|
SystemIdSchema,
|
|
42
47
|
SystemKindSchema,
|
|
@@ -74,7 +79,9 @@ import {
|
|
|
74
79
|
OmTopologyNodeKindSchema,
|
|
75
80
|
OmTopologyNodeRefSchema,
|
|
76
81
|
OmTopologyRelationshipKindSchema,
|
|
77
|
-
OmTopologyRelationshipSchema
|
|
82
|
+
OmTopologyRelationshipSchema,
|
|
83
|
+
OmTopologySystemInterfaceGrantMetadataSchema,
|
|
84
|
+
OmTopologySystemInterfaceGrantSchema
|
|
78
85
|
} from './domains/topology'
|
|
79
86
|
import {
|
|
80
87
|
ActionsDomainSchema,
|
|
@@ -156,6 +163,11 @@ export type OrganizationModelSystemId = z.infer<typeof SystemIdSchema>
|
|
|
156
163
|
export type OrganizationModelSystemPath = z.infer<typeof SystemPathSchema>
|
|
157
164
|
export type OrganizationModelSystemKind = z.infer<typeof SystemKindSchema>
|
|
158
165
|
export type OrganizationModelSystemLifecycle = z.infer<typeof SystemLifecycleSchema>
|
|
166
|
+
export type OrganizationModelSystemInterfaceKey = z.infer<typeof SystemInterfaceKeySchema>
|
|
167
|
+
export type OrganizationModelSystemInterfaceLifecycle = z.infer<typeof SystemInterfaceLifecycleSchema>
|
|
168
|
+
export type OrganizationModelSystemInterfaceReadinessProfile = z.infer<typeof SystemInterfaceReadinessProfileSchema>
|
|
169
|
+
export type OrganizationModelSystemApiInterface = z.infer<typeof SystemApiInterfaceSchema>
|
|
170
|
+
export type OrganizationModelSystemInterfaceRef = z.infer<typeof SystemInterfaceRefSchema>
|
|
159
171
|
/** @deprecated Use OrganizationModelSystemLifecycle. Accepted for one publish cycle. */
|
|
160
172
|
export type OrganizationModelSystemStatus = z.infer<typeof SystemStatusSchema>
|
|
161
173
|
export type OrganizationModelResources = z.infer<typeof ResourcesDomainSchema>
|
|
@@ -185,6 +197,10 @@ export type OrganizationModelTopologyNodeRef = z.infer<typeof OmTopologyNodeRefS
|
|
|
185
197
|
export type OrganizationModelTopologyRelationshipKind = z.infer<typeof OmTopologyRelationshipKindSchema>
|
|
186
198
|
export type OrganizationModelTopologyRelationship = z.infer<typeof OmTopologyRelationshipSchema>
|
|
187
199
|
export type OrganizationModelTopologyMetadata = z.infer<typeof OmTopologyMetadataSchema>
|
|
200
|
+
export type OrganizationModelTopologySystemInterfaceGrant = z.infer<typeof OmTopologySystemInterfaceGrantSchema>
|
|
201
|
+
export type OrganizationModelTopologySystemInterfaceGrantMetadata = z.infer<
|
|
202
|
+
typeof OmTopologySystemInterfaceGrantMetadataSchema
|
|
203
|
+
>
|
|
188
204
|
export type OrganizationModelActions = z.infer<typeof ActionsDomainSchema>
|
|
189
205
|
export type OrganizationModelAction = z.infer<typeof ActionSchema>
|
|
190
206
|
export type OrganizationModelActionId = z.infer<typeof ActionIdSchema>
|