@elevasis/sdk 1.24.0 → 1.25.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.
@@ -23,14 +23,14 @@ Use this recipe when a user asks for work like:
23
23
 
24
24
  ## How Platform Action Dispatch Works
25
25
 
26
- Every default action in `DEFAULT_CRM_ACTIONS` maps to a deployed workflow via its `workflowId` field. When the shared UI calls `POST /deals/:dealId/actions/:actionKey`, the platform:
26
+ Every action in the CRM action catalog maps to a deployed workflow via its `workflowId` field. When the shared UI calls `POST /deals/:dealId/actions/:actionKey`, the platform:
27
27
 
28
28
  1. Validates `isAvailableFor(deal)` server-side (security gate -- cannot be skipped).
29
29
  2. Resolves `actionDef.workflowId` to a deployed resource.
30
30
  3. Dispatches through `SingleExecutionCoordinator` -- same execution engine as every other workflow.
31
31
  4. Returns the refetched deal.
32
32
 
33
- External projects override an action's behavior by deploying a workflow with the same `workflowId` as the default. The resource registry picks the project-owned workflow over the platform default. The `isAvailableFor` predicate is not overridable in V1 -- it stays in `@core` `DEFAULT_CRM_ACTIONS`. Override what the action does, not when the button shows.
33
+ External projects override an action's behavior by deploying a workflow with the same `workflowId` as the action entry. The resource registry picks the project-owned workflow over the platform default. The `isAvailableFor` predicate comes from the caller-supplied action catalog; override what the action does and keep button availability aligned with the server-side gate.
34
34
 
35
35
  ## ActionDef Shape
36
36
 
@@ -120,7 +120,7 @@ export const moveToProposalWorkflow: WorkflowDefinition = {
120
120
  }
121
121
  ```
122
122
 
123
- To add side effects (create a task, send a Slack message, log a deal activity), extend the handler before the `return`. The OM descriptor ID must match the action's `workflowId` in `DEFAULT_CRM_ACTIONS` from `@elevasis/sdk` exactly.
123
+ To add side effects (create a task, send a Slack message, log a deal activity), extend the handler before the `return`. The OM descriptor ID must match the action entry's `workflowId` exactly.
124
124
 
125
125
  Register the workflow in the operations manifest:
126
126
 
@@ -144,23 +144,23 @@ pnpm exec elevasis-sdk deploy
144
144
 
145
145
  To hide, reorder, or relabel buttons in the shared deal UI, create a local action config module:
146
146
 
147
- ```ts
148
- // ui/src/config/crm-actions.ts
149
- import { DEFAULT_CRM_ACTIONS, type ActionDef } from '@elevasis/sdk'
150
-
151
- export const crmActions: ActionDef[] = [
152
- ...DEFAULT_CRM_ACTIONS.filter((action) => action.key !== 'move_to_closed_lost')
153
- ]
154
- ```
147
+ ```ts
148
+ // ui/src/config/crm-actions.ts
149
+ import type { ActionDef } from '@elevasis/sdk'
150
+ import { platformCrmActions } from './platform-crm-actions'
151
+
152
+ export const crmActions: ActionDef[] = platformCrmActions.filter((action) => action.key !== 'move_to_closed_lost')
153
+ ```
155
154
 
156
155
  To add a new action entry alongside the defaults (note: brand-new keys are not server-dispatched until the platform knows their `workflowId`):
157
156
 
158
- ```ts
159
- // ui/src/config/crm-actions.ts
160
- import { DEFAULT_CRM_ACTIONS, type ActionDef } from '@elevasis/sdk'
161
-
162
- export const crmActions: ActionDef[] = [
163
- ...DEFAULT_CRM_ACTIONS,
157
+ ```ts
158
+ // ui/src/config/crm-actions.ts
159
+ import type { ActionDef } from '@elevasis/sdk'
160
+ import { platformCrmActions } from './platform-crm-actions'
161
+
162
+ export const crmActions: ActionDef[] = [
163
+ ...platformCrmActions,
164
164
  {
165
165
  key: 'send_quote',
166
166
  label: 'Send Quote',
@@ -357,20 +357,21 @@ When you own the full page, use the primitives directly:
357
357
  - `useExecuteAction({ dealId })` dispatches platform-known action keys.
358
358
  - Project-owned workflow buttons call `/execute` or `/execute-async` directly when they are outside the server-dispatched action set.
359
359
 
360
- ```tsx
361
- import { DEFAULT_CRM_ACTIONS, deriveActions } from '@elevasis/sdk'
362
- import { Group, Stack } from '@mantine/core'
363
- import { useMemo } from 'react'
364
- import { useDealDetail, useExecuteAction } from '@elevasis/ui/hooks'
365
- import { SendQuoteButton } from './SendQuoteButton'
360
+ ```tsx
361
+ import { deriveActions } from '@elevasis/sdk'
362
+ import { Group, Stack } from '@mantine/core'
363
+ import { useMemo } from 'react'
364
+ import { useDealDetail, useExecuteAction } from '@elevasis/ui/hooks'
365
+ import { crmActions } from '../config/crm-actions'
366
+ import { SendQuoteButton } from './SendQuoteButton'
366
367
 
367
368
  export function CustomDealPage({ dealId }: { dealId: string }) {
368
369
  const { data: deal } = useDealDetail(dealId)
369
- const executeAction = useExecuteAction({ dealId })
370
-
371
- const platformActions = useMemo(() => {
372
- return deal ? deriveActions(deal, DEFAULT_CRM_ACTIONS) : []
373
- }, [deal])
370
+ const executeAction = useExecuteAction({ dealId })
371
+
372
+ const platformActions = useMemo(() => {
373
+ return deal ? deriveActions(deal, crmActions) : []
374
+ }, [deal])
374
375
 
375
376
  if (!deal) return null
376
377
 
@@ -395,24 +396,22 @@ export function CustomDealPage({ dealId }: { dealId: string }) {
395
396
 
396
397
  ## CRM State-Key Source of Truth
397
398
 
398
- `CRM_PIPELINE_DEFINITION` in `packages/core/src/organization-model/domains/sales.ts` is the single canonical source for CRM `state_key` values. It exports a `StatefulPipelineDefinition` that enumerates every valid state per stage (e.g. `interested` → `discovery_replied`, `discovery_link_sent`, `discovery_nudging`, etc.). Named per-state constants (`CRM_DISCOVERY_REPLIED_STATE`, `CRM_DISCOVERY_LINK_SENT_STATE`, and siblings) are also exported for use in conditional logic.
399
-
400
- Import via `@repo/core/organization-model`:
401
-
402
- ```ts
403
- import {
404
- CRM_PIPELINE_DEFINITION,
405
- CRM_DISCOVERY_REPLIED_STATE,
406
- getValidStatesForStage
407
- } from '@repo/core/organization-model'
408
-
409
- const validStates = getValidStatesForStage(CRM_PIPELINE_DEFINITION, 'interested')
410
- // [{ stateKey: 'discovery_replied', label: '...' }, ...]
411
- ```
412
-
413
- Workflows that write `state_key` should import from this definition rather than hardcoding string literals. This keeps the vocabulary in one place and lets the API validate against the allowed set for a deal's current stage.
414
-
415
- **Current gap:** `@elevasis/core` v0.13.0 does not yet expose the `organization-model` subpath. Until a new release ships that export, hardcoded strings in `packages/elevasis-operations/...` are tracked as follow-up. Document usages with a `// TODO: replace with CRM_PIPELINE_DEFINITION import once @elevasis/core exposes organization-model` comment so they are easy to find.
399
+ CRM `stage_key` and `state_key` values are tenant/runtime data. In the Elevasis workspace, the canonical CRM pipeline definition lives in `@repo/elevasis-core/organization-model` and is authored into the `sales.crm:catalog/crm.pipeline` ontology catalog on the canonical organization model. Published `@elevasis/core` keeps only generic `StatefulPipelineDefinition` types/helpers and transport schemas.
400
+
401
+ Within the Elevasis monorepo, import runtime CRM definitions from `@repo/elevasis-core/organization-model`:
402
+
403
+ ```ts
404
+ import {
405
+ CRM_PIPELINE_DEFINITION,
406
+ CRM_DISCOVERY_REPLIED_STATE,
407
+ getValidStatesForStage
408
+ } from '@repo/elevasis-core/organization-model'
409
+
410
+ const validStates = getValidStatesForStage(CRM_PIPELINE_DEFINITION, 'interested')
411
+ // [{ stateKey: 'discovery_replied', label: '...' }, ...]
412
+ ```
413
+
414
+ Template-derived projects should define their own CRM catalog/action config in project code rather than importing Elevasis runtime constants from published core.
416
415
 
417
416
  ## Activity Log Conventions
418
417