@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.
- package/dist/cli.cjs +1178 -1039
- package/dist/index.d.ts +4760 -4567
- package/dist/index.js +989 -2332
- package/dist/node/index.d.ts +660 -1323
- package/dist/node/index.js +1 -1
- package/dist/test-utils/index.d.ts +4101 -4115
- package/dist/test-utils/index.js +1724 -3471
- package/dist/types/worker/index.d.ts +3 -2
- package/dist/types/worker/platform.d.ts +2 -2
- package/dist/worker/index.js +394 -2448
- package/package.json +2 -2
- package/reference/cli.mdx +1107 -808
- package/reference/scaffold/recipes/customize-crm-actions.md +45 -46
- package/reference/scaffold/recipes/extend-crm.md +253 -255
- package/reference/scaffold/recipes/index.md +43 -44
- package/reference/scaffold/reference/contracts.md +976 -1063
|
@@ -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
|
|
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
|
|
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`
|
|
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 {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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 {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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 {
|
|
362
|
-
import { Group, Stack } from '@mantine/core'
|
|
363
|
-
import { useMemo } from 'react'
|
|
364
|
-
import { useDealDetail, useExecuteAction } from '@elevasis/ui/hooks'
|
|
365
|
-
import {
|
|
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,
|
|
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
|
-
`
|
|
399
|
-
|
|
400
|
-
|
|
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
|
-
|
|
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
|
|