@elevasis/core 0.2.1 → 0.4.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/index.d.ts +63 -103
- package/dist/index.js +431 -111
- package/dist/organization-model/index.d.ts +63 -103
- package/dist/organization-model/index.js +431 -111
- package/package.json +1 -1
- package/src/README.md +1 -1
- package/src/__tests__/template-foundations-compatibility.test.ts +28 -36
- package/src/auth/multi-tenancy/types.ts +4 -11
- package/src/auth/multi-tenancy/users/api-schemas.ts +1 -1
- package/src/business/base-entities.test.ts +481 -0
- package/src/business/base-entities.ts +241 -0
- package/src/business/delivery/types.ts +1 -1
- package/src/business/index.ts +3 -0
- package/src/execution/index.ts +3 -6
- package/src/index.ts +1 -1
- package/src/organization-model/README.md +25 -26
- package/src/organization-model/__tests__/graph.test.ts +103 -71
- package/src/organization-model/__tests__/resolve.test.ts +22 -31
- package/src/organization-model/contracts.ts +3 -0
- package/src/organization-model/defaults.ts +59 -7
- package/src/organization-model/domains/features.ts +19 -54
- package/src/organization-model/domains/navigation.ts +266 -17
- package/src/organization-model/domains/shared.ts +1 -10
- package/src/organization-model/foundation.ts +97 -0
- package/src/organization-model/graph/build.ts +34 -67
- package/src/organization-model/graph/schema.ts +2 -4
- package/src/organization-model/graph/types.ts +3 -15
- package/src/organization-model/index.ts +2 -0
- package/src/organization-model/organization-graph.mdx +37 -28
- package/src/organization-model/organization-model.mdx +34 -36
- package/src/organization-model/published.ts +12 -3
- package/src/organization-model/schema.ts +38 -34
- package/src/organization-model/types.ts +5 -10
- package/src/platform/constants/versions.ts +1 -1
- package/src/platform/sse/events.ts +1 -34
- package/src/projects/api-schemas.ts +2 -1
- package/src/reference/_generated/contracts.md +10 -31
- package/src/reference/glossary.md +14 -18
- package/src/supabase/database.types.ts +0 -107
- package/src/test-utils/rls/RLSTestContext.ts +1 -31
- package/src/execution/calibration/__tests__/schemas.test.ts +0 -320
- package/src/execution/calibration/index.ts +0 -3
- package/src/execution/calibration/schemas.ts +0 -121
- package/src/execution/calibration/sse-events.ts +0 -125
- package/src/execution/calibration/types.ts +0 -190
|
@@ -73,16 +73,6 @@ function ensureResourceNode(
|
|
|
73
73
|
})
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
function titleCase(value: string): string {
|
|
77
|
-
return value
|
|
78
|
-
.replace(/[-_.]+/g, ' ')
|
|
79
|
-
.replace(/\s+/g, ' ')
|
|
80
|
-
.trim()
|
|
81
|
-
.split(' ')
|
|
82
|
-
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
83
|
-
.join(' ')
|
|
84
|
-
}
|
|
85
|
-
|
|
86
76
|
type CommandViewResource =
|
|
87
77
|
| CommandViewData['workflows'][number]
|
|
88
78
|
| CommandViewData['agents'][number]
|
|
@@ -126,38 +116,10 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
126
116
|
}
|
|
127
117
|
pushUniqueNode(nodes, nodeIds, organizationNode)
|
|
128
118
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
key: featureKey,
|
|
134
|
-
enabled,
|
|
135
|
-
label: organizationModel.features.labels[key] ?? titleCase(featureKey)
|
|
136
|
-
}
|
|
137
|
-
})
|
|
138
|
-
.sort((a, b) => a.key.localeCompare(b.key))
|
|
139
|
-
|
|
140
|
-
for (const feature of featureEntries) {
|
|
141
|
-
const id = nodeId('feature', feature.key)
|
|
142
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
143
|
-
id,
|
|
144
|
-
kind: 'feature',
|
|
145
|
-
label: feature.label,
|
|
146
|
-
sourceId: feature.key,
|
|
147
|
-
enabled: feature.enabled,
|
|
148
|
-
featureKey: feature.key as OrganizationGraphNode['featureKey']
|
|
149
|
-
})
|
|
150
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
151
|
-
id: edgeId('contains', organizationNode.id, id),
|
|
152
|
-
kind: 'contains',
|
|
153
|
-
sourceId: organizationNode.id,
|
|
154
|
-
targetId: id
|
|
155
|
-
})
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const domainMap = new Map<string, (typeof organizationModel.domains)[number]>()
|
|
159
|
-
for (const domain of organizationModel.domains) {
|
|
160
|
-
domainMap.set(domain.id, domain)
|
|
119
|
+
// Build feature map for lookups
|
|
120
|
+
const featureMap = new Map<string, (typeof organizationModel.features)[number]>()
|
|
121
|
+
for (const feature of organizationModel.features) {
|
|
122
|
+
featureMap.set(feature.id, feature)
|
|
161
123
|
}
|
|
162
124
|
|
|
163
125
|
const surfaceMap = new Map<string, (typeof organizationModel.navigation.surfaces)[number]>()
|
|
@@ -167,7 +129,9 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
167
129
|
|
|
168
130
|
const entityIds = new Set<string>()
|
|
169
131
|
const capabilityIds = new Set<string>()
|
|
170
|
-
const resourceMappings = [...organizationModel.resourceMappings].sort((a, b) =>
|
|
132
|
+
const resourceMappings = [...organizationModel.resourceMappings].sort((a, b) =>
|
|
133
|
+
a.resourceId.localeCompare(b.resourceId)
|
|
134
|
+
)
|
|
171
135
|
for (const resourceMapping of resourceMappings) {
|
|
172
136
|
for (const entityId of resourceMapping.entityIds) {
|
|
173
137
|
entityIds.add(entityId)
|
|
@@ -177,14 +141,17 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
177
141
|
}
|
|
178
142
|
}
|
|
179
143
|
|
|
180
|
-
|
|
181
|
-
|
|
144
|
+
// Unified feature loop: creates feature nodes with semantic data (replaces old feature + domain loops)
|
|
145
|
+
for (const feature of [...organizationModel.features].sort((a, b) => a.id.localeCompare(b.id))) {
|
|
146
|
+
const id = nodeId('feature', feature.id)
|
|
182
147
|
pushUniqueNode(nodes, nodeIds, {
|
|
183
148
|
id,
|
|
184
|
-
kind: '
|
|
185
|
-
label:
|
|
186
|
-
sourceId:
|
|
187
|
-
description:
|
|
149
|
+
kind: 'feature',
|
|
150
|
+
label: feature.label,
|
|
151
|
+
sourceId: feature.id,
|
|
152
|
+
description: feature.description,
|
|
153
|
+
enabled: feature.enabled,
|
|
154
|
+
featureId: feature.id
|
|
188
155
|
})
|
|
189
156
|
pushUniqueEdge(edges, edgeIds, {
|
|
190
157
|
id: edgeId('contains', organizationNode.id, id),
|
|
@@ -193,13 +160,13 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
193
160
|
targetId: id
|
|
194
161
|
})
|
|
195
162
|
|
|
196
|
-
for (const entityId of
|
|
163
|
+
for (const entityId of feature.entityIds) {
|
|
197
164
|
entityIds.add(entityId)
|
|
198
165
|
}
|
|
199
|
-
for (const capabilityId of
|
|
166
|
+
for (const capabilityId of feature.capabilityIds) {
|
|
200
167
|
capabilityIds.add(capabilityId)
|
|
201
168
|
}
|
|
202
|
-
for (const surfaceId of
|
|
169
|
+
for (const surfaceId of feature.surfaceIds) {
|
|
203
170
|
const surface = surfaceMap.get(surfaceId)
|
|
204
171
|
if (surface) {
|
|
205
172
|
pushUniqueEdge(edges, edgeIds, {
|
|
@@ -229,22 +196,22 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
229
196
|
targetId: id
|
|
230
197
|
})
|
|
231
198
|
|
|
232
|
-
if (surface.
|
|
199
|
+
if (surface.featureId) {
|
|
233
200
|
pushUniqueEdge(edges, edgeIds, {
|
|
234
|
-
id: edgeId('exposes', nodeId('feature', surface.
|
|
201
|
+
id: edgeId('exposes', nodeId('feature', surface.featureId), id),
|
|
235
202
|
kind: 'exposes',
|
|
236
|
-
sourceId: nodeId('feature', surface.
|
|
203
|
+
sourceId: nodeId('feature', surface.featureId),
|
|
237
204
|
targetId: id
|
|
238
205
|
})
|
|
239
206
|
}
|
|
240
207
|
|
|
241
|
-
for (const
|
|
242
|
-
if (
|
|
208
|
+
for (const featureId of surface.featureIds) {
|
|
209
|
+
if (featureMap.has(featureId)) {
|
|
243
210
|
pushUniqueEdge(edges, edgeIds, {
|
|
244
|
-
id: edgeId('references', id, nodeId('
|
|
211
|
+
id: edgeId('references', id, nodeId('feature', featureId)),
|
|
245
212
|
kind: 'references',
|
|
246
213
|
sourceId: id,
|
|
247
|
-
targetId: nodeId('
|
|
214
|
+
targetId: nodeId('feature', featureId)
|
|
248
215
|
})
|
|
249
216
|
}
|
|
250
217
|
}
|
|
@@ -317,13 +284,13 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
317
284
|
targetId: id
|
|
318
285
|
})
|
|
319
286
|
|
|
320
|
-
for (const
|
|
321
|
-
if (
|
|
287
|
+
for (const featureId of resourceMapping.featureIds) {
|
|
288
|
+
if (featureMap.has(featureId)) {
|
|
322
289
|
pushUniqueEdge(edges, edgeIds, {
|
|
323
|
-
id: edgeId('maps_to', id, nodeId('
|
|
290
|
+
id: edgeId('maps_to', id, nodeId('feature', featureId)),
|
|
324
291
|
kind: 'maps_to',
|
|
325
292
|
sourceId: id,
|
|
326
|
-
targetId: nodeId('
|
|
293
|
+
targetId: nodeId('feature', featureId)
|
|
327
294
|
})
|
|
328
295
|
}
|
|
329
296
|
}
|
|
@@ -374,13 +341,13 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
|
|
|
374
341
|
resourceType: normalizeCommandViewResourceType(resource.type)
|
|
375
342
|
})
|
|
376
343
|
|
|
377
|
-
for (const
|
|
378
|
-
if (
|
|
344
|
+
for (const featureId of resource.domains ?? []) {
|
|
345
|
+
if (featureMap.has(featureId)) {
|
|
379
346
|
pushUniqueEdge(edges, edgeIds, {
|
|
380
|
-
id: edgeId('references', resourceNode.id, nodeId('
|
|
347
|
+
id: edgeId('references', resourceNode.id, nodeId('feature', featureId), 'feature'),
|
|
381
348
|
kind: 'references',
|
|
382
349
|
sourceId: resourceNode.id,
|
|
383
|
-
targetId: nodeId('
|
|
350
|
+
targetId: nodeId('feature', featureId)
|
|
384
351
|
})
|
|
385
352
|
}
|
|
386
353
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
|
-
import { DescriptionSchema, LabelSchema } from '../domains/shared'
|
|
3
|
-
import { FeatureKeySchema } from '../domains/features'
|
|
2
|
+
import { DescriptionSchema, LabelSchema, ModelIdSchema } from '../domains/shared'
|
|
4
3
|
import { SurfaceTypeSchema } from '../domains/navigation'
|
|
5
4
|
import { OrganizationModelSchema } from '../schema'
|
|
6
5
|
|
|
7
6
|
export const OrganizationGraphNodeKindSchema = z.enum([
|
|
8
7
|
'organization',
|
|
9
8
|
'feature',
|
|
10
|
-
'domain',
|
|
11
9
|
'surface',
|
|
12
10
|
'entity',
|
|
13
11
|
'capability',
|
|
@@ -23,7 +21,7 @@ export const OrganizationGraphNodeSchema = z.object({
|
|
|
23
21
|
sourceId: z.string().trim().min(1).max(255).optional(),
|
|
24
22
|
description: DescriptionSchema.optional(),
|
|
25
23
|
enabled: z.boolean().optional(),
|
|
26
|
-
|
|
24
|
+
featureId: ModelIdSchema.optional(),
|
|
27
25
|
surfaceType: SurfaceTypeSchema.optional(),
|
|
28
26
|
resourceType: z.enum(['workflow', 'agent', 'trigger', 'integration', 'external', 'human_checkpoint']).optional()
|
|
29
27
|
})
|
|
@@ -1,20 +1,8 @@
|
|
|
1
1
|
import type { CommandViewData } from '../../platform/registry/command-view'
|
|
2
|
-
import type {
|
|
3
|
-
OrganizationModel,
|
|
4
|
-
OrganizationModelFeatureKey,
|
|
5
|
-
OrganizationModelResourceMapping,
|
|
6
|
-
OrganizationModelSurface
|
|
7
|
-
} from '../types'
|
|
2
|
+
import type { OrganizationModel, OrganizationModelResourceMapping, OrganizationModelSurface } from '../types'
|
|
8
3
|
import type { RelationshipType } from '../../platform/registry/command-view'
|
|
9
4
|
|
|
10
|
-
export type OrganizationGraphNodeKind =
|
|
11
|
-
| 'organization'
|
|
12
|
-
| 'feature'
|
|
13
|
-
| 'domain'
|
|
14
|
-
| 'surface'
|
|
15
|
-
| 'entity'
|
|
16
|
-
| 'capability'
|
|
17
|
-
| 'resource'
|
|
5
|
+
export type OrganizationGraphNodeKind = 'organization' | 'feature' | 'surface' | 'entity' | 'capability' | 'resource'
|
|
18
6
|
|
|
19
7
|
export type OrganizationGraphEdgeKind = 'contains' | 'references' | 'exposes' | 'maps_to'
|
|
20
8
|
|
|
@@ -25,7 +13,7 @@ export interface OrganizationGraphNode {
|
|
|
25
13
|
sourceId?: string
|
|
26
14
|
description?: string
|
|
27
15
|
enabled?: boolean
|
|
28
|
-
|
|
16
|
+
featureId?: string
|
|
29
17
|
surfaceType?: OrganizationModelSurface['surfaceType']
|
|
30
18
|
resourceType?: OrganizationModelResourceMapping['resourceType']
|
|
31
19
|
}
|
|
@@ -5,7 +5,7 @@ description: Organization OS Graph layer documentation for the Cytoscape-based o
|
|
|
5
5
|
|
|
6
6
|
## Overview
|
|
7
7
|
|
|
8
|
-
Within Organization OS, the organization graph is the dedicated **Graph** layer. It treats the organization model as the top-level ontology and bridges in Command View runtime topology so one graph can support semantic exploration and operations-oriented tracing.
|
|
8
|
+
Within Organization OS, the organization graph is the dedicated **Graph** layer. It treats the organization model as the top-level ontology and bridges in Command View runtime topology so one graph can support semantic exploration and operations-oriented tracing. Command View is now one lens over this shared graph, not a separate live graph renderer.
|
|
9
9
|
|
|
10
10
|
Graph contracts live in `@repo/core` alongside the organization model. Rendering lives in `@repo/ui` with Cytoscape.js. The command-center route is a thin wrapper over the shared page.
|
|
11
11
|
|
|
@@ -32,7 +32,7 @@ Graph types are intentionally **not** part of the published `@elevasis/core` sur
|
|
|
32
32
|
The graph helps users:
|
|
33
33
|
|
|
34
34
|
- orient themselves in the organization model
|
|
35
|
-
- discover how
|
|
35
|
+
- discover how features, capabilities, surfaces, entities, resources, and workflows connect
|
|
36
36
|
- trace upstream/downstream dependencies
|
|
37
37
|
- understand ownership and implementation boundaries
|
|
38
38
|
- assess blast radius before changing a workflow, agent, feature, or integration
|
|
@@ -46,21 +46,22 @@ The graph does not replace workflow editors, execution-run visualizers, or build
|
|
|
46
46
|
|
|
47
47
|
The implementation uses one typed graph, not separate semantic and implementation taxonomies.
|
|
48
48
|
|
|
49
|
-
- Node kinds: `organization`, `feature`, `
|
|
49
|
+
- Node kinds: `organization`, `feature`, `surface`, `entity`, `capability`, `resource`
|
|
50
50
|
- Edge kinds: `contains`, `references`, `exposes`, `maps_to`
|
|
51
51
|
- `resource` nodes carry `resourceType` metadata: `workflow`, `agent`, `trigger`, `integration`, `external`, or `human_checkpoint`
|
|
52
52
|
- `references` edges may also carry `relationshipType`: `triggers`, `uses`, or `approval`
|
|
53
53
|
|
|
54
|
-
This means runtime topology is represented as bridged `resource` nodes plus relationship metadata on shared edge types, rather than as a second disconnected edge/node vocabulary.
|
|
54
|
+
This means runtime topology is represented as bridged `resource` nodes plus relationship metadata on shared edge types, rather than as a second disconnected edge/node vocabulary. `maps_to` is the main crossover edge: the builder emits it from organization-model resource mappings, and the UI presence helpers also treat it as topology-facing when classifying which non-resource nodes participate in runtime-adjacent views.
|
|
55
55
|
|
|
56
56
|
### Compatibility rules with the organization model
|
|
57
57
|
|
|
58
58
|
- `OrganizationModelSchema` is the source of truth for semantic structure. The graph does not introduce a second ontology.
|
|
59
59
|
- Graph node IDs and references reuse organization-model IDs wherever those IDs already exist.
|
|
60
|
-
- `domain` nodes derive from `organizationModel.domains`.
|
|
61
60
|
- `surface` nodes derive from `organizationModel.navigation.surfaces`; graph routing respects surface `path` and `defaultSurfaceId`.
|
|
62
61
|
- Feature gating and labels respect `organizationModel.features.enabled` and `.labels`.
|
|
63
62
|
- Implementation-resource bridging prefers `organizationModel.resourceMappings`.
|
|
63
|
+
- Semantic grouping now comes from the unified `organizationModel.features` array. The builder no longer emits separate `domain` nodes.
|
|
64
|
+
- Command View resource `domains` metadata is currently bridged onto `feature` references, not onto a distinct domain-node layer.
|
|
64
65
|
- Graph defaults remain valid when produced by `resolveOrganizationModel()`.
|
|
65
66
|
- If the graph needs a concept the model cannot express, extend the model first.
|
|
66
67
|
|
|
@@ -70,7 +71,6 @@ This means runtime topology is represented as bridged `resource` nodes plus rela
|
|
|
70
71
|
type OrganizationGraphNodeKind =
|
|
71
72
|
| 'organization'
|
|
72
73
|
| 'feature'
|
|
73
|
-
| 'domain'
|
|
74
74
|
| 'surface'
|
|
75
75
|
| 'entity'
|
|
76
76
|
| 'capability'
|
|
@@ -86,7 +86,7 @@ interface OrganizationGraph {
|
|
|
86
86
|
}
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
`OrganizationGraphNode` also includes optional `sourceId`, `description`, `enabled`, `
|
|
89
|
+
`OrganizationGraphNode` also includes optional `sourceId`, `description`, `enabled`, `featureId`, `surfaceType`, and `resourceType`. `OrganizationGraphEdge` includes optional `label` and `relationshipType`.
|
|
90
90
|
|
|
91
91
|
### Build pipeline
|
|
92
92
|
|
|
@@ -100,9 +100,9 @@ interface BuildOrganizationGraphInput {
|
|
|
100
100
|
`buildOrganizationGraph` accepts optional topology input so the semantic graph still renders when operational bridging is sparse. The derivation flow is additive and upsert-oriented:
|
|
101
101
|
|
|
102
102
|
1. Resolve the active organization model.
|
|
103
|
-
2. Derive semantic nodes and edges from
|
|
103
|
+
2. Derive semantic nodes and edges from features, surfaces, entities, capabilities, and resource mappings.
|
|
104
104
|
3. Upsert bridged runtime resources from Command View data into shared `resource` nodes.
|
|
105
|
-
4.
|
|
105
|
+
4. Bridge Command View runtime topology onto the same DTO as `references` edges between `resource` nodes, using `relationshipType` for runtime relationship labels.
|
|
106
106
|
5. Hand the resulting graph to UI-level lensing, filtering, and Cytoscape projection.
|
|
107
107
|
|
|
108
108
|
Keeping assembly outside the renderer keeps graph semantics testable without UI and prevents Cytoscape concepts from leaking into business logic.
|
|
@@ -110,7 +110,7 @@ Keeping assembly outside the renderer keeps graph semantics testable without UI
|
|
|
110
110
|
### Ownership split
|
|
111
111
|
|
|
112
112
|
- `@repo/core` owns normalized node/edge types, schemas, and build/derivation helpers.
|
|
113
|
-
- `@repo/ui` owns Cytoscape element conversion, layout presets, selection
|
|
113
|
+
- `@repo/ui` owns Cytoscape element conversion, layout presets, selection state, path tracing, viewport mechanics, detail panels, and presentation helpers.
|
|
114
114
|
- `apps/command-center` owns route wiring and page-level integration.
|
|
115
115
|
|
|
116
116
|
## Interaction Model
|
|
@@ -124,6 +124,8 @@ The graph ships with two lens presets in UI code:
|
|
|
124
124
|
|
|
125
125
|
Lenses do not change the core DTO. They configure how the shared graph is initially presented.
|
|
126
126
|
|
|
127
|
+
The command-view preset is intentionally narrow. It starts from topology-focused `resource` nodes so runtime traces stay readable, even though the underlying graph still contains semantic nodes and bridge edges.
|
|
128
|
+
|
|
127
129
|
### Modes
|
|
128
130
|
|
|
129
131
|
- **Map mode** -- clustered for broad graph orientation
|
|
@@ -138,18 +140,13 @@ Layouts are deterministic presets, not unconstrained force simulation:
|
|
|
138
140
|
|
|
139
141
|
### Interactions
|
|
140
142
|
|
|
141
|
-
Primary set
|
|
143
|
+
Primary set in the current shared page:
|
|
142
144
|
|
|
143
145
|
- click node for detail panel
|
|
144
146
|
- click edge for relationship meaning
|
|
145
|
-
- hover for adjacency preview
|
|
146
|
-
- search and jump to node
|
|
147
|
-
- expand immediate neighbors
|
|
148
|
-
- isolate selected node + N-hop neighborhood
|
|
149
147
|
- switch mode
|
|
150
|
-
-
|
|
151
|
-
-
|
|
152
|
-
- filter by node kind, domain, capability, feature, status, environment
|
|
148
|
+
- highlight shortest directed paths between two visible nodes in trace mode
|
|
149
|
+
- filter by node kind, topology presence, and free-text search
|
|
153
150
|
|
|
154
151
|
Deferred: freeform node placement, collaborative annotations, graph editing/authoring, arbitrary canvas drawing.
|
|
155
152
|
|
|
@@ -163,13 +160,15 @@ Filter inputs:
|
|
|
163
160
|
- `nodeKinds`
|
|
164
161
|
- `topologyPresence: 'all' | 'semantic-only' | 'topology-only'`
|
|
165
162
|
|
|
166
|
-
Presence is derived per node:
|
|
163
|
+
Presence is derived per node in UI helpers:
|
|
167
164
|
|
|
168
165
|
- `resource` nodes are `topology-only`
|
|
169
|
-
- nodes with only semantic edges are `semantic-only`
|
|
170
|
-
- nodes with
|
|
166
|
+
- non-resource nodes with only semantic edges are `semantic-only`
|
|
167
|
+
- non-resource nodes with `maps_to` edges or runtime relationship edges alongside semantic edges are treated as `bridge` nodes internally
|
|
168
|
+
|
|
169
|
+
`bridge` is an internal classification used by the filtering helpers. The public filter control only exposes `all`, `semantic-only`, and `topology-only`, so bridge nodes appear when presence is `all`.
|
|
171
170
|
|
|
172
|
-
Search matches node IDs, labels, descriptions, source IDs, feature
|
|
171
|
+
Search matches node IDs, labels, descriptions, source IDs, feature IDs, surface/resource types, edge labels, edge kinds, and `relationshipType`.
|
|
173
172
|
|
|
174
173
|
The page applies `useDeferredValue()` to the active filters so graph search stays responsive while typing.
|
|
175
174
|
|
|
@@ -188,19 +187,28 @@ The graph is exposed through `ElevasisFeaturesProvider` rather than as app-local
|
|
|
188
187
|
- The provider resolves that against `organizationModel.navigation.surfaces` and exposes the result as `organizationGraph` in context.
|
|
189
188
|
- Shared UI/operations code stays manifest-driven while remaining aware of semantic organization topology.
|
|
190
189
|
|
|
190
|
+
This provider bridge resolves the canonical shared graph surface, not a Command View-specific surface. Command View still has its own navigation surface (`operations.command-view`), but the live page delegates into the shared graph renderer.
|
|
191
|
+
|
|
191
192
|
## Command View Integration
|
|
192
193
|
|
|
193
|
-
`CommandViewPage` now delegates to `OrganizationGraphPage` through a command-view lens preset. The
|
|
194
|
+
`CommandViewPage` now delegates to `OrganizationGraphPage` through a command-view lens preset. The shared page adds command-view operational context through:
|
|
194
195
|
|
|
195
|
-
-
|
|
196
|
+
- command-view summary cards rendered in `OrganizationGraphPage`
|
|
196
197
|
- selection-aware resource and human-checkpoint summaries inside the shared graph detail panel
|
|
197
198
|
- follow-up actions for recent executions and pending tasks inside the detail panel
|
|
198
|
-
- dedicated command-view sidebar content
|
|
199
|
+
- dedicated command-view sidebar content alongside the shared graph controls
|
|
199
200
|
|
|
200
201
|
Operational summary and drill-down derivation is covered by tests under `packages/ui/src/features/operations/organization-graph/__tests__/`.
|
|
201
202
|
|
|
202
203
|
The detail experience is shared through `OrganizationGraphDetailPanel`, which can render both semantic context and command-view-specific follow-up sections.
|
|
203
204
|
|
|
205
|
+
Keep the current seam explicit:
|
|
206
|
+
|
|
207
|
+
- The graph canvas, selection model, path tracing, shared filters, and detail panel all live in `OrganizationGraphPage`.
|
|
208
|
+
- `OperationsSidebarMiddle` still renders `CommandViewSidebarContent` for `/operations/command-view`.
|
|
209
|
+
- That sidebar remains a companion operational panel with some legacy store/filter assumptions and is not the source of truth for the shared graph's filter state.
|
|
210
|
+
- Older React Flow Command View code still exists in the repo, but it is no longer the live renderer for the current Command View route.
|
|
211
|
+
|
|
204
212
|
## Cytoscape Responsibility Split
|
|
205
213
|
|
|
206
214
|
Cytoscape owns:
|
|
@@ -217,16 +225,17 @@ React owns:
|
|
|
217
225
|
|
|
218
226
|
- mode switching
|
|
219
227
|
- side panels and inspectors
|
|
220
|
-
- search and
|
|
228
|
+
- filter toolbar search and trace controls
|
|
221
229
|
- route state and deep-linking
|
|
222
230
|
- server data fetching
|
|
223
|
-
- persistence of saved filters and views
|
|
224
231
|
|
|
225
232
|
## Package Boundary
|
|
226
233
|
|
|
227
234
|
- `packages/ui/package.json` declares Cytoscape on the published UI surface.
|
|
228
235
|
- `packages/ui/tsup.config.ts` and `packages/ui/rollup.dts.config.mjs` keep Cytoscape **externalized** for publish output.
|
|
229
|
-
- Graph DTO types
|
|
236
|
+
- Graph DTO types, schemas, and builders live in monorepo `@repo/core` organization-model modules.
|
|
237
|
+
- Cytoscape rendering, lens presets, filtering helpers, and detail/runtime presentation live in `@repo/ui`.
|
|
238
|
+
- The published `@elevasis/core` wrapper still exposes only the narrow organization-model API; this graph contract should be treated as monorepo-internal for now.
|
|
230
239
|
|
|
231
240
|
## Theming
|
|
232
241
|
|
|
@@ -21,7 +21,7 @@ The model does **not** replace the shared feature-provider system. It enriches a
|
|
|
21
21
|
- `packages/core/src/organization-model/types.ts` -- exported TypeScript types
|
|
22
22
|
- `packages/core/src/organization-model/defaults.ts` -- `DEFAULT_ORGANIZATION_MODEL`
|
|
23
23
|
- `packages/core/src/organization-model/resolve.ts` -- `defineOrganizationModel`, `resolveOrganizationModel`
|
|
24
|
-
- `packages/core/src/organization-model/domains/*.ts` -- feature
|
|
24
|
+
- `packages/core/src/organization-model/domains/*.ts` -- feature schema, navigation surfaces, CRM/lead-gen/delivery semantics
|
|
25
25
|
- `packages/core/src/published.ts` -- curated root barrel for the published package
|
|
26
26
|
- `packages/core/src/organization-model/published.ts` -- curated organization-model barrel
|
|
27
27
|
- `packages/core/src/__tests__/template-foundations-compatibility.test.ts` -- adapter-baseline guard
|
|
@@ -31,9 +31,8 @@ The model does **not** replace the shared feature-provider system. It enriches a
|
|
|
31
31
|
Top-level fields on `OrganizationModel`:
|
|
32
32
|
|
|
33
33
|
- `version`
|
|
34
|
-
- `
|
|
34
|
+
- `features` -- unified feature array (`OrganizationModelFeature[]`); each entry combines access gating, semantic grouping, and display metadata
|
|
35
35
|
- `branding`
|
|
36
|
-
- `features` -- `enabled` map and `labels` overrides
|
|
37
36
|
- `navigation` -- surfaces, groups, `defaultSurfaceId`
|
|
38
37
|
- `crm` -- pipeline stages and stage semantics
|
|
39
38
|
- `leadGen` -- company/contact lifecycle stages
|
|
@@ -61,24 +60,21 @@ All `id` fields, `parentId`, `defaultSurfaceId`, and reference ID arrays use `Mo
|
|
|
61
60
|
|
|
62
61
|
This applies to domain IDs, surface IDs, navigation group IDs, and resource mapping IDs.
|
|
63
62
|
|
|
64
|
-
### Default
|
|
63
|
+
### Default Features
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
type OrganizationModelFeatureKey =
|
|
68
|
-
| 'acquisition'
|
|
69
|
-
| 'delivery'
|
|
70
|
-
| 'operations'
|
|
71
|
-
| 'monitoring'
|
|
72
|
-
| 'settings'
|
|
73
|
-
| 'seo'
|
|
74
|
-
| 'calibration'
|
|
75
|
-
```
|
|
65
|
+
Seven features ship by default in `DEFAULT_ORGANIZATION_MODEL.features`:
|
|
76
66
|
|
|
77
|
-
|
|
67
|
+
- `crm` -- enabled; CRM pipeline and deal management
|
|
68
|
+
- `lead-gen` -- enabled; prospecting, qualification, and outreach
|
|
69
|
+
- `projects` -- enabled; projects, milestones, and client work execution (formerly `delivery`)
|
|
70
|
+
- `operations` -- enabled; organizational topology and orchestration visibility
|
|
71
|
+
- `monitoring` -- enabled; execution monitoring
|
|
72
|
+
- `settings` -- enabled; organization settings
|
|
73
|
+
- `seo` -- disabled by default; SEO surface
|
|
78
74
|
|
|
79
|
-
|
|
75
|
+
Each feature entry (`OrganizationModelFeature`) combines what were previously three separate concepts: an access/gating key (the former `OrganizationModelFeatureKey`), a semantic domain (the former `SemanticDomainSchema` entry), and display metadata. The `features` field is now `z.array(FeatureSchema)` -- there is no separate `domains` array and no separate `enabled`/`labels` map.
|
|
80
76
|
|
|
81
|
-
|
|
77
|
+
`FeatureModule.featureId` on the UI side maps directly to one of these IDs. No alias layer is needed. See [Feature Shell](../ui/feature-shell.mdx) for how the provider resolves feature access from this array.
|
|
82
78
|
|
|
83
79
|
### ResourceMapping Shape
|
|
84
80
|
|
|
@@ -88,7 +84,7 @@ Four domains ship by default -- `crm`, `lead-gen`, `delivery`, `operations`. Eac
|
|
|
88
84
|
- `resourceId` -- the actual resource identifier (string, max 255 chars)
|
|
89
85
|
- `resourceType` -- one of `'workflow' | 'agent' | 'trigger' | 'integration' | 'external' | 'human_checkpoint'`
|
|
90
86
|
- `label`, `description`, `color`, `icon` -- display metadata (from `DisplayMetadataSchema`)
|
|
91
|
-
- `
|
|
87
|
+
- `featureIds` -- features this resource belongs to (replaces the former `domainIds`)
|
|
92
88
|
- `entityIds` -- entities this resource operates on
|
|
93
89
|
- `surfaceIds` -- surfaces this resource is exposed in
|
|
94
90
|
- `capabilityIds` -- capabilities this resource fulfills
|
|
@@ -109,9 +105,9 @@ Surfaces such as `crm.pipeline`, `lead-gen.lists`, `projects.index`, `operations
|
|
|
109
105
|
- `surfaceType` -- `'page' | 'dashboard' | 'graph' | 'detail' | 'list' | 'settings'`
|
|
110
106
|
- `description` -- optional
|
|
111
107
|
- `icon` -- optional icon name token (max 80 chars)
|
|
112
|
-
- `
|
|
108
|
+
- `featureId` -- optional feature ID that gates this surface (replaces the former `featureKey` field); must match a feature `id` in the features array
|
|
113
109
|
- `parentId` -- optional ModelId referencing a parent surface; validated to exist
|
|
114
|
-
- `
|
|
110
|
+
- `featureIds` -- features this surface belongs to (bidirectionally validated; replaces the former `domainIds`)
|
|
115
111
|
- `entityIds` -- entity IDs relevant to this surface
|
|
116
112
|
- `resourceIds` -- resources exposed on this surface (bidirectionally validated against resource mappings)
|
|
117
113
|
- `capabilityIds` -- capabilities this surface fulfills
|
|
@@ -126,11 +122,13 @@ Surfaces such as `crm.pipeline`, `lead-gen.lists`, `projects.index`, `operations
|
|
|
126
122
|
|
|
127
123
|
The default groups (`primary-workspace`, `primary-operations`) both use `placement: 'primary'`.
|
|
128
124
|
|
|
129
|
-
###
|
|
125
|
+
### Feature-Specific Semantics
|
|
130
126
|
|
|
131
|
-
-
|
|
132
|
-
|
|
133
|
-
-
|
|
127
|
+
The top-level `crm`, `leadGen`, and `delivery` fields on `OrganizationModel` remain as named fields (not moved into per-feature config) and carry domain-specific semantic shapes:
|
|
128
|
+
|
|
129
|
+
- `crm` -- pipeline stages and stage semantics
|
|
130
|
+
- `leadGen` -- company and contact lifecycle stages
|
|
131
|
+
- `delivery` -- project, milestone, and task statuses (used by the `projects` feature)
|
|
134
132
|
|
|
135
133
|
This is why the organization model is semantic, not just nav config -- it owns product meaning for the business objects the shell surfaces expose.
|
|
136
134
|
|
|
@@ -152,7 +150,7 @@ Merge semantics:
|
|
|
152
150
|
|
|
153
151
|
**Uniqueness checks** -- IDs must be unique within their respective collections:
|
|
154
152
|
|
|
155
|
-
- `
|
|
153
|
+
- `features[].id`
|
|
156
154
|
- `navigation.surfaces[].id`
|
|
157
155
|
- `navigation.groups[].id`
|
|
158
156
|
- `resourceMappings[].id`
|
|
@@ -162,20 +160,20 @@ Merge semantics:
|
|
|
162
160
|
|
|
163
161
|
- `navigation.defaultSurfaceId` must point at a declared surface
|
|
164
162
|
- every `surfaceId` in a navigation group must resolve to a declared surface
|
|
165
|
-
- every `surfaceId` in a
|
|
166
|
-
- every `resourceId` in a
|
|
163
|
+
- every `surfaceId` in a feature must resolve to a declared surface
|
|
164
|
+
- every `resourceId` in a feature must resolve to a declared resource mapping (by `resourceId`)
|
|
167
165
|
- surface `parentId` must reference an existing surface
|
|
168
|
-
- every `
|
|
166
|
+
- every `featureId` on a surface must resolve to a declared feature
|
|
169
167
|
- every `resourceId` on a surface must resolve to a declared resource mapping
|
|
170
|
-
- every `
|
|
168
|
+
- every `featureId` on a resource mapping must resolve to a declared feature
|
|
171
169
|
- every `surfaceId` on a resource mapping must resolve to a declared surface
|
|
172
170
|
|
|
173
171
|
**Bidirectional reference enforcement** -- cross-references must be mutual, not one-sided:
|
|
174
172
|
|
|
175
|
-
- a
|
|
176
|
-
- a surface listing `
|
|
177
|
-
- a
|
|
178
|
-
- a resource mapping listing `
|
|
173
|
+
- a feature listing `surfaceId` S requires surface S to list that feature's ID in its `featureIds`
|
|
174
|
+
- a surface listing `featureId` F requires feature F to list that surface's ID in its `surfaceIds`
|
|
175
|
+
- a feature listing `resourceId` R requires resource mapping R to list that feature's ID in its `featureIds`
|
|
176
|
+
- a resource mapping listing `featureId` F requires feature F to list that resource's `resourceId` in its `resourceIds`
|
|
179
177
|
- a surface listing `resourceId` R requires resource mapping R to list that surface's ID in its `surfaceIds`
|
|
180
178
|
- a resource mapping listing `surfaceId` S requires surface S to list that resource's `resourceId` in its `resourceIds`
|
|
181
179
|
|
|
@@ -185,8 +183,8 @@ This bidirectional enforcement is what keeps the organization model semantically
|
|
|
185
183
|
|
|
186
184
|
`ElevasisFeaturesProvider` uses the organization model in three ways:
|
|
187
185
|
|
|
188
|
-
1. **Feature resolution** -- provider
|
|
189
|
-
2. **Nav label and path resolution** -- when `organizationModel` is present, feature labels resolve from `
|
|
186
|
+
1. **Feature resolution** -- the provider looks up each manifest's `featureId` in `organizationModel.features` to determine `access.enabled`. If no matching feature entry is found, `access.enabled` defaults to `false`.
|
|
187
|
+
2. **Nav label and path resolution** -- when `organizationModel` is present, feature labels resolve from the matching feature entry's `label` field, and surface labels and paths resolve from `organizationModel.navigation.surfaces`. Semantic customization without changing manifest code.
|
|
190
188
|
3. **Organization-graph bridge** -- the `operationsManifest` declares `organizationGraph.surfaceId = 'operations.organization-graph'`. The provider resolves that against organization-model surfaces and exposes the result as `organizationGraph` in context. See [Organization Graph](./organization-graph.mdx).
|
|
191
189
|
|
|
192
190
|
## Published Package: `@elevasis/core`
|
|
@@ -238,7 +236,7 @@ Exports the foundations module provides to consumers:
|
|
|
238
236
|
- `FoundationFeatureKey`, `FoundationSurfaceIcon`, `FoundationNavigationSurface`, `FoundationOrganizationModel`
|
|
239
237
|
- `homeLabel`, `quickAccessSurfaceIds`, `getOrganizationSurface(surfaceId)`
|
|
240
238
|
|
|
241
|
-
Downstream template shells pass `canonicalOrganizationModel` into `ElevasisFeaturesProvider`, preserving host-local dashboard/nav customizations alongside the shared runtime.
|
|
239
|
+
Downstream template shells pass `canonicalOrganizationModel` into `ElevasisFeaturesProvider`, preserving host-local dashboard/nav customizations alongside the shared runtime. Feature IDs are now direct matches -- `crm`, `lead-gen`, `projects` in the org model correspond directly to the same IDs on `FeatureModule.featureId`. No alias layer is needed.
|
|
242
240
|
|
|
243
241
|
Derivative projects (`external/nirvana-marketing`, `external/ZentaraHQ`) follow the same adapter + provider-wiring baseline with their own project-local customizations.
|
|
244
242
|
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export { OrganizationModelSchema } from './schema'
|
|
2
|
+
export { FeatureSchema } from './domains/features'
|
|
3
|
+
export { PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID, DELIVERY_PROJECTS_VIEW_CAPABILITY_ID } from './contracts'
|
|
2
4
|
export { DEFAULT_ORGANIZATION_MODEL } from './defaults'
|
|
3
5
|
export { defineOrganizationModel, resolveOrganizationModel } from './resolve'
|
|
6
|
+
export { createFoundationOrganizationModel } from './foundation'
|
|
4
7
|
|
|
5
8
|
export type {
|
|
6
9
|
DeepPartial,
|
|
@@ -8,11 +11,17 @@ export type {
|
|
|
8
11
|
OrganizationModelBranding,
|
|
9
12
|
OrganizationModelCrm,
|
|
10
13
|
OrganizationModelDelivery,
|
|
11
|
-
|
|
12
|
-
OrganizationModelFeatures,
|
|
14
|
+
OrganizationModelFeature,
|
|
13
15
|
OrganizationModelLeadGen,
|
|
14
16
|
OrganizationModelNavigation,
|
|
15
17
|
OrganizationModelResourceMapping,
|
|
16
|
-
OrganizationModelSemanticDomain,
|
|
17
18
|
OrganizationModelSurface
|
|
18
19
|
} from './types'
|
|
20
|
+
|
|
21
|
+
export type {
|
|
22
|
+
FoundationBranding,
|
|
23
|
+
FoundationNavigationSurface,
|
|
24
|
+
FoundationOrganizationModel,
|
|
25
|
+
FoundationSurfaceIcon,
|
|
26
|
+
FoundationSurfaceType
|
|
27
|
+
} from './foundation'
|