@elevasis/sdk 1.5.3 → 1.5.5
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/cli.cjs +967 -57
- package/dist/index.d.ts +94 -110
- package/package.json +2 -2
- package/reference/_navigation.md +11 -1
- package/reference/_reference-manifest.json +70 -0
- package/reference/claude-config/commands/submit-issue.md +11 -0
- package/reference/claude-config/hooks/post-edit-validate.mjs +109 -0
- package/reference/claude-config/hooks/tool-failure-recovery.mjs +73 -0
- package/reference/claude-config/rules/deployment.md +57 -0
- package/reference/claude-config/rules/docs.md +26 -0
- package/reference/claude-config/rules/error-handling.md +56 -0
- package/reference/claude-config/rules/execution.md +40 -0
- package/reference/claude-config/rules/frontend.md +43 -0
- package/reference/claude-config/rules/observability.md +31 -0
- package/reference/claude-config/rules/organization-os.md +62 -0
- package/reference/claude-config/rules/platform.md +41 -0
- package/reference/claude-config/rules/shared-types.md +46 -0
- package/reference/claude-config/rules/task-tracking.md +47 -0
- package/reference/claude-config/scripts/statusline-command.js +18 -0
- package/reference/claude-config/settings.json +30 -0
- package/reference/claude-config/skills/deploy/SKILL.md +166 -0
- package/reference/claude-config/skills/dsp/SKILL.md +66 -0
- package/reference/claude-config/skills/elevasis/SKILL.md +239 -0
- package/reference/claude-config/skills/explore/SKILL.md +78 -0
- package/reference/claude-config/skills/project/SKILL.md +918 -0
- package/reference/claude-config/skills/save/SKILL.md +197 -0
- package/reference/claude-config/skills/setup/SKILL.md +210 -0
- package/reference/claude-config/skills/status/SKILL.md +60 -0
- package/reference/claude-config/skills/submit-issue/SKILL.md +165 -0
- package/reference/claude-config/skills/sync/SKILL.md +81 -0
- package/reference/cli.mdx +19 -4
- package/reference/deployment/provided-features.mdx +24 -2
- package/reference/framework/agent.mdx +12 -4
- package/reference/framework/project-structure.mdx +9 -3
- package/reference/packages/core/src/README.md +1 -1
- package/reference/packages/core/src/business/README.md +52 -0
- package/reference/packages/core/src/organization-model/README.md +25 -26
- package/reference/packages/ui/src/app/README.md +24 -0
- package/reference/platform-tools/type-safety.mdx +0 -10
- package/reference/scaffold/core/organization-graph.mdx +37 -28
- package/reference/scaffold/core/organization-model.mdx +34 -36
- package/reference/scaffold/index.mdx +1 -0
- package/reference/scaffold/operations/propagation-pipeline.md +7 -3
- package/reference/scaffold/operations/scaffold-maintenance.md +2 -2
- package/reference/scaffold/operations/workflow-recipes.md +18 -1
- package/reference/scaffold/recipes/add-a-feature.md +37 -21
- package/reference/scaffold/recipes/add-a-resource.md +4 -2
- package/reference/scaffold/recipes/customize-organization-model.md +400 -0
- package/reference/scaffold/recipes/extend-a-base-entity.md +140 -0
- package/reference/scaffold/recipes/gate-by-feature-or-admin.md +18 -12
- package/reference/scaffold/recipes/index.md +3 -3
- package/reference/scaffold/reference/contracts.md +11 -32
- package/reference/scaffold/reference/feature-registry.md +10 -9
- package/reference/scaffold/reference/glossary.md +14 -18
- package/reference/scaffold/ui/customization.md +2 -2
- package/reference/scaffold/ui/feature-flags-and-gating.md +40 -54
- package/reference/scaffold/ui/feature-shell.mdx +22 -23
- package/reference/scaffold/ui/recipes.md +118 -3
|
@@ -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
|
|
|
@@ -19,6 +19,7 @@ This scaffold reference contains universal documentation that applies to all Ele
|
|
|
19
19
|
|
|
20
20
|
- [Add a Feature](./recipes/add-a-feature.md) -- end-to-end from org model key through manifest, routes, gating
|
|
21
21
|
- [Add a Resource](./recipes/add-a-resource.md) -- author and deploy a workflow or agent
|
|
22
|
+
- [Extend a Base Entity](./recipes/extend-a-base-entity.md) -- add project-specific metadata to canonical entity shapes via the TMeta slot
|
|
22
23
|
- [Gate by Feature or Admin](./recipes/gate-by-feature-or-admin.md) -- decision table for access control patterns
|
|
23
24
|
|
|
24
25
|
### UI Patterns
|
|
@@ -57,7 +57,7 @@ Drift is healed at the moment it would otherwise leak downstream. This is cheape
|
|
|
57
57
|
|
|
58
58
|
| Tier | Policy | Examples |
|
|
59
59
|
| ------------------------------ | ----------------------------------------- | ------------------------------------------------------------------- |
|
|
60
|
-
| **Tier 1 (Infrastructure)** | Always replaced from template | Configs,
|
|
60
|
+
| **Tier 1 (Infrastructure)** | Always replaced from template | Configs, shared runtime surfaces, `lib/`, `test-utils/`, entry points |
|
|
61
61
|
| **Tier 2 (Standard Features)** | Synced unless project has customized them | Standard UI features, common patterns |
|
|
62
62
|
| **Tier 3 (Project-Specific)** | Never touched | `nav-items.ts`, `operations/src/`, `docs/`, `CLAUDE.md` |
|
|
63
63
|
|
|
@@ -78,8 +78,8 @@ The sync skill doc (`.claude/skills/external/SKILL.md`) defines the full tier mo
|
|
|
78
78
|
| `org-os` | Organization model exists, exports canonical symbols, imports from `@elevasis/core/organization-model`, calls `defineOrganizationModel` + `resolveOrganizationModel`, app-config references org model, `__root.tsx` uses `ElevasisFeaturesProvider` + `canonicalOrganizationModel`, `main.tsx` uses `ElevasisUIProvider`, all 3 CSS subpath imports present |
|
|
79
79
|
| `placeholders` | No unresolved `__PROJECT_SLUG__`, `__PROJECT_NAME__`, `__PROJECT_DESCRIPTION__` in key config files |
|
|
80
80
|
| `scripts` | `ui` and `operations` `package.json` have required npm scripts |
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
81
|
+
| `generated-docs` | `docs/index.md` and `docs/resources.md` are current with `pnpm exec elevasis-sdk generate-docs` and `pnpm exec elevasis-sdk generate-resources`; `pnpm exec elevasis-sdk validate-docs` passes |
|
|
82
|
+
| `lib` | `ui/src/lib/`, `lib/`, `test-utils/` exist with minimum file counts |
|
|
83
83
|
| `tier3` | `nav-items.ts` has project-specific customization (not overwritten by template) |
|
|
84
84
|
| `conflicts` | No merge conflict markers in source files |
|
|
85
85
|
| `git` | Working tree is clean |
|
|
@@ -116,6 +116,10 @@ Some failures are expected and intentional:
|
|
|
116
116
|
|
|
117
117
|
These do not indicate sync failures.
|
|
118
118
|
|
|
119
|
+
### Tier Ownership Note
|
|
120
|
+
|
|
121
|
+
Local `.claude/` guidance remains valuable inside the template, but it is project-owned documentation and agent configuration rather than a Tier 1 sync contract. Template propagation should treat the generated docs, published package surfaces, and runtime entrypoints as the authoritative shared scaffold surface.
|
|
122
|
+
|
|
119
123
|
---
|
|
120
124
|
|
|
121
125
|
## Remaining Gaps (Future Work)
|
|
@@ -35,7 +35,7 @@ Scaffold docs are co-located with their owning package and copied into the SDK r
|
|
|
35
35
|
| Composition & Extensibility | `packages/ui/src/scaffold/composition-extensibility.mdx` | `scaffold/ui/composition-extensibility.mdx` |
|
|
36
36
|
| Feature Registry (auto-gen) | `packages/ui/src/scaffold/_generated/feature-registry.md` | `scaffold/reference/feature-registry.md` |
|
|
37
37
|
| Scaffold Index | `packages/sdk/docs/scaffold/index.mdx` | `scaffold/index.mdx` |
|
|
38
|
-
| Pathway Recipes (
|
|
38
|
+
| Pathway Recipes (4) | `packages/sdk/docs/scaffold/recipes/` | `scaffold/recipes/` |
|
|
39
39
|
| Workflow Recipes | `packages/sdk/docs/scaffold/operations/workflow-recipes.md` | `scaffold/operations/workflow-recipes.md` |
|
|
40
40
|
| Propagation Pipeline | `packages/sdk/docs/scaffold/operations/propagation-pipeline.md` | `scaffold/operations/propagation-pipeline.md` |
|
|
41
41
|
| This doc | `packages/sdk/docs/scaffold/operations/scaffold-maintenance.md` | `scaffold/operations/scaffold-maintenance.md` |
|
|
@@ -120,6 +120,6 @@ The output lands in `packages/sdk/reference/` which is included in the npm packa
|
|
|
120
120
|
|
|
121
121
|
## Freshness Validation
|
|
122
122
|
|
|
123
|
-
External projects
|
|
123
|
+
External projects validate generated docs with `pnpm check:autogenerated-docs`, which now calls `pnpm exec elevasis-sdk validate-docs`. The legacy `scripts/validate-autogenerated-docs.mjs` file may still exist as a temporary compatibility shim in the template, but the SDK CLI is the canonical path.
|
|
124
124
|
|
|
125
125
|
At the monorepo level, `pnpm scaffold:sync` followed by `pnpm sync:verify` confirms that all artifacts are current and all downstream projects are consistent.
|
|
@@ -68,6 +68,23 @@ contract: {
|
|
|
68
68
|
- Both runtimes (frontend and platform) import from `@foundation/types`, keeping validation consistent.
|
|
69
69
|
- `@foundation/types` resolves to `foundations/types/index.ts` via the tsconfig path alias.
|
|
70
70
|
|
|
71
|
+
**Entity-backed workflows:** for workflows that operate on a domain entity, reference the entity contract rather than redeclaring it.
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// foundations/types/index.ts
|
|
75
|
+
import { BaseDealSchema } from '@elevasis/core/entities'
|
|
76
|
+
import { DealSchema } from '@foundation/types/entities' // project-local extended version
|
|
77
|
+
|
|
78
|
+
export const closeDealInputSchema = z.object({
|
|
79
|
+
deal: DealSchema,
|
|
80
|
+
closedReason: z.string()
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
export type CloseDealInput = z.infer<typeof closeDealInputSchema>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`DealSchema` is defined in `foundations/types/entities.ts` by extending `BaseDealSchema` with project-specific metadata. See [../recipes/extend-a-base-entity.md](../recipes/extend-a-base-entity.md) for the pattern.
|
|
87
|
+
|
|
71
88
|
### Steps
|
|
72
89
|
|
|
73
90
|
Each step is a `WorkflowStep` with: `id`, `name`, `description`, `handler`, `inputSchema`, `outputSchema`, and `next`.
|
|
@@ -273,7 +290,7 @@ Use this pattern in React components and hooks. `apiRequest` automatically attac
|
|
|
273
290
|
```typescript
|
|
274
291
|
// ui/src/features/notifications/hooks/useSendEmailNotification.ts
|
|
275
292
|
import { useMutation } from '@tanstack/react-query'
|
|
276
|
-
import { useApiClient } from '@/
|
|
293
|
+
import { useApiClient } from '@/lib/hooks/useApiClient'
|
|
277
294
|
import type { EmailNotificationInput, EmailNotificationOutput } from '@foundation/types'
|
|
278
295
|
|
|
279
296
|
export function useSendEmailNotification() {
|
|
@@ -13,14 +13,14 @@ See [glossary.md](../reference/glossary.md) for term disambiguation throughout t
|
|
|
13
13
|
|
|
14
14
|
## 1. Decide the feature shape
|
|
15
15
|
|
|
16
|
-
A shell feature requires
|
|
16
|
+
A shell feature requires a `feature.id` in the org model's `features[]` array to gate it. You have two options:
|
|
17
17
|
|
|
18
|
-
- **Reuse an existing
|
|
19
|
-
- **Add a new
|
|
18
|
+
- **Reuse an existing feature** (e.g., `operations`, `monitoring`). The new shell module shares the on/off toggle with the existing feature entry. Fine for sub-modules within the same product area.
|
|
19
|
+
- **Add a new feature object** -- add an entry to the `features[]` array in `foundations/config/organization-model.ts`. This is always a template-local change; no core package change is required.
|
|
20
20
|
|
|
21
|
-
For a genuinely new capability (e.g., `analytics`), you
|
|
21
|
+
For a genuinely new capability (e.g., `analytics`), you add a feature object to the defaults array and author a matching manifest.
|
|
22
22
|
|
|
23
|
-
See [glossary.md](../reference/glossary.md) under **Feature** (three contexts)
|
|
23
|
+
See [glossary.md](../reference/glossary.md) under **Feature** (three contexts).
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
@@ -28,26 +28,42 @@ See [glossary.md](../reference/glossary.md) under **Feature** (three contexts) a
|
|
|
28
28
|
|
|
29
29
|
File: `foundations/config/organization-model.ts`
|
|
30
30
|
|
|
31
|
-
Add
|
|
31
|
+
Add a new feature object to the `features[]` array passed to `defineOrganizationModel`.
|
|
32
32
|
|
|
33
33
|
```ts
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
import { defineOrganizationModel } from '@elevasis/core/organization-model'
|
|
35
|
+
```
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
features: {
|
|
39
|
-
enabled: { ..., analytics: false }, // start disabled
|
|
40
|
-
labels: { ..., analytics: 'Analytics' }
|
|
41
|
-
}
|
|
37
|
+
Use typed constants for the 7 platform features (`CRM_FEATURE_ID`, `LEAD_GEN_FEATURE_ID`, `PROJECTS_FEATURE_ID`, `OPERATIONS_FEATURE_ID`, `MONITORING_FEATURE_ID`, `SETTINGS_FEATURE_ID`, `SEO_FEATURE_ID`); use string literals for project-specific features you invent.
|
|
42
38
|
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
```ts
|
|
40
|
+
const foundationOrganizationModelOverride = defineOrganizationModel({
|
|
41
|
+
features: [
|
|
42
|
+
// ... existing features
|
|
43
|
+
{
|
|
44
|
+
id: 'analytics',
|
|
45
|
+
label: 'Analytics',
|
|
46
|
+
enabled: false, // start disabled
|
|
47
|
+
entityIds: [],
|
|
48
|
+
surfaceIds: [],
|
|
49
|
+
resourceIds: [],
|
|
50
|
+
capabilityIds: []
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
// ... rest of model
|
|
54
|
+
})
|
|
48
55
|
```
|
|
49
56
|
|
|
50
|
-
|
|
57
|
+
Each field of the feature object:
|
|
58
|
+
|
|
59
|
+
- `id` -- unique stable identifier; this is the value `FeatureModule.featureId` must match
|
|
60
|
+
- `label` -- display name; used by nav label resolution when no manifest override is provided
|
|
61
|
+
- `enabled` -- org-wide default; `MembershipFeatureConfig.features` can override per member
|
|
62
|
+
- `entityIds`, `surfaceIds`, `resourceIds`, `capabilityIds` -- semantic references (leave empty to start)
|
|
63
|
+
|
|
64
|
+
No domain entry or separate key resolver is needed. The `features[]` array is the sole source of truth.
|
|
65
|
+
|
|
66
|
+
**Two-step pattern:** in a template-derived project, the `defineOrganizationModel` output is passed to `createFoundationOrganizationModel(override)` in `foundations/config/organization-model.ts`. The result exposes `.model`, `.canonical`, and `.homeLabel`. See `external/_template/foundations/config/organization-model.ts` for the canonical two-step example.
|
|
51
67
|
|
|
52
68
|
---
|
|
53
69
|
|
|
@@ -62,7 +78,7 @@ import { AnalyticsSidebar } from './sidebar'
|
|
|
62
78
|
|
|
63
79
|
export const analyticsManifest: FeatureModule = {
|
|
64
80
|
key: 'analytics',
|
|
65
|
-
|
|
81
|
+
featureId: 'analytics', // must match a feature.id in the org model's features[] array
|
|
66
82
|
navEntry: {
|
|
67
83
|
label: 'Analytics',
|
|
68
84
|
icon: IconChartBar,
|
|
@@ -75,7 +91,7 @@ export const analyticsManifest: FeatureModule = {
|
|
|
75
91
|
|
|
76
92
|
Key fields:
|
|
77
93
|
|
|
78
|
-
- `
|
|
94
|
+
- `featureId` -- the org-model feature ID that gates the entire feature. The provider throws at startup if this ID is not found in the org model's `features[]` array. See [glossary.md](../reference/glossary.md) under **featureId**.
|
|
79
95
|
- `sidebar` -- a component that renders the subshell sidebar. Compose from published primitives. See [customization.md](../ui/customization.md).
|
|
80
96
|
- `subshellRoutes` -- every path that should activate this feature's sidebar.
|
|
81
97
|
|
|
@@ -52,6 +52,8 @@ export const myWorkflow: WorkflowDefinition = {
|
|
|
52
52
|
|
|
53
53
|
Define input/output schemas in `foundations/types/index.ts`, not inline. Both runtimes import from `@foundation/types`. See [workflow-recipes.md](../operations/workflow-recipes.md) for Zod schema conventions and adapter usage (`llm`, `storage`, `scheduler`, `notifications` from `@elevasis/sdk/worker`).
|
|
54
54
|
|
|
55
|
+
**Entity-backed workflows:** if your workflow operates on a domain entity (Project, Deal, Company, etc.), define or reference the entity shape in `foundations/types/entities.ts` rather than declaring an ad-hoc shape here. The entity types extend base contracts from `@elevasis/core/entities` (`BaseProject`, `BaseDeal`, etc.) with project-specific metadata. See [./extend-a-base-entity.md](./extend-a-base-entity.md) for the pattern.
|
|
56
|
+
|
|
55
57
|
---
|
|
56
58
|
|
|
57
59
|
## 2. Register in the DeploymentSpec
|
|
@@ -134,7 +136,7 @@ See `OrganizationModelResourceMapping` in [contracts.md](../reference/contracts.
|
|
|
134
136
|
## 5. Regenerate the topology map
|
|
135
137
|
|
|
136
138
|
```bash
|
|
137
|
-
pnpm generate-resources
|
|
139
|
+
pnpm exec elevasis-sdk generate-resources
|
|
138
140
|
```
|
|
139
141
|
|
|
140
142
|
Open `docs/resources.md` and confirm:
|
|
@@ -162,4 +164,4 @@ pnpm exec elevasis describe Elevasis/my-workflow
|
|
|
162
164
|
pnpm exec elevasis exec Elevasis/my-workflow --input '{"field": "value"}'
|
|
163
165
|
```
|
|
164
166
|
|
|
165
|
-
Use `--async` for long-running resources. Use `pnpm exec elevasis --prod exec ...` (flag before `exec`) for production. See [workflow-recipes.md](../operations/workflow-recipes.md) recipe 3 for the frontend trigger pattern.
|
|
167
|
+
Use `--async` for long-running resources. Use `pnpm exec elevasis --prod exec ...` (flag before `exec`) for production. See [workflow-recipes.md](../operations/workflow-recipes.md) recipe 3 for the low-level frontend trigger pattern (`useApiClient` + `useMutation`). For the higher-level UI pattern using `RunResourceButton`, `useExecuteResource`, and `ZodFormRenderer`, see [../ui/recipes.md](../ui/recipes.md) recipe 6.
|