@elevasis/sdk 1.44.3 → 1.46.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/cli.cjs +35026 -30226
- package/dist/index.d.ts +1786 -808
- package/dist/index.js +789 -739
- package/dist/node/index.d.ts +105 -181
- package/dist/node/index.js +2 -2
- package/dist/test-utils/index.d.ts +901 -359
- package/dist/test-utils/index.js +587 -824
- package/dist/worker/index.d.ts +12685 -0
- package/dist/worker/index.js +188 -216
- package/package.json +4 -7
- package/reference/_navigation.md +161 -22
- package/reference/_reference-manifest.json +228 -4
- package/reference/claude-config.md +8 -0
- package/reference/core/exports.mdx +2 -0
- package/reference/core/index.mdx +3 -3
- package/reference/examples/organization-model.ts +117 -111
- package/reference/index.mdx +4 -4
- package/reference/packages/core/src/business/README.md +4 -1
- package/reference/packages/core/src/content/README.md +19 -0
- package/reference/packages/core/src/organization-model/README.md +148 -149
- package/reference/packages/core/src/organization-model/readiness/README.md +42 -0
- package/reference/packages/ui/src/features/README.md +28 -28
- package/reference/rules/active-change-index.md +40 -54
- package/reference/rules/agent-runtime.md +81 -0
- package/reference/rules/agent-start-here.md +71 -163
- package/reference/rules/deployment.md +33 -10
- package/reference/rules/error-handling.md +26 -0
- package/reference/rules/execution.md +13 -0
- package/reference/rules/frontend.md +10 -3
- package/reference/rules/observability.md +9 -1
- package/reference/rules/operations.md +26 -17
- package/reference/rules/organization-model.md +74 -88
- package/reference/rules/organization-os.md +71 -88
- package/reference/rules/package-taxonomy.md +11 -2
- package/reference/rules/platform.md +13 -7
- package/reference/rules/shared-types.md +36 -0
- package/reference/rules/task-tracking.md +30 -5
- package/reference/rules/ui.md +145 -3
- package/reference/rules/vibe-intents.md +271 -0
- package/reference/rules/vibe.md +17 -243
- package/reference/scaffold/core/organization-graph.mdx +112 -99
- package/reference/scaffold/core/organization-model.mdx +231 -215
- package/reference/scaffold/operations/propagation-pipeline.md +16 -17
- package/reference/scaffold/operations/scaffold-maintenance.md +22 -20
- package/reference/scaffold/operations/workflow-recipes.md +72 -20
- package/reference/scaffold/recipes/add-a-feature.md +156 -146
- package/reference/scaffold/recipes/add-a-resource.md +123 -117
- package/reference/scaffold/recipes/customize-crm-actions.md +28 -13
- package/reference/scaffold/recipes/customize-knowledge-browser.md +52 -117
- package/reference/scaffold/recipes/customize-organization-model.md +161 -149
- package/reference/scaffold/recipes/extend-a-base-entity.md +156 -140
- package/reference/scaffold/recipes/extend-content.md +265 -0
- package/reference/scaffold/recipes/extend-crm.md +16 -11
- package/reference/scaffold/recipes/extend-lead-gen.md +37 -21
- package/reference/scaffold/recipes/gate-by-feature-or-admin.md +160 -118
- package/reference/scaffold/recipes/index.md +6 -3
- package/reference/scaffold/recipes/query-the-knowledge-graph.md +23 -23
- package/reference/scaffold/reference/contracts.md +30 -56
- package/reference/scaffold/reference/feature-registry.md +3 -0
- package/reference/scaffold/reference/glossary.md +4 -4
- package/reference/scaffold/reference/system-interface-capabilities.md +5 -4
- package/reference/scaffold/ui/composition-extensibility.mdx +271 -232
- package/reference/scaffold/ui/customization.md +2 -2
- package/reference/scaffold/ui/feature-flags-and-gating.md +14 -6
- package/reference/scaffold/ui/feature-shell.mdx +277 -62
- package/reference/scaffold/ui/recipes.md +229 -197
- package/reference/sdk/cli-management.mdx +166 -33
- package/reference/sdk/cli.mdx +90 -13
- package/reference/sdk/concepts.mdx +2 -0
- package/reference/sdk/define-builders.mdx +76 -0
- package/reference/sdk/deployment/command-center.mdx +6 -2
- package/reference/sdk/deployment/execution-reference.mdx +64 -186
- package/reference/sdk/deployment/index.mdx +2 -0
- package/reference/sdk/exports.mdx +4 -4
- package/reference/sdk/framework/agent.mdx +52 -116
- package/reference/sdk/framework/index.mdx +46 -65
- package/reference/sdk/framework/project-structure.mdx +150 -205
- package/reference/sdk/framework/tutorial-system.mdx +2 -2
- package/reference/sdk/human-in-the-loop.mdx +152 -0
- package/reference/sdk/index.mdx +6 -7
- package/reference/sdk/platform-tools/adapters-platform.mdx +3 -1
- package/reference/sdk/platform-tools/index.mdx +12 -0
- package/reference/sdk/platform-tools/type-safety.mdx +4 -0
- package/reference/sdk/project-deployment-spec.mdx +131 -0
- package/reference/sdk/resources/index.mdx +21 -7
- package/reference/sdk/resources/patterns.mdx +54 -24
- package/reference/sdk/resources/types.mdx +7 -4
- package/reference/sdk/templates/data-enrichment.mdx +7 -3
- package/reference/sdk/templates/email-sender.mdx +139 -135
- package/reference/sdk/templates/lead-scorer.mdx +5 -1
- package/reference/sdk/templates/pdf-generator.mdx +155 -151
- package/reference/sdk/templates/recurring-job.mdx +195 -189
- package/reference/sdk/templates/text-classifier.mdx +4 -0
- package/reference/sdk/templates/web-scraper.mdx +139 -135
- package/reference/spine/spine-primer.md +135 -96
- package/reference/ui/exports.mdx +1 -0
- package/reference/ui/index.mdx +14 -7
- package/dist/types/worker/adapters/anymailfinder.d.ts +0 -14
- package/dist/types/worker/adapters/apify.d.ts +0 -14
- package/dist/types/worker/adapters/approval.d.ts +0 -23
- package/dist/types/worker/adapters/attio.d.ts +0 -22
- package/dist/types/worker/adapters/clickup.d.ts +0 -22
- package/dist/types/worker/adapters/create-adapter.d.ts +0 -41
- package/dist/types/worker/adapters/crm.d.ts +0 -20
- package/dist/types/worker/adapters/dropbox.d.ts +0 -14
- package/dist/types/worker/adapters/email.d.ts +0 -25
- package/dist/types/worker/adapters/execution.d.ts +0 -22
- package/dist/types/worker/adapters/gmail.d.ts +0 -14
- package/dist/types/worker/adapters/google-sheets.d.ts +0 -14
- package/dist/types/worker/adapters/index.d.ts +0 -33
- package/dist/types/worker/adapters/instantly.d.ts +0 -14
- package/dist/types/worker/adapters/lead.d.ts +0 -28
- package/dist/types/worker/adapters/list.d.ts +0 -9
- package/dist/types/worker/adapters/llm.d.ts +0 -45
- package/dist/types/worker/adapters/millionverifier.d.ts +0 -14
- package/dist/types/worker/adapters/notification.d.ts +0 -28
- package/dist/types/worker/adapters/pdf.d.ts +0 -22
- package/dist/types/worker/adapters/projects.d.ts +0 -20
- package/dist/types/worker/adapters/resend.d.ts +0 -14
- package/dist/types/worker/adapters/scheduler.d.ts +0 -25
- package/dist/types/worker/adapters/signature-api.d.ts +0 -14
- package/dist/types/worker/adapters/storage.d.ts +0 -33
- package/dist/types/worker/adapters/stripe.d.ts +0 -14
- package/dist/types/worker/adapters/tomba.d.ts +0 -14
- package/dist/types/worker/index.d.ts +0 -60
- package/dist/types/worker/platform.d.ts +0 -90
- package/dist/types/worker/utils.d.ts +0 -9
- package/reference/claude-config/Overview.md +0 -230
- package/reference/claude-config/hooks/post-edit-validate.mjs +0 -98
- package/reference/claude-config/hooks/scaffold-registry-reminder.mjs +0 -187
- package/reference/claude-config/hooks/tool-failure-recovery.mjs +0 -73
- package/reference/claude-config/registries/graph-skills.json +0 -4
- package/reference/claude-config/registries/knowledge-flags.json +0 -154
- package/reference/claude-config/registries/skill-coverage.json +0 -20
- package/reference/claude-config/rules/active-change-index.md +0 -22
- package/reference/claude-config/rules/agent-start-here.md +0 -22
- package/reference/claude-config/rules/deployment.md +0 -22
- package/reference/claude-config/rules/error-handling.md +0 -22
- package/reference/claude-config/rules/execution.md +0 -22
- package/reference/claude-config/rules/frontend.md +0 -22
- package/reference/claude-config/rules/observability.md +0 -22
- package/reference/claude-config/rules/operations.md +0 -22
- package/reference/claude-config/rules/organization-model.md +0 -22
- package/reference/claude-config/rules/organization-os.md +0 -22
- package/reference/claude-config/rules/package-taxonomy.md +0 -22
- package/reference/claude-config/rules/platform.md +0 -22
- package/reference/claude-config/rules/shared-types.md +0 -22
- package/reference/claude-config/rules/task-tracking.md +0 -22
- package/reference/claude-config/rules/topbar-actions.md +0 -70
- package/reference/claude-config/rules/ui.md +0 -22
- package/reference/claude-config/rules/vibe.md +0 -22
- package/reference/claude-config/scripts/statusline-command.js +0 -18
- package/reference/claude-config/settings.json +0 -30
- package/reference/claude-config/skills/client/SKILL.md +0 -201
- package/reference/claude-config/skills/deploy/SKILL.md +0 -159
- package/reference/claude-config/skills/dsp/SKILL.md +0 -66
- package/reference/claude-config/skills/elevasis/SKILL.md +0 -251
- package/reference/claude-config/skills/explore/SKILL.md +0 -78
- package/reference/claude-config/skills/git-sync/SKILL.md +0 -166
- package/reference/claude-config/skills/om/SKILL.md +0 -475
- package/reference/claude-config/skills/om/operations/build.md +0 -237
- package/reference/claude-config/skills/om/operations/codify-level-a.md +0 -109
- package/reference/claude-config/skills/om/operations/codify-level-b.md +0 -159
- package/reference/claude-config/skills/om/operations/customers.md +0 -114
- package/reference/claude-config/skills/om/operations/features.md +0 -88
- package/reference/claude-config/skills/om/operations/goals.md +0 -123
- package/reference/claude-config/skills/om/operations/identity.md +0 -97
- package/reference/claude-config/skills/om/operations/labels.md +0 -110
- package/reference/claude-config/skills/om/operations/offerings.md +0 -114
- package/reference/claude-config/skills/om/operations/roles.md +0 -104
- package/reference/claude-config/skills/om/operations/scaffold.md +0 -163
- package/reference/claude-config/skills/om/operations/techStack.md +0 -38
- package/reference/claude-config/skills/project/SKILL.md +0 -1114
- package/reference/claude-config/skills/run-ui/SKILL.md +0 -73
- package/reference/claude-config/skills/save/SKILL.md +0 -183
- package/reference/claude-config/skills/setup/SKILL.md +0 -290
- package/reference/claude-config/skills/status/SKILL.md +0 -59
- package/reference/claude-config/skills/submit-request/SKILL.md +0 -180
- package/reference/claude-config/skills/sync/SKILL.md +0 -47
- package/reference/claude-config/skills/tutorial/SKILL.md +0 -259
- package/reference/claude-config/skills/tutorial/progress-template.md +0 -74
- package/reference/claude-config/skills/tutorial/technical.md +0 -1303
- package/reference/claude-config/skills/tutorial/vibe-coder.md +0 -890
- package/reference/claude-config/sync-notes/2026-04-22-git-sync-and-sync-notes.md +0 -27
- package/reference/claude-config/sync-notes/2026-04-22-lead-gen-deliverability-removal.md +0 -30
- package/reference/claude-config/sync-notes/2026-04-24-test-utils-and-template-tests.md +0 -73
- package/reference/claude-config/sync-notes/2026-04-24-ui-consolidation-and-sdk-cli-train.md +0 -86
- package/reference/claude-config/sync-notes/2026-04-25-auth-role-system-and-settings-roles.md +0 -55
- package/reference/claude-config/sync-notes/2026-04-27-crm-hitl-action-layer-cutover.md +0 -97
- package/reference/claude-config/sync-notes/2026-04-27-lead-gen-substrate-train.md +0 -112
- package/reference/claude-config/sync-notes/2026-04-29-crm-state-and-lead-gen-processing-status.md +0 -93
- package/reference/claude-config/sync-notes/2026-05-02-crm-ownership-next-action.md +0 -58
- package/reference/claude-config/sync-notes/2026-05-02-template-hardcode-workos-config.md +0 -56
- package/reference/claude-config/sync-notes/2026-05-04-elevasis-workspace.md +0 -71
- package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +0 -83
- package/reference/claude-config/sync-notes/2026-05-04-template-skills-run-ui-and-tutorial.md +0 -59
- package/reference/claude-config/sync-notes/2026-05-05-list-builder.md +0 -42
- package/reference/claude-config/sync-notes/2026-05-06-crm-spine.md +0 -60
- package/reference/claude-config/sync-notes/2026-05-06-sdk-changes-release-train.md +0 -37
- package/reference/claude-config/sync-notes/2026-05-07-sdk-changes-release-train.md +0 -34
- package/reference/claude-config/sync-notes/2026-05-08-resource-governance-scaffold-guidance.md +0 -38
- package/reference/claude-config/sync-notes/2026-05-09-clients-domain.md +0 -32
- package/reference/claude-config/sync-notes/2026-05-09-command-system.md +0 -33
- package/reference/claude-config/sync-notes/2026-05-09-resource-governance-and-misc.md +0 -69
- package/reference/claude-config/sync-notes/2026-05-12-sdk-ready-release-train.md +0 -30
- package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +0 -45
- package/reference/claude-config/sync-notes/2026-05-15-om-skill-rename-and-write-family.md +0 -52
- package/reference/claude-config/sync-notes/2026-05-17-sdk-boundary-consolidation.md +0 -33
- package/reference/claude-config/sync-notes/2026-05-20-om-define-helpers.md +0 -32
- package/reference/claude-config/sync-notes/2026-05-22-access-model-and-right-panel.md +0 -43
- package/reference/claude-config/sync-notes/2026-05-22-lead-gen-tenant-config.md +0 -40
- package/reference/claude-config/sync-notes/2026-05-22-org-model-multi-file-split.md +0 -61
- package/reference/claude-config/sync-notes/2026-05-23-branding-names-to-identity.md +0 -49
- package/reference/claude-config/sync-notes/2026-05-23-lead-gen-manage-access.md +0 -31
- package/reference/claude-config/sync-notes/2026-05-23-om-deployment-drift-detection.md +0 -42
- package/reference/claude-config/sync-notes/2026-05-23-om-full-model-deploy-contract.md +0 -33
- package/reference/claude-config/sync-notes/2026-05-23-ui-sdk-package-fixes.md +0 -37
- package/reference/claude-config/sync-notes/2026-05-24-platform-invite-router-core-baseline.md +0 -28
- package/reference/claude-config/sync-notes/2026-05-24-system-interface-readiness.md +0 -43
- package/reference/claude-config/sync-notes/2026-05-25-invitation-login-loader.md +0 -26
- package/reference/claude-config/sync-notes/2026-05-25-om-topbar-requests.md +0 -33
- package/reference/claude-config/sync-notes/2026-05-25-system-interface-profile-registry-and-substrate.md +0 -35
- package/reference/claude-config/sync-notes/2026-05-25-tenant-om-scaffold-cli.md +0 -49
- package/reference/claude-config/sync-notes/2026-05-25-vibe-operate-intent.md +0 -47
- package/reference/claude-config/sync-notes/2026-05-28-om-snapshot-sdk-workflow-config.md +0 -33
- package/reference/claude-config/sync-notes/2026-05-30-client-source-and-om-profiles.md +0 -39
- package/reference/claude-config/sync-notes/2026-06-02-knowledge-nested-group-routing.md +0 -27
- package/reference/claude-config/sync-notes/2026-06-02-nest-projects-under-platform.md +0 -45
- package/reference/claude-config/sync-notes/2026-06-03-skill-autogen-and-client-skill.md +0 -34
- package/reference/claude-config/sync-notes/2026-06-04-scaffold-registry-lane-severity.md +0 -34
- package/reference/claude-config/sync-notes/2026-06-05-appearance-app-mode-decouple.md +0 -29
- package/reference/claude-config/sync-notes/2026-06-05-ontology-endpoint-rename-and-knowledge-browser-ui.md +0 -86
- package/reference/claude-config/sync-notes/2026-06-06-om-build-systems-scaffold.md +0 -47
- package/reference/claude-config/sync-notes/2026-06-06-om-item-copy-references.md +0 -50
- package/reference/claude-config/sync-notes/2026-06-08-knowledge-base-page-not-found-fix.md +0 -76
- package/reference/claude-config/sync-notes/2026-06-09-agent-sessions-public-agent-chat-route.md +0 -75
- package/reference/claude-config/sync-notes/2026-06-09-sdk-cli-load-org-model-resolution.md +0 -42
- package/reference/claude-config/sync-notes/2026-06-12-agent-grants-visualizer-operations.md +0 -30
- package/reference/claude-config/sync-notes/2026-06-14-session-ux-and-project-cli-json.md +0 -33
- package/reference/claude-config/sync-notes/2026-06-14-shared-session-conversation-view.md +0 -26
- package/reference/claude-config/sync-notes/2026-06-15-session-chat-zero-wiring.md +0 -46
- package/reference/claude-config/sync-notes/2026-06-17-agent-session-ux-features.md +0 -34
- package/reference/claude-config/sync-notes/2026-06-25-shared-page-scroll-contract-guard.md +0 -52
- package/reference/claude-config/sync-notes/2026-06-26-leadgen-overview-om-telemetry.md +0 -47
- package/reference/claude-config/sync-notes/2026-07-21-agent-scaffold-hardening.md +0 -75
- package/reference/claude-config/sync-notes/2026-07-23-agent-session-memory.md +0 -49
- package/reference/claude-config/sync-notes/2026-07-23-workos-org-marker.md +0 -50
- package/reference/claude-config/sync-notes/2026-07-24-claude-5-models-and-session-surface-fixes.md +0 -116
- package/reference/claude-config/sync-notes/2026-07-27-agent-strict-output-and-turn-drift.md +0 -73
- package/reference/claude-config/sync-notes/2026-07-28-agent-reply-is-its-own-field.md +0 -84
- package/reference/claude-config/sync-notes/2026-07-30-login-screen-and-member-provisioning-state.md +0 -114
- package/reference/claude-config/sync-notes/2026-08-02-auth-guard-defaults-and-truncation-fix.md +0 -122
- package/reference/claude-config/sync-notes/2026-08-03-agent-prose-escape-normalization.md +0 -88
- package/reference/claude-config/sync-notes/2026-08-03-cli-gateway-errors-and-request-timeout.md +0 -120
- package/reference/claude-config/sync-notes/README.md +0 -43
- package/reference/sdk/framework/interaction-guidance.mdx +0 -182
- package/reference/sdk/framework/memory.mdx +0 -326
- package/reference/sdk/framework/resource-documentation.mdx +0 -90
- package/reference/sdk/roadmap.mdx +0 -164
|
@@ -1,143 +1,159 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Extend a Base Entity
|
|
3
|
-
description: Add project-specific metadata to the canonical entity shapes (Project, Deal, Company, etc.) from @elevasis/core/entities using the TMeta extension slot.
|
|
4
|
-
---
|
|
1
|
+
---
|
|
2
|
+
title: Extend a Base Entity
|
|
3
|
+
description: Add project-specific metadata to the canonical entity shapes (Project, Deal, Company, etc.) from @elevasis/core/entities using the TMeta extension slot.
|
|
4
|
+
---
|
|
5
5
|
<!-- @generated by packages/sdk/scripts/copy-reference-docs.mjs -- DO NOT EDIT -->
|
|
6
6
|
<!-- Regenerate: pnpm scaffold:sync -->
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
# Extend a Base Entity
|
|
10
|
-
|
|
11
|
-
Workflows and UI features often operate on domain entities such as projects, deals, companies, or contacts. Rather than each project declaring its own shape from scratch, `@elevasis/core/entities` provides typed base interfaces generic over a `<TMeta>` slot. External projects extend these to add project-specific fields while keeping the canonical shape stable and interoperable with platform tooling.
|
|
12
|
-
|
|
13
|
-
The canonical demo lives in `core/types/entities.ts` of any scaffold project.
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## Available Base Entities
|
|
18
|
-
|
|
19
|
-
Each entity ships as a TypeScript interface, a Zod schema, and an Input type:
|
|
20
|
-
|
|
21
|
-
| Set | Description |
|
|
22
|
-
| -------------------------------------------------------------- | ------------------------------------------- |
|
|
23
|
-
| `BaseProject` / `BaseProjectSchema` / `BaseProjectInput` | Client or internal project record |
|
|
24
|
-
| `BaseMilestone` / `BaseMilestoneSchema` / `BaseMilestoneInput` | Milestone within a project |
|
|
25
|
-
| `BaseTask` / `BaseTaskSchema` / `BaseTaskInput` | Discrete task within a project or milestone |
|
|
26
|
-
| `BaseDeal` / `BaseDealSchema` / `BaseDealInput` | Sales or partnership deal record |
|
|
27
|
-
| `BaseCompany` / `BaseCompanySchema` / `BaseCompanyInput` | Company / account record |
|
|
28
|
-
| `BaseContact` / `BaseContactSchema` / `BaseContactInput` | Individual contact record |
|
|
29
|
-
|
|
30
|
-
All imports come from `@elevasis/core/entities`.
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Recipe 1 -- Extend a base entity with custom metadata
|
|
35
|
-
|
|
36
|
-
Place this in `core/types/entities.ts`. This is the primary pattern -- the scaffold template ships this exact example.
|
|
37
|
-
|
|
38
|
-
```ts
|
|
39
|
-
import { z } from 'zod'
|
|
40
|
-
import type { BaseProject, BaseDeal } from '@elevasis/core/entities'
|
|
41
|
-
import { BaseProjectSchema, BaseDealSchema } from '@elevasis/core/entities'
|
|
42
|
-
|
|
43
|
-
// -- Project: extending metadata on a base entity --
|
|
44
|
-
|
|
45
|
-
export const ProjectMetaSchema = z.object({
|
|
46
|
-
budget: z.number().nonnegative(),
|
|
47
|
-
clientPriority: z.enum(['low', 'medium', 'high'])
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
export type ProjectMeta = z.infer<typeof ProjectMetaSchema>
|
|
51
|
-
|
|
52
|
-
export const ProjectSchema = BaseProjectSchema.extend({ metadata: ProjectMetaSchema })
|
|
53
|
-
|
|
54
|
-
export type Project = BaseProject<ProjectMeta>
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Key points:
|
|
58
|
-
|
|
59
|
-
- `BaseProjectSchema.extend({ metadata: ... })` merges your metadata Zod schema into the validated shape. Zod handles the rest.
|
|
60
|
-
- `BaseProject<ProjectMeta>` infers the TypeScript type with your metadata typed correctly.
|
|
61
|
-
- Only the `metadata` field is extended -- all other base fields (`id`, `organizationId`, `name`, `status`, `createdAt`, `updatedAt`, etc.) are inherited unchanged.
|
|
62
|
-
- This file is the single source of truth for entity shapes across `core/`, `operations/`, and `ui/`.
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## Recipe 2 -- Use a base entity as-is
|
|
67
|
-
|
|
68
|
-
When the base shape covers everything the project needs, skip the extension entirely:
|
|
69
|
-
|
|
70
|
-
```ts
|
|
71
|
-
import type { BaseDeal } from '@elevasis/core/entities'
|
|
72
|
-
import { BaseDealSchema } from '@elevasis/core/entities'
|
|
73
|
-
|
|
74
|
-
export const DealSchema = BaseDealSchema
|
|
75
|
-
|
|
76
|
-
export type Deal = BaseDeal
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
`BaseDeal` without a type argument defaults `TMeta` to an empty object (`{}`), which Zod validates as `z.object({})`. Use this path when the project has no per-deal custom fields -- you still get the canonical shape and full Zod validation for free.
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
## Recipe 3 -- Reference entity types from a workflow input schema
|
|
84
|
-
|
|
85
|
-
Workflows that operate on projects or deals should reference the project-local entity types rather than redeclaring the shape. Add this to `operations/src/<workflow>/workflow.ts`:
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
import {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
8
|
+
|
|
9
|
+
# Extend a Base Entity
|
|
10
|
+
|
|
11
|
+
Workflows and UI features often operate on domain entities such as projects, deals, companies, or contacts. Rather than each project declaring its own shape from scratch, `@elevasis/core/entities` provides typed base interfaces generic over a `<TMeta>` slot. External projects extend these to add project-specific fields while keeping the canonical shape stable and interoperable with platform tooling.
|
|
12
|
+
|
|
13
|
+
The canonical demo lives in `core/types/entities.ts` of any scaffold project.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Available Base Entities
|
|
18
|
+
|
|
19
|
+
Each entity ships as a TypeScript interface, a Zod schema, and an Input type:
|
|
20
|
+
|
|
21
|
+
| Set | Description |
|
|
22
|
+
| -------------------------------------------------------------- | ------------------------------------------- |
|
|
23
|
+
| `BaseProject` / `BaseProjectSchema` / `BaseProjectInput` | Client or internal project record |
|
|
24
|
+
| `BaseMilestone` / `BaseMilestoneSchema` / `BaseMilestoneInput` | Milestone within a project |
|
|
25
|
+
| `BaseTask` / `BaseTaskSchema` / `BaseTaskInput` | Discrete task within a project or milestone |
|
|
26
|
+
| `BaseDeal` / `BaseDealSchema` / `BaseDealInput` | Sales or partnership deal record |
|
|
27
|
+
| `BaseCompany` / `BaseCompanySchema` / `BaseCompanyInput` | Company / account record |
|
|
28
|
+
| `BaseContact` / `BaseContactSchema` / `BaseContactInput` | Individual contact record |
|
|
29
|
+
|
|
30
|
+
All imports come from `@elevasis/core/entities`.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Recipe 1 -- Extend a base entity with custom metadata
|
|
35
|
+
|
|
36
|
+
Place this in `core/types/entities.ts`. This is the primary pattern -- the scaffold template ships this exact example.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { z } from 'zod'
|
|
40
|
+
import type { BaseProject, BaseDeal } from '@elevasis/core/entities'
|
|
41
|
+
import { BaseProjectSchema, BaseDealSchema } from '@elevasis/core/entities'
|
|
42
|
+
|
|
43
|
+
// -- Project: extending metadata on a base entity --
|
|
44
|
+
|
|
45
|
+
export const ProjectMetaSchema = z.object({
|
|
46
|
+
budget: z.number().nonnegative(),
|
|
47
|
+
clientPriority: z.enum(['low', 'medium', 'high'])
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
export type ProjectMeta = z.infer<typeof ProjectMetaSchema>
|
|
51
|
+
|
|
52
|
+
export const ProjectSchema = BaseProjectSchema.extend({ metadata: ProjectMetaSchema })
|
|
53
|
+
|
|
54
|
+
export type Project = BaseProject<ProjectMeta>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Key points:
|
|
58
|
+
|
|
59
|
+
- `BaseProjectSchema.extend({ metadata: ... })` merges your metadata Zod schema into the validated shape. Zod handles the rest.
|
|
60
|
+
- `BaseProject<ProjectMeta>` infers the TypeScript type with your metadata typed correctly.
|
|
61
|
+
- Only the `metadata` field is extended -- all other base fields (`id`, `organizationId`, `name`, `status`, `createdAt`, `updatedAt`, etc.) are inherited unchanged.
|
|
62
|
+
- This file is the single source of truth for entity shapes across `core/`, `operations/`, and `ui/`.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Recipe 2 -- Use a base entity as-is
|
|
67
|
+
|
|
68
|
+
When the base shape covers everything the project needs, skip the extension entirely:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import type { BaseDeal } from '@elevasis/core/entities'
|
|
72
|
+
import { BaseDealSchema } from '@elevasis/core/entities'
|
|
73
|
+
|
|
74
|
+
export const DealSchema = BaseDealSchema
|
|
75
|
+
|
|
76
|
+
export type Deal = BaseDeal
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`BaseDeal` without a type argument defaults `TMeta` to an empty object (`{}`), which Zod validates as `z.object({})`. Use this path when the project has no per-deal custom fields -- you still get the canonical shape and full Zod validation for free.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Recipe 3 -- Reference entity types from a workflow input schema
|
|
84
|
+
|
|
85
|
+
Workflows that operate on projects or deals should reference the project-local entity types rather than redeclaring the shape. Add this to `operations/src/<workflow>/workflow.ts`:
|
|
86
|
+
|
|
87
|
+
<!-- doc-snippet:skip: illustrative excerpt -- `resourceDescriptors` names the project's own resource-descriptors export, and `steps` is shown unimported for readability -->
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { z } from 'zod'
|
|
91
|
+
import type { WorkflowDefinition } from '@elevasis/sdk'
|
|
92
|
+
import { ProjectSchema } from '@core/types/entities'
|
|
93
|
+
import { resourceDescriptors } from '@core/config/organization-model'
|
|
94
|
+
|
|
95
|
+
const inputSchema = z.object({
|
|
96
|
+
project: ProjectSchema,
|
|
97
|
+
notes: z.string().optional()
|
|
98
|
+
})
|
|
99
|
+
const outputSchema = z.object({ ok: z.boolean() })
|
|
100
|
+
|
|
101
|
+
export const myWorkflow: WorkflowDefinition = {
|
|
102
|
+
config: {
|
|
103
|
+
resource: resourceDescriptors.myWorkflow,
|
|
104
|
+
resourceId: resourceDescriptors.myWorkflow.id,
|
|
105
|
+
name: 'My Workflow',
|
|
106
|
+
description: 'Runs against a project entity.',
|
|
107
|
+
type: resourceDescriptors.myWorkflow.kind,
|
|
108
|
+
version: '1.0.0',
|
|
109
|
+
status: 'dev',
|
|
110
|
+
category: 'production'
|
|
111
|
+
},
|
|
112
|
+
contract: { inputSchema, outputSchema },
|
|
113
|
+
steps,
|
|
114
|
+
entryPoint: 'run'
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The `@core/*` alias maps to the `core/` workspace package. This keeps entity contracts in one place and ensures the workflow input type matches whatever the UI passes as the execution payload.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Recipe 4 -- Reference entity types from the UI
|
|
123
|
+
|
|
124
|
+
UI components accept entity types directly in props. The entity type flows from the `core` package through the component into the workflow execution payload:
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
import type { Project } from '@core/types/entities'
|
|
128
|
+
|
|
129
|
+
interface ProjectCardProps {
|
|
130
|
+
project: Project
|
|
131
|
+
onExecute?: (project: Project) => void
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function ProjectCard({ project, onExecute }: ProjectCardProps) {
|
|
135
|
+
return (
|
|
136
|
+
<button onClick={() => onExecute?.(project)}>
|
|
137
|
+
Run workflow for {project.name}
|
|
138
|
+
</button>
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
When wiring this to a `RunResourceButton`, the entity instance becomes the workflow input. See UI Recipes recipe 6 (`Execute a Resource from a Surface`) at `../ui/recipes.md` for the end-to-end pattern where the entity type flows into a resource execution via `RunResourceButton`.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Verification
|
|
148
|
+
|
|
149
|
+
- **Test core contracts:** `pnpm -C core test` runs the Vitest suite. The template ships `core/types/entities.test.ts` as a working smoke-check -- it `safeParse`s a valid project (expects success) and an invalid one (expects failure). Run this after any schema change.
|
|
150
|
+
- **Round-trip safeParse:** Call `ProjectSchema.safeParse(candidateObject)` in a test or REPL to confirm the Zod shape accepts the data your workflows and UI will produce.
|
|
151
|
+
- **Cross-package type check:** `pnpm -C ui build` will surface any TypeScript errors if a UI component or hook passes a mismatched entity type to a workflow input.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Cross-references
|
|
156
|
+
|
|
157
|
+
- [./add-a-resource.md](./add-a-resource.md) -- resource authoring that consumes entity types in `inputSchema`
|
|
158
|
+
- [../ui/recipes.md](../ui/recipes.md) recipe 6 -- execute a resource from a surface, with entity-typed input via `RunResourceButton`
|
|
159
|
+
- [../reference/contracts.md](../reference/contracts.md) -- auto-generated TypeScript contract shapes for all Organization OS types
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Build and Extend Content
|
|
3
|
+
description: Map the content platform primitives available to SDK projects: pipeline and step catalogs, shared review/pipeline/distribution pages, data hooks, the content workflow adapter, artifacts as rules documents, and org-model extension boundaries.
|
|
4
|
+
---
|
|
5
|
+
<!-- @generated by packages/sdk/scripts/copy-reference-docs.mjs -- DO NOT EDIT -->
|
|
6
|
+
<!-- Regenerate: pnpm scaffold:sync -->
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Build and Extend Content
|
|
10
|
+
|
|
11
|
+
Use this recipe when a downstream project wants to build on the shared content system instead of forking it.
|
|
12
|
+
|
|
13
|
+
Good trigger phrases:
|
|
14
|
+
|
|
15
|
+
- "Add a content pipeline for our podcast."
|
|
16
|
+
- "Change the review screen for clip proposals."
|
|
17
|
+
- "Write a workflow that produces the next step of a content item."
|
|
18
|
+
- "Store our style guide so producers read the same rules."
|
|
19
|
+
- "Track where each piece got published."
|
|
20
|
+
|
|
21
|
+
Content is a layered platform surface, not one component:
|
|
22
|
+
|
|
23
|
+
- **Organization OS:** pipelines, steps, statuses, pillars, and platforms are **catalogs** in the content System's ontology, not hardcoded enums. `content.config.defaultPipelineId` names the pipeline the UI opens by default.
|
|
24
|
+
- **Shared UI:** overview, items list, item review, pipelines, pipeline workspace, distributions, and rules-and-artifacts pages live in `@elevasis/ui/features/content`.
|
|
25
|
+
- **Headless hooks:** item, attempt, distribution, artifact, and pipeline-summary hooks live under `@elevasis/ui/hooks`.
|
|
26
|
+
- **Workflow adapter:** `content` from `@elevasis/sdk/worker` lets workflows create items, record attempts, and open distributions through platform tools.
|
|
27
|
+
- **Rules documents:** governing documents (idea banks, ICP docs, style guides, selection briefs) are **artifacts**, reached through the `artifacts` adapter, not a content-specific table.
|
|
28
|
+
- **System API Interface:** `content` uses the flat `system.apiInterface` marker. Readiness is derived from scoped resources, ontology bindings, and required catalogs — `content:object/item` plus the pipeline, step, and status catalogs.
|
|
29
|
+
|
|
30
|
+
## The one thing to understand first: a pipeline is data
|
|
31
|
+
|
|
32
|
+
Every other system in this scaffold has its structure in code. Content does not. A pipeline is a catalog record, its steps are a second catalog record, and a workflow claims a step **by step key**. Adding a pipeline is therefore an org-model edit plus one workflow per step — no changes to shared UI, no new routes, no fork.
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
content:catalog/pipeline which pipelines exist
|
|
36
|
+
content:catalog/{pipeline}-steps the ordered steps of one pipeline
|
|
37
|
+
content:catalog/status item lifecycle statuses
|
|
38
|
+
content:catalog/pillar editorial pillars (optional)
|
|
39
|
+
content:catalog/platform distribution targets
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
A pipeline's step catalog is named `content:catalog/{pipelineId}-steps` and referenced from the pipeline record's `stepCatalog`. Get that name wrong and the workspace renders an empty pipeline with no error — the binding is by string.
|
|
43
|
+
|
|
44
|
+
## Decision Table
|
|
45
|
+
|
|
46
|
+
| User wants | Start here | Notes |
|
|
47
|
+
| ------------------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
48
|
+
| Add a pipeline, step, status, pillar, or platform | `core/config/organization-model.ts` — the content System's `ontology` | Catalog edit. Add the step catalog **and** point the pipeline record's `stepCatalog` at it. |
|
|
49
|
+
| Produce the next step of an item from a workflow | `content` from `@elevasis/sdk/worker` | One workflow per step. Claim the step with `stepKey`; return the next step key. |
|
|
50
|
+
| Change the review screen | `ContentItemReviewPage` slots, or compose `ContentReviewCard` yourself | Prefer slots. The card, action bar, alternates panel, and processing strip are all exported individually. |
|
|
51
|
+
| Add content nav or a content route | `CONTENT_ITEMS`, `ContentSidebar`, `ContentSidebarMiddle` | Same manifest/sidebar composition pattern as CRM and lead-gen. |
|
|
52
|
+
| Store a governing document producers should read | `artifacts` from `@elevasis/sdk/worker` | `kind` MUST start with `content:` or RLS rejects an org-owned write. Pass `pipelineId` or `getActive` never finds it. |
|
|
53
|
+
| Track where a piece was published | `createDistribution` / `updateDistribution` | One distribution row per platform per item. |
|
|
54
|
+
| Add a new persisted content column or table | Platform/API migration work, not just scaffold work | DB, core schemas/types, API service/handlers, hooks, docs, and scaffold contracts move together. |
|
|
55
|
+
|
|
56
|
+
## Published Content Surfaces
|
|
57
|
+
|
|
58
|
+
| Surface | Import from | Use for |
|
|
59
|
+
| -------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | ------------------------------------------------- |
|
|
60
|
+
| `contentManifest`, `CONTENT_ITEMS`, `ContentSidebar`, `ContentSidebarTop`, `ContentSidebarMiddle`, `MyReviewQueuePanel` | `@elevasis/ui/features/content` | Feature registration and sidebar composition |
|
|
61
|
+
| `ContentOverviewPage`, `ContentItemsPage`, `ContentItemReviewPage`, `ContentPipelinesPage`, `ContentPipelineWorkspacePage` | `@elevasis/ui/features/content` | Shared pages you can route to or wrap |
|
|
62
|
+
| `ContentSettingsPage`, `ContentDistributionsPage`, `ContentDistributionDetailPage` | `@elevasis/ui/features/content` | Rules-and-artifacts and distribution surfaces |
|
|
63
|
+
| `ContentReviewCard`, `ReviewActionBar`, `PayloadBody`, `AlternatesPanel`, `ProcessingStateStrip` | `@elevasis/ui/features/content` | Review UI primitives for a custom review screen |
|
|
64
|
+
| `useContentConfig`, `resolveContentStepResource` | `@elevasis/ui/features/content` | Read the resolved pipeline/step catalogs from OM |
|
|
65
|
+
| `useContentItems`, `useContentItem`, `useContentItemAttempts`, `useUpdateContentItem`, `useReviewContentItem` | `@elevasis/ui/hooks` | Item data access and review mutations |
|
|
66
|
+
| `useContentDistributions`, `useContentDistribution`, `useUpdateContentDistribution` | `@elevasis/ui/hooks` | Distribution data access |
|
|
67
|
+
| `useContentArtifacts`, `filterContentArtifacts`, `useContentPipelineSummary` | `@elevasis/ui/hooks` | Rules documents and pipeline roll-ups |
|
|
68
|
+
| `content`, `artifacts` | `@elevasis/sdk/worker` | Workflow-side content and rules-document adapters |
|
|
69
|
+
|
|
70
|
+
Read the generated contracts before changing typed boundaries:
|
|
71
|
+
|
|
72
|
+
`operations/node_modules/@elevasis/sdk/reference/scaffold/reference/contracts.md`
|
|
73
|
+
|
|
74
|
+
Look for the **Content Platform Primitives** section: item/attempt/distribution rows, review decisions, the status and pillar vocabularies, and the `ContentToolMap` adapter map.
|
|
75
|
+
|
|
76
|
+
## 1. Add a Pipeline
|
|
77
|
+
|
|
78
|
+
A pipeline is two catalog records plus the workflows that claim its steps.
|
|
79
|
+
|
|
80
|
+
<!-- doc-snippet:skip: illustrative excerpt -- catalog shape, not a compilable module -->
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
// core/config/organization-model.ts -- inside the content System's `ontology.catalogTypes`
|
|
84
|
+
'content:catalog/pipeline': {
|
|
85
|
+
entries: {
|
|
86
|
+
'podcast-to-clips': {
|
|
87
|
+
label: 'Podcast to Clips',
|
|
88
|
+
stepCatalog: 'content:catalog/podcast-to-clips-steps'
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
'content:catalog/podcast-to-clips-steps': {
|
|
93
|
+
entries: {
|
|
94
|
+
'transcript': { label: 'Transcript', order: 1 },
|
|
95
|
+
'clip-selection': { label: 'Clip Selection', order: 2 },
|
|
96
|
+
'publish': { label: 'Publish', order: 3 }
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Then set `content.config.defaultPipelineId` if this should be the pipeline the UI opens first.
|
|
102
|
+
|
|
103
|
+
**The step catalog name is load-bearing.** `content:catalog/{pipelineId}-steps` must match the pipeline record's `stepCatalog` exactly. Nothing type-checks that string.
|
|
104
|
+
|
|
105
|
+
## 2. Produce a Step in a Workflow
|
|
106
|
+
|
|
107
|
+
One workflow per step. The workflow records an **attempt** against the item, tagged with the step it satisfies:
|
|
108
|
+
|
|
109
|
+
<!-- doc-snippet:skip: illustrative excerpt -- `resourceDescriptors` names the project's own resource-descriptors export -->
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
// operations/src/content/clip-selection.ts
|
|
113
|
+
import type { WorkflowDefinition } from '@elevasis/sdk'
|
|
114
|
+
import { content } from '@elevasis/sdk/worker'
|
|
115
|
+
import { resourceDescriptors } from '@core/config/organization-model'
|
|
116
|
+
import { z } from 'zod'
|
|
117
|
+
|
|
118
|
+
const inputSchema = z.object({ contentItemId: z.string().uuid() })
|
|
119
|
+
const outputSchema = z.object({ attemptId: z.string(), nextStepKey: z.string().nullable() })
|
|
120
|
+
|
|
121
|
+
export const clipSelectionWorkflow: WorkflowDefinition = {
|
|
122
|
+
config: {
|
|
123
|
+
resource: resourceDescriptors.clipSelection,
|
|
124
|
+
resourceId: resourceDescriptors.clipSelection.id,
|
|
125
|
+
name: 'Clip Selection',
|
|
126
|
+
description: 'Chooses clip candidates for a podcast episode.',
|
|
127
|
+
type: resourceDescriptors.clipSelection.kind,
|
|
128
|
+
version: '1.0.0',
|
|
129
|
+
status: 'dev'
|
|
130
|
+
},
|
|
131
|
+
contract: { inputSchema, outputSchema },
|
|
132
|
+
steps: {
|
|
133
|
+
select: {
|
|
134
|
+
id: 'select',
|
|
135
|
+
name: 'Select Clips',
|
|
136
|
+
description: 'Records a clip-selection attempt against the item.',
|
|
137
|
+
inputSchema,
|
|
138
|
+
outputSchema,
|
|
139
|
+
next: null,
|
|
140
|
+
handler: async (rawInput, context) => {
|
|
141
|
+
const input = rawInput as z.infer<typeof inputSchema>
|
|
142
|
+
const item = await content.getItem({ contentItemId: input.contentItemId })
|
|
143
|
+
|
|
144
|
+
const attempt = await content.createAttempt({
|
|
145
|
+
contentItemId: item.id,
|
|
146
|
+
// Tags the attempt with the step it satisfies. Omit it and the
|
|
147
|
+
// attempt is stored with a null step -- the review UI's Step column
|
|
148
|
+
// renders "--" and nothing tells you which step produced the row.
|
|
149
|
+
stepKey: 'clip-selection',
|
|
150
|
+
payload: { clips: [] },
|
|
151
|
+
sourceExecutionId: context.executionId
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
return { attemptId: attempt.id, nextStepKey: 'publish' }
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
entryPoint: 'select'
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
`ContentToolMap` is the full surface: `createItem`, `getItem`, `listItems`, `updateItem`, `createAttempt`, `listAttempts`, `createDistribution`, `updateDistribution`. `organizationId` is injected server-side — never pass it from workflow code.
|
|
163
|
+
|
|
164
|
+
## 3. Store Rules Documents
|
|
165
|
+
|
|
166
|
+
Governing documents are artifacts, not a content table. Two rules decide whether a write is reachable at all:
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
import { artifacts } from '@elevasis/sdk/worker'
|
|
170
|
+
|
|
171
|
+
// `kind` MUST be `content:`-prefixed. The artifacts_manage_content RLS policy
|
|
172
|
+
// grants org-owned writes only for `kind LIKE 'content:%'` -- a non-prefixed
|
|
173
|
+
// kind is rejected server-side with no compile-time warning.
|
|
174
|
+
//
|
|
175
|
+
// `pipelineId` MUST be supplied. getActive filters on
|
|
176
|
+
// (organizationId, pipelineId, kind); an artifact written without one can
|
|
177
|
+
// never be read back by the lookup every consumer uses.
|
|
178
|
+
await artifacts.createArtifact({
|
|
179
|
+
ownerKind: 'organization',
|
|
180
|
+
ownerId: null,
|
|
181
|
+
kind: 'content:style-guide',
|
|
182
|
+
pipelineId: 'podcast-to-clips',
|
|
183
|
+
content: { tone: 'direct', bannedPhrases: ['synergy'] }
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
const { artifact } = await artifacts.getActive({
|
|
187
|
+
pipelineId: 'podcast-to-clips',
|
|
188
|
+
kind: 'content:style-guide'
|
|
189
|
+
})
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Writing again for the same `(pipelineId, kind)` supersedes the previous version rather than colliding: the platform deactivates the predecessor and stores the new row at the next version number, atomically. `getActive` always returns the current one, and `ContentSettingsPage` renders the version history.
|
|
193
|
+
|
|
194
|
+
`ContentSettingsPage` scopes its browser to **declared** pipelines. An artifact written under a `pipelineId` that is not in `content:catalog/pipeline` is stored correctly and is invisible in that UI.
|
|
195
|
+
|
|
196
|
+
## 4. Customize the Review Screen
|
|
197
|
+
|
|
198
|
+
Start with slots on the shared page:
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
// ui/src/routes/content/items.$itemId.tsx
|
|
202
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
203
|
+
import { ContentItemReviewPage } from '@elevasis/ui/features/content'
|
|
204
|
+
import { Button } from '@mantine/core'
|
|
205
|
+
|
|
206
|
+
export const Route = createFileRoute('/content/items/$itemId')({ component: ReviewRoute })
|
|
207
|
+
|
|
208
|
+
function ReviewRoute() {
|
|
209
|
+
const { itemId } = Route.useParams()
|
|
210
|
+
return <ContentItemReviewPage itemId={itemId} headerActions={<Button>Send to Legal</Button>} />
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
When the layout itself has to change, compose the primitives — `ContentReviewCard`, `ReviewActionBar`, `PayloadBody`, `AlternatesPanel`, `ProcessingStateStrip` — with `useContentItem`, `useContentItemAttempts`, and `useReviewContentItem`. Read the pipeline's steps through `useContentConfig` rather than hardcoding them, or a new step silently fails to render.
|
|
215
|
+
|
|
216
|
+
## 5. Extend Navigation
|
|
217
|
+
|
|
218
|
+
Same pattern as the other systems:
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
import { contentManifest, CONTENT_ITEMS, ContentSidebar, ContentSidebarMiddle } from '@elevasis/ui/features/content'
|
|
222
|
+
import type { SystemModule } from '@elevasis/ui/provider'
|
|
223
|
+
import type { NavItem } from '@elevasis/ui/layout'
|
|
224
|
+
import { IconChartBar } from '@tabler/icons-react'
|
|
225
|
+
|
|
226
|
+
const customItems: NavItem[] = [
|
|
227
|
+
...CONTENT_ITEMS,
|
|
228
|
+
{ label: 'Performance', to: '/content/performance', icon: IconChartBar, exact: false }
|
|
229
|
+
]
|
|
230
|
+
|
|
231
|
+
export const customContentManifest: SystemModule = {
|
|
232
|
+
...contentManifest,
|
|
233
|
+
sidebar: () => (
|
|
234
|
+
<ContentSidebar>
|
|
235
|
+
<ContentSidebarMiddle items={customItems} />
|
|
236
|
+
</ContentSidebar>
|
|
237
|
+
)
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Replace `contentManifest` with `customContentManifest` in the local `SYSTEM_MANIFESTS` array and add the matching route under `ui/src/routes/content/`.
|
|
242
|
+
|
|
243
|
+
## 6. Mark the System API-Ready
|
|
244
|
+
|
|
245
|
+
`content.apiInterface.lifecycle` goes `active` only when the System's scoped resources, `content:object/item`, and the pipeline/step/status catalogs are all in place. Two failure modes are worth knowing before you flip it:
|
|
246
|
+
|
|
247
|
+
- An **empty** `apiInterface.resourceIds` array throws rather than opting out. Omitting the whole `apiInterface` block is the opt-out; a `resourceIds: []` stub is the anomaly.
|
|
248
|
+
- Readiness is derived from a **deployed** snapshot. A model edit that has not been redeployed produces a stale-snapshot 503 that looks like a code bug. Redeploy before debugging.
|
|
249
|
+
|
|
250
|
+
## Verify
|
|
251
|
+
|
|
252
|
+
Run the checks for the surfaces you touched:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
pnpm -C ui run check-types
|
|
256
|
+
pnpm -C operations run check
|
|
257
|
+
pnpm -C operations exec elevasis-sdk check
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
If you changed platform-level content contracts in the monorepo, the platform maintainer must also regenerate and verify scaffold output:
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
pnpm scaffold:sync
|
|
264
|
+
pnpm scaffold:verify
|
|
265
|
+
```
|
|
@@ -29,15 +29,15 @@ CRM is a layered platform surface, not one component:
|
|
|
29
29
|
|
|
30
30
|
## Decision Table
|
|
31
31
|
|
|
32
|
-
| User wants
|
|
33
|
-
|
|
|
34
|
-
| Change CRM System availability, labels, pipeline stages, resource descriptors, or API readiness | `core/config/organization-model.ts`
|
|
35
|
-
| Add CRM sidebar nav or a CRM route
|
|
36
|
-
| Wrap a shared CRM page with project chrome
|
|
37
|
-
| Build a custom deal page
|
|
38
|
-
| Add, hide, or replace deal action buttons
|
|
39
|
-
| Read or mutate CRM data inside a workflow
|
|
40
|
-
| Add a new persisted CRM column or table
|
|
32
|
+
| User wants | Start here | Notes |
|
|
33
|
+
| ----------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
34
|
+
| Change CRM System availability, labels, pipeline stages, resource descriptors, or API readiness | `core/config/organization-model.ts` | Treat this as Organization OS work. Mark `sales.crm.apiInterface` active only when scoped CRM resources and ontology are ready for API-backed actions. |
|
|
35
|
+
| Add CRM sidebar nav or a CRM route | `@elevasis/ui/features/crm` and `operations/node_modules/@elevasis/sdk/reference/scaffold/ui/customization.md` | Prefer manifest/sidebar composition. Do not fork shared source first. |
|
|
36
|
+
| Wrap a shared CRM page with project chrome | `DealsListPage`, `DealDetailPage`, `CrmOverview` from `@elevasis/ui/features/crm` | Keep route files thin and put project-specific logic in local feature modules. |
|
|
37
|
+
| Build a custom deal page | `useDealDetail`, `useDealNotes`, `useDealTasks`, `useExecuteAction` from `@elevasis/ui/hooks` | Use hooks for platform data and compose your own UI. |
|
|
38
|
+
| Add, hide, or replace deal action buttons | [customize-crm-actions.md](customize-crm-actions.md) | Start with the shared `crmActions` provider path; use project-owned UI when a custom workflow path is outside platform-known/default action dispatch constraints. |
|
|
39
|
+
| Read or mutate CRM data inside a workflow | `crm` or `acqDb` from `@elevasis/sdk/worker` | `organizationId` is injected server-side by the platform dispatcher. Do not pass it from workflow code. |
|
|
40
|
+
| Add a new persisted CRM column or table | Platform/API migration work, not just scaffold work | Update DB, core schemas/types, API service/handlers, hooks, docs, and scaffold contracts together. |
|
|
41
41
|
|
|
42
42
|
## Published CRM Surfaces
|
|
43
43
|
|
|
@@ -162,6 +162,8 @@ export function CustomDealWorkspace({ dealId }: { dealId: string }) {
|
|
|
162
162
|
|
|
163
163
|
Inside deployed workflows, use worker adapters instead of browser hooks or direct database access:
|
|
164
164
|
|
|
165
|
+
<!-- doc-snippet:skip: illustrative excerpt -- `resourceDescriptors` names the project's own resource-descriptors export -->
|
|
166
|
+
|
|
165
167
|
```ts
|
|
166
168
|
// operations/src/sales/follow-up-stale-deals.ts
|
|
167
169
|
import type { WorkflowDefinition } from '@elevasis/sdk'
|
|
@@ -182,6 +184,7 @@ export const followUpStaleDealsWorkflow: WorkflowDefinition = {
|
|
|
182
184
|
resource: resourceDescriptors.followUpStaleDeals,
|
|
183
185
|
resourceId: resourceDescriptors.followUpStaleDeals.id,
|
|
184
186
|
name: 'Follow Up Stale Deals',
|
|
187
|
+
description: 'Creates follow-up tasks for deals that have gone stale in a stage.',
|
|
185
188
|
type: resourceDescriptors.followUpStaleDeals.kind,
|
|
186
189
|
version: '1.0.0',
|
|
187
190
|
status: 'dev',
|
|
@@ -191,10 +194,12 @@ export const followUpStaleDealsWorkflow: WorkflowDefinition = {
|
|
|
191
194
|
followUp: {
|
|
192
195
|
id: 'followUp',
|
|
193
196
|
name: 'Follow Up',
|
|
197
|
+
description: 'Lists stale deals in the target stage and creates a follow-up task for each.',
|
|
194
198
|
inputSchema,
|
|
195
199
|
outputSchema,
|
|
196
200
|
next: null,
|
|
197
|
-
handler: async (
|
|
201
|
+
handler: async (rawInput, context) => {
|
|
202
|
+
const input = rawInput as z.infer<typeof inputSchema>
|
|
198
203
|
const deals = await crm.listDeals({ stage: input.stage })
|
|
199
204
|
|
|
200
205
|
for (const deal of deals) {
|
|
@@ -245,7 +250,7 @@ Keep these boundaries straight:
|
|
|
245
250
|
Run the checks for the surfaces you touched:
|
|
246
251
|
|
|
247
252
|
```bash
|
|
248
|
-
pnpm -C ui run check
|
|
253
|
+
pnpm -C ui run check-types
|
|
249
254
|
pnpm -C operations run check
|
|
250
255
|
pnpm -C operations exec elevasis-sdk check
|
|
251
256
|
```
|