@elevasis/ui 2.41.0 → 2.42.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/api/index.js +4 -6
- package/dist/app/index.css +384 -0
- package/dist/app/index.d.ts +5 -1
- package/dist/app/index.js +17 -26
- package/dist/auth/index.css +659 -0
- package/dist/auth/index.js +19 -5
- package/dist/charts/index.css +533 -0
- package/dist/charts/index.js +18 -14
- package/dist/{chunk-JAN2ZXN5.js → chunk-3MTAHV5M.js} +28535 -18021
- package/dist/{chunk-73EWE2EW.js → chunk-EDVZ3AHA.js} +1 -1
- package/dist/chunk-GMXGDO3I.js +244 -0
- package/dist/{chunk-CXY7FMUM.js → chunk-GUKY77FJ.js} +50 -4
- package/dist/{chunk-TE4P6OSJ.js → chunk-MA7YCY7C.js} +1 -1
- package/dist/{chunk-5JYKCULK.js → chunk-NZ2F5RQ4.js} +44 -2
- package/dist/{chunk-WF7CONXF.js → chunk-OJJK27GC.js} +658 -6
- package/dist/chunk-YEGMSADG.js +1781 -0
- package/dist/components/chat/index.js +1 -2
- package/dist/components/index.css +149 -149
- package/dist/components/index.d.ts +5 -1
- package/dist/components/index.js +13 -36
- package/dist/components/navigation/index.css +659 -0
- package/dist/components/navigation/index.js +25 -3
- package/dist/features/auth/index.js +14 -37
- package/dist/features/clients/index.css +149 -149
- package/dist/features/clients/index.js +13 -36
- package/dist/features/crm/index.js +13 -36
- package/dist/features/dashboard/index.d.ts +5 -1
- package/dist/features/dashboard/index.js +13 -36
- package/dist/features/delivery/index.js +13 -36
- package/dist/features/knowledge/index.css +659 -0
- package/dist/features/knowledge/index.js +25 -247
- package/dist/features/lead-gen/index.d.ts +5 -1
- package/dist/features/lead-gen/index.js +13 -36
- package/dist/features/monitoring/index.js +13 -36
- package/dist/features/monitoring/requests/index.js +19 -149
- package/dist/features/operations/index.d.ts +5 -1
- package/dist/features/operations/index.js +13 -36
- package/dist/features/seo/index.js +1 -4
- package/dist/features/settings/index.js +13 -36
- package/dist/hooks/access/index.css +659 -0
- package/dist/hooks/access/index.js +19 -4
- package/dist/hooks/delivery/index.js +13 -36
- package/dist/hooks/index.d.ts +5 -1
- package/dist/hooks/index.js +13 -36
- package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +5 -1
- package/dist/hooks/published.d.ts +5 -1
- package/dist/hooks/published.js +13 -36
- package/dist/index.d.ts +5 -1
- package/dist/index.js +14 -37
- package/dist/initialization/index.js +1 -1
- package/dist/knowledge/index.css +659 -0
- package/dist/knowledge/index.d.ts +5 -1
- package/dist/knowledge/index.js +25 -15
- package/dist/layout/index.css +659 -0
- package/dist/layout/index.js +24 -9
- package/dist/organization/index.js +13 -36
- package/dist/provider/index.css +384 -0
- package/dist/provider/index.d.ts +5 -1
- package/dist/provider/index.js +18 -21
- package/dist/provider/published.css +533 -0
- package/dist/provider/published.d.ts +5 -1
- package/dist/provider/published.js +18 -16
- package/dist/test-utils/index.js +4 -6
- package/dist/theme/index.js +2 -5
- package/dist/theme/presets/index.js +1 -2
- package/dist/types/index.d.ts +5 -1
- package/dist/utils/index.d.ts +5 -1
- package/dist/utils/index.js +1 -3
- package/package.json +3 -3
- package/dist/chunk-3KMDHCAR.js +0 -52
- package/dist/chunk-4DRI3G36.js +0 -1016
- package/dist/chunk-56O7QQE7.js +0 -356
- package/dist/chunk-5EYJ2GIN.js +0 -122
- package/dist/chunk-66U7JOWV.js +0 -425
- package/dist/chunk-6D4LCJ52.js +0 -10
- package/dist/chunk-6ROXVZ3L.js +0 -9
- package/dist/chunk-A2XN6PR2.js +0 -111
- package/dist/chunk-B2DZLPDL.js +0 -39
- package/dist/chunk-CLDCYJQT.js +0 -1
- package/dist/chunk-CTJBPF3Z.js +0 -734
- package/dist/chunk-DT3QYZVU.js +0 -23
- package/dist/chunk-FIMGOWOT.js +0 -3644
- package/dist/chunk-IIMU5YAJ.js +0 -53
- package/dist/chunk-JHVEA5NE.js +0 -133
- package/dist/chunk-L7GXUSCV.js +0 -215
- package/dist/chunk-NYBEU5TE.js +0 -118
- package/dist/chunk-QVQMOQXB.js +0 -1240
- package/dist/chunk-RH5VWWSC.js +0 -624
- package/dist/chunk-RXH4D6TY.js +0 -801
- package/dist/chunk-S4R2ZQS7.js +0 -2131
- package/dist/chunk-TYRUKGGD.js +0 -46
- package/dist/chunk-VAAU2Z3S.js +0 -85
- package/dist/chunk-WLOQ4IBG.js +0 -654
- package/dist/chunk-X4WBGKJQ.js +0 -138
- package/dist/chunk-YPWN2WQ3.js +0 -340
package/dist/chunk-FIMGOWOT.js
DELETED
|
@@ -1,3644 +0,0 @@
|
|
|
1
|
-
import { OntologyScopeSchema, OntologyIdSchema, DEFAULT_ONTOLOGY_SCOPE, compileOrganizationOntology, listResolvedOntologyRecords, listAllSystems, defineDomainRecord, ontologyGraphNodeId, parseOntologyId, getAllProspectingStages, getAllPipelines, getAllProjectStatuses, getLeadGenStageCatalog, getAllBuildTemplates, devOnlyFor, requiresAdminFor, topLevel, parentOf, ancestorsOf, childrenOf, findById, findByPath, defaultPathFor } from './chunk-RH5VWWSC.js';
|
|
2
|
-
import { IconMail, IconSend, IconFileText, IconClock, IconArrowUp, IconMessageCircle, IconRocket, IconEye, IconEdit, IconAlertTriangle, IconRefresh, IconX, IconCheck, IconShieldLock, IconActivity, IconTopologyStar3, IconApps, IconBriefcase, IconBuilding, IconBolt, IconSearch, IconChartBar, IconUsers, IconInfoCircle, IconMessagePlus, IconDatabase, IconGitBranch, IconDashboard, IconBuildingStore, IconUser, IconPlug, IconBrain, IconTargetArrow, IconBook, IconLayoutGrid, IconArchive, IconSettings, IconTool, IconCalendar } from '@tabler/icons-react';
|
|
3
|
-
import { jsx } from 'react/jsx-runtime';
|
|
4
|
-
import { createContext, useContext, useMemo, useCallback } from 'react';
|
|
5
|
-
import { z } from 'zod';
|
|
6
|
-
|
|
7
|
-
var DEFAULT_SEMANTIC_ICON_REGISTRY = {
|
|
8
|
-
// Navigation / app areas
|
|
9
|
-
dashboard: IconDashboard,
|
|
10
|
-
calendar: IconCalendar,
|
|
11
|
-
sales: IconChartBar,
|
|
12
|
-
crm: IconBuildingStore,
|
|
13
|
-
"lead-gen": IconTargetArrow,
|
|
14
|
-
projects: IconBriefcase,
|
|
15
|
-
clients: IconUsers,
|
|
16
|
-
operations: IconTool,
|
|
17
|
-
monitoring: IconChartBar,
|
|
18
|
-
knowledge: IconBrain,
|
|
19
|
-
settings: IconSettings,
|
|
20
|
-
admin: IconShieldLock,
|
|
21
|
-
archive: IconArchive,
|
|
22
|
-
business: IconBriefcase,
|
|
23
|
-
finance: IconChartBar,
|
|
24
|
-
platform: IconLayoutGrid,
|
|
25
|
-
seo: IconSearch,
|
|
26
|
-
// Knowledge kinds
|
|
27
|
-
playbook: IconBook,
|
|
28
|
-
strategy: IconTargetArrow,
|
|
29
|
-
reference: IconFileText,
|
|
30
|
-
// Resource kinds
|
|
31
|
-
agent: IconBrain,
|
|
32
|
-
workflow: IconGitBranch,
|
|
33
|
-
integration: IconPlug,
|
|
34
|
-
database: IconDatabase,
|
|
35
|
-
user: IconUser,
|
|
36
|
-
team: IconUsers,
|
|
37
|
-
// Integration specifics
|
|
38
|
-
gmail: IconMail,
|
|
39
|
-
"google-sheets": IconDatabase,
|
|
40
|
-
attio: IconBuildingStore,
|
|
41
|
-
// Surface / UI views
|
|
42
|
-
overview: IconDashboard,
|
|
43
|
-
"command-view": IconTopologyStar3,
|
|
44
|
-
"command-queue": IconSend,
|
|
45
|
-
pipeline: IconGitBranch,
|
|
46
|
-
lists: IconFileText,
|
|
47
|
-
resources: IconDatabase,
|
|
48
|
-
// Topbar action tokens
|
|
49
|
-
"message-plus": IconMessagePlus,
|
|
50
|
-
// Actions
|
|
51
|
-
approve: IconCheck,
|
|
52
|
-
reject: IconX,
|
|
53
|
-
retry: IconRefresh,
|
|
54
|
-
edit: IconEdit,
|
|
55
|
-
view: IconEye,
|
|
56
|
-
launch: IconRocket,
|
|
57
|
-
message: IconMessageCircle,
|
|
58
|
-
escalate: IconAlertTriangle,
|
|
59
|
-
promote: IconArrowUp,
|
|
60
|
-
submit: IconSend,
|
|
61
|
-
email: IconMail,
|
|
62
|
-
// Status
|
|
63
|
-
success: IconCheck,
|
|
64
|
-
error: IconX,
|
|
65
|
-
warning: IconAlertTriangle,
|
|
66
|
-
info: IconInfoCircle,
|
|
67
|
-
pending: IconClock,
|
|
68
|
-
// OM / UI group icons
|
|
69
|
-
bolt: IconBolt,
|
|
70
|
-
building: IconBuilding,
|
|
71
|
-
briefcase: IconBriefcase,
|
|
72
|
-
apps: IconApps,
|
|
73
|
-
graph: IconTopologyStar3,
|
|
74
|
-
shield: IconShieldLock,
|
|
75
|
-
users: IconUsers,
|
|
76
|
-
"chart-bar": IconChartBar,
|
|
77
|
-
search: IconSearch,
|
|
78
|
-
// UI-only om.* group tokens (not in the core enum — kept for registry lookup
|
|
79
|
-
// by components that reference them directly via extendSemanticIconRegistry)
|
|
80
|
-
"om.quick-access": IconBolt,
|
|
81
|
-
"om.profile": IconBuilding,
|
|
82
|
-
"om.business-model": IconBriefcase,
|
|
83
|
-
"om.systems": IconApps,
|
|
84
|
-
"om.graph": IconTopologyStar3,
|
|
85
|
-
"om.governance-wiring": IconShieldLock,
|
|
86
|
-
// Graph node-kind fallback tokens (used internally by knowledge-tree helpers)
|
|
87
|
-
"entity.record": IconActivity,
|
|
88
|
-
"event.lifecycle": IconActivity,
|
|
89
|
-
"policy.governance": IconShieldLock,
|
|
90
|
-
// Compatibility aliases for existing command queue payloads.
|
|
91
|
-
IconCheck,
|
|
92
|
-
IconX,
|
|
93
|
-
IconRefresh,
|
|
94
|
-
IconAlertTriangle,
|
|
95
|
-
IconEdit,
|
|
96
|
-
IconEye,
|
|
97
|
-
IconRocket,
|
|
98
|
-
IconMessageCircle,
|
|
99
|
-
IconArrowUp,
|
|
100
|
-
IconClock,
|
|
101
|
-
IconFileText,
|
|
102
|
-
IconSend,
|
|
103
|
-
IconMail
|
|
104
|
-
};
|
|
105
|
-
var semanticIconRegistry = { ...DEFAULT_SEMANTIC_ICON_REGISTRY };
|
|
106
|
-
function extendSemanticIconRegistry(overrides) {
|
|
107
|
-
semanticIconRegistry = { ...semanticIconRegistry, ...overrides };
|
|
108
|
-
}
|
|
109
|
-
function getSemanticIconComponent(token, fallbackToken) {
|
|
110
|
-
const icon = resolveSemanticIconComponent(token);
|
|
111
|
-
if (icon) return icon;
|
|
112
|
-
if (fallbackToken && semanticIconRegistry[fallbackToken]) return semanticIconRegistry[fallbackToken];
|
|
113
|
-
return IconInfoCircle;
|
|
114
|
-
}
|
|
115
|
-
function resolveSemanticIconComponent(token) {
|
|
116
|
-
if (!token) return null;
|
|
117
|
-
return semanticIconRegistry[token] ?? null;
|
|
118
|
-
}
|
|
119
|
-
function SemanticIcon({
|
|
120
|
-
token,
|
|
121
|
-
fallbackToken,
|
|
122
|
-
size = 16,
|
|
123
|
-
stroke = 1.8,
|
|
124
|
-
className,
|
|
125
|
-
style,
|
|
126
|
-
"aria-hidden": ariaHidden = true
|
|
127
|
-
}) {
|
|
128
|
-
const Icon = getSemanticIconComponent(token, fallbackToken);
|
|
129
|
-
return /* @__PURE__ */ jsx(
|
|
130
|
-
"span",
|
|
131
|
-
{
|
|
132
|
-
className,
|
|
133
|
-
"aria-hidden": ariaHidden,
|
|
134
|
-
style: {
|
|
135
|
-
display: "inline-flex",
|
|
136
|
-
alignItems: "center",
|
|
137
|
-
justifyContent: "center",
|
|
138
|
-
width: size,
|
|
139
|
-
height: size,
|
|
140
|
-
minWidth: size,
|
|
141
|
-
color: "currentColor",
|
|
142
|
-
flexShrink: 0,
|
|
143
|
-
...style
|
|
144
|
-
},
|
|
145
|
-
children: /* @__PURE__ */ jsx(Icon, { size, stroke })
|
|
146
|
-
}
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// ../core/src/organization-model/cross-ref.ts
|
|
151
|
-
var ONTOLOGY_REFERENCE_KEY_KINDS = {
|
|
152
|
-
valueType: "value-type",
|
|
153
|
-
catalogType: "catalog",
|
|
154
|
-
objectType: "object",
|
|
155
|
-
eventType: "event",
|
|
156
|
-
actionType: "action",
|
|
157
|
-
linkType: "link",
|
|
158
|
-
interfaceType: "interface",
|
|
159
|
-
propertyType: "property",
|
|
160
|
-
groupType: "group",
|
|
161
|
-
surfaceType: "surface",
|
|
162
|
-
stepCatalog: "catalog"
|
|
163
|
-
};
|
|
164
|
-
function buildOmCrossRefIndex(model) {
|
|
165
|
-
const systemsById = /* @__PURE__ */ new Map();
|
|
166
|
-
for (const { path, system } of listAllSystems(model)) {
|
|
167
|
-
systemsById.set(path, system);
|
|
168
|
-
systemsById.set(system.id, system);
|
|
169
|
-
}
|
|
170
|
-
const resourceIds = new Set(Object.keys(model.resources ?? {}));
|
|
171
|
-
const knowledgeIds = new Set(Object.keys(model.knowledge ?? {}));
|
|
172
|
-
const roleIds = new Set(Object.keys(model.roles ?? {}));
|
|
173
|
-
const goalIds = new Set(Object.keys(model.goals ?? {}));
|
|
174
|
-
const actionIds = new Set(Object.keys(model.actions ?? {}));
|
|
175
|
-
const customerSegmentIds = new Set(Object.keys(model.customers ?? {}));
|
|
176
|
-
const offeringIds = new Set(Object.keys(model.offerings ?? {}));
|
|
177
|
-
const ontologyCompilation = compileOrganizationOntology(model);
|
|
178
|
-
const ontologyIndexByKind = {
|
|
179
|
-
object: ontologyCompilation.ontology.objectTypes,
|
|
180
|
-
link: ontologyCompilation.ontology.linkTypes,
|
|
181
|
-
action: ontologyCompilation.ontology.actionTypes,
|
|
182
|
-
catalog: ontologyCompilation.ontology.catalogTypes,
|
|
183
|
-
event: ontologyCompilation.ontology.eventTypes,
|
|
184
|
-
interface: ontologyCompilation.ontology.interfaceTypes,
|
|
185
|
-
"value-type": ontologyCompilation.ontology.valueTypes,
|
|
186
|
-
property: ontologyCompilation.ontology.sharedProperties,
|
|
187
|
-
group: ontologyCompilation.ontology.groups,
|
|
188
|
-
surface: ontologyCompilation.ontology.surfaces
|
|
189
|
-
};
|
|
190
|
-
const ontologyIds = new Set(Object.values(ontologyIndexByKind).flatMap((index) => Object.keys(index)));
|
|
191
|
-
const stageIds = /* @__PURE__ */ new Set();
|
|
192
|
-
for (const catalog of Object.values(ontologyCompilation.ontology.catalogTypes)) {
|
|
193
|
-
if (catalog.kind !== "stage") continue;
|
|
194
|
-
const entries = catalog.entries;
|
|
195
|
-
if (entries !== void 0) {
|
|
196
|
-
for (const stageId of Object.keys(entries)) {
|
|
197
|
-
stageIds.add(stageId);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
return {
|
|
202
|
-
systemsById,
|
|
203
|
-
resourceIds,
|
|
204
|
-
knowledgeIds,
|
|
205
|
-
roleIds,
|
|
206
|
-
goalIds,
|
|
207
|
-
actionIds,
|
|
208
|
-
customerSegmentIds,
|
|
209
|
-
offeringIds,
|
|
210
|
-
ontologyIds,
|
|
211
|
-
ontologyIndexByKind,
|
|
212
|
-
stageIds
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
function knowledgeTargetExists(index, kind, id) {
|
|
216
|
-
if (kind === "system") return index.systemsById.has(id);
|
|
217
|
-
if (kind === "resource") return index.resourceIds.has(id);
|
|
218
|
-
if (kind === "knowledge") return index.knowledgeIds.has(id);
|
|
219
|
-
if (kind === "stage") return index.stageIds.has(id);
|
|
220
|
-
if (kind === "action") return index.actionIds.has(id);
|
|
221
|
-
if (kind === "role") return index.roleIds.has(id);
|
|
222
|
-
if (kind === "goal") return index.goalIds.has(id);
|
|
223
|
-
if (kind === "customer-segment") return index.customerSegmentIds.has(id);
|
|
224
|
-
if (kind === "offering") return index.offeringIds.has(id);
|
|
225
|
-
if (kind === "ontology") return index.ontologyIds.has(id);
|
|
226
|
-
return false;
|
|
227
|
-
}
|
|
228
|
-
var ORGANIZATION_MODEL_ICON_TOKENS = [
|
|
229
|
-
// Navigation / app areas
|
|
230
|
-
"dashboard",
|
|
231
|
-
"calendar",
|
|
232
|
-
"sales",
|
|
233
|
-
"crm",
|
|
234
|
-
"lead-gen",
|
|
235
|
-
"projects",
|
|
236
|
-
"clients",
|
|
237
|
-
"operations",
|
|
238
|
-
"monitoring",
|
|
239
|
-
"knowledge",
|
|
240
|
-
"settings",
|
|
241
|
-
"admin",
|
|
242
|
-
"archive",
|
|
243
|
-
"business",
|
|
244
|
-
"finance",
|
|
245
|
-
"platform",
|
|
246
|
-
"seo",
|
|
247
|
-
// Knowledge kinds
|
|
248
|
-
"playbook",
|
|
249
|
-
"strategy",
|
|
250
|
-
"reference",
|
|
251
|
-
// Resource kinds
|
|
252
|
-
"agent",
|
|
253
|
-
"workflow",
|
|
254
|
-
"integration",
|
|
255
|
-
"database",
|
|
256
|
-
"user",
|
|
257
|
-
"team",
|
|
258
|
-
// Integration specifics
|
|
259
|
-
"gmail",
|
|
260
|
-
"google-sheets",
|
|
261
|
-
"attio",
|
|
262
|
-
// Surface / UI views
|
|
263
|
-
"overview",
|
|
264
|
-
"command-view",
|
|
265
|
-
"command-queue",
|
|
266
|
-
"pipeline",
|
|
267
|
-
"lists",
|
|
268
|
-
"resources",
|
|
269
|
-
// Actions
|
|
270
|
-
"approve",
|
|
271
|
-
"reject",
|
|
272
|
-
"retry",
|
|
273
|
-
"edit",
|
|
274
|
-
"view",
|
|
275
|
-
"launch",
|
|
276
|
-
"message",
|
|
277
|
-
"message-plus",
|
|
278
|
-
"escalate",
|
|
279
|
-
"promote",
|
|
280
|
-
"submit",
|
|
281
|
-
"email",
|
|
282
|
-
// Status
|
|
283
|
-
"success",
|
|
284
|
-
"error",
|
|
285
|
-
"warning",
|
|
286
|
-
"info",
|
|
287
|
-
"pending",
|
|
288
|
-
// OM / UI group icons
|
|
289
|
-
"bolt",
|
|
290
|
-
"building",
|
|
291
|
-
"briefcase",
|
|
292
|
-
"apps",
|
|
293
|
-
"graph",
|
|
294
|
-
"shield",
|
|
295
|
-
"users",
|
|
296
|
-
"chart-bar",
|
|
297
|
-
"search"
|
|
298
|
-
];
|
|
299
|
-
var CustomIconTokenSchema = z.string().trim().max(80).regex(
|
|
300
|
-
/^custom\.[a-z0-9]+(?:[-._][a-z0-9]+)*$/,
|
|
301
|
-
'Custom icon tokens must start with "custom." followed by lowercase alphanumeric segments'
|
|
302
|
-
);
|
|
303
|
-
var OrganizationModelBuiltinIconTokenSchema = z.enum(ORGANIZATION_MODEL_ICON_TOKENS);
|
|
304
|
-
var OrganizationModelIconTokenSchema = z.union([
|
|
305
|
-
OrganizationModelBuiltinIconTokenSchema,
|
|
306
|
-
CustomIconTokenSchema
|
|
307
|
-
]);
|
|
308
|
-
|
|
309
|
-
// ../core/src/organization-model/domains/shared.ts
|
|
310
|
-
var ModelIdSchema = z.string().trim().min(1).max(100).regex(/^[a-z0-9]+(?:[-._][a-z0-9]+)*$/, "IDs must be lowercase and use -, _, or . separators");
|
|
311
|
-
var LabelSchema = z.string().trim().min(1).max(120);
|
|
312
|
-
var DescriptionSchema = z.string().trim().min(1).max(2e3);
|
|
313
|
-
var ColorTokenSchema = z.string().trim().min(1).max(50);
|
|
314
|
-
var IconNameSchema = OrganizationModelIconTokenSchema;
|
|
315
|
-
var PathSchema = z.string().trim().startsWith("/").max(300);
|
|
316
|
-
var ReferenceIdsSchema = z.array(ModelIdSchema).default([]);
|
|
317
|
-
var DisplayMetadataSchema = z.object({
|
|
318
|
-
label: LabelSchema,
|
|
319
|
-
description: DescriptionSchema.optional(),
|
|
320
|
-
color: ColorTokenSchema.optional(),
|
|
321
|
-
icon: IconNameSchema.optional()
|
|
322
|
-
});
|
|
323
|
-
var TechStackEntrySchema = z.object({
|
|
324
|
-
/** Name of the external platform (e.g. "HubSpot", "Stripe", "Notion"). */
|
|
325
|
-
platform: z.string().trim().min(1).max(200),
|
|
326
|
-
/** Free-form description of what this integration is used for. */
|
|
327
|
-
purpose: z.string().trim().min(1).max(500),
|
|
328
|
-
/**
|
|
329
|
-
* Health of the credential backing this integration.
|
|
330
|
-
* - configured: credential present and valid
|
|
331
|
-
* - pending: not yet set up
|
|
332
|
-
* - expired: credential existed but has lapsed
|
|
333
|
-
* - missing: expected but not present
|
|
334
|
-
*/
|
|
335
|
-
credentialStatus: z.enum(["configured", "pending", "expired", "missing"]),
|
|
336
|
-
/**
|
|
337
|
-
* Whether this integration is the primary system of record for its domain
|
|
338
|
-
* (e.g. HubSpot is SoR for contacts). Defaults to false.
|
|
339
|
-
*/
|
|
340
|
-
isSystemOfRecord: z.boolean().default(false)
|
|
341
|
-
});
|
|
342
|
-
DisplayMetadataSchema.extend({
|
|
343
|
-
id: ModelIdSchema,
|
|
344
|
-
resourceId: z.string().trim().min(1).max(255),
|
|
345
|
-
resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint"]),
|
|
346
|
-
systemIds: ReferenceIdsSchema,
|
|
347
|
-
entityIds: ReferenceIdsSchema,
|
|
348
|
-
surfaceIds: ReferenceIdsSchema,
|
|
349
|
-
actionIds: ReferenceIdsSchema,
|
|
350
|
-
/** Optional tech-stack metadata for external-SaaS integrations. */
|
|
351
|
-
techStack: TechStackEntrySchema.optional()
|
|
352
|
-
});
|
|
353
|
-
|
|
354
|
-
// ../core/src/organization-model/domains/branding.ts
|
|
355
|
-
var OrganizationModelBrandingSchema = z.object({
|
|
356
|
-
/**
|
|
357
|
-
* @deprecated Prefer `identity.organizationName`; branding retains it for back-compat.
|
|
358
|
-
* Legacy tenants that have not set `identity.organizationName` fall back to this field.
|
|
359
|
-
*/
|
|
360
|
-
organizationName: LabelSchema,
|
|
361
|
-
/**
|
|
362
|
-
* @deprecated Prefer `identity.productName`; branding retains it for back-compat.
|
|
363
|
-
* Legacy tenants that have not set `identity.productName` fall back to this field.
|
|
364
|
-
*/
|
|
365
|
-
productName: LabelSchema,
|
|
366
|
-
/**
|
|
367
|
-
* @deprecated Prefer `identity.shortName`; branding retains it for back-compat.
|
|
368
|
-
* Legacy tenants that have not set `identity.shortName` fall back to this field.
|
|
369
|
-
*/
|
|
370
|
-
shortName: z.string().trim().min(1).max(40),
|
|
371
|
-
/**
|
|
372
|
-
* @deprecated Prefer `identity.description`; branding retains it for back-compat.
|
|
373
|
-
* Legacy tenants that have not set `identity.description` fall back to this field.
|
|
374
|
-
*/
|
|
375
|
-
description: DescriptionSchema.optional(),
|
|
376
|
-
logos: z.object({
|
|
377
|
-
light: z.string().trim().min(1).max(2048).optional(),
|
|
378
|
-
dark: z.string().trim().min(1).max(2048).optional()
|
|
379
|
-
}).default({}),
|
|
380
|
-
/**
|
|
381
|
-
* Brand voice — how the organization communicates. Plain-language description
|
|
382
|
-
* of tone, register, and personality (e.g. "Direct and human — no jargon").
|
|
383
|
-
* Max 280 characters.
|
|
384
|
-
*/
|
|
385
|
-
voice: z.string().trim().max(280).optional(),
|
|
386
|
-
/**
|
|
387
|
-
* Brand tagline or positioning statement — the memorable one-liner that
|
|
388
|
-
* captures the brand's promise or differentiator. Max 200 characters.
|
|
389
|
-
*/
|
|
390
|
-
tagline: z.string().trim().max(200).optional(),
|
|
391
|
-
/**
|
|
392
|
-
* Core brand values — an ordered list of principles the organization stands
|
|
393
|
-
* for (e.g. ["Transparency", "Craftsmanship", "Velocity"]). Each entry must
|
|
394
|
-
* be a non-empty trimmed string.
|
|
395
|
-
*/
|
|
396
|
-
values: z.array(z.string().trim().min(1)).optional(),
|
|
397
|
-
/**
|
|
398
|
-
* ID of the active UI theme preset from the UI theme-presets registry.
|
|
399
|
-
* The UI layer resolves this to colors and typography via `usePresetsContext()`.
|
|
400
|
-
* Free-form string — validation and fallback state are handled at the UI layer.
|
|
401
|
-
* Min 1, max 64 characters.
|
|
402
|
-
*/
|
|
403
|
-
themePresetId: z.string().trim().min(1).max(64).optional()
|
|
404
|
-
}).passthrough();
|
|
405
|
-
var DEFAULT_ORGANIZATION_MODEL_BRANDING = {
|
|
406
|
-
organizationName: "Default Organization",
|
|
407
|
-
productName: "Organization OS",
|
|
408
|
-
shortName: "Org OS",
|
|
409
|
-
logos: {}
|
|
410
|
-
};
|
|
411
|
-
var SurfaceTypeSchema = z.enum(["page", "dashboard", "graph", "detail", "list", "settings"]).meta({ label: "Surface type", color: "blue" });
|
|
412
|
-
var SurfaceDefinitionSchema = z.object({
|
|
413
|
-
id: ModelIdSchema,
|
|
414
|
-
label: LabelSchema,
|
|
415
|
-
path: PathSchema,
|
|
416
|
-
surfaceType: SurfaceTypeSchema,
|
|
417
|
-
description: DescriptionSchema.optional(),
|
|
418
|
-
enabled: z.boolean().default(true),
|
|
419
|
-
devOnly: z.boolean().optional(),
|
|
420
|
-
icon: IconNameSchema.optional(),
|
|
421
|
-
systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
|
|
422
|
-
entityIds: z.array(ModelIdSchema.meta({ ref: "entity" })).default([]),
|
|
423
|
-
resourceIds: z.array(ModelIdSchema.meta({ ref: "resource" })).default([]),
|
|
424
|
-
actionIds: z.array(ModelIdSchema.meta({ ref: "action" })).default([]),
|
|
425
|
-
parentId: ModelIdSchema.meta({ ref: "surface" }).optional()
|
|
426
|
-
});
|
|
427
|
-
var SidebarSurfaceTargetsSchema = z.object({
|
|
428
|
-
systems: z.array(ModelIdSchema.meta({ ref: "system" })).default([]).optional(),
|
|
429
|
-
entities: z.array(ModelIdSchema.meta({ ref: "entity" })).default([]).optional(),
|
|
430
|
-
resources: z.array(ModelIdSchema.meta({ ref: "resource" })).default([]).optional(),
|
|
431
|
-
actions: z.array(ModelIdSchema.meta({ ref: "action" })).default([]).optional()
|
|
432
|
-
}).default({});
|
|
433
|
-
var SidebarNodeSchema = z.lazy(
|
|
434
|
-
() => z.discriminatedUnion("type", [
|
|
435
|
-
z.object({
|
|
436
|
-
type: z.literal("group"),
|
|
437
|
-
label: LabelSchema,
|
|
438
|
-
description: DescriptionSchema.optional(),
|
|
439
|
-
icon: IconNameSchema.optional(),
|
|
440
|
-
order: z.number().int().optional(),
|
|
441
|
-
children: z.record(z.string(), SidebarNodeSchema).default({})
|
|
442
|
-
}),
|
|
443
|
-
z.object({
|
|
444
|
-
type: z.literal("surface"),
|
|
445
|
-
label: LabelSchema,
|
|
446
|
-
path: PathSchema,
|
|
447
|
-
surfaceType: SurfaceTypeSchema,
|
|
448
|
-
description: DescriptionSchema.optional(),
|
|
449
|
-
icon: IconNameSchema.optional(),
|
|
450
|
-
order: z.number().int().optional(),
|
|
451
|
-
targets: SidebarSurfaceTargetsSchema.optional(),
|
|
452
|
-
devOnly: z.boolean().optional(),
|
|
453
|
-
requiresAdmin: z.boolean().optional()
|
|
454
|
-
})
|
|
455
|
-
])
|
|
456
|
-
);
|
|
457
|
-
var SidebarSectionSchema = z.record(z.string(), SidebarNodeSchema).default({});
|
|
458
|
-
var SidebarNavigationSchema = z.object({
|
|
459
|
-
primary: SidebarSectionSchema,
|
|
460
|
-
bottom: SidebarSectionSchema
|
|
461
|
-
}).default({ primary: {}, bottom: {} });
|
|
462
|
-
var TopbarActionNodeSchema = z.object({
|
|
463
|
-
id: ModelIdSchema,
|
|
464
|
-
label: LabelSchema,
|
|
465
|
-
tooltip: DescriptionSchema.optional(),
|
|
466
|
-
icon: IconNameSchema.optional(),
|
|
467
|
-
order: z.number().int().optional(),
|
|
468
|
-
enabled: z.boolean().default(true),
|
|
469
|
-
devOnly: z.boolean().optional(),
|
|
470
|
-
requiresAdmin: z.boolean().optional(),
|
|
471
|
-
targets: SidebarSurfaceTargetsSchema.optional()
|
|
472
|
-
});
|
|
473
|
-
var TopbarSectionSchema = z.record(z.string(), TopbarActionNodeSchema).default({});
|
|
474
|
-
var OrganizationModelNavigationSchema = z.object({
|
|
475
|
-
sidebar: SidebarNavigationSchema,
|
|
476
|
-
topbar: TopbarSectionSchema
|
|
477
|
-
}).default({ sidebar: { primary: {}, bottom: {} }, topbar: {} });
|
|
478
|
-
function getSortedSidebarEntries(nodes) {
|
|
479
|
-
return Object.entries(nodes).sort(([leftId, left], [rightId, right]) => {
|
|
480
|
-
const orderDelta = (left.order ?? Number.MAX_SAFE_INTEGER) - (right.order ?? Number.MAX_SAFE_INTEGER);
|
|
481
|
-
return orderDelta === 0 ? leftId.localeCompare(rightId) : orderDelta;
|
|
482
|
-
});
|
|
483
|
-
}
|
|
484
|
-
z.object({
|
|
485
|
-
id: ModelIdSchema,
|
|
486
|
-
label: LabelSchema,
|
|
487
|
-
placement: z.string().trim().min(1).max(50),
|
|
488
|
-
surfaceIds: z.array(ModelIdSchema.meta({ ref: "surface" })).default([])
|
|
489
|
-
});
|
|
490
|
-
var BusinessHoursDaySchema = z.object({
|
|
491
|
-
open: z.string().trim().regex(/^\d{2}:\d{2}$/, "Expected HH:MM format"),
|
|
492
|
-
close: z.string().trim().regex(/^\d{2}:\d{2}$/, "Expected HH:MM format")
|
|
493
|
-
});
|
|
494
|
-
var BusinessHoursSchema = z.object({
|
|
495
|
-
monday: BusinessHoursDaySchema.optional(),
|
|
496
|
-
tuesday: BusinessHoursDaySchema.optional(),
|
|
497
|
-
wednesday: BusinessHoursDaySchema.optional(),
|
|
498
|
-
thursday: BusinessHoursDaySchema.optional(),
|
|
499
|
-
friday: BusinessHoursDaySchema.optional(),
|
|
500
|
-
saturday: BusinessHoursDaySchema.optional(),
|
|
501
|
-
sunday: BusinessHoursDaySchema.optional()
|
|
502
|
-
}).default({});
|
|
503
|
-
var IdentityDomainSchema = z.object({
|
|
504
|
-
/** Why the organization exists — one or two plain-language sentences. */
|
|
505
|
-
mission: z.string().trim().max(1e3).default(""),
|
|
506
|
-
/** Long-term direction the organization is moving toward. */
|
|
507
|
-
vision: z.string().trim().max(1e3).default(""),
|
|
508
|
-
/** Legal registered name of the entity. */
|
|
509
|
-
legalName: z.string().trim().max(200).default(""),
|
|
510
|
-
/**
|
|
511
|
-
* Type of legal entity (e.g. "LLC", "Corporation", "Sole Proprietor",
|
|
512
|
-
* "Non-profit"). Free-form string so it covers any jurisdiction.
|
|
513
|
-
*/
|
|
514
|
-
entityType: z.string().trim().max(100).default(""),
|
|
515
|
-
/**
|
|
516
|
-
* Primary jurisdiction of registration or operation
|
|
517
|
-
* (e.g. "United States – Delaware", "Canada – Ontario").
|
|
518
|
-
*/
|
|
519
|
-
jurisdiction: z.string().trim().max(200).default(""),
|
|
520
|
-
/**
|
|
521
|
-
* Industry category — broad classification (e.g. "Marketing Agency",
|
|
522
|
-
* "Software / SaaS", "Professional Services").
|
|
523
|
-
*/
|
|
524
|
-
industryCategory: z.string().trim().max(200).default(""),
|
|
525
|
-
/**
|
|
526
|
-
* Geographic focus — where the organization primarily operates or serves
|
|
527
|
-
* (e.g. "North America", "Global", "Southeast Asia").
|
|
528
|
-
*/
|
|
529
|
-
geographicFocus: z.string().trim().max(200).default(""),
|
|
530
|
-
/**
|
|
531
|
-
* IANA timezone identifier for the organization's primary operating timezone
|
|
532
|
-
* (e.g. "America/Los_Angeles", "Europe/London", "UTC").
|
|
533
|
-
*/
|
|
534
|
-
timeZone: z.string().trim().max(100).default("UTC"),
|
|
535
|
-
/** Typical operating hours per day of week. Empty object means not configured. */
|
|
536
|
-
businessHours: BusinessHoursSchema,
|
|
537
|
-
/**
|
|
538
|
-
* Long-form markdown capturing client context, problem narrative, and domain
|
|
539
|
-
* background. Populated by /setup; surfaced to agents as organizational context.
|
|
540
|
-
* Optional — many projects have no external client.
|
|
541
|
-
*/
|
|
542
|
-
clientBrief: z.string().trim().default(""),
|
|
543
|
-
/**
|
|
544
|
-
* Display name of the organization as shown to end users.
|
|
545
|
-
* Recommended placement for display naming — prefer this over the deprecated
|
|
546
|
-
* `branding.organizationName`. Falls back to `branding.organizationName` for
|
|
547
|
-
* legacy tenants that have not yet migrated.
|
|
548
|
-
*/
|
|
549
|
-
organizationName: LabelSchema.optional(),
|
|
550
|
-
/**
|
|
551
|
-
* Display name of the primary product or platform.
|
|
552
|
-
* Recommended placement for display naming — prefer this over the deprecated
|
|
553
|
-
* `branding.productName`. Falls back to `branding.productName` for legacy tenants.
|
|
554
|
-
*/
|
|
555
|
-
productName: LabelSchema.optional(),
|
|
556
|
-
/**
|
|
557
|
-
* Short abbreviated name used in space-constrained UI surfaces (max 40 chars).
|
|
558
|
-
* Recommended placement for display naming — prefer this over the deprecated
|
|
559
|
-
* `branding.shortName`. Falls back to `branding.shortName` for legacy tenants.
|
|
560
|
-
*/
|
|
561
|
-
shortName: z.string().trim().min(1).max(40).optional(),
|
|
562
|
-
/**
|
|
563
|
-
* Plain-language description of the organization for display and discovery.
|
|
564
|
-
* Recommended placement for display naming — prefer this over the deprecated
|
|
565
|
-
* `branding.description`. Falls back to `branding.description` for legacy tenants.
|
|
566
|
-
*/
|
|
567
|
-
description: DescriptionSchema.optional()
|
|
568
|
-
}).passthrough();
|
|
569
|
-
var DEFAULT_ORGANIZATION_MODEL_IDENTITY = {
|
|
570
|
-
mission: "",
|
|
571
|
-
vision: "",
|
|
572
|
-
legalName: "",
|
|
573
|
-
entityType: "",
|
|
574
|
-
jurisdiction: "",
|
|
575
|
-
industryCategory: "",
|
|
576
|
-
geographicFocus: "",
|
|
577
|
-
timeZone: "UTC",
|
|
578
|
-
businessHours: {},
|
|
579
|
-
clientBrief: ""
|
|
580
|
-
};
|
|
581
|
-
var FirmographicsSchema = z.object({
|
|
582
|
-
/** Industry vertical (e.g. "Marketing Agency", "Legal", "Real Estate"). */
|
|
583
|
-
industry: z.string().trim().max(200).optional(),
|
|
584
|
-
/**
|
|
585
|
-
* Company headcount band (e.g. "1–10", "11–50", "51–200", "200+").
|
|
586
|
-
* Free-form string to accommodate any band notation.
|
|
587
|
-
*/
|
|
588
|
-
companySize: z.string().trim().max(100).optional(),
|
|
589
|
-
/**
|
|
590
|
-
* Primary geographic region the segment operates in or is targeted from
|
|
591
|
-
* (e.g. "North America", "Europe", "Global").
|
|
592
|
-
*/
|
|
593
|
-
region: z.string().trim().max(200).optional()
|
|
594
|
-
});
|
|
595
|
-
var CustomerSegmentSchema = z.object({
|
|
596
|
-
/** Stable unique identifier for the segment (e.g. "segment-smb-agencies"). */
|
|
597
|
-
id: z.string().trim().min(1).max(100),
|
|
598
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
599
|
-
order: z.number(),
|
|
600
|
-
/** Human-readable name shown to agents and in UI (e.g. "SMB Marketing Agencies"). */
|
|
601
|
-
name: z.string().trim().max(200).default(""),
|
|
602
|
-
/** One or two sentences describing who this segment is. */
|
|
603
|
-
description: z.string().trim().max(2e3).default(""),
|
|
604
|
-
/**
|
|
605
|
-
* The primary job(s) this segment is trying to get done — the goal they hire
|
|
606
|
-
* a product/service to accomplish. Plain-language narrative or bullet list.
|
|
607
|
-
*/
|
|
608
|
-
jobsToBeDone: z.string().trim().max(2e3).default(""),
|
|
609
|
-
/**
|
|
610
|
-
* Pains — frustrations, obstacles, and risks the segment experiences
|
|
611
|
-
* when trying to accomplish their jobs-to-be-done.
|
|
612
|
-
*/
|
|
613
|
-
pains: z.array(z.string().trim().max(500)).default([]),
|
|
614
|
-
/**
|
|
615
|
-
* Gains — outcomes and benefits the segment desires; positive motivators
|
|
616
|
-
* beyond merely resolving pains.
|
|
617
|
-
*/
|
|
618
|
-
gains: z.array(z.string().trim().max(500)).default([]),
|
|
619
|
-
/** Firmographic profile for targeting and filtering. */
|
|
620
|
-
firmographics: FirmographicsSchema.default({}),
|
|
621
|
-
/**
|
|
622
|
-
* Value proposition — one or two sentences stating why this organization's
|
|
623
|
-
* offering is uniquely suited for this segment's needs.
|
|
624
|
-
*/
|
|
625
|
-
valueProp: z.string().trim().max(2e3).default("")
|
|
626
|
-
});
|
|
627
|
-
var CustomersDomainSchema = z.record(z.string(), CustomerSegmentSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
628
|
-
message: "Each segment entry id must match its map key"
|
|
629
|
-
}).default({});
|
|
630
|
-
var DEFAULT_ORGANIZATION_MODEL_CUSTOMERS = {};
|
|
631
|
-
var PricingModelSchema = z.enum(["one-time", "subscription", "usage-based", "custom"]).meta({ label: "Pricing model", color: "green" });
|
|
632
|
-
var ProductSchema = z.object({
|
|
633
|
-
/** Stable unique identifier for the product (e.g. "product-starter-plan"). */
|
|
634
|
-
id: z.string().trim().min(1).max(100),
|
|
635
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
636
|
-
order: z.number(),
|
|
637
|
-
/** Human-readable name shown to agents and in UI (e.g. "Starter Plan"). */
|
|
638
|
-
name: z.string().trim().max(200).default(""),
|
|
639
|
-
/** One or two sentences describing what this product/service delivers. */
|
|
640
|
-
description: z.string().trim().max(2e3).default(""),
|
|
641
|
-
/**
|
|
642
|
-
* How this product is priced:
|
|
643
|
-
* - "one-time" — single purchase (setup fee, project fee)
|
|
644
|
-
* - "subscription" — recurring (monthly/annual SaaS, retainer)
|
|
645
|
-
* - "usage-based" — metered by consumption (API calls, seats)
|
|
646
|
-
* - "custom" — negotiated or bespoke pricing
|
|
647
|
-
*/
|
|
648
|
-
pricingModel: PricingModelSchema.default("custom"),
|
|
649
|
-
/** Base price amount (≥ 0). Currency unit defined by `currency`. */
|
|
650
|
-
price: z.number().min(0).default(0),
|
|
651
|
-
/**
|
|
652
|
-
* ISO 4217 currency code (e.g. "USD", "EUR", "GBP").
|
|
653
|
-
* Free-form string to accommodate any currency; defaults to "USD".
|
|
654
|
-
*/
|
|
655
|
-
currency: z.string().trim().max(10).default("USD"),
|
|
656
|
-
/**
|
|
657
|
-
* IDs of customer segments this product targets.
|
|
658
|
-
* Each id must reference a declared `customers.segments[].id`.
|
|
659
|
-
* Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
|
|
660
|
-
*/
|
|
661
|
-
targetSegmentIds: z.array(z.string().trim().min(1)).default([]),
|
|
662
|
-
/**
|
|
663
|
-
* Optional: ID of the platform system responsible for delivering this product.
|
|
664
|
-
* When present, must reference a declared `systems.systems[].id`.
|
|
665
|
-
* Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
|
|
666
|
-
*/
|
|
667
|
-
deliveryFeatureId: z.string().trim().min(1).optional()
|
|
668
|
-
});
|
|
669
|
-
var OfferingsDomainSchema = z.record(z.string(), ProductSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
670
|
-
message: "Each product entry id must match its map key"
|
|
671
|
-
}).default({});
|
|
672
|
-
var DEFAULT_ORGANIZATION_MODEL_OFFERINGS = {};
|
|
673
|
-
var EntityIdSchema = ModelIdSchema;
|
|
674
|
-
var EntityLinkKindSchema = z.enum(["belongs-to", "has-many", "has-one", "many-to-many"]).meta({ label: "Link kind" });
|
|
675
|
-
var EntityLinkSchema = z.object({
|
|
676
|
-
toEntity: EntityIdSchema.meta({ ref: "entity" }),
|
|
677
|
-
kind: EntityLinkKindSchema,
|
|
678
|
-
via: z.string().trim().min(1).max(255).optional(),
|
|
679
|
-
label: LabelSchema.optional()
|
|
680
|
-
});
|
|
681
|
-
var EntitySchema = z.object({
|
|
682
|
-
id: EntityIdSchema,
|
|
683
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
684
|
-
order: z.number(),
|
|
685
|
-
label: LabelSchema,
|
|
686
|
-
description: DescriptionSchema.optional(),
|
|
687
|
-
ownedBySystemId: ModelIdSchema.meta({ ref: "system" }),
|
|
688
|
-
table: z.string().trim().min(1).max(255).optional(),
|
|
689
|
-
rowSchema: ModelIdSchema.optional(),
|
|
690
|
-
stateCatalogId: ModelIdSchema.optional(),
|
|
691
|
-
links: z.array(EntityLinkSchema).optional()
|
|
692
|
-
});
|
|
693
|
-
var EntitiesDomainSchema = z.record(z.string(), EntitySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
694
|
-
message: "Each entity entry id must match its map key"
|
|
695
|
-
}).default({});
|
|
696
|
-
function defineEntities(entries) {
|
|
697
|
-
return defineDomainRecord(EntitySchema, entries);
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
// ../core/src/organization-model/domains/actions.ts
|
|
701
|
-
var ActionResourceIdSchema = z.string().trim().min(1).max(255).regex(/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*$/, "Resource IDs must use letters, numbers, -, _, or . separators");
|
|
702
|
-
z.enum(["slash-command", "mcp-tool", "api-endpoint", "script-execution"]).meta({ label: "Invocation kind" });
|
|
703
|
-
var ActionIdSchema = ModelIdSchema;
|
|
704
|
-
var ActionScopeSchema = z.union([
|
|
705
|
-
z.literal("global"),
|
|
706
|
-
z.object({
|
|
707
|
-
domain: ModelIdSchema
|
|
708
|
-
})
|
|
709
|
-
]);
|
|
710
|
-
var ActionRefSchema = z.object({
|
|
711
|
-
actionId: ActionIdSchema.meta({ ref: "action" }),
|
|
712
|
-
intent: z.enum(["exposes", "consumes"]).meta({ label: "Intent" })
|
|
713
|
-
});
|
|
714
|
-
var SlashCommandInvocationSchema = z.object({
|
|
715
|
-
kind: z.literal("slash-command"),
|
|
716
|
-
command: z.string().trim().min(1).max(200).regex(/^\/[^\s].*$/, "Slash commands must start with /"),
|
|
717
|
-
toolFactory: ModelIdSchema.optional()
|
|
718
|
-
});
|
|
719
|
-
var McpToolInvocationSchema = z.object({
|
|
720
|
-
kind: z.literal("mcp-tool"),
|
|
721
|
-
server: ModelIdSchema,
|
|
722
|
-
name: ModelIdSchema
|
|
723
|
-
});
|
|
724
|
-
var ApiEndpointInvocationSchema = z.object({
|
|
725
|
-
kind: z.literal("api-endpoint"),
|
|
726
|
-
method: z.enum(["GET", "POST", "PATCH", "DELETE"]).meta({ label: "HTTP method" }),
|
|
727
|
-
path: z.string().trim().startsWith("/").max(500),
|
|
728
|
-
requestSchema: ModelIdSchema.optional(),
|
|
729
|
-
responseSchema: ModelIdSchema.optional()
|
|
730
|
-
});
|
|
731
|
-
var ScriptExecutionInvocationSchema = z.object({
|
|
732
|
-
kind: z.literal("script-execution"),
|
|
733
|
-
resourceId: ActionResourceIdSchema
|
|
734
|
-
});
|
|
735
|
-
var ActionInvocationSchema = z.discriminatedUnion("kind", [
|
|
736
|
-
SlashCommandInvocationSchema,
|
|
737
|
-
McpToolInvocationSchema,
|
|
738
|
-
ApiEndpointInvocationSchema,
|
|
739
|
-
ScriptExecutionInvocationSchema
|
|
740
|
-
]);
|
|
741
|
-
var ActionSchema = z.object({
|
|
742
|
-
id: ActionIdSchema,
|
|
743
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
744
|
-
order: z.number(),
|
|
745
|
-
label: LabelSchema,
|
|
746
|
-
description: DescriptionSchema.optional(),
|
|
747
|
-
scope: ActionScopeSchema.default("global"),
|
|
748
|
-
resourceId: ActionResourceIdSchema.optional(),
|
|
749
|
-
affects: z.array(EntityIdSchema.meta({ ref: "entity" })).optional(),
|
|
750
|
-
invocations: z.array(ActionInvocationSchema).default([]),
|
|
751
|
-
knowledge: z.array(ModelIdSchema.meta({ ref: "knowledge" })).default([]).optional(),
|
|
752
|
-
lifecycle: z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" }).default("active")
|
|
753
|
-
});
|
|
754
|
-
var ActionsDomainSchema = z.record(z.string(), ActionSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
755
|
-
message: "Each action entry id must match its map key"
|
|
756
|
-
}).default({});
|
|
757
|
-
var DEFAULT_ORGANIZATION_MODEL_ACTIONS = {};
|
|
758
|
-
function defineActions(entries) {
|
|
759
|
-
return defineDomainRecord(ActionSchema, entries);
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
// ../core/src/organization-model/domains/systems.ts
|
|
763
|
-
var SystemKindSchema = z.enum(["product", "operational", "platform", "diagnostic"]).meta({ label: "System kind", color: "blue" });
|
|
764
|
-
var SystemLifecycleSchema = z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" });
|
|
765
|
-
var SystemStatusSchema = z.enum(["active", "deprecated", "archived"]).meta({ label: "Status", color: "teal" });
|
|
766
|
-
var SystemIdSchema = ModelIdSchema;
|
|
767
|
-
var SystemPathSchema = z.string().trim().min(1).regex(
|
|
768
|
-
/^[a-z0-9][a-z0-9-]*(?:\.[a-z0-9][a-z0-9-]*)*$/,
|
|
769
|
-
'must be a dotted lowercase path (e.g. "sales.lead-gen" or "sales.crm")'
|
|
770
|
-
);
|
|
771
|
-
var UiPositionSchema = z.enum(["sidebar-primary", "sidebar-bottom"]).meta({ label: "UI position" });
|
|
772
|
-
var NodeIdStringSchema = z.string().trim().min(1).max(200).regex(
|
|
773
|
-
/^[a-z][a-z-]*:([a-z0-9-]+)(\.[a-z0-9-]+)*(:[a-z0-9.-]+)*$/,
|
|
774
|
-
"Node references must use kind:dotted-path (e.g. system:sales.crm or resource:lead-gen.company.qualify)"
|
|
775
|
-
);
|
|
776
|
-
var SystemUiSchema = z.object({
|
|
777
|
-
path: PathSchema,
|
|
778
|
-
surfaces: ReferenceIdsSchema,
|
|
779
|
-
icon: IconNameSchema.optional(),
|
|
780
|
-
order: z.number().int().optional()
|
|
781
|
-
});
|
|
782
|
-
var SystemInterfaceKeySchema = ModelIdSchema;
|
|
783
|
-
var SystemInterfaceLifecycleSchema = z.enum(["draft", "active", "disabled", "deprecated", "archived"]).meta({ label: "System interface lifecycle", color: "teal" });
|
|
784
|
-
var SystemInterfaceReadinessProfileSchema = z.string().trim().min(1).max(200).regex(
|
|
785
|
-
/^[a-z0-9][a-z0-9-]*(?:\.[a-z0-9][a-z0-9-]*)*(?:\.[a-z0-9][a-z0-9-]*)?$/,
|
|
786
|
-
'Readiness profiles must use dotted lowercase identifiers (e.g. "sales.lead-gen.api")'
|
|
787
|
-
);
|
|
788
|
-
var SystemInterfaceResourceScopeSchema = z.array(ModelIdSchema).default([]);
|
|
789
|
-
var SystemApiInterfaceSchema = z.object({
|
|
790
|
-
lifecycle: SystemInterfaceLifecycleSchema.default("active"),
|
|
791
|
-
readinessProfile: SystemInterfaceReadinessProfileSchema.optional(),
|
|
792
|
-
/**
|
|
793
|
-
* Resource ids that participate in this API interface. This scopes readiness
|
|
794
|
-
* derivation without duplicating authored required/provided contract refs.
|
|
795
|
-
*/
|
|
796
|
-
resourceIds: SystemInterfaceResourceScopeSchema.optional()
|
|
797
|
-
}).strict();
|
|
798
|
-
var SystemInterfaceRefSchema = z.object({
|
|
799
|
-
systemPath: SystemPathSchema,
|
|
800
|
-
interfaceKey: SystemInterfaceKeySchema
|
|
801
|
-
}).strict();
|
|
802
|
-
var JsonValueSchema = z.lazy(
|
|
803
|
-
() => z.union([
|
|
804
|
-
z.string(),
|
|
805
|
-
z.number(),
|
|
806
|
-
z.boolean(),
|
|
807
|
-
z.null(),
|
|
808
|
-
z.array(JsonValueSchema),
|
|
809
|
-
z.record(z.string(), JsonValueSchema)
|
|
810
|
-
])
|
|
811
|
-
);
|
|
812
|
-
var SystemConfigSchema = z.record(z.string().trim().min(1).max(200), JsonValueSchema).default({}).optional();
|
|
813
|
-
var SystemEntrySchema = z.object({
|
|
814
|
-
/** Stable tenant-defined system id (e.g. "sys.lead-gen" or "sales.crm"). */
|
|
815
|
-
id: SystemIdSchema,
|
|
816
|
-
/** Human-readable system label shown in UI, governance, and operations surfaces. */
|
|
817
|
-
label: LabelSchema.optional(),
|
|
818
|
-
/** @deprecated Use label. Accepted for pre-consolidation System declarations. */
|
|
819
|
-
title: LabelSchema.optional(),
|
|
820
|
-
/** One-paragraph purpose statement for the bounded context. */
|
|
821
|
-
description: DescriptionSchema.optional(),
|
|
822
|
-
/** Closed system shape enum; catalog values remain tenant-defined. */
|
|
823
|
-
kind: SystemKindSchema.optional(),
|
|
824
|
-
/** Optional self-reference for System hierarchy. */
|
|
825
|
-
parentSystemId: SystemIdSchema.optional(),
|
|
826
|
-
/** Optional UI presence. Systems without UI omit this. */
|
|
827
|
-
ui: SystemUiSchema.optional(),
|
|
828
|
-
/** Canonical lifecycle state. Replaces Feature.enabled/devOnly and System.status. */
|
|
829
|
-
lifecycle: SystemLifecycleSchema.optional(),
|
|
830
|
-
/** Optional role responsible for this system. */
|
|
831
|
-
responsibleRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
|
|
832
|
-
/** Optional knowledge nodes that govern this system. */
|
|
833
|
-
governedByKnowledge: z.array(ModelIdSchema.meta({ ref: "knowledge" })).default([]).optional(),
|
|
834
|
-
/** Optional actions this system exposes or consumes. */
|
|
835
|
-
actions: z.array(ActionRefSchema).optional(),
|
|
836
|
-
/** Optional operational policies that apply to this system. */
|
|
837
|
-
policies: z.array(ModelIdSchema.meta({ ref: "policy" })).default([]).optional(),
|
|
838
|
-
/** Optional goals this system contributes to. */
|
|
839
|
-
drivesGoals: z.array(ModelIdSchema.meta({ ref: "goal" })).default([]).optional(),
|
|
840
|
-
/** Thin API runtime-boundary marker. Readiness is derived from scoped resources and topology. */
|
|
841
|
-
apiInterface: SystemApiInterfaceSchema.optional(),
|
|
842
|
-
/** @deprecated Use lifecycle. Accepted for one publish cycle. */
|
|
843
|
-
status: SystemStatusSchema.optional(),
|
|
844
|
-
/** @deprecated Use ui.path. Kept for one-cycle Feature compatibility. */
|
|
845
|
-
path: PathSchema.optional(),
|
|
846
|
-
/** @deprecated Use ui.icon. Kept for one-cycle Feature compatibility. */
|
|
847
|
-
icon: IconNameSchema.optional(),
|
|
848
|
-
/** @deprecated Feature color token, retained for one-cycle compatibility. */
|
|
849
|
-
color: ColorTokenSchema.optional(),
|
|
850
|
-
/** @deprecated UI placement hint, retained for one-cycle compatibility. */
|
|
851
|
-
uiPosition: UiPositionSchema.optional(),
|
|
852
|
-
/** @deprecated Use lifecycle. */
|
|
853
|
-
enabled: z.boolean().optional(),
|
|
854
|
-
/** @deprecated Use lifecycle: "beta". */
|
|
855
|
-
devOnly: z.boolean().optional(),
|
|
856
|
-
requiresAdmin: z.boolean().optional(),
|
|
857
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
858
|
-
order: z.number(),
|
|
859
|
-
/**
|
|
860
|
-
* System-local JSON settings and defaults. Strongly typed OM fields,
|
|
861
|
-
* secrets, credentials, and runtime state stay outside this bucket.
|
|
862
|
-
*/
|
|
863
|
-
config: SystemConfigSchema,
|
|
864
|
-
/**
|
|
865
|
-
* System-owned ontology declarations. `systems` is now the canonical child
|
|
866
|
-
* key; this scope holds the object, action, catalog, link, event, and
|
|
867
|
-
* shared contract records owned by this system.
|
|
868
|
-
*/
|
|
869
|
-
ontology: OntologyScopeSchema.optional(),
|
|
870
|
-
/**
|
|
871
|
-
* Recursive child systems, authored via nesting (per L11).
|
|
872
|
-
* The key is the local system id; the full path is computed by joining
|
|
873
|
-
* ancestor keys with `.` (e.g. parent key `'sales'` + child key `'crm'` → `'sales.crm'`).
|
|
874
|
-
* Per Phase 4: `id` and `parentSystemId` fields will be removed in favour of
|
|
875
|
-
* position-derived paths. Both still exist on this schema for backward compat.
|
|
876
|
-
*/
|
|
877
|
-
systems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional(),
|
|
878
|
-
/** @deprecated Use systems. Accepted as a compatibility alias during the ontology bridge. */
|
|
879
|
-
subsystems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional()
|
|
880
|
-
}).strict().refine((system) => system.label !== void 0 || system.title !== void 0, {
|
|
881
|
-
path: ["label"],
|
|
882
|
-
message: "System must provide label or title"
|
|
883
|
-
}).transform((system) => {
|
|
884
|
-
const normalizedSystem = system.systems !== void 0 && system.subsystems === void 0 ? { ...system, subsystems: system.systems } : system;
|
|
885
|
-
if (normalizedSystem.status === void 0) return normalizedSystem;
|
|
886
|
-
console.warn("[organization-model] System.status is deprecated; use System.lifecycle instead.");
|
|
887
|
-
return normalizedSystem.lifecycle === void 0 ? { ...normalizedSystem, lifecycle: normalizedSystem.status } : normalizedSystem;
|
|
888
|
-
});
|
|
889
|
-
var SystemsDomainSchema = z.record(z.string(), SystemEntrySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
890
|
-
message: "Each system entry id must match its map key"
|
|
891
|
-
}).default({});
|
|
892
|
-
var DEFAULT_ORGANIZATION_MODEL_SYSTEMS = {};
|
|
893
|
-
|
|
894
|
-
// ../core/src/organization-model/domains/resources.ts
|
|
895
|
-
var ContractRefSchema = z.string().trim().min(1).max(500).regex(
|
|
896
|
-
/^[A-Za-z0-9@](?:[A-Za-z0-9_./@-]*[A-Za-z0-9_])?\/?[A-Za-z0-9_./@-]*#[A-Za-z_$][A-Za-z0-9_$]*$/,
|
|
897
|
-
"ContractRef must be in the format package/subpath#ExportName (e.g. @repo/elevasis-core/contracts/apollo-import#inputSchema)"
|
|
898
|
-
);
|
|
899
|
-
z.enum(["workflow", "agent", "integration", "script"]).meta({ label: "Resource kind", color: "orange" });
|
|
900
|
-
var ResourceGovernanceStatusSchema = z.enum(["active", "deprecated", "archived"]).meta({ label: "Governance status", color: "teal" });
|
|
901
|
-
var AgentKindSchema = z.enum(["orchestrator", "specialist", "utility", "platform"]).meta({ label: "Agent kind", color: "violet" });
|
|
902
|
-
var ScriptResourceLanguageSchema = z.enum(["shell", "sql", "typescript", "python"]).meta({ label: "Language" });
|
|
903
|
-
var CodeReferenceRoleSchema = z.enum(["entrypoint", "handler", "schema", "test", "docs", "config"]).meta({ label: "Code reference role", color: "blue" });
|
|
904
|
-
var ResourceIdSchema = z.string().trim().min(1).max(255).regex(/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*$/, "Resource IDs must use letters, numbers, -, _, or . separators");
|
|
905
|
-
var EventIdSchema = z.string().trim().min(1).max(300).regex(
|
|
906
|
-
/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*:[a-z0-9]+(?:[-._][a-z0-9]+)*$/,
|
|
907
|
-
"Event IDs must use <owner-id>:<event-key>"
|
|
908
|
-
);
|
|
909
|
-
var EventKeySchema = ModelIdSchema;
|
|
910
|
-
var EventEmissionDescriptorSchema = z.object({
|
|
911
|
-
eventKey: EventKeySchema,
|
|
912
|
-
label: z.string().trim().min(1).max(120),
|
|
913
|
-
payloadSchema: ModelIdSchema.optional(),
|
|
914
|
-
lifecycle: SystemLifecycleSchema.optional()
|
|
915
|
-
});
|
|
916
|
-
EventEmissionDescriptorSchema.extend({
|
|
917
|
-
id: EventIdSchema,
|
|
918
|
-
ownerId: z.union([ResourceIdSchema, ModelIdSchema]),
|
|
919
|
-
ownerKind: z.enum(["resource", "entity"]).meta({ label: "Owner kind" })
|
|
920
|
-
});
|
|
921
|
-
var ResourceOntologyBindingSchema = z.object({
|
|
922
|
-
actions: z.array(OntologyIdSchema).optional(),
|
|
923
|
-
primaryAction: OntologyIdSchema.optional(),
|
|
924
|
-
reads: z.array(OntologyIdSchema).optional(),
|
|
925
|
-
writes: z.array(OntologyIdSchema).optional(),
|
|
926
|
-
usesCatalogs: z.array(OntologyIdSchema).optional(),
|
|
927
|
-
emits: z.array(OntologyIdSchema).optional(),
|
|
928
|
-
/**
|
|
929
|
-
* Optional typed contract binding for this resource's workflow I/O.
|
|
930
|
-
* Each ref is a `package/subpath#ExportName` string that resolves to a
|
|
931
|
-
* Zod schema in `@repo/elevasis-core` (or the consumer's equivalent package).
|
|
932
|
-
*
|
|
933
|
-
* Absence of this field preserves all existing behavior — it is additive + optional.
|
|
934
|
-
* Tier-1 validation (schema.ts): ref-string shape only (browser-safe, no imports).
|
|
935
|
-
* Tier-2 validation (om:verify): intra-package typed-map resolution asserts ZodType.
|
|
936
|
-
*/
|
|
937
|
-
contract: z.object({
|
|
938
|
-
input: ContractRefSchema.optional(),
|
|
939
|
-
output: ContractRefSchema.optional()
|
|
940
|
-
}).optional()
|
|
941
|
-
}).superRefine((binding, ctx) => {
|
|
942
|
-
if (binding.primaryAction === void 0) return;
|
|
943
|
-
if (binding.actions?.includes(binding.primaryAction)) return;
|
|
944
|
-
ctx.addIssue({
|
|
945
|
-
code: z.ZodIssueCode.custom,
|
|
946
|
-
path: ["primaryAction"],
|
|
947
|
-
message: "Resource ontology primaryAction must be included in actions"
|
|
948
|
-
});
|
|
949
|
-
});
|
|
950
|
-
var CodeReferenceSchema = z.object({
|
|
951
|
-
path: z.string().trim().min(1).max(500).regex(/^[A-Za-z0-9_./$@()[\] -]+$/, "Code reference paths must be repo-relative paths"),
|
|
952
|
-
role: CodeReferenceRoleSchema,
|
|
953
|
-
symbol: z.string().trim().min(1).max(200).optional(),
|
|
954
|
-
description: z.string().trim().min(1).max(300).optional()
|
|
955
|
-
});
|
|
956
|
-
var ResourceEntryBaseSchema = z.object({
|
|
957
|
-
/** Canonical resource id; runtime resourceId derives from this value. */
|
|
958
|
-
id: ResourceIdSchema,
|
|
959
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
960
|
-
order: z.number().default(0),
|
|
961
|
-
/** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
|
|
962
|
-
systemPath: SystemPathSchema.meta({ ref: "system" }),
|
|
963
|
-
/** Executable display title owned by the OM Resource descriptor. */
|
|
964
|
-
title: LabelSchema.optional(),
|
|
965
|
-
/** Executable display description owned by the OM Resource descriptor. */
|
|
966
|
-
description: DescriptionSchema.optional(),
|
|
967
|
-
/** Optional role responsible for maintaining this resource. */
|
|
968
|
-
ownerRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
|
|
969
|
-
status: ResourceGovernanceStatusSchema,
|
|
970
|
-
/**
|
|
971
|
-
* Ontology contract bindings for the semantic work this resource performs.
|
|
972
|
-
* `emits` stays nested here so top-level resource emits descriptors remain
|
|
973
|
-
* compatible with graph event projection during the bridge.
|
|
974
|
-
*/
|
|
975
|
-
ontology: ResourceOntologyBindingSchema.optional(),
|
|
976
|
-
/** Repo-relative implementation breadcrumbs for agents and operators. */
|
|
977
|
-
codeRefs: z.array(CodeReferenceSchema).default([])
|
|
978
|
-
});
|
|
979
|
-
var WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
980
|
-
kind: z.literal("workflow"),
|
|
981
|
-
emits: z.array(EventEmissionDescriptorSchema).optional()
|
|
982
|
-
});
|
|
983
|
-
var AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
984
|
-
kind: z.literal("agent"),
|
|
985
|
-
/** Mirrors code-side AgentConfig.kind. */
|
|
986
|
-
agentKind: AgentKindSchema,
|
|
987
|
-
/** Role this agent embodies, if any. */
|
|
988
|
-
actsAsRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
|
|
989
|
-
/** Mirrors AgentConfig.sessionCapable. */
|
|
990
|
-
sessionCapable: z.boolean(),
|
|
991
|
-
/** Broad/composite callable entry points orchestrated by this agent. */
|
|
992
|
-
invocations: z.array(ActionInvocationSchema).default([]),
|
|
993
|
-
emits: z.array(EventEmissionDescriptorSchema).optional()
|
|
994
|
-
});
|
|
995
|
-
var IntegrationResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
996
|
-
kind: z.literal("integration"),
|
|
997
|
-
provider: z.string().trim().min(1).max(100)
|
|
998
|
-
});
|
|
999
|
-
var ScriptResourceSourceSchema = z.union([
|
|
1000
|
-
z.string().trim().min(1).max(5e4),
|
|
1001
|
-
z.object({
|
|
1002
|
-
file: z.string().trim().min(1).max(500)
|
|
1003
|
-
})
|
|
1004
|
-
]);
|
|
1005
|
-
var ScriptResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
1006
|
-
kind: z.literal("script"),
|
|
1007
|
-
language: ScriptResourceLanguageSchema,
|
|
1008
|
-
source: ScriptResourceSourceSchema
|
|
1009
|
-
});
|
|
1010
|
-
var ResourceEntrySchema = z.discriminatedUnion("kind", [
|
|
1011
|
-
WorkflowResourceEntrySchema,
|
|
1012
|
-
AgentResourceEntrySchema,
|
|
1013
|
-
IntegrationResourceEntrySchema,
|
|
1014
|
-
ScriptResourceEntrySchema
|
|
1015
|
-
]);
|
|
1016
|
-
var ResourcesDomainSchema = z.record(z.string(), ResourceEntrySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
1017
|
-
message: "Each resource entry id must match its map key"
|
|
1018
|
-
}).default({});
|
|
1019
|
-
var DEFAULT_ORGANIZATION_MODEL_RESOURCES = {};
|
|
1020
|
-
function defineResources(resources) {
|
|
1021
|
-
return Object.fromEntries(
|
|
1022
|
-
Object.entries(resources).map(([key, resource]) => [key, ResourceEntrySchema.parse(resource)])
|
|
1023
|
-
);
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
// ../core/src/organization-model/domains/roles.ts
|
|
1027
|
-
var RoleIdSchema = ModelIdSchema;
|
|
1028
|
-
var HumanRoleHolderSchema = z.object({
|
|
1029
|
-
kind: z.literal("human"),
|
|
1030
|
-
userId: z.string().trim().min(1).max(200)
|
|
1031
|
-
});
|
|
1032
|
-
var AgentRoleHolderSchema = z.object({
|
|
1033
|
-
kind: z.literal("agent"),
|
|
1034
|
-
agentId: ResourceIdSchema.meta({ ref: "resource" })
|
|
1035
|
-
});
|
|
1036
|
-
var TeamRoleHolderSchema = z.object({
|
|
1037
|
-
kind: z.literal("team"),
|
|
1038
|
-
memberIds: z.array(z.string().trim().min(1).max(200)).min(1)
|
|
1039
|
-
});
|
|
1040
|
-
var RoleHolderSchema = z.discriminatedUnion("kind", [
|
|
1041
|
-
HumanRoleHolderSchema,
|
|
1042
|
-
AgentRoleHolderSchema,
|
|
1043
|
-
TeamRoleHolderSchema
|
|
1044
|
-
]);
|
|
1045
|
-
var RoleHoldersSchema = z.union([RoleHolderSchema, z.array(RoleHolderSchema).min(1)]);
|
|
1046
|
-
var RoleSchema = z.object({
|
|
1047
|
-
/** Stable unique identifier for the role (e.g. "role-ceo", "role-head-of-sales"). */
|
|
1048
|
-
id: RoleIdSchema,
|
|
1049
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
1050
|
-
order: z.number(),
|
|
1051
|
-
/** Human-readable title shown to agents and in UI (e.g. "CEO", "Head of Sales"). */
|
|
1052
|
-
title: z.string().trim().min(1).max(200),
|
|
1053
|
-
/**
|
|
1054
|
-
* List of responsibilities this role owns - plain-language descriptions of
|
|
1055
|
-
* what the person in this role is accountable for delivering.
|
|
1056
|
-
* Defaults to empty array so minimal role definitions stay concise.
|
|
1057
|
-
*/
|
|
1058
|
-
responsibilities: z.array(z.string().trim().max(500)).default([]),
|
|
1059
|
-
/**
|
|
1060
|
-
* Optional: ID of another role this role reports to.
|
|
1061
|
-
* When present, must reference another `roles[].id` in the same organization.
|
|
1062
|
-
*/
|
|
1063
|
-
reportsToId: RoleIdSchema.meta({ ref: "role" }).optional(),
|
|
1064
|
-
/**
|
|
1065
|
-
* Optional: human, agent, or team holder currently filling this role.
|
|
1066
|
-
* Agent holders reference OM Resource IDs and are validated at the model level.
|
|
1067
|
-
*/
|
|
1068
|
-
heldBy: RoleHoldersSchema.optional(),
|
|
1069
|
-
/**
|
|
1070
|
-
* Optional Systems this role is accountable for.
|
|
1071
|
-
* Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
|
|
1072
|
-
*/
|
|
1073
|
-
responsibleFor: z.array(SystemIdSchema.meta({ ref: "system" })).optional()
|
|
1074
|
-
});
|
|
1075
|
-
var RolesDomainSchema = z.record(z.string(), RoleSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
1076
|
-
message: "Each role entry id must match its map key"
|
|
1077
|
-
}).default({});
|
|
1078
|
-
var DEFAULT_ORGANIZATION_MODEL_ROLES = {};
|
|
1079
|
-
var KeyResultSchema = z.object({
|
|
1080
|
-
/** Stable unique identifier for the measurable outcome (e.g. "kr-revenue-q1"). */
|
|
1081
|
-
id: z.string().trim().min(1).max(100),
|
|
1082
|
-
/** Plain-language description of this measurable outcome (e.g. "Increase trial-to-paid conversion"). */
|
|
1083
|
-
description: z.string().trim().min(1).max(500),
|
|
1084
|
-
/**
|
|
1085
|
-
* What is being measured — the metric name (e.g. "monthly revenue", "NPS score",
|
|
1086
|
-
* "trial-to-paid conversion rate"). Free-form string.
|
|
1087
|
-
*/
|
|
1088
|
-
targetMetric: z.string().trim().min(1).max(200),
|
|
1089
|
-
/** Current measured value. Defaults to 0 when not yet tracked. */
|
|
1090
|
-
currentValue: z.number().default(0),
|
|
1091
|
-
/**
|
|
1092
|
-
* Target value to reach for this measurable outcome to be considered achieved.
|
|
1093
|
-
* Optional — omit if the outcome is directional (e.g. "reduce churn") without
|
|
1094
|
-
* a hard numeric target.
|
|
1095
|
-
*/
|
|
1096
|
-
targetValue: z.number().optional()
|
|
1097
|
-
});
|
|
1098
|
-
var ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
1099
|
-
var ObjectiveSchema = z.object({
|
|
1100
|
-
/** Stable unique identifier for the goal (e.g. "goal-grow-arr-q1-2026"). */
|
|
1101
|
-
id: z.string().trim().min(1).max(100),
|
|
1102
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
1103
|
-
order: z.number(),
|
|
1104
|
-
/** Plain-language description of what the organization wants to achieve. */
|
|
1105
|
-
description: z.string().trim().min(1).max(1e3),
|
|
1106
|
-
/**
|
|
1107
|
-
* Start of the period this goal is active for — ISO 8601 date string (YYYY-MM-DD).
|
|
1108
|
-
* Must be strictly before `periodEnd`.
|
|
1109
|
-
*/
|
|
1110
|
-
periodStart: z.string().regex(ISO_DATE_REGEX, "periodStart must be an ISO date string (YYYY-MM-DD)"),
|
|
1111
|
-
/**
|
|
1112
|
-
* End of the period this goal is active for — ISO 8601 date string (YYYY-MM-DD).
|
|
1113
|
-
* Must be strictly after `periodStart`.
|
|
1114
|
-
* Enforced via `OrganizationModelSchema.superRefine()`.
|
|
1115
|
-
*/
|
|
1116
|
-
periodEnd: z.string().regex(ISO_DATE_REGEX, "periodEnd must be an ISO date string (YYYY-MM-DD)"),
|
|
1117
|
-
/**
|
|
1118
|
-
* List of measurable outcomes that define success for this goal.
|
|
1119
|
-
* Defaults to empty array so goals can be declared before outcomes are defined.
|
|
1120
|
-
*/
|
|
1121
|
-
keyResults: z.array(KeyResultSchema).default([])
|
|
1122
|
-
});
|
|
1123
|
-
var GoalsDomainSchema = z.record(z.string(), ObjectiveSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
1124
|
-
message: "Each objective entry id must match its map key"
|
|
1125
|
-
}).default({});
|
|
1126
|
-
var DEFAULT_ORGANIZATION_MODEL_GOALS = {};
|
|
1127
|
-
var KnowledgeTargetKindSchema = z.enum([
|
|
1128
|
-
"system",
|
|
1129
|
-
"resource",
|
|
1130
|
-
"knowledge",
|
|
1131
|
-
"stage",
|
|
1132
|
-
"action",
|
|
1133
|
-
"role",
|
|
1134
|
-
"goal",
|
|
1135
|
-
"customer-segment",
|
|
1136
|
-
"offering",
|
|
1137
|
-
"ontology"
|
|
1138
|
-
]).meta({ label: "Target kind" });
|
|
1139
|
-
var KnowledgeTargetRefSchema = z.object({
|
|
1140
|
-
kind: KnowledgeTargetKindSchema,
|
|
1141
|
-
// Ontology targets use the canonical '<scope>:<kind>/<local-id>' ontology id format.
|
|
1142
|
-
// Business-logic validation of target existence is done in OrganizationModelSchema.superRefine.
|
|
1143
|
-
id: z.string().trim().min(1).max(300)
|
|
1144
|
-
}).superRefine((target, ctx) => {
|
|
1145
|
-
if (target.kind !== "ontology") return;
|
|
1146
|
-
const result = OntologyIdSchema.safeParse(target.id);
|
|
1147
|
-
if (!result.success) {
|
|
1148
|
-
ctx.addIssue({
|
|
1149
|
-
code: z.ZodIssueCode.custom,
|
|
1150
|
-
path: ["id"],
|
|
1151
|
-
message: "Ontology knowledge targets must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
|
|
1152
|
-
});
|
|
1153
|
-
}
|
|
1154
|
-
});
|
|
1155
|
-
var LegacyKnowledgeLinkSchema = z.object({
|
|
1156
|
-
nodeId: z.union([NodeIdStringSchema, z.templateLiteral(["ontology:", OntologyIdSchema])])
|
|
1157
|
-
}).superRefine((link, ctx) => {
|
|
1158
|
-
const [kind] = link.nodeId.split(":");
|
|
1159
|
-
if (!KnowledgeTargetKindSchema.safeParse(kind).success) {
|
|
1160
|
-
ctx.addIssue({
|
|
1161
|
-
code: z.ZodIssueCode.custom,
|
|
1162
|
-
path: ["nodeId"],
|
|
1163
|
-
message: `Unknown knowledge target kind "${kind}"`
|
|
1164
|
-
});
|
|
1165
|
-
}
|
|
1166
|
-
});
|
|
1167
|
-
var CanonicalKnowledgeLinkSchema = z.object({
|
|
1168
|
-
target: KnowledgeTargetRefSchema
|
|
1169
|
-
});
|
|
1170
|
-
function nodeIdFromTarget(target) {
|
|
1171
|
-
return `${target.kind}:${target.id}`;
|
|
1172
|
-
}
|
|
1173
|
-
function targetFromNodeId(nodeId2) {
|
|
1174
|
-
const [kind, ...idParts] = nodeId2.split(":");
|
|
1175
|
-
return {
|
|
1176
|
-
kind: KnowledgeTargetKindSchema.parse(kind),
|
|
1177
|
-
id: idParts.join(":")
|
|
1178
|
-
};
|
|
1179
|
-
}
|
|
1180
|
-
var KnowledgeLinkSchema = z.union([CanonicalKnowledgeLinkSchema, LegacyKnowledgeLinkSchema]).transform((link) => {
|
|
1181
|
-
const target = "target" in link ? link.target : targetFromNodeId(link.nodeId);
|
|
1182
|
-
return {
|
|
1183
|
-
target,
|
|
1184
|
-
nodeId: nodeIdFromTarget(target)
|
|
1185
|
-
};
|
|
1186
|
-
});
|
|
1187
|
-
var OrgKnowledgeKindSchema = z.enum(["playbook", "strategy", "reference"]).meta({ label: "Knowledge kind", color: "grape" });
|
|
1188
|
-
var OrgKnowledgeNodeSchema = z.object({
|
|
1189
|
-
id: ModelIdSchema,
|
|
1190
|
-
kind: OrgKnowledgeKindSchema,
|
|
1191
|
-
title: z.string().trim().min(1).max(200),
|
|
1192
|
-
summary: z.string().trim().min(1).max(1e3),
|
|
1193
|
-
icon: IconNameSchema.optional(),
|
|
1194
|
-
/** Canonical documentation URL when body content is a local summary. */
|
|
1195
|
-
externalUrl: z.string().trim().url().max(500).optional(),
|
|
1196
|
-
/** Optional generated source file path for local MDX-backed knowledge nodes. */
|
|
1197
|
-
sourceFilePath: z.string().trim().min(1).max(500).optional(),
|
|
1198
|
-
/** Raw MDX string. Phase 2 will introduce a structured block format. */
|
|
1199
|
-
body: z.string().trim().min(1),
|
|
1200
|
-
/**
|
|
1201
|
-
* Graph links to other OM nodes this knowledge node governs.
|
|
1202
|
-
* Each link emits a `governs` edge: knowledge-node -> target node.
|
|
1203
|
-
*/
|
|
1204
|
-
links: z.array(KnowledgeLinkSchema).default([]),
|
|
1205
|
-
/** Role identifiers that own this knowledge node. */
|
|
1206
|
-
ownerIds: z.array(RoleIdSchema.meta({ ref: "role" })).default([]),
|
|
1207
|
-
/** ISO date string (YYYY-MM-DD or full ISO 8601) of last meaningful update. */
|
|
1208
|
-
updatedAt: z.string().trim().min(1).max(50)
|
|
1209
|
-
});
|
|
1210
|
-
var KnowledgeDomainSchema = z.record(ModelIdSchema, OrgKnowledgeNodeSchema).default({});
|
|
1211
|
-
var SecretLikeMetadataKeySchema = /(?:secret|password|passwd|token|api[-_]?key|credential|private[-_]?key)/i;
|
|
1212
|
-
var SecretLikeMetadataValueSchema = /(?:sk-[A-Za-z0-9_-]{12,}|pk_live_[A-Za-z0-9_-]{12,}|eyJ[A-Za-z0-9_-]{20,}|-----BEGIN (?:RSA |OPENSSH |EC )?PRIVATE KEY-----)/;
|
|
1213
|
-
z.enum([
|
|
1214
|
-
"system",
|
|
1215
|
-
"resource",
|
|
1216
|
-
"ontology",
|
|
1217
|
-
"policy",
|
|
1218
|
-
"role",
|
|
1219
|
-
"trigger",
|
|
1220
|
-
"humanCheckpoint",
|
|
1221
|
-
"externalResource"
|
|
1222
|
-
]);
|
|
1223
|
-
var OmTopologyRelationshipKindSchema = z.enum(["triggers", "uses", "approval"]);
|
|
1224
|
-
var OmTopologyNodeRefSchema = z.discriminatedUnion("kind", [
|
|
1225
|
-
z.object({ kind: z.literal("system"), id: ModelIdSchema }),
|
|
1226
|
-
z.object({ kind: z.literal("resource"), id: ResourceIdSchema }),
|
|
1227
|
-
z.object({ kind: z.literal("ontology"), id: OntologyIdSchema }),
|
|
1228
|
-
z.object({ kind: z.literal("policy"), id: ModelIdSchema }),
|
|
1229
|
-
z.object({ kind: z.literal("role"), id: ModelIdSchema }),
|
|
1230
|
-
z.object({ kind: z.literal("trigger"), id: ResourceIdSchema }),
|
|
1231
|
-
z.object({ kind: z.literal("humanCheckpoint"), id: ResourceIdSchema }),
|
|
1232
|
-
z.object({ kind: z.literal("externalResource"), id: ResourceIdSchema })
|
|
1233
|
-
]);
|
|
1234
|
-
var OmTopologyMetadataSchema = z.record(z.string().trim().min(1).max(120), JsonValueSchema).superRefine((metadata, ctx) => {
|
|
1235
|
-
function visit(value, path) {
|
|
1236
|
-
if (typeof value === "string" && SecretLikeMetadataValueSchema.test(value)) {
|
|
1237
|
-
ctx.addIssue({
|
|
1238
|
-
code: z.ZodIssueCode.custom,
|
|
1239
|
-
path,
|
|
1240
|
-
message: "Topology metadata must not contain secret-like values"
|
|
1241
|
-
});
|
|
1242
|
-
return;
|
|
1243
|
-
}
|
|
1244
|
-
if (Array.isArray(value)) {
|
|
1245
|
-
value.forEach((entry, index) => visit(entry, [...path, index]));
|
|
1246
|
-
return;
|
|
1247
|
-
}
|
|
1248
|
-
if (typeof value !== "object" || value === null) return;
|
|
1249
|
-
Object.entries(value).forEach(([key, entry]) => {
|
|
1250
|
-
if (SecretLikeMetadataKeySchema.test(key)) {
|
|
1251
|
-
ctx.addIssue({
|
|
1252
|
-
code: z.ZodIssueCode.custom,
|
|
1253
|
-
path: [...path, key],
|
|
1254
|
-
message: `Topology metadata key "${key}" looks secret-like`
|
|
1255
|
-
});
|
|
1256
|
-
}
|
|
1257
|
-
visit(entry, [...path, key]);
|
|
1258
|
-
});
|
|
1259
|
-
}
|
|
1260
|
-
visit(metadata, []);
|
|
1261
|
-
});
|
|
1262
|
-
var OmTopologySystemInterfaceGrantSchema = z.object({
|
|
1263
|
-
consumer: SystemInterfaceRefSchema,
|
|
1264
|
-
provider: SystemInterfaceRefSchema,
|
|
1265
|
-
resourceIds: z.array(ResourceIdSchema).default([]),
|
|
1266
|
-
ontologyIds: z.array(OntologyIdSchema).default([])
|
|
1267
|
-
}).strict();
|
|
1268
|
-
z.object({
|
|
1269
|
-
systemInterfaceGrant: OmTopologySystemInterfaceGrantSchema
|
|
1270
|
-
}).strict();
|
|
1271
|
-
var OmTopologyRelationshipSchema = z.object({
|
|
1272
|
-
from: OmTopologyNodeRefSchema,
|
|
1273
|
-
kind: OmTopologyRelationshipKindSchema,
|
|
1274
|
-
to: OmTopologyNodeRefSchema,
|
|
1275
|
-
systemPath: SystemPathSchema.optional(),
|
|
1276
|
-
required: z.boolean().optional(),
|
|
1277
|
-
metadata: OmTopologyMetadataSchema.optional()
|
|
1278
|
-
});
|
|
1279
|
-
var OmTopologyDomainSchema = z.object({
|
|
1280
|
-
version: z.literal(1).default(1),
|
|
1281
|
-
relationships: z.record(z.string().trim().min(1).max(255), OmTopologyRelationshipSchema).default({})
|
|
1282
|
-
}).default({ version: 1, relationships: {} });
|
|
1283
|
-
var DEFAULT_ORGANIZATION_MODEL_TOPOLOGY = {
|
|
1284
|
-
version: 1,
|
|
1285
|
-
relationships: {}
|
|
1286
|
-
};
|
|
1287
|
-
function idFrom(input) {
|
|
1288
|
-
return typeof input === "string" ? input : input.id;
|
|
1289
|
-
}
|
|
1290
|
-
function parseRef(kind, id) {
|
|
1291
|
-
return OmTopologyNodeRefSchema.parse({ kind, id });
|
|
1292
|
-
}
|
|
1293
|
-
function isNodeRef(input) {
|
|
1294
|
-
return OmTopologyNodeRefSchema.safeParse(input).success;
|
|
1295
|
-
}
|
|
1296
|
-
function isResourceEntry(input) {
|
|
1297
|
-
if (typeof input !== "object" || input === null) return false;
|
|
1298
|
-
const candidate = input;
|
|
1299
|
-
return typeof candidate.id === "string" && typeof candidate.systemPath === "string" && typeof candidate.status === "string" && ["workflow", "agent", "integration", "script"].includes(String(candidate.kind));
|
|
1300
|
-
}
|
|
1301
|
-
var topologyRef = {
|
|
1302
|
-
system: (system) => parseRef("system", idFrom(system)),
|
|
1303
|
-
resource: (resource) => parseRef("resource", idFrom(resource)),
|
|
1304
|
-
ontology: (record) => parseRef("ontology", idFrom(record)),
|
|
1305
|
-
policy: (policy) => parseRef("policy", idFrom(policy)),
|
|
1306
|
-
role: (role) => parseRef("role", idFrom(role)),
|
|
1307
|
-
trigger: (trigger) => parseRef("trigger", idFrom(trigger)),
|
|
1308
|
-
humanCheckpoint: (checkpoint) => parseRef("humanCheckpoint", idFrom(checkpoint)),
|
|
1309
|
-
externalResource: (externalResource) => parseRef("externalResource", idFrom(externalResource))
|
|
1310
|
-
};
|
|
1311
|
-
var topologyRelationship = {
|
|
1312
|
-
triggers: (from, to, options = {}) => defineTopologyRelationship({
|
|
1313
|
-
...options,
|
|
1314
|
-
from,
|
|
1315
|
-
kind: "triggers",
|
|
1316
|
-
to
|
|
1317
|
-
}),
|
|
1318
|
-
uses: (from, to, options = {}) => defineTopologyRelationship({
|
|
1319
|
-
...options,
|
|
1320
|
-
from,
|
|
1321
|
-
kind: "uses",
|
|
1322
|
-
to
|
|
1323
|
-
}),
|
|
1324
|
-
approval: (from, to, options = {}) => defineTopologyRelationship({
|
|
1325
|
-
...options,
|
|
1326
|
-
from,
|
|
1327
|
-
kind: "approval",
|
|
1328
|
-
to
|
|
1329
|
-
}),
|
|
1330
|
-
usesIntegration: (from, integration, options = {}) => defineTopologyRelationship({
|
|
1331
|
-
required: true,
|
|
1332
|
-
...options,
|
|
1333
|
-
from,
|
|
1334
|
-
kind: "uses",
|
|
1335
|
-
to: integration
|
|
1336
|
-
}),
|
|
1337
|
-
requestsApproval: (from, checkpoint, options = {}) => defineTopologyRelationship({
|
|
1338
|
-
required: true,
|
|
1339
|
-
...options,
|
|
1340
|
-
from,
|
|
1341
|
-
kind: "approval",
|
|
1342
|
-
to: topologyRef.humanCheckpoint(checkpoint)
|
|
1343
|
-
}),
|
|
1344
|
-
checkpointRoutesTo: (checkpoint, to, options = {}) => defineTopologyRelationship({
|
|
1345
|
-
required: true,
|
|
1346
|
-
...options,
|
|
1347
|
-
from: topologyRef.humanCheckpoint(checkpoint),
|
|
1348
|
-
kind: "triggers",
|
|
1349
|
-
to
|
|
1350
|
-
})
|
|
1351
|
-
};
|
|
1352
|
-
function compileTopologyNodeRef(input) {
|
|
1353
|
-
if (isNodeRef(input)) return input;
|
|
1354
|
-
if (isResourceEntry(input)) return topologyRef.resource(input);
|
|
1355
|
-
throw new Error("Topology node refs must be typed node objects or serializable { kind, id } refs");
|
|
1356
|
-
}
|
|
1357
|
-
function defineTopologyRelationship(input) {
|
|
1358
|
-
return OmTopologyRelationshipSchema.parse({
|
|
1359
|
-
...input,
|
|
1360
|
-
from: compileTopologyNodeRef(input.from),
|
|
1361
|
-
to: compileTopologyNodeRef(input.to)
|
|
1362
|
-
});
|
|
1363
|
-
}
|
|
1364
|
-
function defineTopology(relationships) {
|
|
1365
|
-
const entries = Array.isArray(relationships) ? relationships.map((relationship, index) => [`relationship-${index + 1}`, relationship]) : Object.entries(relationships);
|
|
1366
|
-
return OmTopologyDomainSchema.parse({
|
|
1367
|
-
version: 1,
|
|
1368
|
-
relationships: Object.fromEntries(entries.map(([key, relationship]) => [key, defineTopologyRelationship(relationship)]))
|
|
1369
|
-
});
|
|
1370
|
-
}
|
|
1371
|
-
var PolicyIdSchema = ModelIdSchema;
|
|
1372
|
-
var PolicyApplicabilitySchema = z.object({
|
|
1373
|
-
systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
|
|
1374
|
-
actionIds: z.array(ModelIdSchema.meta({ ref: "action" })).default([]),
|
|
1375
|
-
resourceIds: z.array(ModelIdSchema.meta({ ref: "resource" })).default([]),
|
|
1376
|
-
roleIds: z.array(ModelIdSchema.meta({ ref: "role" })).default([])
|
|
1377
|
-
});
|
|
1378
|
-
var PolicyTriggerSchema = z.discriminatedUnion("kind", [
|
|
1379
|
-
z.object({
|
|
1380
|
-
kind: z.literal("event"),
|
|
1381
|
-
eventId: EventIdSchema.meta({ ref: "event" })
|
|
1382
|
-
}),
|
|
1383
|
-
z.object({
|
|
1384
|
-
kind: z.literal("action-invocation"),
|
|
1385
|
-
actionId: ModelIdSchema.meta({ ref: "action" })
|
|
1386
|
-
}),
|
|
1387
|
-
z.object({
|
|
1388
|
-
kind: z.literal("schedule"),
|
|
1389
|
-
cron: z.string().trim().min(1).max(120)
|
|
1390
|
-
}),
|
|
1391
|
-
z.object({
|
|
1392
|
-
kind: z.literal("manual")
|
|
1393
|
-
})
|
|
1394
|
-
]);
|
|
1395
|
-
var PolicyPredicateSchema = z.discriminatedUnion("kind", [
|
|
1396
|
-
z.object({
|
|
1397
|
-
kind: z.literal("always")
|
|
1398
|
-
}),
|
|
1399
|
-
z.object({
|
|
1400
|
-
kind: z.literal("expression"),
|
|
1401
|
-
expression: z.string().trim().min(1).max(2e3)
|
|
1402
|
-
}),
|
|
1403
|
-
z.object({
|
|
1404
|
-
kind: z.literal("threshold"),
|
|
1405
|
-
metric: ModelIdSchema,
|
|
1406
|
-
operator: z.enum(["lt", "lte", "eq", "gte", "gt"]).meta({ label: "Operator" }),
|
|
1407
|
-
value: z.number()
|
|
1408
|
-
})
|
|
1409
|
-
]);
|
|
1410
|
-
var PolicyEffectSchema = z.discriminatedUnion("kind", [
|
|
1411
|
-
z.object({
|
|
1412
|
-
kind: z.literal("require-approval"),
|
|
1413
|
-
roleId: ModelIdSchema.meta({ ref: "role" }).optional()
|
|
1414
|
-
}),
|
|
1415
|
-
z.object({
|
|
1416
|
-
kind: z.literal("invoke-action"),
|
|
1417
|
-
actionId: ModelIdSchema.meta({ ref: "action" })
|
|
1418
|
-
}),
|
|
1419
|
-
z.object({
|
|
1420
|
-
kind: z.literal("notify-role"),
|
|
1421
|
-
roleId: ModelIdSchema.meta({ ref: "role" })
|
|
1422
|
-
}),
|
|
1423
|
-
z.object({
|
|
1424
|
-
kind: z.literal("block")
|
|
1425
|
-
})
|
|
1426
|
-
]);
|
|
1427
|
-
var PolicySchema = z.object({
|
|
1428
|
-
id: PolicyIdSchema,
|
|
1429
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
1430
|
-
order: z.number(),
|
|
1431
|
-
label: LabelSchema,
|
|
1432
|
-
description: DescriptionSchema.optional(),
|
|
1433
|
-
trigger: PolicyTriggerSchema,
|
|
1434
|
-
predicate: PolicyPredicateSchema.default({ kind: "always" }),
|
|
1435
|
-
actions: z.array(PolicyEffectSchema).min(1),
|
|
1436
|
-
appliesTo: PolicyApplicabilitySchema.default({
|
|
1437
|
-
systemIds: [],
|
|
1438
|
-
actionIds: [],
|
|
1439
|
-
resourceIds: [],
|
|
1440
|
-
roleIds: []
|
|
1441
|
-
}),
|
|
1442
|
-
lifecycle: z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" }).default("active")
|
|
1443
|
-
});
|
|
1444
|
-
var PoliciesDomainSchema = z.record(z.string(), PolicySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
1445
|
-
message: "Each policy entry id must match its map key"
|
|
1446
|
-
}).default({});
|
|
1447
|
-
var DEFAULT_ORGANIZATION_MODEL_POLICIES = {};
|
|
1448
|
-
function addIssue(ctx, path, message) {
|
|
1449
|
-
ctx.addIssue({
|
|
1450
|
-
code: z.ZodIssueCode.custom,
|
|
1451
|
-
path,
|
|
1452
|
-
message
|
|
1453
|
-
});
|
|
1454
|
-
}
|
|
1455
|
-
function isLifecycleEnabled(lifecycle, enabled) {
|
|
1456
|
-
if (enabled === false) return false;
|
|
1457
|
-
return lifecycle !== "deprecated" && lifecycle !== "archived";
|
|
1458
|
-
}
|
|
1459
|
-
function defaultSystemPathFor(id) {
|
|
1460
|
-
return `/${id.replaceAll(".", "/")}`;
|
|
1461
|
-
}
|
|
1462
|
-
function asRoleHolderArray(heldBy) {
|
|
1463
|
-
return Array.isArray(heldBy) ? heldBy : [heldBy];
|
|
1464
|
-
}
|
|
1465
|
-
function isKnowledgeKindCompatibleWithTarget(knowledgeKind, targetKind) {
|
|
1466
|
-
if (knowledgeKind === "reference") return true;
|
|
1467
|
-
if (knowledgeKind === "playbook") {
|
|
1468
|
-
return ["system", "resource", "stage", "action", "ontology"].includes(targetKind);
|
|
1469
|
-
}
|
|
1470
|
-
if (knowledgeKind === "strategy") {
|
|
1471
|
-
return ["system", "goal", "offering", "customer-segment", "ontology"].includes(targetKind);
|
|
1472
|
-
}
|
|
1473
|
-
return false;
|
|
1474
|
-
}
|
|
1475
|
-
function isRecord(value) {
|
|
1476
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1477
|
-
}
|
|
1478
|
-
function refineOrganizationModel(model, ctx) {
|
|
1479
|
-
function collectAllSystems(systems, prefix = "", schemaPath = ["systems"]) {
|
|
1480
|
-
const result = [];
|
|
1481
|
-
for (const [key, system] of Object.entries(systems)) {
|
|
1482
|
-
const path = prefix ? `${prefix}.${key}` : key;
|
|
1483
|
-
const currentSchemaPath = [...schemaPath, key];
|
|
1484
|
-
result.push({ path, schemaPath: currentSchemaPath, system });
|
|
1485
|
-
const childSystems = system.systems ?? system.subsystems;
|
|
1486
|
-
if (childSystems !== void 0) {
|
|
1487
|
-
result.push(
|
|
1488
|
-
...collectAllSystems(childSystems, path, [
|
|
1489
|
-
...currentSchemaPath,
|
|
1490
|
-
system.systems !== void 0 ? "systems" : "subsystems"
|
|
1491
|
-
])
|
|
1492
|
-
);
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
return result;
|
|
1496
|
-
}
|
|
1497
|
-
const allSystems = collectAllSystems(model.systems);
|
|
1498
|
-
const systemsById = /* @__PURE__ */ new Map();
|
|
1499
|
-
for (const { path, system } of allSystems) {
|
|
1500
|
-
systemsById.set(path, system);
|
|
1501
|
-
systemsById.set(system.id, system);
|
|
1502
|
-
}
|
|
1503
|
-
const systemIdsByEffectivePath = /* @__PURE__ */ new Map();
|
|
1504
|
-
allSystems.forEach(({ path, schemaPath, system }) => {
|
|
1505
|
-
if (system.parentSystemId !== void 0 && !systemsById.has(system.parentSystemId)) {
|
|
1506
|
-
addIssue(
|
|
1507
|
-
ctx,
|
|
1508
|
-
[...schemaPath, "parentSystemId"],
|
|
1509
|
-
`System "${system.id}" references unknown parent "${system.parentSystemId}"`
|
|
1510
|
-
);
|
|
1511
|
-
}
|
|
1512
|
-
const hasChildren = Object.keys(system.systems ?? system.subsystems ?? {}).length > 0 || allSystems.some(
|
|
1513
|
-
(candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes(".")
|
|
1514
|
-
);
|
|
1515
|
-
const contributesRoutePath = system.ui?.path !== void 0 || system.path !== void 0 || !hasChildren;
|
|
1516
|
-
if (contributesRoutePath) {
|
|
1517
|
-
const effectivePath = system.ui?.path ?? system.path ?? defaultSystemPathFor(path);
|
|
1518
|
-
const existingSystemId = systemIdsByEffectivePath.get(effectivePath);
|
|
1519
|
-
if (existingSystemId !== void 0) {
|
|
1520
|
-
addIssue(
|
|
1521
|
-
ctx,
|
|
1522
|
-
[...schemaPath, system.ui?.path !== void 0 ? "ui" : "path"],
|
|
1523
|
-
`System "${path}" effective path "${effectivePath}" duplicates system "${existingSystemId}"`
|
|
1524
|
-
);
|
|
1525
|
-
} else {
|
|
1526
|
-
systemIdsByEffectivePath.set(effectivePath, path);
|
|
1527
|
-
}
|
|
1528
|
-
}
|
|
1529
|
-
if (hasChildren && isLifecycleEnabled(system.lifecycle, system.enabled)) {
|
|
1530
|
-
const hasEnabledDescendant = Object.values(system.systems ?? system.subsystems ?? {}).some(
|
|
1531
|
-
(candidate) => isLifecycleEnabled(candidate.lifecycle, candidate.enabled)
|
|
1532
|
-
) || allSystems.some(
|
|
1533
|
-
(candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes(".") && isLifecycleEnabled(candidate.system.lifecycle, candidate.system.enabled)
|
|
1534
|
-
);
|
|
1535
|
-
if (!hasEnabledDescendant) {
|
|
1536
|
-
addIssue(ctx, [...schemaPath, "lifecycle"], `System "${path}" is active but has no active descendants`);
|
|
1537
|
-
}
|
|
1538
|
-
}
|
|
1539
|
-
});
|
|
1540
|
-
allSystems.forEach(({ schemaPath, system }) => {
|
|
1541
|
-
const visited = /* @__PURE__ */ new Set();
|
|
1542
|
-
let currentParentId = system.parentSystemId;
|
|
1543
|
-
while (currentParentId !== void 0) {
|
|
1544
|
-
if (currentParentId === system.id || visited.has(currentParentId)) {
|
|
1545
|
-
addIssue(ctx, [...schemaPath, "parentSystemId"], `System "${system.id}" has a parent cycle`);
|
|
1546
|
-
return;
|
|
1547
|
-
}
|
|
1548
|
-
visited.add(currentParentId);
|
|
1549
|
-
currentParentId = systemsById.get(currentParentId)?.parentSystemId;
|
|
1550
|
-
}
|
|
1551
|
-
});
|
|
1552
|
-
function normalizeRoutePath2(path) {
|
|
1553
|
-
return path.length > 1 ? path.replace(/\/+$/, "") : path;
|
|
1554
|
-
}
|
|
1555
|
-
const sidebarNodeIds = /* @__PURE__ */ new Map();
|
|
1556
|
-
const sidebarSurfacePaths = /* @__PURE__ */ new Map();
|
|
1557
|
-
const sidebarSurfaces = [];
|
|
1558
|
-
function collectSidebarNodes(nodes, schemaPath) {
|
|
1559
|
-
Object.entries(nodes).forEach(([nodeId2, node]) => {
|
|
1560
|
-
const nodePath = [...schemaPath, nodeId2];
|
|
1561
|
-
const existingNodePath = sidebarNodeIds.get(nodeId2);
|
|
1562
|
-
if (existingNodePath !== void 0) {
|
|
1563
|
-
addIssue(ctx, nodePath, `Sidebar node id "${nodeId2}" duplicates another sidebar node`);
|
|
1564
|
-
} else {
|
|
1565
|
-
sidebarNodeIds.set(nodeId2, nodePath);
|
|
1566
|
-
}
|
|
1567
|
-
if (node.type === "group") {
|
|
1568
|
-
collectSidebarNodes(node.children, [...nodePath, "children"]);
|
|
1569
|
-
return;
|
|
1570
|
-
}
|
|
1571
|
-
sidebarSurfaces.push({ id: nodeId2, node, path: nodePath });
|
|
1572
|
-
const normalizedPath = normalizeRoutePath2(node.path);
|
|
1573
|
-
const existingSurfaceId = sidebarSurfacePaths.get(normalizedPath);
|
|
1574
|
-
if (existingSurfaceId !== void 0) {
|
|
1575
|
-
addIssue(
|
|
1576
|
-
ctx,
|
|
1577
|
-
[...nodePath, "path"],
|
|
1578
|
-
`Sidebar surface path "${node.path}" duplicates surface "${existingSurfaceId}"`
|
|
1579
|
-
);
|
|
1580
|
-
} else {
|
|
1581
|
-
sidebarSurfacePaths.set(normalizedPath, nodeId2);
|
|
1582
|
-
}
|
|
1583
|
-
node.targets?.systems?.forEach((systemId, systemIndex) => {
|
|
1584
|
-
if (!systemsById.has(systemId)) {
|
|
1585
|
-
addIssue(
|
|
1586
|
-
ctx,
|
|
1587
|
-
[...nodePath, "targets", "systems", systemIndex],
|
|
1588
|
-
`Sidebar surface "${nodeId2}" references unknown system "${systemId}"`
|
|
1589
|
-
);
|
|
1590
|
-
}
|
|
1591
|
-
});
|
|
1592
|
-
});
|
|
1593
|
-
}
|
|
1594
|
-
collectSidebarNodes(model.navigation.sidebar.primary, ["navigation", "sidebar", "primary"]);
|
|
1595
|
-
collectSidebarNodes(model.navigation.sidebar.bottom, ["navigation", "sidebar", "bottom"]);
|
|
1596
|
-
const segmentsById = new Map(Object.entries(model.customers));
|
|
1597
|
-
Object.values(model.offerings).forEach((product) => {
|
|
1598
|
-
product.targetSegmentIds.forEach((segmentId, segmentIndex) => {
|
|
1599
|
-
if (!segmentsById.has(segmentId)) {
|
|
1600
|
-
addIssue(
|
|
1601
|
-
ctx,
|
|
1602
|
-
["offerings", product.id, "targetSegmentIds", segmentIndex],
|
|
1603
|
-
`Product "${product.id}" references unknown customer segment "${segmentId}"`
|
|
1604
|
-
);
|
|
1605
|
-
}
|
|
1606
|
-
});
|
|
1607
|
-
if (product.deliveryFeatureId !== void 0 && !systemsById.has(product.deliveryFeatureId)) {
|
|
1608
|
-
addIssue(
|
|
1609
|
-
ctx,
|
|
1610
|
-
["offerings", product.id, "deliveryFeatureId"],
|
|
1611
|
-
`Product "${product.id}" references unknown delivery system "${product.deliveryFeatureId}"`
|
|
1612
|
-
);
|
|
1613
|
-
}
|
|
1614
|
-
});
|
|
1615
|
-
Object.values(model.goals).forEach((objective) => {
|
|
1616
|
-
if (objective.periodEnd <= objective.periodStart) {
|
|
1617
|
-
addIssue(
|
|
1618
|
-
ctx,
|
|
1619
|
-
["goals", objective.id, "periodEnd"],
|
|
1620
|
-
`Goal "${objective.id}" has periodEnd "${objective.periodEnd}" which must be strictly after periodStart "${objective.periodStart}"`
|
|
1621
|
-
);
|
|
1622
|
-
}
|
|
1623
|
-
});
|
|
1624
|
-
const goalsById = new Map(Object.entries(model.goals));
|
|
1625
|
-
const knowledgeById = new Map(Object.entries(model.knowledge));
|
|
1626
|
-
const actionsById = new Map(Object.entries(model.actions));
|
|
1627
|
-
const entitiesById = new Map(Object.entries(model.entities));
|
|
1628
|
-
const policiesById = new Map(Object.entries(model.policies));
|
|
1629
|
-
sidebarSurfaces.forEach(({ id, node, path }) => {
|
|
1630
|
-
node.targets?.entities?.forEach((entityId, entityIndex) => {
|
|
1631
|
-
if (!entitiesById.has(entityId)) {
|
|
1632
|
-
addIssue(
|
|
1633
|
-
ctx,
|
|
1634
|
-
[...path, "targets", "entities", entityIndex],
|
|
1635
|
-
`Sidebar surface "${id}" references unknown entity "${entityId}"`
|
|
1636
|
-
);
|
|
1637
|
-
}
|
|
1638
|
-
});
|
|
1639
|
-
node.targets?.actions?.forEach((actionId, actionIndex) => {
|
|
1640
|
-
if (!actionsById.has(actionId)) {
|
|
1641
|
-
addIssue(
|
|
1642
|
-
ctx,
|
|
1643
|
-
[...path, "targets", "actions", actionIndex],
|
|
1644
|
-
`Sidebar surface "${id}" references unknown action "${actionId}"`
|
|
1645
|
-
);
|
|
1646
|
-
}
|
|
1647
|
-
});
|
|
1648
|
-
});
|
|
1649
|
-
Object.values(model.entities).forEach((entity) => {
|
|
1650
|
-
if (systemsById.size > 0 && !systemsById.has(entity.ownedBySystemId)) {
|
|
1651
|
-
addIssue(
|
|
1652
|
-
ctx,
|
|
1653
|
-
["entities", entity.id, "ownedBySystemId"],
|
|
1654
|
-
`Entity "${entity.id}" references unknown ownedBySystemId "${entity.ownedBySystemId}"`
|
|
1655
|
-
);
|
|
1656
|
-
}
|
|
1657
|
-
entity.links?.forEach((link, linkIndex) => {
|
|
1658
|
-
if (!entitiesById.has(link.toEntity)) {
|
|
1659
|
-
addIssue(
|
|
1660
|
-
ctx,
|
|
1661
|
-
["entities", entity.id, "links", linkIndex, "toEntity"],
|
|
1662
|
-
`Entity "${entity.id}" links to unknown entity "${link.toEntity}"`
|
|
1663
|
-
);
|
|
1664
|
-
}
|
|
1665
|
-
});
|
|
1666
|
-
});
|
|
1667
|
-
const rolesById = new Map(Object.entries(model.roles));
|
|
1668
|
-
Object.values(model.roles).forEach((role) => {
|
|
1669
|
-
if (role.reportsToId !== void 0 && !rolesById.has(role.reportsToId)) {
|
|
1670
|
-
addIssue(
|
|
1671
|
-
ctx,
|
|
1672
|
-
["roles", role.id, "reportsToId"],
|
|
1673
|
-
`Role "${role.id}" references unknown reportsToId "${role.reportsToId}"`
|
|
1674
|
-
);
|
|
1675
|
-
}
|
|
1676
|
-
});
|
|
1677
|
-
Object.values(model.roles).forEach((role) => {
|
|
1678
|
-
const visited = /* @__PURE__ */ new Set();
|
|
1679
|
-
let currentReportsToId = role.reportsToId;
|
|
1680
|
-
while (currentReportsToId !== void 0) {
|
|
1681
|
-
if (currentReportsToId === role.id || visited.has(currentReportsToId)) {
|
|
1682
|
-
addIssue(ctx, ["roles", role.id, "reportsToId"], `Role "${role.id}" has a reportsToId cycle`);
|
|
1683
|
-
return;
|
|
1684
|
-
}
|
|
1685
|
-
visited.add(currentReportsToId);
|
|
1686
|
-
currentReportsToId = rolesById.get(currentReportsToId)?.reportsToId;
|
|
1687
|
-
}
|
|
1688
|
-
});
|
|
1689
|
-
Object.values(model.roles).forEach((role) => {
|
|
1690
|
-
role.responsibleFor?.forEach((systemId, systemIndex) => {
|
|
1691
|
-
if (!systemsById.has(systemId)) {
|
|
1692
|
-
addIssue(
|
|
1693
|
-
ctx,
|
|
1694
|
-
["roles", role.id, "responsibleFor", systemIndex],
|
|
1695
|
-
`Role "${role.id}" references unknown responsibleFor system "${systemId}"`
|
|
1696
|
-
);
|
|
1697
|
-
}
|
|
1698
|
-
});
|
|
1699
|
-
});
|
|
1700
|
-
allSystems.forEach(({ schemaPath, system }) => {
|
|
1701
|
-
if (system.responsibleRoleId !== void 0 && !rolesById.has(system.responsibleRoleId)) {
|
|
1702
|
-
addIssue(
|
|
1703
|
-
ctx,
|
|
1704
|
-
[...schemaPath, "responsibleRoleId"],
|
|
1705
|
-
`System "${system.id}" references unknown responsibleRoleId "${system.responsibleRoleId}"`
|
|
1706
|
-
);
|
|
1707
|
-
}
|
|
1708
|
-
system.governedByKnowledge?.forEach((nodeId2, nodeIndex) => {
|
|
1709
|
-
if (!knowledgeById.has(nodeId2)) {
|
|
1710
|
-
addIssue(
|
|
1711
|
-
ctx,
|
|
1712
|
-
[...schemaPath, "governedByKnowledge", nodeIndex],
|
|
1713
|
-
`System "${system.id}" references unknown knowledge node "${nodeId2}"`
|
|
1714
|
-
);
|
|
1715
|
-
}
|
|
1716
|
-
});
|
|
1717
|
-
system.drivesGoals?.forEach((goalId, goalIndex) => {
|
|
1718
|
-
if (!goalsById.has(goalId)) {
|
|
1719
|
-
addIssue(
|
|
1720
|
-
ctx,
|
|
1721
|
-
[...schemaPath, "drivesGoals", goalIndex],
|
|
1722
|
-
`System "${system.id}" references unknown goal "${goalId}"`
|
|
1723
|
-
);
|
|
1724
|
-
}
|
|
1725
|
-
});
|
|
1726
|
-
system.actions?.forEach((actionRef, actionIndex) => {
|
|
1727
|
-
if (!actionsById.has(actionRef.actionId)) {
|
|
1728
|
-
addIssue(
|
|
1729
|
-
ctx,
|
|
1730
|
-
[...schemaPath, "actions", actionIndex, "actionId"],
|
|
1731
|
-
`System "${system.id}" references unknown action "${actionRef.actionId}"`
|
|
1732
|
-
);
|
|
1733
|
-
}
|
|
1734
|
-
});
|
|
1735
|
-
system.policies?.forEach((policyId, policyIndex) => {
|
|
1736
|
-
if (!policiesById.has(policyId)) {
|
|
1737
|
-
addIssue(
|
|
1738
|
-
ctx,
|
|
1739
|
-
[...schemaPath, "policies", policyIndex],
|
|
1740
|
-
`System "${system.id}" references unknown policy "${policyId}"`
|
|
1741
|
-
);
|
|
1742
|
-
}
|
|
1743
|
-
});
|
|
1744
|
-
});
|
|
1745
|
-
Object.values(model.actions).forEach((action) => {
|
|
1746
|
-
action.affects?.forEach((entityId, entityIndex) => {
|
|
1747
|
-
if (!entitiesById.has(entityId)) {
|
|
1748
|
-
addIssue(
|
|
1749
|
-
ctx,
|
|
1750
|
-
["actions", action.id, "affects", entityIndex],
|
|
1751
|
-
`Action "${action.id}" affects unknown entity "${entityId}"`
|
|
1752
|
-
);
|
|
1753
|
-
}
|
|
1754
|
-
});
|
|
1755
|
-
});
|
|
1756
|
-
const resourcesById = new Map(Object.entries(model.resources));
|
|
1757
|
-
sidebarSurfaces.forEach(({ id, node, path }) => {
|
|
1758
|
-
node.targets?.resources?.forEach((resourceId, resourceIndex) => {
|
|
1759
|
-
if (!resourcesById.has(resourceId)) {
|
|
1760
|
-
addIssue(
|
|
1761
|
-
ctx,
|
|
1762
|
-
[...path, "targets", "resources", resourceIndex],
|
|
1763
|
-
`Sidebar surface "${id}" references unknown resource "${resourceId}"`
|
|
1764
|
-
);
|
|
1765
|
-
}
|
|
1766
|
-
});
|
|
1767
|
-
});
|
|
1768
|
-
const idx = buildOmCrossRefIndex(model);
|
|
1769
|
-
const { ontologyIndexByKind, ontologyIds } = idx;
|
|
1770
|
-
const ontologyCompilation = compileOrganizationOntology(model);
|
|
1771
|
-
function topologyTargetExists(ref) {
|
|
1772
|
-
if (ref.kind === "system") return systemsById.has(ref.id);
|
|
1773
|
-
if (ref.kind === "resource") return resourcesById.has(ref.id);
|
|
1774
|
-
if (ref.kind === "ontology") return ontologyIds.has(ref.id);
|
|
1775
|
-
if (ref.kind === "policy") return policiesById.has(ref.id);
|
|
1776
|
-
if (ref.kind === "role") return rolesById.has(ref.id);
|
|
1777
|
-
return true;
|
|
1778
|
-
}
|
|
1779
|
-
Object.entries(model.topology.relationships).forEach(([relationshipId, relationship]) => {
|
|
1780
|
-
["from", "to"].forEach((side) => {
|
|
1781
|
-
const ref = relationship[side];
|
|
1782
|
-
if (topologyTargetExists(ref)) return;
|
|
1783
|
-
addIssue(
|
|
1784
|
-
ctx,
|
|
1785
|
-
["topology", "relationships", relationshipId, side],
|
|
1786
|
-
`Topology relationship "${relationshipId}" ${side} references unknown ${ref.kind} "${ref.id}"`
|
|
1787
|
-
);
|
|
1788
|
-
});
|
|
1789
|
-
});
|
|
1790
|
-
function validateKnownOntologyReferences(ownerId, value, path, seen = /* @__PURE__ */ new WeakSet()) {
|
|
1791
|
-
if (Array.isArray(value)) {
|
|
1792
|
-
value.forEach((entry, index) => validateKnownOntologyReferences(ownerId, entry, [...path, index], seen));
|
|
1793
|
-
return;
|
|
1794
|
-
}
|
|
1795
|
-
if (!isRecord(value)) return;
|
|
1796
|
-
if (seen.has(value)) return;
|
|
1797
|
-
seen.add(value);
|
|
1798
|
-
Object.entries(value).forEach(([key, entry]) => {
|
|
1799
|
-
const expectedKind = ONTOLOGY_REFERENCE_KEY_KINDS[key];
|
|
1800
|
-
if (expectedKind !== void 0) {
|
|
1801
|
-
if (typeof entry !== "string") {
|
|
1802
|
-
addIssue(ctx, [...path, key], `Ontology record "${ownerId}" ${key} must be an ontology ID string`);
|
|
1803
|
-
} else if (ontologyIndexByKind[expectedKind][entry] === void 0) {
|
|
1804
|
-
addIssue(
|
|
1805
|
-
ctx,
|
|
1806
|
-
[...path, key],
|
|
1807
|
-
`Ontology record "${ownerId}" ${key} references unknown ${expectedKind} ontology ID "${entry}"`
|
|
1808
|
-
);
|
|
1809
|
-
}
|
|
1810
|
-
}
|
|
1811
|
-
validateKnownOntologyReferences(ownerId, entry, [...path, key], seen);
|
|
1812
|
-
});
|
|
1813
|
-
}
|
|
1814
|
-
for (const { id, record } of listResolvedOntologyRecords(ontologyCompilation.ontology)) {
|
|
1815
|
-
validateKnownOntologyReferences(id, record, record.origin.path);
|
|
1816
|
-
}
|
|
1817
|
-
Object.values(model.policies).forEach((policy) => {
|
|
1818
|
-
policy.appliesTo.systemIds.forEach((systemId, systemIndex) => {
|
|
1819
|
-
if (!systemsById.has(systemId)) {
|
|
1820
|
-
addIssue(
|
|
1821
|
-
ctx,
|
|
1822
|
-
["policies", policy.id, "appliesTo", "systemIds", systemIndex],
|
|
1823
|
-
`Policy "${policy.id}" applies to unknown system "${systemId}"`
|
|
1824
|
-
);
|
|
1825
|
-
}
|
|
1826
|
-
});
|
|
1827
|
-
policy.appliesTo.actionIds.forEach((actionId, actionIndex) => {
|
|
1828
|
-
if (!actionsById.has(actionId)) {
|
|
1829
|
-
addIssue(
|
|
1830
|
-
ctx,
|
|
1831
|
-
["policies", policy.id, "appliesTo", "actionIds", actionIndex],
|
|
1832
|
-
`Policy "${policy.id}" applies to unknown action "${actionId}"`
|
|
1833
|
-
);
|
|
1834
|
-
}
|
|
1835
|
-
});
|
|
1836
|
-
policy.actions.forEach((action, actionIndex) => {
|
|
1837
|
-
if (action.kind === "invoke-action" && !actionsById.has(action.actionId)) {
|
|
1838
|
-
addIssue(
|
|
1839
|
-
ctx,
|
|
1840
|
-
["policies", policy.id, "actions", actionIndex, "actionId"],
|
|
1841
|
-
`Policy "${policy.id}" invokes unknown action "${action.actionId}"`
|
|
1842
|
-
);
|
|
1843
|
-
}
|
|
1844
|
-
if ((action.kind === "notify-role" || action.kind === "require-approval") && action.roleId !== void 0 && !rolesById.has(action.roleId)) {
|
|
1845
|
-
addIssue(
|
|
1846
|
-
ctx,
|
|
1847
|
-
["policies", policy.id, "actions", actionIndex, "roleId"],
|
|
1848
|
-
`Policy "${policy.id}" references unknown role "${action.roleId}"`
|
|
1849
|
-
);
|
|
1850
|
-
}
|
|
1851
|
-
});
|
|
1852
|
-
if (policy.trigger.kind === "action-invocation" && !actionsById.has(policy.trigger.actionId)) {
|
|
1853
|
-
addIssue(
|
|
1854
|
-
ctx,
|
|
1855
|
-
["policies", policy.id, "trigger", "actionId"],
|
|
1856
|
-
`Policy "${policy.id}" references unknown trigger action "${policy.trigger.actionId}"`
|
|
1857
|
-
);
|
|
1858
|
-
}
|
|
1859
|
-
});
|
|
1860
|
-
Object.entries(model.knowledge).forEach(([nodeId2, node]) => {
|
|
1861
|
-
node.links.forEach((link, linkIndex) => {
|
|
1862
|
-
if (!knowledgeTargetExists(idx, link.target.kind, link.target.id)) {
|
|
1863
|
-
addIssue(
|
|
1864
|
-
ctx,
|
|
1865
|
-
["knowledge", nodeId2, "links", linkIndex, "target"],
|
|
1866
|
-
`Knowledge node "${node.id}" references unknown ${link.target.kind} target "${link.target.id}"`
|
|
1867
|
-
);
|
|
1868
|
-
}
|
|
1869
|
-
if (!isKnowledgeKindCompatibleWithTarget(node.kind, link.target.kind)) {
|
|
1870
|
-
addIssue(
|
|
1871
|
-
ctx,
|
|
1872
|
-
["knowledge", nodeId2, "links", linkIndex, "target", "kind"],
|
|
1873
|
-
`Knowledge node "${node.id}" kind "${node.kind}" cannot govern ${link.target.kind} targets`
|
|
1874
|
-
);
|
|
1875
|
-
}
|
|
1876
|
-
});
|
|
1877
|
-
});
|
|
1878
|
-
Object.values(model.resources).forEach((resource) => {
|
|
1879
|
-
if (!systemsById.has(resource.systemPath)) {
|
|
1880
|
-
addIssue(
|
|
1881
|
-
ctx,
|
|
1882
|
-
["resources", resource.id, "systemPath"],
|
|
1883
|
-
`Resource "${resource.id}" references unknown system path "${resource.systemPath}"`
|
|
1884
|
-
);
|
|
1885
|
-
}
|
|
1886
|
-
if (resource.ownerRoleId !== void 0 && !rolesById.has(resource.ownerRoleId)) {
|
|
1887
|
-
addIssue(
|
|
1888
|
-
ctx,
|
|
1889
|
-
["resources", resource.id, "ownerRoleId"],
|
|
1890
|
-
`Resource "${resource.id}" references unknown ownerRoleId "${resource.ownerRoleId}"`
|
|
1891
|
-
);
|
|
1892
|
-
}
|
|
1893
|
-
if (resource.kind === "agent" && resource.actsAsRoleId !== void 0 && !rolesById.has(resource.actsAsRoleId)) {
|
|
1894
|
-
addIssue(
|
|
1895
|
-
ctx,
|
|
1896
|
-
["resources", resource.id, "actsAsRoleId"],
|
|
1897
|
-
`Agent resource "${resource.id}" references unknown actsAsRoleId "${resource.actsAsRoleId}"`
|
|
1898
|
-
);
|
|
1899
|
-
}
|
|
1900
|
-
});
|
|
1901
|
-
allSystems.forEach(({ path: systemPath2, schemaPath, system }) => {
|
|
1902
|
-
system.apiInterface?.resourceIds?.forEach((resourceId, resourceIndex) => {
|
|
1903
|
-
const resource = resourcesById.get(resourceId);
|
|
1904
|
-
if (resource === void 0) {
|
|
1905
|
-
addIssue(
|
|
1906
|
-
ctx,
|
|
1907
|
-
[...schemaPath, "apiInterface", "resourceIds", resourceIndex],
|
|
1908
|
-
`System Interface "${systemPath2}/api" scopes unknown resource "${resourceId}"`
|
|
1909
|
-
);
|
|
1910
|
-
return;
|
|
1911
|
-
}
|
|
1912
|
-
if (resource.systemPath !== systemPath2) {
|
|
1913
|
-
addIssue(
|
|
1914
|
-
ctx,
|
|
1915
|
-
[...schemaPath, "apiInterface", "resourceIds", resourceIndex],
|
|
1916
|
-
`System Interface "${systemPath2}/api" scopes resource "${resourceId}" from system "${resource.systemPath}"`
|
|
1917
|
-
);
|
|
1918
|
-
}
|
|
1919
|
-
});
|
|
1920
|
-
});
|
|
1921
|
-
function validateResourceOntologyBinding(resourceId, bindingKey, expectedKind, ids) {
|
|
1922
|
-
const ontologyIds2 = ids === void 0 ? [] : Array.isArray(ids) ? ids : [ids];
|
|
1923
|
-
ontologyIds2.forEach((ontologyId, ontologyIndex) => {
|
|
1924
|
-
if (ontologyIndexByKind[expectedKind][ontologyId] === void 0) {
|
|
1925
|
-
addIssue(
|
|
1926
|
-
ctx,
|
|
1927
|
-
["resources", resourceId, "ontology", bindingKey, ...Array.isArray(ids) ? [ontologyIndex] : []],
|
|
1928
|
-
`Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
|
|
1929
|
-
);
|
|
1930
|
-
}
|
|
1931
|
-
});
|
|
1932
|
-
}
|
|
1933
|
-
Object.values(model.resources).forEach((resource) => {
|
|
1934
|
-
const binding = resource.ontology;
|
|
1935
|
-
if (binding === void 0) return;
|
|
1936
|
-
validateResourceOntologyBinding(resource.id, "actions", "action", binding.actions);
|
|
1937
|
-
validateResourceOntologyBinding(resource.id, "primaryAction", "action", binding.primaryAction);
|
|
1938
|
-
validateResourceOntologyBinding(resource.id, "reads", "object", binding.reads);
|
|
1939
|
-
validateResourceOntologyBinding(resource.id, "writes", "object", binding.writes);
|
|
1940
|
-
validateResourceOntologyBinding(resource.id, "usesCatalogs", "catalog", binding.usesCatalogs);
|
|
1941
|
-
validateResourceOntologyBinding(resource.id, "emits", "event", binding.emits);
|
|
1942
|
-
if (binding.contract !== void 0) {
|
|
1943
|
-
const contractEntries = [
|
|
1944
|
-
["input", binding.contract.input],
|
|
1945
|
-
["output", binding.contract.output]
|
|
1946
|
-
];
|
|
1947
|
-
for (const [side, ref] of contractEntries) {
|
|
1948
|
-
if (ref === void 0) continue;
|
|
1949
|
-
const result = ContractRefSchema.safeParse(ref);
|
|
1950
|
-
if (!result.success) {
|
|
1951
|
-
addIssue(
|
|
1952
|
-
ctx,
|
|
1953
|
-
["resources", resource.id, "ontology", "contract", side],
|
|
1954
|
-
`Resource "${resource.id}" contract.${side} "${ref}" is not a valid ContractRef (expected "package/subpath#ExportName")`
|
|
1955
|
-
);
|
|
1956
|
-
}
|
|
1957
|
-
}
|
|
1958
|
-
}
|
|
1959
|
-
});
|
|
1960
|
-
Object.values(model.roles).forEach((role) => {
|
|
1961
|
-
if (role.heldBy === void 0) return;
|
|
1962
|
-
asRoleHolderArray(role.heldBy).forEach((holder, holderIndex) => {
|
|
1963
|
-
if (holder.kind !== "agent") return;
|
|
1964
|
-
const resource = resourcesById.get(holder.agentId);
|
|
1965
|
-
if (resource === void 0) {
|
|
1966
|
-
addIssue(
|
|
1967
|
-
ctx,
|
|
1968
|
-
["roles", role.id, "heldBy", Array.isArray(role.heldBy) ? holderIndex : "agentId"],
|
|
1969
|
-
`Role "${role.id}" references unknown agent holder resource "${holder.agentId}"`
|
|
1970
|
-
);
|
|
1971
|
-
return;
|
|
1972
|
-
}
|
|
1973
|
-
if (resource.kind !== "agent") {
|
|
1974
|
-
addIssue(
|
|
1975
|
-
ctx,
|
|
1976
|
-
["roles", role.id, "heldBy", Array.isArray(role.heldBy) ? holderIndex : "agentId"],
|
|
1977
|
-
`Role "${role.id}" agent holder "${holder.agentId}" must reference an agent resource`
|
|
1978
|
-
);
|
|
1979
|
-
}
|
|
1980
|
-
});
|
|
1981
|
-
});
|
|
1982
|
-
Object.entries(model.knowledge).forEach(([nodeId2, node]) => {
|
|
1983
|
-
node.ownerIds.forEach((roleId, ownerIndex) => {
|
|
1984
|
-
if (!rolesById.has(roleId)) {
|
|
1985
|
-
addIssue(
|
|
1986
|
-
ctx,
|
|
1987
|
-
["knowledge", nodeId2, "ownerIds", ownerIndex],
|
|
1988
|
-
`Knowledge node "${node.id}" references unknown owner role "${roleId}"`
|
|
1989
|
-
);
|
|
1990
|
-
}
|
|
1991
|
-
});
|
|
1992
|
-
});
|
|
1993
|
-
for (const diagnostic of ontologyCompilation.diagnostics) {
|
|
1994
|
-
addIssue(ctx, diagnostic.path, diagnostic.message);
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
1997
|
-
|
|
1998
|
-
// ../core/src/organization-model/schema.ts
|
|
1999
|
-
z.enum([
|
|
2000
|
-
"branding",
|
|
2001
|
-
"identity",
|
|
2002
|
-
"customers",
|
|
2003
|
-
"offerings",
|
|
2004
|
-
"roles",
|
|
2005
|
-
"goals",
|
|
2006
|
-
"systems",
|
|
2007
|
-
"ontology",
|
|
2008
|
-
"resources",
|
|
2009
|
-
"topology",
|
|
2010
|
-
"actions",
|
|
2011
|
-
"entities",
|
|
2012
|
-
"policies",
|
|
2013
|
-
"knowledge"
|
|
2014
|
-
]);
|
|
2015
|
-
var OrganizationModelDomainMetadataSchema = z.object({
|
|
2016
|
-
version: z.literal(1).default(1),
|
|
2017
|
-
lastModified: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "lastModified must be an ISO date string (YYYY-MM-DD)")
|
|
2018
|
-
});
|
|
2019
|
-
var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
|
|
2020
|
-
branding: { version: 1, lastModified: "2026-05-10" },
|
|
2021
|
-
identity: { version: 1, lastModified: "2026-05-10" },
|
|
2022
|
-
customers: { version: 1, lastModified: "2026-05-10" },
|
|
2023
|
-
offerings: { version: 1, lastModified: "2026-05-10" },
|
|
2024
|
-
roles: { version: 1, lastModified: "2026-05-10" },
|
|
2025
|
-
goals: { version: 1, lastModified: "2026-05-10" },
|
|
2026
|
-
systems: { version: 1, lastModified: "2026-05-10" },
|
|
2027
|
-
ontology: { version: 1, lastModified: "2026-05-14" },
|
|
2028
|
-
resources: { version: 1, lastModified: "2026-05-10" },
|
|
2029
|
-
topology: { version: 1, lastModified: "2026-05-14" },
|
|
2030
|
-
actions: { version: 1, lastModified: "2026-05-10" },
|
|
2031
|
-
entities: { version: 1, lastModified: "2026-05-10" },
|
|
2032
|
-
policies: { version: 1, lastModified: "2026-05-10" },
|
|
2033
|
-
knowledge: { version: 1, lastModified: "2026-05-10" }
|
|
2034
|
-
};
|
|
2035
|
-
var OrganizationModelDomainMetadataByDomainSchema = z.object({
|
|
2036
|
-
branding: OrganizationModelDomainMetadataSchema,
|
|
2037
|
-
identity: OrganizationModelDomainMetadataSchema,
|
|
2038
|
-
customers: OrganizationModelDomainMetadataSchema,
|
|
2039
|
-
offerings: OrganizationModelDomainMetadataSchema,
|
|
2040
|
-
roles: OrganizationModelDomainMetadataSchema,
|
|
2041
|
-
goals: OrganizationModelDomainMetadataSchema,
|
|
2042
|
-
systems: OrganizationModelDomainMetadataSchema,
|
|
2043
|
-
ontology: OrganizationModelDomainMetadataSchema,
|
|
2044
|
-
resources: OrganizationModelDomainMetadataSchema,
|
|
2045
|
-
topology: OrganizationModelDomainMetadataSchema,
|
|
2046
|
-
actions: OrganizationModelDomainMetadataSchema,
|
|
2047
|
-
entities: OrganizationModelDomainMetadataSchema,
|
|
2048
|
-
policies: OrganizationModelDomainMetadataSchema,
|
|
2049
|
-
knowledge: OrganizationModelDomainMetadataSchema
|
|
2050
|
-
}).partial().default(DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA).transform((metadata) => ({ ...DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA, ...metadata }));
|
|
2051
|
-
var OrganizationModelSchemaBase = z.object({
|
|
2052
|
-
version: z.literal(1).default(1),
|
|
2053
|
-
domainMetadata: OrganizationModelDomainMetadataByDomainSchema,
|
|
2054
|
-
branding: OrganizationModelBrandingSchema.default(DEFAULT_ORGANIZATION_MODEL_BRANDING),
|
|
2055
|
-
navigation: OrganizationModelNavigationSchema,
|
|
2056
|
-
identity: IdentityDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_IDENTITY),
|
|
2057
|
-
customers: CustomersDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_CUSTOMERS),
|
|
2058
|
-
offerings: OfferingsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_OFFERINGS),
|
|
2059
|
-
roles: RolesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ROLES),
|
|
2060
|
-
goals: GoalsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_GOALS),
|
|
2061
|
-
systems: SystemsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_SYSTEMS),
|
|
2062
|
-
ontology: OntologyScopeSchema.default(DEFAULT_ONTOLOGY_SCOPE),
|
|
2063
|
-
resources: ResourcesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_RESOURCES),
|
|
2064
|
-
topology: OmTopologyDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_TOPOLOGY),
|
|
2065
|
-
actions: ActionsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ACTIONS),
|
|
2066
|
-
entities: EntitiesDomainSchema.default({}),
|
|
2067
|
-
policies: PoliciesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_POLICIES),
|
|
2068
|
-
// D3: flat Record<id, OrgKnowledgeNode> — no wrapper object
|
|
2069
|
-
knowledge: KnowledgeDomainSchema.default({})
|
|
2070
|
-
});
|
|
2071
|
-
var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine(refineOrganizationModel);
|
|
2072
|
-
|
|
2073
|
-
// ../core/src/organization-model/contracts.ts
|
|
2074
|
-
var PROJECTS_VIEW_ACTION_ID = "delivery.projects.view";
|
|
2075
|
-
|
|
2076
|
-
// ../core/src/organization-model/defaults.ts
|
|
2077
|
-
var DEFAULT_ORGANIZATION_MODEL_KNOWLEDGE = {};
|
|
2078
|
-
var DEFAULT_ORGANIZATION_MODEL_ENTITIES = {};
|
|
2079
|
-
var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
2080
|
-
sidebar: {
|
|
2081
|
-
primary: {},
|
|
2082
|
-
bottom: {}
|
|
2083
|
-
},
|
|
2084
|
-
topbar: {}
|
|
2085
|
-
};
|
|
2086
|
-
var DEFAULT_ORGANIZATION_MODEL = {
|
|
2087
|
-
version: 1,
|
|
2088
|
-
domainMetadata: DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA,
|
|
2089
|
-
branding: DEFAULT_ORGANIZATION_MODEL_BRANDING,
|
|
2090
|
-
navigation: DEFAULT_ORGANIZATION_MODEL_NAVIGATION,
|
|
2091
|
-
identity: DEFAULT_ORGANIZATION_MODEL_IDENTITY,
|
|
2092
|
-
customers: DEFAULT_ORGANIZATION_MODEL_CUSTOMERS,
|
|
2093
|
-
offerings: DEFAULT_ORGANIZATION_MODEL_OFFERINGS,
|
|
2094
|
-
roles: DEFAULT_ORGANIZATION_MODEL_ROLES,
|
|
2095
|
-
goals: DEFAULT_ORGANIZATION_MODEL_GOALS,
|
|
2096
|
-
// Generic empty systems map. Elevasis-specific systems (platform, sales, sales.crm,
|
|
2097
|
-
// sales.lead-gen, monitoring, settings, admin, etc.) have been relocated to
|
|
2098
|
-
// `@repo/elevasis-core/src/organization-model/systems.ts` via `canonicalOrganizationModel`.
|
|
2099
|
-
// Tenant OM configs supply their own systems via `resolveOrganizationModel`.
|
|
2100
|
-
systems: {},
|
|
2101
|
-
ontology: DEFAULT_ONTOLOGY_SCOPE,
|
|
2102
|
-
resources: DEFAULT_ORGANIZATION_MODEL_RESOURCES,
|
|
2103
|
-
topology: DEFAULT_ORGANIZATION_MODEL_TOPOLOGY,
|
|
2104
|
-
// Generic empty actions map. Elevasis-specific action entries have been relocated to
|
|
2105
|
-
// `@repo/elevasis-core/src/organization-model/actions.ts`.
|
|
2106
|
-
actions: {},
|
|
2107
|
-
entities: DEFAULT_ORGANIZATION_MODEL_ENTITIES,
|
|
2108
|
-
policies: DEFAULT_ORGANIZATION_MODEL_POLICIES,
|
|
2109
|
-
knowledge: DEFAULT_ORGANIZATION_MODEL_KNOWLEDGE
|
|
2110
|
-
};
|
|
2111
|
-
|
|
2112
|
-
// ../core/src/organization-model/resolve.ts
|
|
2113
|
-
function isPlainObject(value) {
|
|
2114
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2115
|
-
}
|
|
2116
|
-
function collectNestedSystemPaths(systems, prefix = "") {
|
|
2117
|
-
const paths = /* @__PURE__ */ new Set();
|
|
2118
|
-
for (const [key, value] of Object.entries(systems)) {
|
|
2119
|
-
if (!isPlainObject(value)) continue;
|
|
2120
|
-
const path = prefix ? `${prefix}.${key}` : key;
|
|
2121
|
-
for (const childKey of ["systems", "subsystems"]) {
|
|
2122
|
-
const childSystems = value[childKey];
|
|
2123
|
-
if (!isPlainObject(childSystems)) continue;
|
|
2124
|
-
for (const childPath of collectNestedSystemPaths(childSystems, path)) {
|
|
2125
|
-
paths.add(childPath);
|
|
2126
|
-
}
|
|
2127
|
-
}
|
|
2128
|
-
if (prefix !== "") {
|
|
2129
|
-
paths.add(path);
|
|
2130
|
-
}
|
|
2131
|
-
}
|
|
2132
|
-
return paths;
|
|
2133
|
-
}
|
|
2134
|
-
function pruneFlatSystemDescendantCollisions(base, override) {
|
|
2135
|
-
const result = { ...base };
|
|
2136
|
-
for (const nestedPath of collectNestedSystemPaths(override)) {
|
|
2137
|
-
delete result[nestedPath];
|
|
2138
|
-
}
|
|
2139
|
-
return result;
|
|
2140
|
-
}
|
|
2141
|
-
function deepMerge(base, override) {
|
|
2142
|
-
if (override === void 0) {
|
|
2143
|
-
return base;
|
|
2144
|
-
}
|
|
2145
|
-
if (Array.isArray(base)) {
|
|
2146
|
-
return override ?? base;
|
|
2147
|
-
}
|
|
2148
|
-
if (!isPlainObject(base) || !isPlainObject(override)) {
|
|
2149
|
-
return override ?? base;
|
|
2150
|
-
}
|
|
2151
|
-
const result = { ...base };
|
|
2152
|
-
for (const [key, value] of Object.entries(override)) {
|
|
2153
|
-
if (value === void 0) continue;
|
|
2154
|
-
const existing = result[key];
|
|
2155
|
-
if (key === "systems" && isPlainObject(existing) && isPlainObject(value)) {
|
|
2156
|
-
result[key] = deepMerge(pruneFlatSystemDescendantCollisions(existing, value), value);
|
|
2157
|
-
continue;
|
|
2158
|
-
}
|
|
2159
|
-
result[key] = isPlainObject(existing) && isPlainObject(value) ? deepMerge(existing, value) : value;
|
|
2160
|
-
}
|
|
2161
|
-
return result;
|
|
2162
|
-
}
|
|
2163
|
-
function resolveOrganizationModel(override, organizationIdOrOptions, options) {
|
|
2164
|
-
const resolvedOptions = typeof organizationIdOrOptions === "object" ? organizationIdOrOptions : options;
|
|
2165
|
-
const mergeDefaults = resolvedOptions?.mergeDefaults ?? true;
|
|
2166
|
-
const merged = mergeDefaults ? deepMerge(DEFAULT_ORGANIZATION_MODEL, override) : override ?? {};
|
|
2167
|
-
return OrganizationModelSchema.parse(merged);
|
|
2168
|
-
}
|
|
2169
|
-
|
|
2170
|
-
// ../core/src/organization-model/surface-projection.ts
|
|
2171
|
-
function collectSystemsById(model) {
|
|
2172
|
-
const systemsById = /* @__PURE__ */ new Map();
|
|
2173
|
-
for (const { path, system } of listAllSystems(model)) {
|
|
2174
|
-
systemsById.set(path, system);
|
|
2175
|
-
systemsById.set(system.id, system);
|
|
2176
|
-
}
|
|
2177
|
-
return systemsById;
|
|
2178
|
-
}
|
|
2179
|
-
function getSystemWithAncestors(systemsById, systemId) {
|
|
2180
|
-
const systems = [];
|
|
2181
|
-
let current = systemsById.get(systemId);
|
|
2182
|
-
while (current !== void 0) {
|
|
2183
|
-
systems.unshift(current);
|
|
2184
|
-
current = current.parentSystemId ? systemsById.get(current.parentSystemId) : void 0;
|
|
2185
|
-
}
|
|
2186
|
-
return systems;
|
|
2187
|
-
}
|
|
2188
|
-
function hasInheritedFlag(systemsById, systemIds, flag) {
|
|
2189
|
-
return systemIds.some(
|
|
2190
|
-
(systemId) => getSystemWithAncestors(systemsById, systemId).some((system) => system[flag] === true)
|
|
2191
|
-
);
|
|
2192
|
-
}
|
|
2193
|
-
function isLifecycleEnabled2(system) {
|
|
2194
|
-
if (system.enabled === false) return false;
|
|
2195
|
-
return system.lifecycle !== "deprecated" && system.lifecycle !== "archived";
|
|
2196
|
-
}
|
|
2197
|
-
function isLifecycleDevOnly(system) {
|
|
2198
|
-
return system.devOnly === true || system.lifecycle === "beta";
|
|
2199
|
-
}
|
|
2200
|
-
function isSystemEnabled(systemsById, systemId) {
|
|
2201
|
-
const systemLineage = getSystemWithAncestors(systemsById, systemId);
|
|
2202
|
-
return systemLineage.length > 0 && systemLineage.every(isLifecycleEnabled2);
|
|
2203
|
-
}
|
|
2204
|
-
function unique(values) {
|
|
2205
|
-
return [...new Set(values)];
|
|
2206
|
-
}
|
|
2207
|
-
function collectSidebarSurfaces(nodes, schemaPath, surfaces = []) {
|
|
2208
|
-
getSortedSidebarEntries(nodes).forEach(([id, node]) => {
|
|
2209
|
-
const nodePath = [...schemaPath, id];
|
|
2210
|
-
if (node.type === "group") {
|
|
2211
|
-
collectSidebarSurfaces(node.children, [...nodePath, "children"], surfaces);
|
|
2212
|
-
return;
|
|
2213
|
-
}
|
|
2214
|
-
surfaces.push({ id, surface: node, path: nodePath });
|
|
2215
|
-
});
|
|
2216
|
-
return surfaces;
|
|
2217
|
-
}
|
|
2218
|
-
function getSidebarSurfaces(model) {
|
|
2219
|
-
return [
|
|
2220
|
-
...collectSidebarSurfaces(model.navigation.sidebar.primary, ["navigation", "sidebar", "primary"]),
|
|
2221
|
-
...collectSidebarSurfaces(model.navigation.sidebar.bottom, ["navigation", "sidebar", "bottom"])
|
|
2222
|
-
];
|
|
2223
|
-
}
|
|
2224
|
-
function projectOrganizationSurfaces(model) {
|
|
2225
|
-
const systemsById = collectSystemsById(model);
|
|
2226
|
-
return getSidebarSurfaces(model).map(({ id, surface }) => {
|
|
2227
|
-
const targets = surface.targets ?? {};
|
|
2228
|
-
const systemIds = unique((targets.systems ?? []).filter((systemId) => systemsById.has(systemId)));
|
|
2229
|
-
const enabled = systemIds.every((candidate) => isSystemEnabled(systemsById, candidate));
|
|
2230
|
-
const devOnly = surface.devOnly === true || hasInheritedFlag(systemsById, systemIds, "devOnly") || systemIds.some((candidate) => getSystemWithAncestors(systemsById, candidate).some(isLifecycleDevOnly));
|
|
2231
|
-
const requiresAdmin = hasInheritedFlag(systemsById, systemIds, "requiresAdmin");
|
|
2232
|
-
return {
|
|
2233
|
-
id,
|
|
2234
|
-
label: surface.label,
|
|
2235
|
-
path: surface.path,
|
|
2236
|
-
surfaceType: surface.surfaceType,
|
|
2237
|
-
...surface.description !== void 0 ? { description: surface.description } : {},
|
|
2238
|
-
...surface.icon !== void 0 ? { icon: surface.icon } : {},
|
|
2239
|
-
...surface.order !== void 0 ? { order: surface.order } : {},
|
|
2240
|
-
systemIds,
|
|
2241
|
-
entityIds: [...targets.entities ?? []],
|
|
2242
|
-
resourceIds: [...targets.resources ?? []],
|
|
2243
|
-
actionIds: [...targets.actions ?? []],
|
|
2244
|
-
enabled,
|
|
2245
|
-
...devOnly ? { devOnly } : {},
|
|
2246
|
-
...surface.requiresAdmin === true || requiresAdmin ? { requiresAdmin: true } : {}
|
|
2247
|
-
};
|
|
2248
|
-
});
|
|
2249
|
-
}
|
|
2250
|
-
var OrganizationGraphNodeKindSchema = z.enum([
|
|
2251
|
-
"organization",
|
|
2252
|
-
"system",
|
|
2253
|
-
"role",
|
|
2254
|
-
"action",
|
|
2255
|
-
"entity",
|
|
2256
|
-
"event",
|
|
2257
|
-
"policy",
|
|
2258
|
-
"stage",
|
|
2259
|
-
"resource",
|
|
2260
|
-
"knowledge",
|
|
2261
|
-
"customer-segment",
|
|
2262
|
-
"offering",
|
|
2263
|
-
"goal",
|
|
2264
|
-
"surface",
|
|
2265
|
-
"navigation-group",
|
|
2266
|
-
// Ontology records are projected from compiled System.ontology scopes.
|
|
2267
|
-
"ontology"
|
|
2268
|
-
]);
|
|
2269
|
-
var OrganizationGraphEdgeKindSchema = z.enum([
|
|
2270
|
-
"contains",
|
|
2271
|
-
"references",
|
|
2272
|
-
"maps_to",
|
|
2273
|
-
"uses",
|
|
2274
|
-
"governs",
|
|
2275
|
-
"links",
|
|
2276
|
-
"affects",
|
|
2277
|
-
"emits",
|
|
2278
|
-
"originates_from",
|
|
2279
|
-
"triggers",
|
|
2280
|
-
"approval",
|
|
2281
|
-
"applies_to",
|
|
2282
|
-
"effects",
|
|
2283
|
-
"actions",
|
|
2284
|
-
"reads",
|
|
2285
|
-
"writes",
|
|
2286
|
-
"uses_catalog"
|
|
2287
|
-
]);
|
|
2288
|
-
var OrganizationGraphNodeSchema = z.object({
|
|
2289
|
-
id: z.string().trim().min(1).max(400),
|
|
2290
|
-
kind: OrganizationGraphNodeKindSchema,
|
|
2291
|
-
label: LabelSchema,
|
|
2292
|
-
sourceId: z.string().trim().min(1).max(400).optional(),
|
|
2293
|
-
description: DescriptionSchema.optional(),
|
|
2294
|
-
icon: IconNameSchema.optional(),
|
|
2295
|
-
enabled: z.boolean().optional(),
|
|
2296
|
-
ontologyKind: z.string().trim().min(1).max(80).optional(),
|
|
2297
|
-
resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint", "script"]).optional()
|
|
2298
|
-
});
|
|
2299
|
-
var OrganizationGraphEdgeSchema = z.object({
|
|
2300
|
-
id: z.string().trim().min(1).max(900),
|
|
2301
|
-
kind: OrganizationGraphEdgeKindSchema,
|
|
2302
|
-
sourceId: z.string().trim().min(1).max(400),
|
|
2303
|
-
targetId: z.string().trim().min(1).max(400),
|
|
2304
|
-
label: z.string().trim().min(1).max(120).optional(),
|
|
2305
|
-
relationshipType: z.enum(["triggers", "uses", "approval"]).optional()
|
|
2306
|
-
});
|
|
2307
|
-
var OrganizationGraphSchema = z.object({
|
|
2308
|
-
version: z.literal(1),
|
|
2309
|
-
organizationModelVersion: OrganizationModelSchema.shape.version,
|
|
2310
|
-
nodes: z.array(OrganizationGraphNodeSchema),
|
|
2311
|
-
edges: z.array(OrganizationGraphEdgeSchema)
|
|
2312
|
-
});
|
|
2313
|
-
var BuildOrganizationGraphInputSchema = z.object({
|
|
2314
|
-
organizationModel: OrganizationModelSchema,
|
|
2315
|
-
commandViewData: z.unknown().optional()
|
|
2316
|
-
});
|
|
2317
|
-
|
|
2318
|
-
// ../core/src/organization-model/graph/build.ts
|
|
2319
|
-
function nodeId(kind, sourceId) {
|
|
2320
|
-
return kind === "organization" ? "organization-model" : `${kind}:${sourceId ?? ""}`;
|
|
2321
|
-
}
|
|
2322
|
-
function edgeId(kind, sourceId, targetId, variant) {
|
|
2323
|
-
return variant ? `edge:${kind}:${variant}:${sourceId}:${targetId}` : `edge:${kind}:${sourceId}:${targetId}`;
|
|
2324
|
-
}
|
|
2325
|
-
function pushUniqueNode(nodes, seen, node) {
|
|
2326
|
-
if (seen.has(node.id)) return;
|
|
2327
|
-
seen.add(node.id);
|
|
2328
|
-
nodes.push(node);
|
|
2329
|
-
}
|
|
2330
|
-
function pushUniqueEdge(edges, seen, edge) {
|
|
2331
|
-
if (seen.has(edge.id)) return;
|
|
2332
|
-
seen.add(edge.id);
|
|
2333
|
-
edges.push(edge);
|
|
2334
|
-
}
|
|
2335
|
-
function collectSidebarGraphNodes(nodes, groups, surfaces, parentGroupId) {
|
|
2336
|
-
Object.entries(nodes).sort(([leftId, left], [rightId, right]) => {
|
|
2337
|
-
const orderDelta = (left.order ?? Number.MAX_SAFE_INTEGER) - (right.order ?? Number.MAX_SAFE_INTEGER);
|
|
2338
|
-
return orderDelta === 0 ? leftId.localeCompare(rightId) : orderDelta;
|
|
2339
|
-
}).forEach(([id, node]) => {
|
|
2340
|
-
if (node.type === "group") {
|
|
2341
|
-
groups.push({ id, node, ...parentGroupId !== void 0 ? { parentGroupId } : {} });
|
|
2342
|
-
collectSidebarGraphNodes(node.children, groups, surfaces, id);
|
|
2343
|
-
return;
|
|
2344
|
-
}
|
|
2345
|
-
surfaces.push({ id, node, ...parentGroupId !== void 0 ? { parentGroupId } : {} });
|
|
2346
|
-
});
|
|
2347
|
-
}
|
|
2348
|
-
function upsertResourceNode(nodes, seen, resourceNodesById, node) {
|
|
2349
|
-
const existing = resourceNodesById.get(node.id);
|
|
2350
|
-
if (existing) {
|
|
2351
|
-
if (!existing.label || existing.label === existing.sourceId) {
|
|
2352
|
-
existing.label = node.label;
|
|
2353
|
-
}
|
|
2354
|
-
if (!existing.description && node.description) {
|
|
2355
|
-
existing.description = node.description;
|
|
2356
|
-
}
|
|
2357
|
-
if (!existing.sourceId && node.sourceId) {
|
|
2358
|
-
existing.sourceId = node.sourceId;
|
|
2359
|
-
}
|
|
2360
|
-
if (!existing.resourceType && node.resourceType) {
|
|
2361
|
-
existing.resourceType = node.resourceType;
|
|
2362
|
-
}
|
|
2363
|
-
return existing;
|
|
2364
|
-
}
|
|
2365
|
-
resourceNodesById.set(node.id, node);
|
|
2366
|
-
pushUniqueNode(nodes, seen, node);
|
|
2367
|
-
return node;
|
|
2368
|
-
}
|
|
2369
|
-
function ensureResourceNode(nodes, seen, resourceNodesById, resourceId) {
|
|
2370
|
-
const existing = resourceNodesById.get(nodeId("resource", resourceId));
|
|
2371
|
-
if (existing) return existing;
|
|
2372
|
-
return upsertResourceNode(nodes, seen, resourceNodesById, {
|
|
2373
|
-
id: nodeId("resource", resourceId),
|
|
2374
|
-
kind: "resource",
|
|
2375
|
-
label: resourceId,
|
|
2376
|
-
sourceId: resourceId
|
|
2377
|
-
});
|
|
2378
|
-
}
|
|
2379
|
-
function normalizeCommandViewResourceType(resourceType) {
|
|
2380
|
-
return resourceType === "human" ? "human_checkpoint" : resourceType;
|
|
2381
|
-
}
|
|
2382
|
-
function normalizeOrganizationModelResourceType(resourceType) {
|
|
2383
|
-
return resourceType;
|
|
2384
|
-
}
|
|
2385
|
-
function collectCommandViewResources(commandViewData) {
|
|
2386
|
-
return [
|
|
2387
|
-
...commandViewData.workflows,
|
|
2388
|
-
...commandViewData.agents,
|
|
2389
|
-
...commandViewData.triggers,
|
|
2390
|
-
...commandViewData.integrations,
|
|
2391
|
-
...commandViewData.externalResources,
|
|
2392
|
-
...commandViewData.humanCheckpoints
|
|
2393
|
-
];
|
|
2394
|
-
}
|
|
2395
|
-
function invocationSignature(invocation) {
|
|
2396
|
-
switch (invocation.kind) {
|
|
2397
|
-
case "slash-command":
|
|
2398
|
-
return `${invocation.kind}:${invocation.command}`;
|
|
2399
|
-
case "mcp-tool":
|
|
2400
|
-
return `${invocation.kind}:${invocation.server}:${invocation.name}`;
|
|
2401
|
-
case "api-endpoint":
|
|
2402
|
-
return `${invocation.kind}:${invocation.method}:${invocation.path}`;
|
|
2403
|
-
case "script-execution":
|
|
2404
|
-
return `${invocation.kind}:${invocation.resourceId}`;
|
|
2405
|
-
}
|
|
2406
|
-
}
|
|
2407
|
-
function invocationLabel(invocation) {
|
|
2408
|
-
switch (invocation.kind) {
|
|
2409
|
-
case "slash-command":
|
|
2410
|
-
return invocation.command;
|
|
2411
|
-
case "mcp-tool":
|
|
2412
|
-
return `${invocation.server}.${invocation.name}`;
|
|
2413
|
-
case "api-endpoint":
|
|
2414
|
-
return `${invocation.method} ${invocation.path}`;
|
|
2415
|
-
case "script-execution":
|
|
2416
|
-
return `script ${invocation.resourceId}`;
|
|
2417
|
-
}
|
|
2418
|
-
}
|
|
2419
|
-
function eventNodeId(eventId) {
|
|
2420
|
-
return nodeId("event", eventId);
|
|
2421
|
-
}
|
|
2422
|
-
function ontologyLabel(id, label) {
|
|
2423
|
-
return label ?? parseOntologyId(id).localId;
|
|
2424
|
-
}
|
|
2425
|
-
function pushOntologyBindingEdges(edges, edgeIds, resourceNodeId, kind, ids) {
|
|
2426
|
-
ids?.forEach((ontologyId) => {
|
|
2427
|
-
const targetId = ontologyGraphNodeId(ontologyId);
|
|
2428
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2429
|
-
id: edgeId(kind, resourceNodeId, targetId),
|
|
2430
|
-
kind,
|
|
2431
|
-
sourceId: resourceNodeId,
|
|
2432
|
-
targetId
|
|
2433
|
-
});
|
|
2434
|
-
});
|
|
2435
|
-
}
|
|
2436
|
-
function buildResourceEventDescriptor(resourceId, emission) {
|
|
2437
|
-
return {
|
|
2438
|
-
...emission,
|
|
2439
|
-
id: `${resourceId}:${emission.eventKey}`,
|
|
2440
|
-
ownerId: resourceId,
|
|
2441
|
-
ownerKind: "resource"
|
|
2442
|
-
};
|
|
2443
|
-
}
|
|
2444
|
-
function buildEntityEventDescriptor(entity, eventKey, label) {
|
|
2445
|
-
return {
|
|
2446
|
-
id: `${entity.id}:${eventKey}`,
|
|
2447
|
-
ownerId: entity.id,
|
|
2448
|
-
ownerKind: "entity",
|
|
2449
|
-
eventKey,
|
|
2450
|
-
label
|
|
2451
|
-
};
|
|
2452
|
-
}
|
|
2453
|
-
function pushEventProjection(nodes, nodeIds, edges, edgeIds, eventNodeIdsByEventId, event, sourceNodeId, edgeKind) {
|
|
2454
|
-
const id = eventNodeId(event.id);
|
|
2455
|
-
eventNodeIdsByEventId.set(event.id, id);
|
|
2456
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
2457
|
-
id,
|
|
2458
|
-
kind: "event",
|
|
2459
|
-
label: event.label,
|
|
2460
|
-
sourceId: event.id
|
|
2461
|
-
});
|
|
2462
|
-
const sourceId = edgeKind === "originates_from" ? id : sourceNodeId;
|
|
2463
|
-
const targetId = edgeKind === "originates_from" ? sourceNodeId : id;
|
|
2464
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2465
|
-
id: edgeId(edgeKind, sourceId, targetId),
|
|
2466
|
-
kind: edgeKind,
|
|
2467
|
-
sourceId,
|
|
2468
|
-
targetId
|
|
2469
|
-
});
|
|
2470
|
-
}
|
|
2471
|
-
function buildOrganizationGraph(input) {
|
|
2472
|
-
const parsed = BuildOrganizationGraphInputSchema.parse(input);
|
|
2473
|
-
const organizationModel = parsed.organizationModel;
|
|
2474
|
-
const commandViewData = parsed.commandViewData;
|
|
2475
|
-
const nodes = [];
|
|
2476
|
-
const edges = [];
|
|
2477
|
-
const nodeIds = /* @__PURE__ */ new Set();
|
|
2478
|
-
const edgeIds = /* @__PURE__ */ new Set();
|
|
2479
|
-
const resourceNodesById = /* @__PURE__ */ new Map();
|
|
2480
|
-
const organizationModelResourceIds = new Set(Object.keys(organizationModel.resources));
|
|
2481
|
-
const actionIdsByInvocation = /* @__PURE__ */ new Map();
|
|
2482
|
-
const projectedEventNodeIdsByEventId = /* @__PURE__ */ new Map();
|
|
2483
|
-
const ontologyCompilation = compileOrganizationOntology(organizationModel);
|
|
2484
|
-
const organizationNode = {
|
|
2485
|
-
id: nodeId("organization"),
|
|
2486
|
-
kind: "organization",
|
|
2487
|
-
label: "Organization Model"
|
|
2488
|
-
};
|
|
2489
|
-
pushUniqueNode(nodes, nodeIds, organizationNode);
|
|
2490
|
-
const systemsWithPaths = listAllSystems(organizationModel);
|
|
2491
|
-
const systemPathByRef = /* @__PURE__ */ new Map();
|
|
2492
|
-
for (const { path, system } of systemsWithPaths) {
|
|
2493
|
-
systemPathByRef.set(path, path);
|
|
2494
|
-
systemPathByRef.set(system.id, path);
|
|
2495
|
-
}
|
|
2496
|
-
const validSystemRefs = new Set(systemPathByRef.keys());
|
|
2497
|
-
const systemNodeId = (systemRef) => nodeId("system", systemPathByRef.get(systemRef) ?? systemRef);
|
|
2498
|
-
function topologyNodeId(ref) {
|
|
2499
|
-
if (ref.kind === "system") return systemNodeId(ref.id);
|
|
2500
|
-
if (ref.kind === "resource") return nodeId("resource", ref.id);
|
|
2501
|
-
if (ref.kind === "ontology") return ontologyGraphNodeId(ref.id);
|
|
2502
|
-
if (ref.kind === "policy") return nodeId("policy", ref.id);
|
|
2503
|
-
if (ref.kind === "role") return nodeId("role", ref.id);
|
|
2504
|
-
return nodeId("resource", ref.id);
|
|
2505
|
-
}
|
|
2506
|
-
function ensureTopologyNode(ref) {
|
|
2507
|
-
const id = topologyNodeId(ref);
|
|
2508
|
-
if (nodeIds.has(id)) return id;
|
|
2509
|
-
if (ref.kind === "resource") {
|
|
2510
|
-
ensureResourceNode(nodes, nodeIds, resourceNodesById, ref.id);
|
|
2511
|
-
return id;
|
|
2512
|
-
}
|
|
2513
|
-
if (ref.kind === "trigger" || ref.kind === "humanCheckpoint" || ref.kind === "externalResource") {
|
|
2514
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
2515
|
-
id,
|
|
2516
|
-
kind: "resource",
|
|
2517
|
-
label: ref.id,
|
|
2518
|
-
sourceId: ref.id,
|
|
2519
|
-
resourceType: ref.kind === "trigger" ? "trigger" : ref.kind === "humanCheckpoint" ? "human_checkpoint" : "external"
|
|
2520
|
-
});
|
|
2521
|
-
}
|
|
2522
|
-
return id;
|
|
2523
|
-
}
|
|
2524
|
-
for (const { path, system } of systemsWithPaths.sort((a, b) => a.path.localeCompare(b.path))) {
|
|
2525
|
-
const id = nodeId("system", path);
|
|
2526
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
2527
|
-
id,
|
|
2528
|
-
kind: "system",
|
|
2529
|
-
label: system.label ?? system.title ?? system.id,
|
|
2530
|
-
sourceId: path,
|
|
2531
|
-
description: system.description,
|
|
2532
|
-
icon: system.ui?.icon ?? system.icon,
|
|
2533
|
-
enabled: system.enabled
|
|
2534
|
-
});
|
|
2535
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2536
|
-
id: edgeId("contains", organizationNode.id, id),
|
|
2537
|
-
kind: "contains",
|
|
2538
|
-
sourceId: organizationNode.id,
|
|
2539
|
-
targetId: id
|
|
2540
|
-
});
|
|
2541
|
-
const parentSystemId = path.includes(".") ? path.slice(0, path.lastIndexOf(".")) : void 0;
|
|
2542
|
-
if (parentSystemId !== void 0) {
|
|
2543
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2544
|
-
id: edgeId("contains", nodeId("system", parentSystemId), id),
|
|
2545
|
-
kind: "contains",
|
|
2546
|
-
sourceId: nodeId("system", parentSystemId),
|
|
2547
|
-
targetId: id
|
|
2548
|
-
});
|
|
2549
|
-
}
|
|
2550
|
-
}
|
|
2551
|
-
for (const { id: ontologyId, kind, record } of listResolvedOntologyRecords(ontologyCompilation.ontology).sort(
|
|
2552
|
-
(a, b) => a.id.localeCompare(b.id)
|
|
2553
|
-
)) {
|
|
2554
|
-
const id = ontologyGraphNodeId(ontologyId);
|
|
2555
|
-
const parsedId = parseOntologyId(ontologyId);
|
|
2556
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
2557
|
-
id,
|
|
2558
|
-
kind: "ontology",
|
|
2559
|
-
label: ontologyLabel(ontologyId, record.label),
|
|
2560
|
-
sourceId: ontologyId,
|
|
2561
|
-
description: record.description,
|
|
2562
|
-
ontologyKind: kind
|
|
2563
|
-
});
|
|
2564
|
-
const ownerSystemId = record.ownerSystemId ?? (parsedId.isGlobal ? void 0 : parsedId.scope);
|
|
2565
|
-
if (ownerSystemId !== void 0 && validSystemRefs.has(ownerSystemId)) {
|
|
2566
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2567
|
-
id: edgeId("contains", systemNodeId(ownerSystemId), id, `ontology-${kind}`),
|
|
2568
|
-
kind: "contains",
|
|
2569
|
-
sourceId: systemNodeId(ownerSystemId),
|
|
2570
|
-
targetId: id
|
|
2571
|
-
});
|
|
2572
|
-
} else {
|
|
2573
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2574
|
-
id: edgeId("contains", organizationNode.id, id, `ontology-${kind}`),
|
|
2575
|
-
kind: "contains",
|
|
2576
|
-
sourceId: organizationNode.id,
|
|
2577
|
-
targetId: id
|
|
2578
|
-
});
|
|
2579
|
-
}
|
|
2580
|
-
if (kind === "link") {
|
|
2581
|
-
const link = record;
|
|
2582
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2583
|
-
id: edgeId("links", ontologyGraphNodeId(link.from), ontologyGraphNodeId(link.to), ontologyId),
|
|
2584
|
-
kind: "links",
|
|
2585
|
-
sourceId: ontologyGraphNodeId(link.from),
|
|
2586
|
-
targetId: ontologyGraphNodeId(link.to),
|
|
2587
|
-
label: link.label ?? parsedId.localId
|
|
2588
|
-
});
|
|
2589
|
-
}
|
|
2590
|
-
if (kind === "action") {
|
|
2591
|
-
const action = record;
|
|
2592
|
-
for (const targetOntologyId of action.actsOn ?? []) {
|
|
2593
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2594
|
-
id: edgeId("affects", id, ontologyGraphNodeId(targetOntologyId), ontologyId),
|
|
2595
|
-
kind: "affects",
|
|
2596
|
-
sourceId: id,
|
|
2597
|
-
targetId: ontologyGraphNodeId(targetOntologyId)
|
|
2598
|
-
});
|
|
2599
|
-
}
|
|
2600
|
-
}
|
|
2601
|
-
if (kind === "catalog") {
|
|
2602
|
-
const catalog = record;
|
|
2603
|
-
if (catalog.appliesTo === void 0) continue;
|
|
2604
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2605
|
-
id: edgeId("applies_to", id, ontologyGraphNodeId(catalog.appliesTo), ontologyId),
|
|
2606
|
-
kind: "applies_to",
|
|
2607
|
-
sourceId: id,
|
|
2608
|
-
targetId: ontologyGraphNodeId(catalog.appliesTo)
|
|
2609
|
-
});
|
|
2610
|
-
}
|
|
2611
|
-
if (kind === "group") {
|
|
2612
|
-
const group = record;
|
|
2613
|
-
for (const memberOntologyId of group.members ?? []) {
|
|
2614
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2615
|
-
id: edgeId("contains", id, ontologyGraphNodeId(memberOntologyId), ontologyId),
|
|
2616
|
-
kind: "contains",
|
|
2617
|
-
sourceId: id,
|
|
2618
|
-
targetId: ontologyGraphNodeId(memberOntologyId)
|
|
2619
|
-
});
|
|
2620
|
-
}
|
|
2621
|
-
}
|
|
2622
|
-
}
|
|
2623
|
-
for (const role of Object.values(organizationModel.roles).sort((a, b) => a.id.localeCompare(b.id))) {
|
|
2624
|
-
const id = nodeId("role", role.id);
|
|
2625
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
2626
|
-
id,
|
|
2627
|
-
kind: "role",
|
|
2628
|
-
label: role.title,
|
|
2629
|
-
sourceId: role.id,
|
|
2630
|
-
description: role.responsibilities.length > 0 ? role.responsibilities.join("; ") : void 0
|
|
2631
|
-
});
|
|
2632
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2633
|
-
id: edgeId("contains", organizationNode.id, id),
|
|
2634
|
-
kind: "contains",
|
|
2635
|
-
sourceId: organizationNode.id,
|
|
2636
|
-
targetId: id
|
|
2637
|
-
});
|
|
2638
|
-
if (role.reportsToId !== void 0) {
|
|
2639
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2640
|
-
id: edgeId("references", id, nodeId("role", role.reportsToId), "reports-to"),
|
|
2641
|
-
kind: "references",
|
|
2642
|
-
sourceId: id,
|
|
2643
|
-
targetId: nodeId("role", role.reportsToId),
|
|
2644
|
-
label: "reports to"
|
|
2645
|
-
});
|
|
2646
|
-
}
|
|
2647
|
-
for (const systemId of role.responsibleFor ?? []) {
|
|
2648
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2649
|
-
id: edgeId("governs", id, systemNodeId(systemId), "responsible-for"),
|
|
2650
|
-
kind: "governs",
|
|
2651
|
-
sourceId: id,
|
|
2652
|
-
targetId: systemNodeId(systemId),
|
|
2653
|
-
label: "responsible for"
|
|
2654
|
-
});
|
|
2655
|
-
}
|
|
2656
|
-
}
|
|
2657
|
-
for (const node of Object.values(organizationModel.knowledge).sort((a, b) => a.id.localeCompare(b.id))) {
|
|
2658
|
-
const id = nodeId("knowledge", node.id);
|
|
2659
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
2660
|
-
id,
|
|
2661
|
-
kind: "knowledge",
|
|
2662
|
-
label: node.title,
|
|
2663
|
-
sourceId: node.id,
|
|
2664
|
-
description: node.summary,
|
|
2665
|
-
icon: node.icon
|
|
2666
|
-
});
|
|
2667
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2668
|
-
id: edgeId("contains", organizationNode.id, id),
|
|
2669
|
-
kind: "contains",
|
|
2670
|
-
sourceId: organizationNode.id,
|
|
2671
|
-
targetId: id
|
|
2672
|
-
});
|
|
2673
|
-
for (const link of node.links) {
|
|
2674
|
-
const targetId = link.target.kind === "system" ? systemNodeId(link.target.id) : link.target.kind === "ontology" ? ontologyGraphNodeId(link.target.id) : link.nodeId;
|
|
2675
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2676
|
-
id: edgeId("governs", id, targetId),
|
|
2677
|
-
kind: "governs",
|
|
2678
|
-
sourceId: id,
|
|
2679
|
-
targetId
|
|
2680
|
-
});
|
|
2681
|
-
}
|
|
2682
|
-
}
|
|
2683
|
-
const allStages = [
|
|
2684
|
-
...getAllProspectingStages(organizationModel, "company"),
|
|
2685
|
-
...getAllProspectingStages(organizationModel, "contact")
|
|
2686
|
-
].sort((a, b) => a.order - b.order || a.id.localeCompare(b.id));
|
|
2687
|
-
for (const stage of allStages) {
|
|
2688
|
-
const id = nodeId("stage", stage.id);
|
|
2689
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
2690
|
-
id,
|
|
2691
|
-
kind: "stage",
|
|
2692
|
-
label: stage.label,
|
|
2693
|
-
sourceId: stage.id,
|
|
2694
|
-
...stage.description ? { description: stage.description } : {},
|
|
2695
|
-
...stage.icon ? { icon: stage.icon } : {}
|
|
2696
|
-
});
|
|
2697
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2698
|
-
id: edgeId("contains", organizationNode.id, id),
|
|
2699
|
-
kind: "contains",
|
|
2700
|
-
sourceId: organizationNode.id,
|
|
2701
|
-
targetId: id
|
|
2702
|
-
});
|
|
2703
|
-
}
|
|
2704
|
-
for (const action of Object.values(organizationModel.actions).sort((a, b) => a.id.localeCompare(b.id))) {
|
|
2705
|
-
const id = nodeId("action", action.id);
|
|
2706
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
2707
|
-
id,
|
|
2708
|
-
kind: "action",
|
|
2709
|
-
label: action.label,
|
|
2710
|
-
sourceId: action.id,
|
|
2711
|
-
description: action.description
|
|
2712
|
-
});
|
|
2713
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2714
|
-
id: edgeId("contains", organizationNode.id, id),
|
|
2715
|
-
kind: "contains",
|
|
2716
|
-
sourceId: organizationNode.id,
|
|
2717
|
-
targetId: id
|
|
2718
|
-
});
|
|
2719
|
-
if (action.resourceId !== void 0) {
|
|
2720
|
-
const resourceNode = ensureResourceNode(nodes, nodeIds, resourceNodesById, action.resourceId);
|
|
2721
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2722
|
-
id: edgeId("maps_to", id, resourceNode.id),
|
|
2723
|
-
kind: "maps_to",
|
|
2724
|
-
sourceId: id,
|
|
2725
|
-
targetId: resourceNode.id
|
|
2726
|
-
});
|
|
2727
|
-
}
|
|
2728
|
-
for (const entityId of action.affects ?? []) {
|
|
2729
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2730
|
-
id: edgeId("affects", id, nodeId("entity", entityId)),
|
|
2731
|
-
kind: "affects",
|
|
2732
|
-
sourceId: id,
|
|
2733
|
-
targetId: nodeId("entity", entityId)
|
|
2734
|
-
});
|
|
2735
|
-
}
|
|
2736
|
-
for (const invocation of action.invocations) {
|
|
2737
|
-
const key = invocationSignature(invocation);
|
|
2738
|
-
const existing = actionIdsByInvocation.get(key);
|
|
2739
|
-
if (existing) {
|
|
2740
|
-
existing.push(id);
|
|
2741
|
-
} else {
|
|
2742
|
-
actionIdsByInvocation.set(key, [id]);
|
|
2743
|
-
}
|
|
2744
|
-
}
|
|
2745
|
-
}
|
|
2746
|
-
for (const entity of Object.values(organizationModel.entities).sort(
|
|
2747
|
-
(a, b) => a.order - b.order || a.id.localeCompare(b.id)
|
|
2748
|
-
)) {
|
|
2749
|
-
const id = nodeId("entity", entity.id);
|
|
2750
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
2751
|
-
id,
|
|
2752
|
-
kind: "entity",
|
|
2753
|
-
label: entity.label,
|
|
2754
|
-
sourceId: entity.id,
|
|
2755
|
-
description: entity.description
|
|
2756
|
-
});
|
|
2757
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2758
|
-
id: edgeId("contains", systemNodeId(entity.ownedBySystemId), id, "system-entity"),
|
|
2759
|
-
kind: "contains",
|
|
2760
|
-
sourceId: systemNodeId(entity.ownedBySystemId),
|
|
2761
|
-
targetId: id
|
|
2762
|
-
});
|
|
2763
|
-
for (const [linkIndex, link] of (entity.links ?? []).entries()) {
|
|
2764
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2765
|
-
id: edgeId("links", id, nodeId("entity", link.toEntity), `${link.kind}-${linkIndex}`),
|
|
2766
|
-
kind: "links",
|
|
2767
|
-
sourceId: id,
|
|
2768
|
-
targetId: nodeId("entity", link.toEntity),
|
|
2769
|
-
label: link.label ?? link.kind
|
|
2770
|
-
});
|
|
2771
|
-
}
|
|
2772
|
-
if (entity.stateCatalogId !== void 0) {
|
|
2773
|
-
const stateEvents = [];
|
|
2774
|
-
if (entity.stateCatalogId === "crm.pipeline") {
|
|
2775
|
-
for (const { pipeline } of getAllPipelines(organizationModel).filter(({ pipeline: p }) => p.entityId === entity.id).sort((a, b) => a.pipeline.id.localeCompare(b.pipeline.id))) {
|
|
2776
|
-
for (const stage of [...pipeline.stages].sort((a, b) => a.order - b.order || a.id.localeCompare(b.id))) {
|
|
2777
|
-
stateEvents.push(buildEntityEventDescriptor(entity, stage.id, stage.label));
|
|
2778
|
-
}
|
|
2779
|
-
}
|
|
2780
|
-
}
|
|
2781
|
-
if (entity.stateCatalogId === "delivery.task") {
|
|
2782
|
-
for (const status of getAllProjectStatuses(organizationModel, "task").sort(
|
|
2783
|
-
(a, b) => a.order - b.order || a.id.localeCompare(b.id)
|
|
2784
|
-
)) {
|
|
2785
|
-
stateEvents.push(buildEntityEventDescriptor(entity, status.id, status.label));
|
|
2786
|
-
}
|
|
2787
|
-
}
|
|
2788
|
-
if (entity.stateCatalogId === "lead-gen.company" || entity.stateCatalogId === "lead-gen.contact") {
|
|
2789
|
-
const leadGenEntity = entity.stateCatalogId === "lead-gen.company" ? "company" : "contact";
|
|
2790
|
-
for (const stage of Object.values(getLeadGenStageCatalog(organizationModel)).sort(
|
|
2791
|
-
(a, b) => a.order - b.order || a.key.localeCompare(b.key)
|
|
2792
|
-
)) {
|
|
2793
|
-
if (stage.entity !== leadGenEntity && !(stage.additionalEntities ?? []).includes(leadGenEntity)) continue;
|
|
2794
|
-
stateEvents.push(buildEntityEventDescriptor(entity, stage.key, stage.label));
|
|
2795
|
-
}
|
|
2796
|
-
}
|
|
2797
|
-
for (const event of stateEvents) {
|
|
2798
|
-
pushEventProjection(
|
|
2799
|
-
nodes,
|
|
2800
|
-
nodeIds,
|
|
2801
|
-
edges,
|
|
2802
|
-
edgeIds,
|
|
2803
|
-
projectedEventNodeIdsByEventId,
|
|
2804
|
-
event,
|
|
2805
|
-
id,
|
|
2806
|
-
"originates_from"
|
|
2807
|
-
);
|
|
2808
|
-
}
|
|
2809
|
-
}
|
|
2810
|
-
}
|
|
2811
|
-
for (const { path, system } of systemsWithPaths.sort((a, b) => a.path.localeCompare(b.path))) {
|
|
2812
|
-
for (const actionRef of system.actions ?? []) {
|
|
2813
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2814
|
-
id: edgeId("uses", nodeId("system", path), nodeId("action", actionRef.actionId), actionRef.intent),
|
|
2815
|
-
kind: "uses",
|
|
2816
|
-
sourceId: nodeId("system", path),
|
|
2817
|
-
targetId: nodeId("action", actionRef.actionId),
|
|
2818
|
-
label: actionRef.intent
|
|
2819
|
-
});
|
|
2820
|
-
}
|
|
2821
|
-
}
|
|
2822
|
-
const validSystemPaths = /* @__PURE__ */ new Set([...validSystemRefs]);
|
|
2823
|
-
for (const resource of Object.values(organizationModel.resources).sort((a, b) => a.id.localeCompare(b.id))) {
|
|
2824
|
-
const resourceNode = upsertResourceNode(nodes, nodeIds, resourceNodesById, {
|
|
2825
|
-
id: nodeId("resource", resource.id),
|
|
2826
|
-
kind: "resource",
|
|
2827
|
-
label: resource.id,
|
|
2828
|
-
sourceId: resource.id,
|
|
2829
|
-
resourceType: normalizeOrganizationModelResourceType(resource.kind)
|
|
2830
|
-
});
|
|
2831
|
-
if (validSystemPaths.has(resource.systemPath)) {
|
|
2832
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2833
|
-
id: edgeId("contains", systemNodeId(resource.systemPath), resourceNode.id, "system-resource"),
|
|
2834
|
-
kind: "contains",
|
|
2835
|
-
sourceId: systemNodeId(resource.systemPath),
|
|
2836
|
-
targetId: resourceNode.id
|
|
2837
|
-
});
|
|
2838
|
-
}
|
|
2839
|
-
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "actions", resource.ontology?.actions);
|
|
2840
|
-
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "reads", resource.ontology?.reads);
|
|
2841
|
-
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "writes", resource.ontology?.writes);
|
|
2842
|
-
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "uses_catalog", resource.ontology?.usesCatalogs);
|
|
2843
|
-
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "emits", resource.ontology?.emits);
|
|
2844
|
-
if (resource.kind === "workflow" || resource.kind === "agent") {
|
|
2845
|
-
for (const emission of resource.emits ?? []) {
|
|
2846
|
-
pushEventProjection(
|
|
2847
|
-
nodes,
|
|
2848
|
-
nodeIds,
|
|
2849
|
-
edges,
|
|
2850
|
-
edgeIds,
|
|
2851
|
-
projectedEventNodeIdsByEventId,
|
|
2852
|
-
buildResourceEventDescriptor(resource.id, emission),
|
|
2853
|
-
resourceNode.id,
|
|
2854
|
-
"emits"
|
|
2855
|
-
);
|
|
2856
|
-
}
|
|
2857
|
-
}
|
|
2858
|
-
if (resource.kind === "agent") {
|
|
2859
|
-
for (const [index, invocation] of resource.invocations.entries()) {
|
|
2860
|
-
const label = invocationLabel(invocation);
|
|
2861
|
-
if (invocation.kind === "script-execution") {
|
|
2862
|
-
const targetNode = ensureResourceNode(nodes, nodeIds, resourceNodesById, invocation.resourceId);
|
|
2863
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2864
|
-
id: edgeId("uses", resourceNode.id, targetNode.id, `agent-invocation-${index}`),
|
|
2865
|
-
kind: "uses",
|
|
2866
|
-
sourceId: resourceNode.id,
|
|
2867
|
-
targetId: targetNode.id,
|
|
2868
|
-
label
|
|
2869
|
-
});
|
|
2870
|
-
continue;
|
|
2871
|
-
}
|
|
2872
|
-
for (const actionNodeId of actionIdsByInvocation.get(invocationSignature(invocation)) ?? []) {
|
|
2873
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2874
|
-
id: edgeId("references", resourceNode.id, actionNodeId, `agent-invocation-${index}`),
|
|
2875
|
-
kind: "references",
|
|
2876
|
-
sourceId: resourceNode.id,
|
|
2877
|
-
targetId: actionNodeId,
|
|
2878
|
-
label
|
|
2879
|
-
});
|
|
2880
|
-
}
|
|
2881
|
-
}
|
|
2882
|
-
}
|
|
2883
|
-
}
|
|
2884
|
-
for (const policy of Object.values(organizationModel.policies).sort(
|
|
2885
|
-
(a, b) => a.order - b.order || a.id.localeCompare(b.id)
|
|
2886
|
-
)) {
|
|
2887
|
-
const id = nodeId("policy", policy.id);
|
|
2888
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
2889
|
-
id,
|
|
2890
|
-
kind: "policy",
|
|
2891
|
-
label: policy.label,
|
|
2892
|
-
sourceId: policy.id,
|
|
2893
|
-
description: policy.description
|
|
2894
|
-
});
|
|
2895
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2896
|
-
id: edgeId("contains", organizationNode.id, id),
|
|
2897
|
-
kind: "contains",
|
|
2898
|
-
sourceId: organizationNode.id,
|
|
2899
|
-
targetId: id
|
|
2900
|
-
});
|
|
2901
|
-
for (const systemId of policy.appliesTo.systemIds) {
|
|
2902
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2903
|
-
id: edgeId("applies_to", id, systemNodeId(systemId), "system"),
|
|
2904
|
-
kind: "applies_to",
|
|
2905
|
-
sourceId: id,
|
|
2906
|
-
targetId: systemNodeId(systemId)
|
|
2907
|
-
});
|
|
2908
|
-
}
|
|
2909
|
-
for (const actionId of policy.appliesTo.actionIds) {
|
|
2910
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2911
|
-
id: edgeId("applies_to", id, nodeId("action", actionId), "action"),
|
|
2912
|
-
kind: "applies_to",
|
|
2913
|
-
sourceId: id,
|
|
2914
|
-
targetId: nodeId("action", actionId)
|
|
2915
|
-
});
|
|
2916
|
-
}
|
|
2917
|
-
for (const resourceId of policy.appliesTo.resourceIds) {
|
|
2918
|
-
const resourceNode = ensureResourceNode(nodes, nodeIds, resourceNodesById, resourceId);
|
|
2919
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2920
|
-
id: edgeId("applies_to", id, resourceNode.id, "resource"),
|
|
2921
|
-
kind: "applies_to",
|
|
2922
|
-
sourceId: id,
|
|
2923
|
-
targetId: resourceNode.id
|
|
2924
|
-
});
|
|
2925
|
-
}
|
|
2926
|
-
for (const roleId of policy.appliesTo.roleIds) {
|
|
2927
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2928
|
-
id: edgeId("applies_to", id, nodeId("role", roleId), "role"),
|
|
2929
|
-
kind: "applies_to",
|
|
2930
|
-
sourceId: id,
|
|
2931
|
-
targetId: nodeId("role", roleId)
|
|
2932
|
-
});
|
|
2933
|
-
}
|
|
2934
|
-
if (policy.trigger.kind === "event") {
|
|
2935
|
-
const eventNode = projectedEventNodeIdsByEventId.get(policy.trigger.eventId);
|
|
2936
|
-
if (eventNode !== void 0) {
|
|
2937
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2938
|
-
id: edgeId("triggers", eventNode, id),
|
|
2939
|
-
kind: "triggers",
|
|
2940
|
-
sourceId: eventNode,
|
|
2941
|
-
targetId: id
|
|
2942
|
-
});
|
|
2943
|
-
}
|
|
2944
|
-
} else if (policy.trigger.kind === "action-invocation") {
|
|
2945
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2946
|
-
id: edgeId("triggers", nodeId("action", policy.trigger.actionId), id),
|
|
2947
|
-
kind: "triggers",
|
|
2948
|
-
sourceId: nodeId("action", policy.trigger.actionId),
|
|
2949
|
-
targetId: id
|
|
2950
|
-
});
|
|
2951
|
-
}
|
|
2952
|
-
for (const [effectIndex, effect] of policy.actions.entries()) {
|
|
2953
|
-
if (effect.kind === "invoke-action") {
|
|
2954
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2955
|
-
id: edgeId("effects", id, nodeId("action", effect.actionId), `invoke-action-${effectIndex}`),
|
|
2956
|
-
kind: "effects",
|
|
2957
|
-
sourceId: id,
|
|
2958
|
-
targetId: nodeId("action", effect.actionId),
|
|
2959
|
-
label: "invoke action"
|
|
2960
|
-
});
|
|
2961
|
-
}
|
|
2962
|
-
if ((effect.kind === "notify-role" || effect.kind === "require-approval") && effect.roleId !== void 0) {
|
|
2963
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2964
|
-
id: edgeId("effects", id, nodeId("role", effect.roleId), `${effect.kind}-${effectIndex}`),
|
|
2965
|
-
kind: "effects",
|
|
2966
|
-
sourceId: id,
|
|
2967
|
-
targetId: nodeId("role", effect.roleId),
|
|
2968
|
-
label: effect.kind
|
|
2969
|
-
});
|
|
2970
|
-
}
|
|
2971
|
-
}
|
|
2972
|
-
}
|
|
2973
|
-
for (const [relationshipId, relationship] of Object.entries(organizationModel.topology.relationships).sort(
|
|
2974
|
-
([a], [b]) => a.localeCompare(b)
|
|
2975
|
-
)) {
|
|
2976
|
-
const sourceId = ensureTopologyNode(relationship.from);
|
|
2977
|
-
const targetId = ensureTopologyNode(relationship.to);
|
|
2978
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2979
|
-
id: edgeId(relationship.kind, sourceId, targetId, `topology-${relationshipId}`),
|
|
2980
|
-
kind: relationship.kind,
|
|
2981
|
-
sourceId,
|
|
2982
|
-
targetId,
|
|
2983
|
-
relationshipType: relationship.kind
|
|
2984
|
-
});
|
|
2985
|
-
}
|
|
2986
|
-
for (const segment of Object.values(organizationModel.customers).sort(
|
|
2987
|
-
(a, b) => a.order - b.order || a.id.localeCompare(b.id)
|
|
2988
|
-
)) {
|
|
2989
|
-
const id = nodeId("customer-segment", segment.id);
|
|
2990
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
2991
|
-
id,
|
|
2992
|
-
kind: "customer-segment",
|
|
2993
|
-
label: segment.name,
|
|
2994
|
-
sourceId: segment.id,
|
|
2995
|
-
description: segment.description || void 0
|
|
2996
|
-
});
|
|
2997
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
2998
|
-
id: edgeId("contains", organizationNode.id, id),
|
|
2999
|
-
kind: "contains",
|
|
3000
|
-
sourceId: organizationNode.id,
|
|
3001
|
-
targetId: id
|
|
3002
|
-
});
|
|
3003
|
-
}
|
|
3004
|
-
for (const product of Object.values(organizationModel.offerings).sort(
|
|
3005
|
-
(a, b) => a.order - b.order || a.id.localeCompare(b.id)
|
|
3006
|
-
)) {
|
|
3007
|
-
const id = nodeId("offering", product.id);
|
|
3008
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
3009
|
-
id,
|
|
3010
|
-
kind: "offering",
|
|
3011
|
-
label: product.name,
|
|
3012
|
-
sourceId: product.id,
|
|
3013
|
-
description: product.description || void 0
|
|
3014
|
-
});
|
|
3015
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
3016
|
-
id: edgeId("contains", organizationNode.id, id),
|
|
3017
|
-
kind: "contains",
|
|
3018
|
-
sourceId: organizationNode.id,
|
|
3019
|
-
targetId: id
|
|
3020
|
-
});
|
|
3021
|
-
for (const segmentId of product.targetSegmentIds) {
|
|
3022
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
3023
|
-
id: edgeId("applies_to", id, nodeId("customer-segment", segmentId), "targets-segment"),
|
|
3024
|
-
kind: "applies_to",
|
|
3025
|
-
sourceId: id,
|
|
3026
|
-
targetId: nodeId("customer-segment", segmentId),
|
|
3027
|
-
label: "targets"
|
|
3028
|
-
});
|
|
3029
|
-
}
|
|
3030
|
-
}
|
|
3031
|
-
for (const objective of Object.values(organizationModel.goals).sort(
|
|
3032
|
-
(a, b) => a.order - b.order || a.id.localeCompare(b.id)
|
|
3033
|
-
)) {
|
|
3034
|
-
const id = nodeId("goal", objective.id);
|
|
3035
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
3036
|
-
id,
|
|
3037
|
-
kind: "goal",
|
|
3038
|
-
label: objective.description,
|
|
3039
|
-
sourceId: objective.id
|
|
3040
|
-
});
|
|
3041
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
3042
|
-
id: edgeId("contains", organizationNode.id, id),
|
|
3043
|
-
kind: "contains",
|
|
3044
|
-
sourceId: organizationNode.id,
|
|
3045
|
-
targetId: id
|
|
3046
|
-
});
|
|
3047
|
-
}
|
|
3048
|
-
const sidebarGroups = [];
|
|
3049
|
-
const sidebarSurfaces = [];
|
|
3050
|
-
collectSidebarGraphNodes(organizationModel.navigation.sidebar.primary, sidebarGroups, sidebarSurfaces);
|
|
3051
|
-
collectSidebarGraphNodes(organizationModel.navigation.sidebar.bottom, sidebarGroups, sidebarSurfaces);
|
|
3052
|
-
for (const { id: surfaceSourceId, node: surface, parentGroupId } of sidebarSurfaces) {
|
|
3053
|
-
const id = nodeId("surface", surfaceSourceId);
|
|
3054
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
3055
|
-
id,
|
|
3056
|
-
kind: "surface",
|
|
3057
|
-
label: surface.label,
|
|
3058
|
-
sourceId: surfaceSourceId,
|
|
3059
|
-
description: surface.description,
|
|
3060
|
-
icon: surface.icon,
|
|
3061
|
-
enabled: true
|
|
3062
|
-
});
|
|
3063
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
3064
|
-
id: edgeId("contains", parentGroupId ? nodeId("navigation-group", parentGroupId) : organizationNode.id, id),
|
|
3065
|
-
kind: "contains",
|
|
3066
|
-
sourceId: parentGroupId ? nodeId("navigation-group", parentGroupId) : organizationNode.id,
|
|
3067
|
-
targetId: id
|
|
3068
|
-
});
|
|
3069
|
-
for (const systemId of surface.targets?.systems ?? []) {
|
|
3070
|
-
if (!validSystemRefs.has(systemId)) continue;
|
|
3071
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
3072
|
-
id: edgeId("applies_to", id, systemNodeId(systemId), "surface-system"),
|
|
3073
|
-
kind: "applies_to",
|
|
3074
|
-
sourceId: id,
|
|
3075
|
-
targetId: systemNodeId(systemId)
|
|
3076
|
-
});
|
|
3077
|
-
}
|
|
3078
|
-
}
|
|
3079
|
-
for (const { id: groupSourceId, node: group, parentGroupId } of sidebarGroups) {
|
|
3080
|
-
const id = nodeId("navigation-group", groupSourceId);
|
|
3081
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
3082
|
-
id,
|
|
3083
|
-
kind: "navigation-group",
|
|
3084
|
-
label: group.label,
|
|
3085
|
-
sourceId: groupSourceId
|
|
3086
|
-
});
|
|
3087
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
3088
|
-
id: edgeId("contains", parentGroupId ? nodeId("navigation-group", parentGroupId) : organizationNode.id, id),
|
|
3089
|
-
kind: "contains",
|
|
3090
|
-
sourceId: parentGroupId ? nodeId("navigation-group", parentGroupId) : organizationNode.id,
|
|
3091
|
-
targetId: id
|
|
3092
|
-
});
|
|
3093
|
-
}
|
|
3094
|
-
for (const template of getAllBuildTemplates(organizationModel).sort((a, b) => a.id.localeCompare(b.id))) {
|
|
3095
|
-
const steps = template.steps;
|
|
3096
|
-
const stepById = new Map(steps.map((s) => [s.id, s]));
|
|
3097
|
-
for (const step of [...steps].sort((a, b) => a.id.localeCompare(b.id))) {
|
|
3098
|
-
const stageNodeId = nodeId("stage", step.stageKey);
|
|
3099
|
-
const actionNodeId = nodeId("action", step.actionKey);
|
|
3100
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
3101
|
-
id: edgeId("uses", stageNodeId, actionNodeId, step.id),
|
|
3102
|
-
kind: "uses",
|
|
3103
|
-
sourceId: stageNodeId,
|
|
3104
|
-
targetId: actionNodeId
|
|
3105
|
-
});
|
|
3106
|
-
for (const depId of step.dependsOn ?? []) {
|
|
3107
|
-
const depStep = stepById.get(depId);
|
|
3108
|
-
if (depStep) {
|
|
3109
|
-
const depStageNodeId = nodeId("stage", depStep.stageKey);
|
|
3110
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
3111
|
-
id: edgeId("references", stageNodeId, depStageNodeId, step.id),
|
|
3112
|
-
kind: "references",
|
|
3113
|
-
sourceId: stageNodeId,
|
|
3114
|
-
targetId: depStageNodeId
|
|
3115
|
-
});
|
|
3116
|
-
}
|
|
3117
|
-
}
|
|
3118
|
-
}
|
|
3119
|
-
}
|
|
3120
|
-
if (commandViewData) {
|
|
3121
|
-
const commandViewResources = collectCommandViewResources(commandViewData).sort(
|
|
3122
|
-
(a, b) => a.resourceId.localeCompare(b.resourceId)
|
|
3123
|
-
);
|
|
3124
|
-
for (const resource of commandViewResources) {
|
|
3125
|
-
const id = nodeId("resource", resource.resourceId);
|
|
3126
|
-
const resourceNode = upsertResourceNode(nodes, nodeIds, resourceNodesById, {
|
|
3127
|
-
id,
|
|
3128
|
-
kind: "resource",
|
|
3129
|
-
label: resource.name,
|
|
3130
|
-
sourceId: resource.resourceId,
|
|
3131
|
-
description: resource.description,
|
|
3132
|
-
resourceType: normalizeCommandViewResourceType(resource.type)
|
|
3133
|
-
});
|
|
3134
|
-
if (!organizationModelResourceIds.has(resource.resourceId)) {
|
|
3135
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
3136
|
-
id: edgeId("contains", organizationNode.id, resourceNode.id),
|
|
3137
|
-
kind: "contains",
|
|
3138
|
-
sourceId: organizationNode.id,
|
|
3139
|
-
targetId: resourceNode.id
|
|
3140
|
-
});
|
|
3141
|
-
}
|
|
3142
|
-
}
|
|
3143
|
-
for (const relationship of [...commandViewData.edges].sort((a, b) => a.id.localeCompare(b.id))) {
|
|
3144
|
-
const sourceNode = ensureResourceNode(nodes, nodeIds, resourceNodesById, relationship.source);
|
|
3145
|
-
const targetNode = ensureResourceNode(nodes, nodeIds, resourceNodesById, relationship.target);
|
|
3146
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
3147
|
-
id: edgeId("contains", organizationNode.id, sourceNode.id),
|
|
3148
|
-
kind: "contains",
|
|
3149
|
-
sourceId: organizationNode.id,
|
|
3150
|
-
targetId: sourceNode.id
|
|
3151
|
-
});
|
|
3152
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
3153
|
-
id: edgeId("contains", organizationNode.id, targetNode.id),
|
|
3154
|
-
kind: "contains",
|
|
3155
|
-
sourceId: organizationNode.id,
|
|
3156
|
-
targetId: targetNode.id
|
|
3157
|
-
});
|
|
3158
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
3159
|
-
id: edgeId("references", sourceNode.id, targetNode.id, relationship.relationship),
|
|
3160
|
-
kind: "references",
|
|
3161
|
-
sourceId: sourceNode.id,
|
|
3162
|
-
targetId: targetNode.id,
|
|
3163
|
-
label: relationship.relationship,
|
|
3164
|
-
relationshipType: relationship.relationship
|
|
3165
|
-
});
|
|
3166
|
-
}
|
|
3167
|
-
}
|
|
3168
|
-
const graph = {
|
|
3169
|
-
version: 1,
|
|
3170
|
-
organizationModelVersion: organizationModel.version,
|
|
3171
|
-
nodes,
|
|
3172
|
-
edges
|
|
3173
|
-
};
|
|
3174
|
-
return OrganizationGraphSchema.parse(graph);
|
|
3175
|
-
}
|
|
3176
|
-
|
|
3177
|
-
// src/provider/resolvers/RouteResolver.ts
|
|
3178
|
-
function normalizeRoutePath(path) {
|
|
3179
|
-
const trimmedPath = path.trim();
|
|
3180
|
-
if (!trimmedPath || trimmedPath === "/") {
|
|
3181
|
-
return "/";
|
|
3182
|
-
}
|
|
3183
|
-
return trimmedPath.replace(/\/+$/, "") || "/";
|
|
3184
|
-
}
|
|
3185
|
-
function isRouteMatch(currentPath, route) {
|
|
3186
|
-
const normalizedCurrentPath = normalizeRoutePath(currentPath);
|
|
3187
|
-
const normalizedRoute = normalizeRoutePath(route);
|
|
3188
|
-
return normalizedCurrentPath === normalizedRoute || normalizedCurrentPath.startsWith(`${normalizedRoute}/`);
|
|
3189
|
-
}
|
|
3190
|
-
|
|
3191
|
-
// src/provider/resolvers/NavResolver.ts
|
|
3192
|
-
function uniqueIds(ids) {
|
|
3193
|
-
return ids ? [...new Set(ids)] : [];
|
|
3194
|
-
}
|
|
3195
|
-
|
|
3196
|
-
// src/provider/validateManifests.ts
|
|
3197
|
-
function listSystemRefs(systems) {
|
|
3198
|
-
const refs = [];
|
|
3199
|
-
function walk(map, prefix = "") {
|
|
3200
|
-
for (const [key, system] of Object.entries(map)) {
|
|
3201
|
-
const path = prefix ? `${prefix}.${key}` : key;
|
|
3202
|
-
refs.push(path, system.id);
|
|
3203
|
-
const subsystems = system.subsystems;
|
|
3204
|
-
if (subsystems) {
|
|
3205
|
-
walk(subsystems, path);
|
|
3206
|
-
}
|
|
3207
|
-
}
|
|
3208
|
-
}
|
|
3209
|
-
walk(systems);
|
|
3210
|
-
return refs;
|
|
3211
|
-
}
|
|
3212
|
-
function validateManifests(manifests, organizationModel) {
|
|
3213
|
-
if (!organizationModel) {
|
|
3214
|
-
return;
|
|
3215
|
-
}
|
|
3216
|
-
const validSystemIds = /* @__PURE__ */ new Set([
|
|
3217
|
-
...Object.keys(organizationModel.systems ?? {}),
|
|
3218
|
-
...listSystemRefs(organizationModel.systems ?? {})
|
|
3219
|
-
]);
|
|
3220
|
-
const errors = [];
|
|
3221
|
-
for (const manifest of manifests) {
|
|
3222
|
-
const key = manifest.key;
|
|
3223
|
-
const systemId = manifest.systemId;
|
|
3224
|
-
if (!systemId) {
|
|
3225
|
-
continue;
|
|
3226
|
-
}
|
|
3227
|
-
if (!validSystemIds.has(systemId)) {
|
|
3228
|
-
errors.push(
|
|
3229
|
-
`Manifest "${key}": systemId "${systemId}" is not a known system id. Valid values: ${[...validSystemIds].sort().join(", ")}`
|
|
3230
|
-
);
|
|
3231
|
-
}
|
|
3232
|
-
}
|
|
3233
|
-
if (errors.length > 0) {
|
|
3234
|
-
throw new Error(
|
|
3235
|
-
`System manifest validation failed with ${errors.length} error(s):
|
|
3236
|
-
` + errors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")
|
|
3237
|
-
);
|
|
3238
|
-
}
|
|
3239
|
-
}
|
|
3240
|
-
var ElevasisSystemsContext = createContext(null);
|
|
3241
|
-
|
|
3242
|
-
// src/provider/sidebarProjection.ts
|
|
3243
|
-
function isLifecycleEnabled3(system) {
|
|
3244
|
-
if (system.enabled === false) return false;
|
|
3245
|
-
return system.lifecycle !== "deprecated" && system.lifecycle !== "archived";
|
|
3246
|
-
}
|
|
3247
|
-
function isSystemAccessible(systemId, context) {
|
|
3248
|
-
const system = context.shellModel.findById(systemId);
|
|
3249
|
-
if (!system || !isLifecycleEnabled3(system)) return false;
|
|
3250
|
-
if (!context.isSystemEnabled(systemId)) return false;
|
|
3251
|
-
if (context.shellModel.requiresAdminFor(systemId) && !context.isPlatformAdmin) return false;
|
|
3252
|
-
if (context.shellModel.devOnlyFor(systemId) && !context.isDev) return false;
|
|
3253
|
-
return true;
|
|
3254
|
-
}
|
|
3255
|
-
function isSurfaceAccessible(node, context) {
|
|
3256
|
-
if (node.devOnly && !context.isDev) return false;
|
|
3257
|
-
if (node.requiresAdmin && !context.isPlatformAdmin) return false;
|
|
3258
|
-
const systemTargets = node.targets?.systems ?? [];
|
|
3259
|
-
if (systemTargets.length === 0) return true;
|
|
3260
|
-
return systemTargets.some((systemId) => isSystemAccessible(systemId, context));
|
|
3261
|
-
}
|
|
3262
|
-
function iconForNode(node, context) {
|
|
3263
|
-
if (node.type === "surface") {
|
|
3264
|
-
const targetIcon = node.targets?.systems?.map((systemId) => context.shellModel.findById(systemId)?.iconComponent).find(Boolean);
|
|
3265
|
-
if (targetIcon) return targetIcon;
|
|
3266
|
-
}
|
|
3267
|
-
return getSemanticIconComponent(node.icon);
|
|
3268
|
-
}
|
|
3269
|
-
function activeMatchPathsForSurface(node, context) {
|
|
3270
|
-
const targets = node.targets?.systems ?? [];
|
|
3271
|
-
if (targets.length !== 1) return void 0;
|
|
3272
|
-
const paths = context.shellModel.childrenOf(targets[0]).map((child) => child.path).filter((path) => Boolean(path && path !== node.path));
|
|
3273
|
-
return paths.length > 0 ? [...new Set(paths)] : void 0;
|
|
3274
|
-
}
|
|
3275
|
-
function surfaceToLinkItem(node, context, siblings) {
|
|
3276
|
-
if (!isSurfaceAccessible(node, context)) return void 0;
|
|
3277
|
-
const siblingShadows = siblings.some((sibling) => sibling !== node && sibling.path.startsWith(`${node.path}/`));
|
|
3278
|
-
const activeMatchPaths = activeMatchPathsForSurface(node, context);
|
|
3279
|
-
return {
|
|
3280
|
-
label: node.label,
|
|
3281
|
-
link: node.path,
|
|
3282
|
-
...siblingShadows ? { exact: true } : {},
|
|
3283
|
-
...activeMatchPaths ? { activeMatchPaths } : {}
|
|
3284
|
-
};
|
|
3285
|
-
}
|
|
3286
|
-
function projectNode(node, context) {
|
|
3287
|
-
if (node.type === "surface") {
|
|
3288
|
-
if (!isSurfaceAccessible(node, context)) return void 0;
|
|
3289
|
-
return {
|
|
3290
|
-
label: node.label,
|
|
3291
|
-
icon: iconForNode(node, context),
|
|
3292
|
-
link: node.path
|
|
3293
|
-
};
|
|
3294
|
-
}
|
|
3295
|
-
const childEntries = getSortedSidebarEntries(node.children);
|
|
3296
|
-
const childSurfaces = childEntries.map(([, child]) => child).filter((child) => child.type === "surface");
|
|
3297
|
-
const links = childEntries.flatMap(([, child]) => {
|
|
3298
|
-
if (child.type === "surface") {
|
|
3299
|
-
const link = surfaceToLinkItem(child, context, childSurfaces);
|
|
3300
|
-
return link ? [link] : [];
|
|
3301
|
-
}
|
|
3302
|
-
const nestedGroup = projectNode(child, context);
|
|
3303
|
-
return nestedGroup?.link ? [
|
|
3304
|
-
{
|
|
3305
|
-
label: nestedGroup.label,
|
|
3306
|
-
link: nestedGroup.link
|
|
3307
|
-
}
|
|
3308
|
-
] : nestedGroup?.links ?? [];
|
|
3309
|
-
});
|
|
3310
|
-
if (links.length === 0) return void 0;
|
|
3311
|
-
return {
|
|
3312
|
-
label: node.label,
|
|
3313
|
-
icon: iconForNode(node, context),
|
|
3314
|
-
links
|
|
3315
|
-
};
|
|
3316
|
-
}
|
|
3317
|
-
function projectSection(section, context) {
|
|
3318
|
-
const entries = getSortedSidebarEntries(section);
|
|
3319
|
-
return entries.flatMap(([, node]) => {
|
|
3320
|
-
const group = projectNode(node, context);
|
|
3321
|
-
return group ? [group] : [];
|
|
3322
|
-
});
|
|
3323
|
-
}
|
|
3324
|
-
function projectSidebarLinks({
|
|
3325
|
-
shellModel,
|
|
3326
|
-
organizationModel,
|
|
3327
|
-
isSystemEnabled: isSystemEnabled2,
|
|
3328
|
-
isPlatformAdmin = false,
|
|
3329
|
-
isDev = false,
|
|
3330
|
-
section
|
|
3331
|
-
}) {
|
|
3332
|
-
const context = {
|
|
3333
|
-
shellModel,
|
|
3334
|
-
isSystemEnabled: isSystemEnabled2,
|
|
3335
|
-
isPlatformAdmin,
|
|
3336
|
-
isDev
|
|
3337
|
-
};
|
|
3338
|
-
const sidebar = organizationModel?.navigation.sidebar;
|
|
3339
|
-
if (!sidebar) return [];
|
|
3340
|
-
if (section) {
|
|
3341
|
-
return projectSection(sidebar[section], context);
|
|
3342
|
-
}
|
|
3343
|
-
return [...projectSection(sidebar.primary, context), ...projectSection(sidebar.bottom, context)];
|
|
3344
|
-
}
|
|
3345
|
-
|
|
3346
|
-
// src/provider/topbarProjection.ts
|
|
3347
|
-
function isTopbarActionVisible(node, context) {
|
|
3348
|
-
if (node.enabled === false) return false;
|
|
3349
|
-
if (node.devOnly && !context.isDev) return false;
|
|
3350
|
-
if (node.requiresAdmin && !context.isPlatformAdmin) return false;
|
|
3351
|
-
return true;
|
|
3352
|
-
}
|
|
3353
|
-
function resolveTopbarAction(node, index) {
|
|
3354
|
-
return {
|
|
3355
|
-
id: node.id,
|
|
3356
|
-
label: node.label,
|
|
3357
|
-
tooltip: node.tooltip,
|
|
3358
|
-
icon: getSemanticIconComponent(node.icon),
|
|
3359
|
-
order: node.order ?? index
|
|
3360
|
-
};
|
|
3361
|
-
}
|
|
3362
|
-
function projectTopbarActions(topbar, modules, context) {
|
|
3363
|
-
const modulesByKey = new Map(modules.map((m) => [m.key, m]));
|
|
3364
|
-
const entries = Object.values(topbar);
|
|
3365
|
-
const visibleNodes = entries.filter((node) => isTopbarActionVisible(node, context));
|
|
3366
|
-
visibleNodes.sort((a, b) => {
|
|
3367
|
-
const aOrder = a.order ?? Number.MAX_SAFE_INTEGER;
|
|
3368
|
-
const bOrder = b.order ?? Number.MAX_SAFE_INTEGER;
|
|
3369
|
-
if (aOrder !== bOrder) return aOrder - bOrder;
|
|
3370
|
-
return a.id.localeCompare(b.id);
|
|
3371
|
-
});
|
|
3372
|
-
const result = [];
|
|
3373
|
-
for (let i = 0; i < visibleNodes.length; i++) {
|
|
3374
|
-
const node = visibleNodes[i];
|
|
3375
|
-
const module = modulesByKey.get(node.id);
|
|
3376
|
-
if (!module) continue;
|
|
3377
|
-
result.push({
|
|
3378
|
-
node: resolveTopbarAction(node, i),
|
|
3379
|
-
render: module.render
|
|
3380
|
-
});
|
|
3381
|
-
}
|
|
3382
|
-
return result;
|
|
3383
|
-
}
|
|
3384
|
-
function useElevasisSystems() {
|
|
3385
|
-
const context = useContext(ElevasisSystemsContext);
|
|
3386
|
-
if (!context) {
|
|
3387
|
-
throw new Error(
|
|
3388
|
-
"useElevasisSystems must be used within an ElevasisSystemsProvider. Wrap your app (or the relevant subtree) with <ElevasisSystemsProvider>."
|
|
3389
|
-
);
|
|
3390
|
-
}
|
|
3391
|
-
return context;
|
|
3392
|
-
}
|
|
3393
|
-
function useOptionalElevasisSystems() {
|
|
3394
|
-
return useContext(ElevasisSystemsContext);
|
|
3395
|
-
}
|
|
3396
|
-
function defaultSystems(organizationModel) {
|
|
3397
|
-
if (!organizationModel) return [];
|
|
3398
|
-
return listAllSystems(organizationModel).map(({ path, system }) => ({ ...system, id: path }));
|
|
3399
|
-
}
|
|
3400
|
-
function systemPath(system) {
|
|
3401
|
-
return system.ui?.path ?? system.path ?? defaultPathFor(system.id);
|
|
3402
|
-
}
|
|
3403
|
-
function systemLabel(system) {
|
|
3404
|
-
return system.label ?? system.title ?? system.id;
|
|
3405
|
-
}
|
|
3406
|
-
function moduleSystemId(module) {
|
|
3407
|
-
return module.systemId ?? module.key;
|
|
3408
|
-
}
|
|
3409
|
-
function isLifecycleEnabled4(system) {
|
|
3410
|
-
if (system.enabled === false) return false;
|
|
3411
|
-
return system.lifecycle !== "deprecated" && system.lifecycle !== "archived";
|
|
3412
|
-
}
|
|
3413
|
-
function isOrganizationModelSystemEnabled(organizationModel, systemId) {
|
|
3414
|
-
const system = defaultSystems(organizationModel).find((candidate) => candidate.id === systemId);
|
|
3415
|
-
return system ? isLifecycleEnabled4(system) : void 0;
|
|
3416
|
-
}
|
|
3417
|
-
function resolveSystemModules(systems, isSystemEnabled2) {
|
|
3418
|
-
return systems.map((system) => {
|
|
3419
|
-
const systemId = system.systemId;
|
|
3420
|
-
const accessKey = systemId ?? system.key;
|
|
3421
|
-
return {
|
|
3422
|
-
...system,
|
|
3423
|
-
systemId,
|
|
3424
|
-
access: {
|
|
3425
|
-
systemKey: system.key,
|
|
3426
|
-
systemId,
|
|
3427
|
-
enabled: isSystemEnabled2(accessKey)
|
|
3428
|
-
},
|
|
3429
|
-
semantics: {
|
|
3430
|
-
capabilityIds: uniqueIds(system.capabilityIds ?? [])
|
|
3431
|
-
}
|
|
3432
|
-
};
|
|
3433
|
-
});
|
|
3434
|
-
}
|
|
3435
|
-
function buildShellSystems(organizationModel, modules) {
|
|
3436
|
-
const iconBySystemId = new Map(
|
|
3437
|
-
modules.flatMap((module) => module.systemId ? [[moduleSystemId(module), module.icon]] : [])
|
|
3438
|
-
);
|
|
3439
|
-
return defaultSystems(organizationModel).map((system) => ({
|
|
3440
|
-
...system,
|
|
3441
|
-
label: systemLabel(system),
|
|
3442
|
-
path: systemPath(system),
|
|
3443
|
-
iconComponent: iconBySystemId.get(system.id)
|
|
3444
|
-
}));
|
|
3445
|
-
}
|
|
3446
|
-
function createShellModel(systems) {
|
|
3447
|
-
const systemsRecord = Object.fromEntries(systems.map((s) => [s.id, s]));
|
|
3448
|
-
return {
|
|
3449
|
-
systems,
|
|
3450
|
-
findByPath: (path) => findByPath(systemsRecord, normalizeRoutePath(path)),
|
|
3451
|
-
findById: (id) => findById(systemsRecord, id),
|
|
3452
|
-
childrenOf: (id) => childrenOf(systemsRecord, id),
|
|
3453
|
-
ancestorsOf: (id) => ancestorsOf(systemsRecord, id),
|
|
3454
|
-
parentOf: (id) => parentOf(systemsRecord, id),
|
|
3455
|
-
topLevel: () => topLevel(systemsRecord),
|
|
3456
|
-
requiresAdminFor: (id) => requiresAdminFor(systemsRecord, id),
|
|
3457
|
-
devOnlyFor: (id) => devOnlyFor(systemsRecord, id)
|
|
3458
|
-
};
|
|
3459
|
-
}
|
|
3460
|
-
function resolveOrganizationGraphSystem(systems, shellModel) {
|
|
3461
|
-
for (const system of systems) {
|
|
3462
|
-
const graphBridge = system.organizationGraph;
|
|
3463
|
-
if (!graphBridge) continue;
|
|
3464
|
-
const systemId = graphBridge.systemId;
|
|
3465
|
-
if (!systemId) continue;
|
|
3466
|
-
const node = shellModel.findById(systemId);
|
|
3467
|
-
return {
|
|
3468
|
-
available: Boolean(node),
|
|
3469
|
-
systemId,
|
|
3470
|
-
systemPath: node ? systemPath(node) : void 0
|
|
3471
|
-
};
|
|
3472
|
-
}
|
|
3473
|
-
return {
|
|
3474
|
-
available: false
|
|
3475
|
-
};
|
|
3476
|
-
}
|
|
3477
|
-
function findMatchingNode(shellModel, currentPath) {
|
|
3478
|
-
const normalizedPath = normalizeRoutePath(currentPath);
|
|
3479
|
-
const exact = shellModel.findByPath(normalizedPath);
|
|
3480
|
-
if (exact) return exact;
|
|
3481
|
-
return [...shellModel.systems].filter((system) => {
|
|
3482
|
-
const path = normalizeRoutePath(systemPath(system));
|
|
3483
|
-
return path !== "/" && isRouteMatch(normalizedPath, path);
|
|
3484
|
-
}).sort((a, b) => systemPath(b).length - systemPath(a).length)[0];
|
|
3485
|
-
}
|
|
3486
|
-
function ownsNode(module, node) {
|
|
3487
|
-
if (!node || !module.systemId) return false;
|
|
3488
|
-
return node.id === module.systemId || node.id.startsWith(`${module.systemId}.`);
|
|
3489
|
-
}
|
|
3490
|
-
function ownsRoutePrefix(module, normalizedPath) {
|
|
3491
|
-
return (module.routePrefixes ?? []).some((prefix) => isRouteMatch(normalizedPath, normalizeRoutePath(prefix)));
|
|
3492
|
-
}
|
|
3493
|
-
function resolveRoute(systems, shellModel, currentPath, disabledSubsectionPaths) {
|
|
3494
|
-
const node = findMatchingNode(shellModel, currentPath);
|
|
3495
|
-
const normalizedPath = normalizeRoutePath(currentPath);
|
|
3496
|
-
if (disabledSubsectionPaths.some((disabledPath) => isRouteMatch(normalizedPath, disabledPath))) {
|
|
3497
|
-
return {
|
|
3498
|
-
status: "hidden",
|
|
3499
|
-
path: currentPath,
|
|
3500
|
-
node
|
|
3501
|
-
};
|
|
3502
|
-
}
|
|
3503
|
-
const system = systems.find((candidate) => ownsNode(candidate, node)) ?? systems.filter((candidate) => ownsRoutePrefix(candidate, normalizedPath)).sort(
|
|
3504
|
-
(a, b) => Math.max(...(b.routePrefixes ?? []).map((prefix) => prefix.length)) - Math.max(...(a.routePrefixes ?? []).map((prefix) => prefix.length))
|
|
3505
|
-
)[0];
|
|
3506
|
-
if (!system) {
|
|
3507
|
-
return {
|
|
3508
|
-
status: "unmatched",
|
|
3509
|
-
path: currentPath,
|
|
3510
|
-
node
|
|
3511
|
-
};
|
|
3512
|
-
}
|
|
3513
|
-
return {
|
|
3514
|
-
status: "matched",
|
|
3515
|
-
path: currentPath,
|
|
3516
|
-
system,
|
|
3517
|
-
node
|
|
3518
|
-
};
|
|
3519
|
-
}
|
|
3520
|
-
function ElevasisSystemsProvider({
|
|
3521
|
-
systems,
|
|
3522
|
-
topbarActions,
|
|
3523
|
-
organizationModel,
|
|
3524
|
-
timeRange,
|
|
3525
|
-
operationsApiUrl,
|
|
3526
|
-
operationsSSEManager,
|
|
3527
|
-
deliveryApiUrl,
|
|
3528
|
-
deliverySSEManager,
|
|
3529
|
-
disabledSubsectionPaths = [],
|
|
3530
|
-
children
|
|
3531
|
-
}) {
|
|
3532
|
-
const activeSystems = systems ?? [];
|
|
3533
|
-
const resolvedOrganizationModel = useMemo(() => {
|
|
3534
|
-
if (!organizationModel) {
|
|
3535
|
-
return void 0;
|
|
3536
|
-
}
|
|
3537
|
-
return {
|
|
3538
|
-
...organizationModel,
|
|
3539
|
-
knowledge: organizationModel.knowledge ?? {}
|
|
3540
|
-
};
|
|
3541
|
-
}, [organizationModel]);
|
|
3542
|
-
useMemo(() => validateManifests(activeSystems, resolvedOrganizationModel), [activeSystems, resolvedOrganizationModel]);
|
|
3543
|
-
const hasResolvedSystem = useCallback(
|
|
3544
|
-
(key) => {
|
|
3545
|
-
const organizationModelSystemEnabled = isOrganizationModelSystemEnabled(resolvedOrganizationModel, key);
|
|
3546
|
-
return organizationModelSystemEnabled ?? true;
|
|
3547
|
-
},
|
|
3548
|
-
[resolvedOrganizationModel]
|
|
3549
|
-
);
|
|
3550
|
-
const shellSystems = useMemo(
|
|
3551
|
-
() => buildShellSystems(resolvedOrganizationModel, activeSystems),
|
|
3552
|
-
[resolvedOrganizationModel, activeSystems]
|
|
3553
|
-
);
|
|
3554
|
-
const shellModel = useMemo(() => createShellModel(shellSystems), [shellSystems]);
|
|
3555
|
-
const normalizedDisabledSubsectionPaths = useMemo(
|
|
3556
|
-
() => [...new Set(disabledSubsectionPaths.map((path) => normalizeRoutePath(path)))],
|
|
3557
|
-
[disabledSubsectionPaths]
|
|
3558
|
-
);
|
|
3559
|
-
const resolvedSystems = useMemo(
|
|
3560
|
-
() => resolveSystemModules(activeSystems, hasResolvedSystem),
|
|
3561
|
-
[activeSystems, hasResolvedSystem]
|
|
3562
|
-
);
|
|
3563
|
-
const enabledResolvedSystems = useMemo(
|
|
3564
|
-
() => resolvedSystems.filter((system) => system.access.enabled),
|
|
3565
|
-
[resolvedSystems]
|
|
3566
|
-
);
|
|
3567
|
-
const organizationGraph = useMemo(
|
|
3568
|
-
() => resolveOrganizationGraphSystem(enabledResolvedSystems, shellModel),
|
|
3569
|
-
[enabledResolvedSystems, shellModel]
|
|
3570
|
-
);
|
|
3571
|
-
const getResolvedSystem = useCallback(
|
|
3572
|
-
(key) => resolvedSystems.find((system) => system.key === key),
|
|
3573
|
-
[resolvedSystems]
|
|
3574
|
-
);
|
|
3575
|
-
const isSystemEnabled2 = useCallback((key) => hasResolvedSystem(key), [hasResolvedSystem]);
|
|
3576
|
-
const getSidebarLinks = useCallback(
|
|
3577
|
-
(options = {}) => projectSidebarLinks({
|
|
3578
|
-
shellModel,
|
|
3579
|
-
organizationModel: resolvedOrganizationModel,
|
|
3580
|
-
isSystemEnabled: isSystemEnabled2,
|
|
3581
|
-
...options
|
|
3582
|
-
}),
|
|
3583
|
-
[shellModel, resolvedOrganizationModel, isSystemEnabled2]
|
|
3584
|
-
);
|
|
3585
|
-
const activeTopbarActions = topbarActions ?? [];
|
|
3586
|
-
const getTopbarActions = useCallback(
|
|
3587
|
-
(options = {}) => projectTopbarActions(resolvedOrganizationModel?.navigation.topbar ?? {}, activeTopbarActions, {
|
|
3588
|
-
isPlatformAdmin: options.isPlatformAdmin ?? false,
|
|
3589
|
-
isDev: options.isDev ?? false
|
|
3590
|
-
}),
|
|
3591
|
-
[resolvedOrganizationModel, activeTopbarActions]
|
|
3592
|
-
);
|
|
3593
|
-
const resolveRouteByPath = useCallback(
|
|
3594
|
-
(path) => resolveRoute(enabledResolvedSystems, shellModel, path, normalizedDisabledSubsectionPaths),
|
|
3595
|
-
[enabledResolvedSystems, shellModel, normalizedDisabledSubsectionPaths]
|
|
3596
|
-
);
|
|
3597
|
-
const shellRuntime = useMemo(
|
|
3598
|
-
() => ({
|
|
3599
|
-
resolveRoute: resolveRouteByPath
|
|
3600
|
-
}),
|
|
3601
|
-
[resolveRouteByPath]
|
|
3602
|
-
);
|
|
3603
|
-
const value = useMemo(
|
|
3604
|
-
() => ({
|
|
3605
|
-
shellModel,
|
|
3606
|
-
shellRuntime,
|
|
3607
|
-
getSidebarLinks,
|
|
3608
|
-
getTopbarActions,
|
|
3609
|
-
enabledResolvedSystems,
|
|
3610
|
-
resolvedSystems,
|
|
3611
|
-
organizationGraph,
|
|
3612
|
-
organizationModel: resolvedOrganizationModel,
|
|
3613
|
-
timeRange,
|
|
3614
|
-
operationsApiUrl,
|
|
3615
|
-
operationsSSEManager,
|
|
3616
|
-
deliveryApiUrl,
|
|
3617
|
-
deliverySSEManager,
|
|
3618
|
-
disabledSubsectionPaths: normalizedDisabledSubsectionPaths,
|
|
3619
|
-
isSystemEnabled: isSystemEnabled2,
|
|
3620
|
-
getResolvedSystem
|
|
3621
|
-
}),
|
|
3622
|
-
[
|
|
3623
|
-
shellModel,
|
|
3624
|
-
shellRuntime,
|
|
3625
|
-
enabledResolvedSystems,
|
|
3626
|
-
resolvedSystems,
|
|
3627
|
-
organizationGraph,
|
|
3628
|
-
resolvedOrganizationModel,
|
|
3629
|
-
timeRange,
|
|
3630
|
-
operationsApiUrl,
|
|
3631
|
-
operationsSSEManager,
|
|
3632
|
-
deliveryApiUrl,
|
|
3633
|
-
deliverySSEManager,
|
|
3634
|
-
normalizedDisabledSubsectionPaths,
|
|
3635
|
-
isSystemEnabled2,
|
|
3636
|
-
getResolvedSystem,
|
|
3637
|
-
getSidebarLinks,
|
|
3638
|
-
getTopbarActions
|
|
3639
|
-
]
|
|
3640
|
-
);
|
|
3641
|
-
return /* @__PURE__ */ jsx(ElevasisSystemsContext.Provider, { value, children });
|
|
3642
|
-
}
|
|
3643
|
-
|
|
3644
|
-
export { ActionSchema, AgentResourceEntrySchema, DEFAULT_ORGANIZATION_MODEL, DEFAULT_SEMANTIC_ICON_REGISTRY, ElevasisSystemsProvider, EntitySchema, IdentityDomainSchema, IntegrationResourceEntrySchema, OrgKnowledgeNodeSchema, PROJECTS_VIEW_ACTION_ID, PolicySchema, RoleSchema, ScriptResourceEntrySchema, SemanticIcon, SurfaceDefinitionSchema, SystemEntrySchema, WorkflowResourceEntrySchema, buildOrganizationGraph, defineActions, defineEntities, defineResources, defineTopology, extendSemanticIconRegistry, getSemanticIconComponent, getSortedSidebarEntries, projectOrganizationSurfaces, resolveOrganizationModel, resolveSemanticIconComponent, topologyRef, topologyRelationship, useElevasisSystems, useOptionalElevasisSystems };
|