@elevasis/core 0.22.0 → 0.23.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 +2330 -2391
- package/dist/index.js +2322 -1147
- package/dist/knowledge/index.d.ts +702 -1136
- package/dist/knowledge/index.js +9 -9
- package/dist/organization-model/index.d.ts +2330 -2391
- package/dist/organization-model/index.js +2322 -1147
- package/dist/test-utils/index.d.ts +703 -1106
- package/dist/test-utils/index.js +1735 -1089
- package/package.json +1 -1
- package/src/__tests__/template-core-compatibility.test.ts +11 -79
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +360 -98
- package/src/business/acquisition/api-schemas.test.ts +2 -2
- package/src/business/acquisition/api-schemas.ts +7 -9
- package/src/business/acquisition/build-templates.test.ts +4 -4
- package/src/business/acquisition/build-templates.ts +72 -30
- package/src/business/acquisition/crm-state-actions.test.ts +13 -11
- package/src/business/acquisition/types.ts +7 -3
- package/src/execution/engine/agent/core/types.ts +1 -1
- package/src/execution/engine/workflow/types.ts +2 -2
- package/src/knowledge/README.md +8 -7
- package/src/knowledge/__tests__/queries.test.ts +74 -73
- package/src/knowledge/format.ts +10 -9
- package/src/knowledge/index.ts +1 -1
- package/src/knowledge/published.ts +1 -1
- package/src/knowledge/queries.ts +26 -25
- package/src/organization-model/README.md +66 -26
- package/src/organization-model/__tests__/content-kinds-registry.test.ts +210 -0
- package/src/organization-model/__tests__/defaults.test.ts +72 -98
- package/src/organization-model/__tests__/domains/actions.test.ts +56 -0
- package/src/organization-model/__tests__/domains/customers.test.ts +299 -295
- package/src/organization-model/__tests__/domains/entities.test.ts +56 -0
- package/src/organization-model/__tests__/domains/goals.test.ts +493 -479
- package/src/organization-model/__tests__/domains/identity.test.ts +280 -279
- package/src/organization-model/__tests__/domains/navigation.test.ts +268 -212
- package/src/organization-model/__tests__/domains/offerings.test.ts +414 -419
- package/src/organization-model/__tests__/domains/policies.test.ts +323 -0
- package/src/organization-model/__tests__/domains/resource-mappings.test.ts +271 -271
- package/src/organization-model/__tests__/domains/resources.test.ts +159 -37
- package/src/organization-model/__tests__/domains/roles.test.ts +147 -86
- package/src/organization-model/__tests__/domains/statuses.test.ts +246 -243
- package/src/organization-model/__tests__/domains/systems.test.ts +67 -51
- package/src/organization-model/__tests__/flatten-additive-merge.test.ts +361 -0
- package/src/organization-model/__tests__/foundation.test.ts +74 -102
- package/src/organization-model/__tests__/get-resources-for-system.test.ts +144 -0
- package/src/organization-model/__tests__/graph.test.ts +899 -71
- package/src/organization-model/__tests__/knowledge.test.ts +173 -52
- package/src/organization-model/__tests__/lookup-helpers.test.ts +438 -0
- package/src/organization-model/__tests__/migration-helpers.test.ts +591 -0
- package/src/organization-model/__tests__/prospecting-ssot.test.ts +36 -27
- package/src/organization-model/__tests__/recursive-system-schema.test.ts +520 -0
- package/src/organization-model/__tests__/resolve.test.ts +174 -23
- package/src/organization-model/__tests__/schema.test.ts +291 -114
- package/src/organization-model/__tests__/surface-projection.test.ts +207 -97
- package/src/organization-model/catalogs/lead-gen.ts +144 -0
- package/src/organization-model/content-kinds/config.ts +36 -0
- package/src/organization-model/content-kinds/index.ts +74 -0
- package/src/organization-model/content-kinds/pipeline.ts +68 -0
- package/src/organization-model/content-kinds/registry.ts +44 -0
- package/src/organization-model/content-kinds/status.ts +71 -0
- package/src/organization-model/content-kinds/template.ts +83 -0
- package/src/organization-model/content-kinds/types.ts +117 -0
- package/src/organization-model/contracts.ts +13 -3
- package/src/organization-model/defaults.ts +488 -96
- package/src/organization-model/domains/actions.ts +239 -0
- package/src/organization-model/domains/customers.ts +78 -75
- package/src/organization-model/domains/entities.ts +144 -0
- package/src/organization-model/domains/goals.ts +83 -80
- package/src/organization-model/domains/knowledge.ts +74 -16
- package/src/organization-model/domains/navigation.ts +107 -384
- package/src/organization-model/domains/offerings.ts +71 -66
- package/src/organization-model/domains/policies.ts +102 -0
- package/src/organization-model/domains/projects.ts +14 -48
- package/src/organization-model/domains/prospecting.ts +62 -181
- package/src/organization-model/domains/resources.ts +81 -24
- package/src/organization-model/domains/roles.ts +13 -10
- package/src/organization-model/domains/sales.ts +10 -219
- package/src/organization-model/domains/shared.ts +57 -57
- package/src/organization-model/domains/statuses.ts +339 -130
- package/src/organization-model/domains/systems.ts +186 -29
- package/src/organization-model/foundation.ts +54 -67
- package/src/organization-model/graph/build.ts +682 -54
- package/src/organization-model/graph/link.ts +1 -1
- package/src/organization-model/graph/schema.ts +24 -9
- package/src/organization-model/graph/types.ts +20 -7
- package/src/organization-model/helpers.ts +231 -26
- package/src/organization-model/index.ts +116 -5
- package/src/organization-model/migration-helpers.ts +249 -0
- package/src/organization-model/organization-graph.mdx +16 -15
- package/src/organization-model/organization-model.mdx +89 -41
- package/src/organization-model/published.ts +120 -18
- package/src/organization-model/resolve.ts +117 -54
- package/src/organization-model/schema.ts +561 -140
- package/src/organization-model/surface-projection.ts +116 -122
- package/src/organization-model/types.ts +102 -21
- package/src/platform/constants/versions.ts +1 -1
- package/src/platform/registry/__tests__/command-view.test.ts +6 -8
- package/src/platform/registry/__tests__/resource-link.test.ts +13 -8
- package/src/platform/registry/__tests__/resource-registry.integration.test.ts +16 -31
- package/src/platform/registry/__tests__/resource-registry.nested-systems.test.ts +245 -0
- package/src/platform/registry/__tests__/resource-registry.test.ts +9 -7
- package/src/platform/registry/__tests__/validation.test.ts +15 -11
- package/src/platform/registry/resource-registry.ts +20 -8
- package/src/platform/registry/serialization.ts +7 -7
- package/src/platform/registry/types.ts +3 -3
- package/src/platform/registry/validation.ts +17 -15
- package/src/reference/_generated/contracts.md +362 -99
- package/src/reference/glossary.md +18 -18
- package/src/supabase/database.types.ts +60 -0
- package/src/test-utils/test-utils.test.ts +1 -6
- package/src/organization-model/__tests__/domains/operations.test.ts +0 -203
- package/src/organization-model/domains/features.ts +0 -31
- package/src/organization-model/domains/operations.ts +0 -85
|
@@ -1,46 +1,203 @@
|
|
|
1
|
-
import { z } from 'zod'
|
|
2
|
-
import {
|
|
1
|
+
import { z, type ZodType } from 'zod'
|
|
2
|
+
import { ActionRefSchema } from './actions'
|
|
3
|
+
import {
|
|
4
|
+
ColorTokenSchema,
|
|
5
|
+
DescriptionSchema,
|
|
6
|
+
IconNameSchema,
|
|
7
|
+
LabelSchema,
|
|
8
|
+
ModelIdSchema,
|
|
9
|
+
PathSchema,
|
|
10
|
+
ReferenceIdsSchema
|
|
11
|
+
} from './shared'
|
|
12
|
+
import { ContentNodeSchema } from '../content-kinds/types'
|
|
3
13
|
|
|
4
14
|
// ---------------------------------------------------------------------------
|
|
5
15
|
// Systems domain
|
|
6
16
|
// ---------------------------------------------------------------------------
|
|
7
17
|
//
|
|
8
|
-
// A System is a tenant-defined bounded context
|
|
9
|
-
//
|
|
10
|
-
// shape and references; each tenant supplies its own catalog.
|
|
18
|
+
// A System is a tenant-defined bounded context. It can carry UI presence,
|
|
19
|
+
// hierarchy, and governance metadata; non-UI systems simply omit `ui`.
|
|
11
20
|
|
|
12
|
-
export const SystemKindSchema = z
|
|
13
|
-
|
|
21
|
+
export const SystemKindSchema = z
|
|
22
|
+
.enum(['product', 'operational', 'platform', 'diagnostic'])
|
|
23
|
+
.meta({ label: 'System kind', color: 'blue' })
|
|
24
|
+
export const SystemLifecycleSchema = z
|
|
25
|
+
.enum(['draft', 'beta', 'active', 'deprecated', 'archived'])
|
|
26
|
+
.meta({ label: 'Lifecycle', color: 'teal' })
|
|
27
|
+
/** @deprecated Use SystemLifecycleSchema. Accepted for one publish cycle. */
|
|
28
|
+
export const SystemStatusSchema = z.enum(['active', 'deprecated', 'archived']).meta({ label: 'Status', color: 'teal' })
|
|
14
29
|
export const SystemIdSchema = ModelIdSchema
|
|
30
|
+
/**
|
|
31
|
+
* Validates a dot-separated system path (e.g. "sales.lead-gen", "sales.crm").
|
|
32
|
+
* Each segment is lowercase, starts with a letter or digit, and may contain hyphens.
|
|
33
|
+
* This is the canonical form used in `resource.systemPath`.
|
|
34
|
+
*/
|
|
35
|
+
export const SystemPathSchema = z
|
|
36
|
+
.string()
|
|
37
|
+
.trim()
|
|
38
|
+
.min(1)
|
|
39
|
+
.regex(
|
|
40
|
+
/^[a-z0-9][a-z0-9-]*(?:\.[a-z0-9][a-z0-9-]*)*$/,
|
|
41
|
+
'must be a dotted lowercase path (e.g. "sales.lead-gen" or "sales.crm")'
|
|
42
|
+
)
|
|
43
|
+
export const UiPositionSchema = z.enum(['sidebar-primary', 'sidebar-bottom']).meta({ label: 'UI position' })
|
|
44
|
+
export const NodeIdPathSchema = SystemIdSchema
|
|
45
|
+
export const NodeIdStringSchema = z
|
|
46
|
+
.string()
|
|
47
|
+
.trim()
|
|
48
|
+
.min(1)
|
|
49
|
+
.max(200)
|
|
50
|
+
// D4: kind prefix allows hyphens (e.g. 'content-node'); id allows colons for
|
|
51
|
+
// qualified content-node references ('content-node:sales.crm:default-pipeline').
|
|
52
|
+
.regex(
|
|
53
|
+
/^[a-z][a-z-]*:([a-z0-9-]+)(\.[a-z0-9-]+)*(:[a-z0-9.-]+)*$/,
|
|
54
|
+
'Node references must use kind:dotted-path (e.g. system:sales.crm or content-node:sales.crm:pipeline-id)'
|
|
55
|
+
)
|
|
15
56
|
|
|
16
|
-
export const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
/** One-paragraph purpose statement for the bounded context. */
|
|
22
|
-
description: DescriptionSchema,
|
|
23
|
-
/** Closed system shape enum; catalog values remain tenant-defined. */
|
|
24
|
-
kind: SystemKindSchema,
|
|
25
|
-
/** Optional role responsible for this system. */
|
|
26
|
-
responsibleRoleId: ModelIdSchema.optional(),
|
|
27
|
-
/** Optional knowledge nodes that govern this system. */
|
|
28
|
-
governedByKnowledge: ReferenceIdsSchema,
|
|
29
|
-
/** Optional goals this system contributes to. */
|
|
30
|
-
drivesGoals: ReferenceIdsSchema,
|
|
31
|
-
status: SystemStatusSchema
|
|
57
|
+
export const SystemUiSchema = z.object({
|
|
58
|
+
path: PathSchema,
|
|
59
|
+
surfaces: ReferenceIdsSchema,
|
|
60
|
+
icon: IconNameSchema.optional(),
|
|
61
|
+
order: z.number().int().optional()
|
|
32
62
|
})
|
|
33
63
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Recursive SystemEntry schema.
|
|
66
|
+
//
|
|
67
|
+
// TypeScript cannot infer the type of a schema that references itself through
|
|
68
|
+
// z.lazy(). The standard Zod fix is to:
|
|
69
|
+
// 1. Declare the output type as an explicit interface BEFORE the schema.
|
|
70
|
+
// 2. Annotate the schema variable with `ZodType<SystemEntry>` so TS uses
|
|
71
|
+
// the declared interface instead of trying to infer through the cycle.
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
import type { ContentNode } from '../content-kinds/types'
|
|
37
75
|
|
|
38
|
-
|
|
39
|
-
|
|
76
|
+
/** Explicit interface needed to annotate the recursive SystemEntrySchema. */
|
|
77
|
+
export interface SystemEntry {
|
|
78
|
+
id: string
|
|
79
|
+
label?: string
|
|
80
|
+
title?: string
|
|
81
|
+
description?: string
|
|
82
|
+
kind?: 'product' | 'operational' | 'platform' | 'diagnostic'
|
|
83
|
+
parentSystemId?: string
|
|
84
|
+
ui?: { path: string; surfaces: string[]; icon?: string; order?: number }
|
|
85
|
+
lifecycle?: 'draft' | 'beta' | 'active' | 'deprecated' | 'archived'
|
|
86
|
+
responsibleRoleId?: string
|
|
87
|
+
governedByKnowledge?: string[]
|
|
88
|
+
actions?: { actionId: string; intent: 'exposes' | 'consumes'; invocation?: unknown }[]
|
|
89
|
+
policies?: string[]
|
|
90
|
+
drivesGoals?: string[]
|
|
91
|
+
/** @deprecated Use lifecycle. Accepted for one publish cycle. */
|
|
92
|
+
status?: 'active' | 'deprecated' | 'archived'
|
|
93
|
+
path?: string
|
|
94
|
+
icon?: string
|
|
95
|
+
color?: string
|
|
96
|
+
uiPosition?: 'sidebar-primary' | 'sidebar-bottom'
|
|
97
|
+
enabled?: boolean
|
|
98
|
+
devOnly?: boolean
|
|
99
|
+
requiresAdmin?: boolean
|
|
100
|
+
order: number
|
|
101
|
+
content?: Record<string, ContentNode>
|
|
102
|
+
subsystems?: Record<string, SystemEntry>
|
|
40
103
|
}
|
|
41
104
|
|
|
105
|
+
export const SystemEntrySchema: ZodType<SystemEntry> = z
|
|
106
|
+
.object({
|
|
107
|
+
/** Stable tenant-defined system id (e.g. "sys.lead-gen" or "sales.crm"). */
|
|
108
|
+
id: SystemIdSchema,
|
|
109
|
+
/** Human-readable system label shown in UI, governance, and operations surfaces. */
|
|
110
|
+
label: LabelSchema.optional(),
|
|
111
|
+
/** @deprecated Use label. Accepted for pre-consolidation System declarations. */
|
|
112
|
+
title: LabelSchema.optional(),
|
|
113
|
+
/** One-paragraph purpose statement for the bounded context. */
|
|
114
|
+
description: DescriptionSchema.optional(),
|
|
115
|
+
/** Closed system shape enum; catalog values remain tenant-defined. */
|
|
116
|
+
kind: SystemKindSchema.optional(),
|
|
117
|
+
/** Optional self-reference for System hierarchy. */
|
|
118
|
+
parentSystemId: SystemIdSchema.optional(),
|
|
119
|
+
/** Optional UI presence. Systems without UI omit this. */
|
|
120
|
+
ui: SystemUiSchema.optional(),
|
|
121
|
+
/** Canonical lifecycle state. Replaces Feature.enabled/devOnly and System.status. */
|
|
122
|
+
lifecycle: SystemLifecycleSchema.optional(),
|
|
123
|
+
/** Optional role responsible for this system. */
|
|
124
|
+
responsibleRoleId: ModelIdSchema.meta({ ref: 'role' }).optional(),
|
|
125
|
+
/** Optional knowledge nodes that govern this system. */
|
|
126
|
+
governedByKnowledge: z
|
|
127
|
+
.array(ModelIdSchema.meta({ ref: 'knowledge' }))
|
|
128
|
+
.default([])
|
|
129
|
+
.optional(),
|
|
130
|
+
/** Optional actions this system exposes or consumes. */
|
|
131
|
+
actions: z.array(ActionRefSchema).optional(),
|
|
132
|
+
/** Optional operational policies that apply to this system. */
|
|
133
|
+
policies: z
|
|
134
|
+
.array(ModelIdSchema.meta({ ref: 'policy' }))
|
|
135
|
+
.default([])
|
|
136
|
+
.optional(),
|
|
137
|
+
/** Optional goals this system contributes to. */
|
|
138
|
+
drivesGoals: z
|
|
139
|
+
.array(ModelIdSchema.meta({ ref: 'goal' }))
|
|
140
|
+
.default([])
|
|
141
|
+
.optional(),
|
|
142
|
+
/** @deprecated Use lifecycle. Accepted for one publish cycle. */
|
|
143
|
+
status: SystemStatusSchema.optional(),
|
|
144
|
+
/** @deprecated Use ui.path. Kept for one-cycle Feature compatibility. */
|
|
145
|
+
path: PathSchema.optional(),
|
|
146
|
+
/** @deprecated Use ui.icon. Kept for one-cycle Feature compatibility. */
|
|
147
|
+
icon: IconNameSchema.optional(),
|
|
148
|
+
/** @deprecated Feature color token, retained for one-cycle compatibility. */
|
|
149
|
+
color: ColorTokenSchema.optional(),
|
|
150
|
+
/** @deprecated UI placement hint, retained for one-cycle compatibility. */
|
|
151
|
+
uiPosition: UiPositionSchema.optional(),
|
|
152
|
+
/** @deprecated Use lifecycle. */
|
|
153
|
+
enabled: z.boolean().optional(),
|
|
154
|
+
/** @deprecated Use lifecycle: "beta". */
|
|
155
|
+
devOnly: z.boolean().optional(),
|
|
156
|
+
requiresAdmin: z.boolean().optional(),
|
|
157
|
+
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
158
|
+
order: z.number(),
|
|
159
|
+
/**
|
|
160
|
+
* System-scoped operational data, co-located with the owning system.
|
|
161
|
+
* Per L1, L3, L13: keyed by local NodeId (the key is the local id; qualified
|
|
162
|
+
* id is `<system-path>:<local-id>`, computed by graph projection).
|
|
163
|
+
* Per L14: every ContentNode carries both `kind` and `type`.
|
|
164
|
+
* Per D2: unregistered (kind, type) pairs parse successfully.
|
|
165
|
+
*/
|
|
166
|
+
content: z.record(z.string().trim().min(1).max(200), ContentNodeSchema).optional(),
|
|
167
|
+
/**
|
|
168
|
+
* Recursive child systems, authored via nesting (per L11).
|
|
169
|
+
* The key is the local system id; the full path is computed by joining
|
|
170
|
+
* ancestor keys with `.` (e.g. parent key `'sales'` + child key `'crm'` → `'sales.crm'`).
|
|
171
|
+
* Per Phase 4: `id` and `parentSystemId` fields will be removed in favour of
|
|
172
|
+
* position-derived paths. Both still exist on this schema for backward compat.
|
|
173
|
+
*/
|
|
174
|
+
subsystems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional()
|
|
175
|
+
})
|
|
176
|
+
.refine((system: SystemEntry) => system.label !== undefined || system.title !== undefined, {
|
|
177
|
+
path: ['label'],
|
|
178
|
+
message: 'System must provide label or title'
|
|
179
|
+
})
|
|
180
|
+
.transform((system: SystemEntry) => {
|
|
181
|
+
if (system.status === undefined) return system
|
|
182
|
+
|
|
183
|
+
console.warn('[organization-model] System.status is deprecated; use System.lifecycle instead.')
|
|
184
|
+
return system.lifecycle === undefined ? { ...system, lifecycle: system.status } : system
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
export const SystemsDomainSchema = z
|
|
188
|
+
.record(z.string(), SystemEntrySchema)
|
|
189
|
+
.refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
190
|
+
message: 'Each system entry id must match its map key'
|
|
191
|
+
})
|
|
192
|
+
.default({})
|
|
193
|
+
|
|
194
|
+
export const DEFAULT_ORGANIZATION_MODEL_SYSTEMS: z.infer<typeof SystemsDomainSchema> = {}
|
|
195
|
+
|
|
42
196
|
export type SystemId = z.infer<typeof SystemIdSchema>
|
|
43
197
|
export type SystemKind = z.infer<typeof SystemKindSchema>
|
|
198
|
+
export type SystemLifecycle = z.infer<typeof SystemLifecycleSchema>
|
|
199
|
+
/** @deprecated Use SystemLifecycle. Accepted for one publish cycle. */
|
|
44
200
|
export type SystemStatus = z.infer<typeof SystemStatusSchema>
|
|
45
|
-
|
|
201
|
+
// SystemEntry is declared as an explicit interface above the schema (required for
|
|
202
|
+
// recursive z.lazy() type inference). Re-export omitted — the interface IS the type.
|
|
46
203
|
export type SystemsDomain = z.infer<typeof SystemsDomainSchema>
|
|
@@ -1,88 +1,75 @@
|
|
|
1
1
|
import { resolveOrganizationModel } from './resolve'
|
|
2
2
|
import type { OrganizationModelBuiltinIconToken } from './icons'
|
|
3
|
-
import
|
|
3
|
+
import { projectOrganizationSurfaces, type OrganizationSurfaceProjection } from './surface-projection'
|
|
4
|
+
import type { DeepPartial, OrganizationModel } from './types'
|
|
4
5
|
|
|
5
6
|
export type FoundationSurfaceType = 'page' | 'dashboard' | 'graph' | 'detail' | 'list' | 'settings'
|
|
6
7
|
|
|
7
8
|
export type FoundationSurfaceIcon = Extract<
|
|
8
9
|
OrganizationModelBuiltinIconToken,
|
|
9
|
-
|
|
10
|
+
| 'feature.dashboard'
|
|
11
|
+
| 'feature.crm'
|
|
12
|
+
| 'feature.lead-gen'
|
|
13
|
+
| 'feature.projects'
|
|
14
|
+
| 'feature.operations'
|
|
15
|
+
| 'feature.settings'
|
|
10
16
|
>
|
|
11
17
|
|
|
12
|
-
export
|
|
13
|
-
icon?: FoundationSurfaceIcon
|
|
14
|
-
surfaceType
|
|
18
|
+
export type FoundationNavigationSurface = Omit<OrganizationSurfaceProjection, 'icon' | 'surfaceType'> & {
|
|
19
|
+
icon?: FoundationSurfaceIcon | OrganizationModelBuiltinIconToken | string
|
|
20
|
+
surfaceType: FoundationSurfaceType
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
export interface FoundationOrganizationModel extends Omit<OrganizationModel, 'navigation'> {
|
|
18
24
|
navigation: {
|
|
19
25
|
defaultSurfaceId: string
|
|
20
26
|
homeLabel: string
|
|
21
|
-
quickAccessSurfaceIds: readonly string[]
|
|
22
|
-
surfaces: FoundationNavigationSurface[]
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface FoundationBranding {
|
|
27
|
-
organizationName: string
|
|
28
|
-
productName: string
|
|
29
|
-
shortName: string
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function createFoundationOrganizationModel(override: DeepPartial<OrganizationModel>): {
|
|
33
|
-
canonical: OrganizationModel
|
|
34
|
-
model: FoundationOrganizationModel
|
|
35
|
-
homeLabel: string
|
|
36
|
-
quickAccessSurfaceIds: readonly string[]
|
|
37
|
-
getOrganizationSurface: (surfaceId: string) => FoundationNavigationSurface | undefined
|
|
38
|
-
} {
|
|
39
|
-
const canonical = resolveOrganizationModel(override)
|
|
27
|
+
quickAccessSurfaceIds: readonly string[]
|
|
28
|
+
surfaces: FoundationNavigationSurface[]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
40
31
|
|
|
41
|
-
|
|
42
|
-
|
|
32
|
+
export interface FoundationBranding {
|
|
33
|
+
organizationName: string
|
|
34
|
+
productName: string
|
|
35
|
+
shortName: string
|
|
36
|
+
}
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
export function createFoundationOrganizationModel(override: DeepPartial<OrganizationModel>): {
|
|
39
|
+
canonical: OrganizationModel
|
|
40
|
+
model: FoundationOrganizationModel
|
|
41
|
+
homeLabel: string
|
|
42
|
+
quickAccessSurfaceIds: readonly string[]
|
|
43
|
+
getOrganizationSurface: (surfaceId: string) => FoundationNavigationSurface | undefined
|
|
44
|
+
} {
|
|
45
|
+
const canonical = resolveOrganizationModel(override)
|
|
46
|
+
const navigationSurfaces: FoundationNavigationSurface[] = projectOrganizationSurfaces(canonical)
|
|
47
|
+
const defaultSurface = navigationSurfaces.find((surface) => surface.path === '/') ?? navigationSurfaces[0]
|
|
48
|
+
const homeLabel = defaultSurface?.label ?? 'Dashboard'
|
|
49
|
+
const quickAccessSurfaceIds = navigationSurfaces
|
|
50
|
+
.filter((surface) => surface.id !== defaultSurface?.id && surface.surfaceType !== 'settings')
|
|
51
|
+
.slice(0, 4)
|
|
52
|
+
.map((surface) => surface.id)
|
|
47
53
|
|
|
48
|
-
|
|
54
|
+
const model: FoundationOrganizationModel = {
|
|
55
|
+
...canonical,
|
|
56
|
+
navigation: {
|
|
57
|
+
defaultSurfaceId: defaultSurface?.id ?? '',
|
|
58
|
+
homeLabel,
|
|
59
|
+
quickAccessSurfaceIds: [...quickAccessSurfaceIds],
|
|
60
|
+
surfaces: navigationSurfaces
|
|
61
|
+
}
|
|
49
62
|
}
|
|
50
63
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const crmFeature = requireCoreFeature('sales.crm')
|
|
64
|
+
function getOrganizationSurface(surfaceId: string): FoundationNavigationSurface | undefined {
|
|
65
|
+
return model.navigation.surfaces.find((candidate) => candidate.id === surfaceId)
|
|
66
|
+
}
|
|
55
67
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const homeLabel = 'Dashboard'
|
|
65
|
-
const quickAccessSurfaceIds = ['operations', 'projects', 'lead-gen', 'crm'] as const
|
|
66
|
-
|
|
67
|
-
const model: FoundationOrganizationModel = {
|
|
68
|
-
...canonical,
|
|
69
|
-
navigation: {
|
|
70
|
-
defaultSurfaceId: 'operations',
|
|
71
|
-
homeLabel,
|
|
72
|
-
quickAccessSurfaceIds: [...quickAccessSurfaceIds],
|
|
73
|
-
surfaces: navigationSurfaces
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function getOrganizationSurface(surfaceId: string): FoundationNavigationSurface | undefined {
|
|
78
|
-
return model.navigation.surfaces.find((candidate) => candidate.id === surfaceId)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
canonical,
|
|
83
|
-
model,
|
|
84
|
-
homeLabel,
|
|
85
|
-
quickAccessSurfaceIds,
|
|
86
|
-
getOrganizationSurface
|
|
87
|
-
}
|
|
88
|
-
}
|
|
68
|
+
return {
|
|
69
|
+
canonical,
|
|
70
|
+
model,
|
|
71
|
+
homeLabel,
|
|
72
|
+
quickAccessSurfaceIds,
|
|
73
|
+
getOrganizationSurface
|
|
74
|
+
}
|
|
75
|
+
}
|