@elevasis/sdk 1.14.1 → 1.15.1
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 +1 -1
- package/dist/index.d.ts +529 -359
- package/dist/index.js +149 -6
- package/dist/test-utils/index.d.ts +516 -358
- package/dist/test-utils/index.js +3 -0
- package/dist/types/worker/adapters/lead.d.ts +1 -1
- package/dist/worker/index.js +1 -0
- package/package.json +2 -2
- package/reference/claude-config/rules/agent-start-here.md +235 -235
- package/reference/claude-config/rules/organization-os.md +103 -103
- package/reference/claude-config/rules/platform.md +1 -1
- package/reference/claude-config/rules/ui.md +200 -204
- package/reference/claude-config/rules/vibe.md +208 -208
- package/reference/claude-config/sync-notes/2026-04-27-lead-gen-substrate-train.md +2 -0
- package/reference/claude-config/sync-notes/2026-04-29-crm-state-and-lead-gen-processing-status.md +93 -0
- package/reference/claude-config/sync-notes/2026-05-02-crm-ownership-next-action.md +58 -0
- package/reference/claude-config/sync-notes/2026-05-02-template-hardcode-workos-config.md +56 -0
- package/reference/scaffold/index.mdx +67 -67
- package/reference/scaffold/recipes/customize-crm-actions.md +38 -13
- package/reference/scaffold/recipes/extend-crm.md +12 -8
- package/reference/scaffold/recipes/extend-lead-gen.md +102 -30
- package/reference/scaffold/recipes/index.md +41 -41
- package/reference/scaffold/reference/contracts.md +444 -309
- package/reference/scaffold/ui/customization.md +1 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Template WorkOS Hardcode + Strict Dev Port
|
|
2
|
+
|
|
3
|
+
## Why this note exists
|
|
4
|
+
|
|
5
|
+
The template UI no longer reads WorkOS configuration from `VITE_WORKOS_*` env vars. WorkOS `clientId`, `redirectUri`, and `signoutUri` are hardcoded in a new file `ui/src/config/workos.ts` so a freshly bootstrapped template runs without any UI `.env` setup. The Vite dev server now uses `strictPort: true` on port `4300` so a second `pnpm -C ui dev` on the same machine fails fast instead of silently drifting to another port.
|
|
6
|
+
|
|
7
|
+
This sync moves three pieces into derived projects:
|
|
8
|
+
|
|
9
|
+
- `ui/src/config/workos.ts` -- new merge-baseline file holding `clientId`, `redirectUri`, `signoutUri`
|
|
10
|
+
- `ui/src/main.tsx` and `ui/src/routes/__root.tsx` -- merge-regions updates that import `WORKOS_CONFIG` from `@/config/workos` instead of reading `import.meta.env.VITE_WORKOS_*`
|
|
11
|
+
- `ui/vite.config.ts` -- `strictPort: true` added next to `port: 4300`
|
|
12
|
+
- `ui/.env.example` -- WorkOS section removed (replaced with a single comment pointing at `ui/src/config/workos.ts`)
|
|
13
|
+
- `.claude/rules/ui.md` and `CLAUDE.md` -- prose updated; project-owned `CLAUDE.md` is verify-only and the project keeps its own narrative
|
|
14
|
+
|
|
15
|
+
`nirvana-marketing` and `ZentaraHQ` already received `ui/src/config/workos.ts`, the `strictPort` flag, and the `.claude/rules/ui.md` baseline as prep-gate repairs in the previous train. This note formally attributes those changes to an owning task doc and covers any remaining template-derived projects.
|
|
16
|
+
|
|
17
|
+
## Applies to
|
|
18
|
+
|
|
19
|
+
Template-derived projects that:
|
|
20
|
+
|
|
21
|
+
- run a WorkOS-authenticated UI from `ui/src/main.tsx` and `ui/src/routes/__root.tsx`
|
|
22
|
+
- run the Vite dev server on port `4300`
|
|
23
|
+
- have a project-owned `ui/src/config/workos.ts` (created via prep-gate repair) or are seeing it land for the first time on this sync
|
|
24
|
+
- maintain a `ui/.env` file that previously set `VITE_WORKOS_CLIENT_ID`, `VITE_WORKOS_REDIRECT_URI`, or `VITE_WORKOS_SIGNOUT_URI`
|
|
25
|
+
|
|
26
|
+
Projects with no WorkOS surface or no Vite dev server are not affected.
|
|
27
|
+
|
|
28
|
+
## Required actions
|
|
29
|
+
|
|
30
|
+
1. Pull template changes with `/git-sync` after this train publishes so the WorkOS hardcode and strict-port baselines reach the project's UI shell.
|
|
31
|
+
|
|
32
|
+
2. Confirm the project's `ui/src/config/workos.ts` reflects the WorkOS client ID the project should authenticate against. The template ships the platform team's dev-tier `clientId`; client-facing projects must overwrite that value with the project's own WorkOS client ID before going to production. Edit the literal in `ui/src/config/workos.ts` -- no env vars are involved.
|
|
33
|
+
|
|
34
|
+
3. Stop providing `VITE_WORKOS_CLIENT_ID`, `VITE_WORKOS_REDIRECT_URI`, and `VITE_WORKOS_SIGNOUT_URI` in `ui/.env`. They are no longer read. Delete the entries to keep the file honest. The WorkOS values now live in `ui/src/config/workos.ts`.
|
|
35
|
+
|
|
36
|
+
4. Confirm `ui/vite.config.ts` carries `strictPort: true` next to `server.port: 4300`. If a second dev server starts on the same port, expect a hard failure instead of a drift to `4301`.
|
|
37
|
+
|
|
38
|
+
5. If the project hand-rolled an env-vars notice component or a `REQUIRED_ENV_VARS` array around WorkOS, remove it. `createElevasisApp` no longer needs the `MissingEnvNotice` prop now that `clientId` is always truthy.
|
|
39
|
+
|
|
40
|
+
## Verification
|
|
41
|
+
|
|
42
|
+
After upgrading:
|
|
43
|
+
|
|
44
|
+
- `pnpm -C ui check-types` and `pnpm -C ui build` pass with `WORKOS_CONFIG` imported from `@/config/workos`.
|
|
45
|
+
- `pnpm -C ui dev` boots on `4300`. Starting a second `pnpm -C ui dev` in another terminal fails with a port-in-use error instead of incrementing to `4301`.
|
|
46
|
+
- WorkOS sign-in and sign-out still round-trip through the project's WorkOS tenant. Sign-out lands on the URL configured in `ui/src/config/workos.ts` (`signoutUri`).
|
|
47
|
+
- `grep -r VITE_WORKOS_ ui/src` returns nothing.
|
|
48
|
+
|
|
49
|
+
## Not handled by /git-sync
|
|
50
|
+
|
|
51
|
+
`/git-sync` does not:
|
|
52
|
+
|
|
53
|
+
- delete `VITE_WORKOS_*` entries from project-local `ui/.env` files
|
|
54
|
+
- overwrite `ui/src/config/workos.ts` if the project has already customized the `clientId` for a non-default WorkOS tenant (the file is merge-baseline; customizations are preserved)
|
|
55
|
+
- update WorkOS dashboard redirect URIs or CORS origins for projects that run the dev server on a non-`4300` port; if the project changed the dev port, it must also change the WorkOS dashboard accordingly
|
|
56
|
+
- redeploy any project-owned operations bundle; this train is UI-shell only
|
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Scaffold Reference
|
|
3
|
-
description: Universal scaffold documentation for Elevasis SDK projects -- recipes, patterns, architecture, and reference materials that apply to all workspaces.
|
|
4
|
-
---
|
|
1
|
+
---
|
|
2
|
+
title: Scaffold Reference
|
|
3
|
+
description: Universal scaffold documentation for Elevasis SDK projects -- recipes, patterns, architecture, and reference materials that apply to all workspaces.
|
|
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
|
-
## Overview
|
|
10
|
-
|
|
11
|
-
This scaffold reference contains universal documentation that applies to all Elevasis SDK projects. Content is organized by package ownership:
|
|
12
|
-
|
|
13
|
-
- **recipes/** -- Cross-package pathway recipes (add a feature, add a resource, gating patterns)
|
|
14
|
-
- **ui/** -- UI patterns, feature shell architecture, composition, and customization
|
|
15
|
-
- **core/** -- Organization model architecture, graph layer, and semantic contracts
|
|
16
|
-
- **operations/** -- Workflow authoring patterns and adapter usage
|
|
17
|
-
- **reference/** -- Glossary, auto-generated contracts, and feature registry
|
|
18
|
-
|
|
19
|
-
## Quick Navigation
|
|
20
|
-
|
|
21
|
-
### Pathway Recipes
|
|
22
|
-
|
|
23
|
-
- [Add a Feature](./recipes/add-a-feature.md) -- end-to-end from org model key through manifest, routes, gating
|
|
24
|
-
- [Add a Resource](./recipes/add-a-resource.md) -- author and deploy a workflow or agent
|
|
25
|
-
- [Extend a Base Entity](./recipes/extend-a-base-entity.md) -- add project-specific metadata to canonical entity shapes via the TMeta slot
|
|
26
|
-
- [Gate by Feature or Admin](./recipes/gate-by-feature-or-admin.md) -- decision table for access control patterns
|
|
27
|
-
- [Build and Extend CRM](./recipes/extend-crm.md) -- map CRM UI pages, hooks, actions, workflow adapters, contracts, and org-model boundaries
|
|
28
|
-
- [Build and Extend Lead Gen](./recipes/extend-lead-gen.md) -- map lead-gen UI pages, hooks, list/member state, artifacts,
|
|
29
|
-
- [Customize CRM Actions](./recipes/customize-crm-actions.md) -- add, hide, or replace CRM deal actions, use the shared `crmActions` provider path, and understand workflow dispatch constraints
|
|
30
|
-
|
|
31
|
-
### UI Patterns
|
|
32
|
-
|
|
33
|
-
- [UI Recipes](./ui/recipes.md) -- copy-paste recipes for pages, nav items, components, theme tokens
|
|
34
|
-
- [Feature Flags & Gating](./ui/feature-flags-and-gating.md) -- three-concept model for feature access
|
|
35
|
-
- [Customizing Features](./ui/customization.md) -- sidebar composition via manifest overrides
|
|
36
|
-
- [Feature Shell & Provider](./ui/feature-shell.mdx) -- FeatureModule manifest contract, provider runtime
|
|
37
|
-
- [Composition & Extensibility](./ui/composition-extensibility.mdx) -- layout primitives, router abstraction
|
|
38
|
-
|
|
39
|
-
### Core Architecture
|
|
40
|
-
|
|
41
|
-
- [Organization Model](./core/organization-model.mdx) -- semantic contract, schema, authoring helpers
|
|
42
|
-
- [Organization Graph](./core/organization-graph.mdx) -- graph derivation, node/edge taxonomy, lenses
|
|
43
|
-
|
|
44
|
-
### Operations
|
|
45
|
-
|
|
46
|
-
- [Workflow Recipes](./operations/workflow-recipes.md) -- workflow anatomy, adapter patterns, trigger patterns
|
|
47
|
-
- [Propagation Pipeline](./operations/propagation-pipeline.md) -- three-layer sync pipeline, verification checks, integration points
|
|
48
|
-
- [Scaffold Maintenance](./operations/scaffold-maintenance.md) -- content placement, auto-generation, adding new scaffold docs
|
|
49
|
-
|
|
50
|
-
### Reference
|
|
51
|
-
|
|
52
|
-
- [Glossary](./reference/glossary.md) -- term definitions for Organization OS concepts
|
|
53
|
-
- [Contracts](./reference/contracts.md) -- auto-generated TypeScript contract shapes
|
|
54
|
-
- [Feature Registry](./reference/feature-registry.md) -- auto-generated feature manifest catalog
|
|
55
|
-
|
|
56
|
-
## Source Locations
|
|
57
|
-
|
|
58
|
-
Content is co-located with its owning package and copied here during SDK build:
|
|
59
|
-
|
|
60
|
-
| Bundle Path | Source Location | Owner |
|
|
61
|
-
| --------------------------------------------- | --------------------------------------------------------- | --------------- |
|
|
62
|
-
| `scaffold/recipes/` | `packages/sdk/docs/scaffold/recipes/` | SDK |
|
|
63
|
-
| `scaffold/operations/` | `packages/sdk/docs/scaffold/operations/` | SDK |
|
|
64
|
-
| `scaffold/operations/propagation-pipeline.md` | `packages/sdk/docs/scaffold/operations/` | SDK |
|
|
65
|
-
| `scaffold/operations/scaffold-maintenance.md` | `packages/sdk/docs/scaffold/operations/` | SDK |
|
|
66
|
-
| `scaffold/ui/` | `packages/ui/src/scaffold/` | UI |
|
|
67
|
-
| `scaffold/core/` | `packages/core/src/organization-model/` | Core |
|
|
68
|
-
| `scaffold/reference/glossary.md` | `packages/core/src/reference/glossary.md` | Core |
|
|
69
|
-
| `scaffold/reference/contracts.md` | `packages/core/src/reference/_generated/contracts.md` | Core (auto-gen) |
|
|
70
|
-
| `scaffold/reference/feature-registry.md` | `packages/ui/src/scaffold/_generated/feature-registry.md` | UI (auto-gen) |
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
This scaffold reference contains universal documentation that applies to all Elevasis SDK projects. Content is organized by package ownership:
|
|
12
|
+
|
|
13
|
+
- **recipes/** -- Cross-package pathway recipes (add a feature, add a resource, gating patterns)
|
|
14
|
+
- **ui/** -- UI patterns, feature shell architecture, composition, and customization
|
|
15
|
+
- **core/** -- Organization model architecture, graph layer, and semantic contracts
|
|
16
|
+
- **operations/** -- Workflow authoring patterns and adapter usage
|
|
17
|
+
- **reference/** -- Glossary, auto-generated contracts, and feature registry
|
|
18
|
+
|
|
19
|
+
## Quick Navigation
|
|
20
|
+
|
|
21
|
+
### Pathway Recipes
|
|
22
|
+
|
|
23
|
+
- [Add a Feature](./recipes/add-a-feature.md) -- end-to-end from org model key through manifest, routes, gating
|
|
24
|
+
- [Add a Resource](./recipes/add-a-resource.md) -- author and deploy a workflow or agent
|
|
25
|
+
- [Extend a Base Entity](./recipes/extend-a-base-entity.md) -- add project-specific metadata to canonical entity shapes via the TMeta slot
|
|
26
|
+
- [Gate by Feature or Admin](./recipes/gate-by-feature-or-admin.md) -- decision table for access control patterns
|
|
27
|
+
- [Build and Extend CRM](./recipes/extend-crm.md) -- map CRM UI pages, hooks, actions, workflow adapters, contracts, and org-model boundaries
|
|
28
|
+
- [Build and Extend Lead Gen](./recipes/extend-lead-gen.md) -- map lead-gen UI pages, hooks, list/member state, artifacts, workflow adapters, contracts, and org-model boundaries
|
|
29
|
+
- [Customize CRM Actions](./recipes/customize-crm-actions.md) -- add, hide, or replace CRM deal actions, use the shared `crmActions` provider path, and understand workflow dispatch constraints
|
|
30
|
+
|
|
31
|
+
### UI Patterns
|
|
32
|
+
|
|
33
|
+
- [UI Recipes](./ui/recipes.md) -- copy-paste recipes for pages, nav items, components, theme tokens
|
|
34
|
+
- [Feature Flags & Gating](./ui/feature-flags-and-gating.md) -- three-concept model for feature access
|
|
35
|
+
- [Customizing Features](./ui/customization.md) -- sidebar composition via manifest overrides
|
|
36
|
+
- [Feature Shell & Provider](./ui/feature-shell.mdx) -- FeatureModule manifest contract, provider runtime
|
|
37
|
+
- [Composition & Extensibility](./ui/composition-extensibility.mdx) -- layout primitives, router abstraction
|
|
38
|
+
|
|
39
|
+
### Core Architecture
|
|
40
|
+
|
|
41
|
+
- [Organization Model](./core/organization-model.mdx) -- semantic contract, schema, authoring helpers
|
|
42
|
+
- [Organization Graph](./core/organization-graph.mdx) -- graph derivation, node/edge taxonomy, lenses
|
|
43
|
+
|
|
44
|
+
### Operations
|
|
45
|
+
|
|
46
|
+
- [Workflow Recipes](./operations/workflow-recipes.md) -- workflow anatomy, adapter patterns, trigger patterns
|
|
47
|
+
- [Propagation Pipeline](./operations/propagation-pipeline.md) -- three-layer sync pipeline, verification checks, integration points
|
|
48
|
+
- [Scaffold Maintenance](./operations/scaffold-maintenance.md) -- content placement, auto-generation, adding new scaffold docs
|
|
49
|
+
|
|
50
|
+
### Reference
|
|
51
|
+
|
|
52
|
+
- [Glossary](./reference/glossary.md) -- term definitions for Organization OS concepts
|
|
53
|
+
- [Contracts](./reference/contracts.md) -- auto-generated TypeScript contract shapes
|
|
54
|
+
- [Feature Registry](./reference/feature-registry.md) -- auto-generated feature manifest catalog
|
|
55
|
+
|
|
56
|
+
## Source Locations
|
|
57
|
+
|
|
58
|
+
Content is co-located with its owning package and copied here during SDK build:
|
|
59
|
+
|
|
60
|
+
| Bundle Path | Source Location | Owner |
|
|
61
|
+
| --------------------------------------------- | --------------------------------------------------------- | --------------- |
|
|
62
|
+
| `scaffold/recipes/` | `packages/sdk/docs/scaffold/recipes/` | SDK |
|
|
63
|
+
| `scaffold/operations/` | `packages/sdk/docs/scaffold/operations/` | SDK |
|
|
64
|
+
| `scaffold/operations/propagation-pipeline.md` | `packages/sdk/docs/scaffold/operations/` | SDK |
|
|
65
|
+
| `scaffold/operations/scaffold-maintenance.md` | `packages/sdk/docs/scaffold/operations/` | SDK |
|
|
66
|
+
| `scaffold/ui/` | `packages/ui/src/scaffold/` | UI |
|
|
67
|
+
| `scaffold/core/` | `packages/core/src/organization-model/` | Core |
|
|
68
|
+
| `scaffold/reference/glossary.md` | `packages/core/src/reference/glossary.md` | Core |
|
|
69
|
+
| `scaffold/reference/contracts.md` | `packages/core/src/reference/_generated/contracts.md` | Core (auto-gen) |
|
|
70
|
+
| `scaffold/reference/feature-registry.md` | `packages/ui/src/scaffold/_generated/feature-registry.md` | UI (auto-gen) |
|
|
@@ -69,12 +69,10 @@ A minimal entry looks like:
|
|
|
69
69
|
Workflows backing CRM actions use worker adapters instead of raw Supabase calls. The acquisition adapter is imported as `acqDb` from `@elevasis/sdk/worker` and exposes the action-workflow helpers:
|
|
70
70
|
|
|
71
71
|
- `acqDb.transitionDeal({ dealId, toStage, toState? })` -- moves a deal to a new stage, optionally updating state_key.
|
|
72
|
-
- `acqDb.recordDealActivity({ dealId, type, title, description?, payload? })` -- appends an entry to `
|
|
73
|
-
- `acqDb.recordTouchpoint({ dealId, direction, channel, kind, payload, contactId, sourceExecutionId })` -- writes an `acq_touchpoints` row for outbound/inbound audit.
|
|
72
|
+
- `acqDb.recordDealActivity({ dealId, type, title, description?, payload? })` -- appends an entry to the deal's `activity_log` JSONB column. Use this for outbound/inbound audit and lifecycle events.
|
|
74
73
|
- `acqDb.loadDeal({ dealId })` -- returns the deal row joined with contact and company.
|
|
75
|
-
- `acqDb.listDealTouchpoints({ dealId, kind?, limit? })` -- returns touchpoint history for a deal.
|
|
76
74
|
|
|
77
|
-
These wrap existing `LeadService` logic -- they are extraction, not new business logic. The separate `crm` adapter also exposes focused CRM methods such as `crm.recordActivity(...)`; use `acqDb` for action workflows that need deal transitions
|
|
75
|
+
These wrap existing `LeadService` logic -- they are extraction, not new business logic. The separate `crm` adapter also exposes focused CRM methods such as `crm.recordActivity(...)`; use `acqDb` for action workflows that need deal transitions and the broader acquisition substrate.
|
|
78
76
|
|
|
79
77
|
## Override a Default Action
|
|
80
78
|
|
|
@@ -121,7 +119,7 @@ export const moveToProposalWorkflow: WorkflowDefinition = {
|
|
|
121
119
|
}
|
|
122
120
|
```
|
|
123
121
|
|
|
124
|
-
To add side effects (create a task, send a Slack message,
|
|
122
|
+
To add side effects (create a task, send a Slack message, log a deal activity), extend the handler before the `return`. The `resourceId` must match the action's `workflowId` in `DEFAULT_CRM_ACTIONS` from `@elevasis/sdk` exactly.
|
|
125
123
|
|
|
126
124
|
Register the workflow in the operations manifest:
|
|
127
125
|
|
|
@@ -205,7 +203,7 @@ This controls the shared `DealDetailPage` and `DealDrawer` action row.
|
|
|
205
203
|
|
|
206
204
|
For a brand-new action key that calls a project-owned workflow, define the workflow first.
|
|
207
205
|
|
|
208
|
-
If the action sends email, writes to another channel, or otherwise touches a customer, use `acqDb.
|
|
206
|
+
If the action sends email, writes to another channel, or otherwise touches a customer, use `acqDb.recordDealActivity` inside the workflow handler to append an audit entry to the deal's `activity_log`. For an advanced Instantly-thread-aware variant that prefers in-thread replies and falls back to fresh outbound, see the canonical CRM action examples in `external/elevasis/operations/src/sales/crm/actions/`.
|
|
209
207
|
|
|
210
208
|
### Define the Workflow Contract
|
|
211
209
|
|
|
@@ -272,14 +270,11 @@ export const sendQuoteWorkflow: WorkflowDefinition = {
|
|
|
272
270
|
html: `<p>Your quote is ready. Reply to this email with questions.</p>`
|
|
273
271
|
})
|
|
274
272
|
|
|
275
|
-
await acqDb.
|
|
273
|
+
await acqDb.recordDealActivity({
|
|
276
274
|
dealId,
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
payload: { triggered_by_action: 'send_quote' },
|
|
281
|
-
contactId: deal.contact.id,
|
|
282
|
-
sourceExecutionId: context.executionId
|
|
275
|
+
type: 'quote_sent',
|
|
276
|
+
title: 'Sent quote',
|
|
277
|
+
payload: { triggered_by_action: 'send_quote', channel: 'email' }
|
|
283
278
|
})
|
|
284
279
|
|
|
285
280
|
return {
|
|
@@ -394,6 +389,36 @@ export function CustomDealPage({ dealId }: { dealId: string }) {
|
|
|
394
389
|
}
|
|
395
390
|
```
|
|
396
391
|
|
|
392
|
+
## CRM State-Key Source of Truth
|
|
393
|
+
|
|
394
|
+
`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.
|
|
395
|
+
|
|
396
|
+
Import via `@repo/core/organization-model`:
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
import {
|
|
400
|
+
CRM_PIPELINE_DEFINITION,
|
|
401
|
+
CRM_DISCOVERY_REPLIED_STATE,
|
|
402
|
+
getValidStatesForStage
|
|
403
|
+
} from '@repo/core/organization-model'
|
|
404
|
+
|
|
405
|
+
const validStates = getValidStatesForStage(CRM_PIPELINE_DEFINITION, 'interested')
|
|
406
|
+
// [{ stateKey: 'discovery_replied', label: '...' }, ...]
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
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.
|
|
410
|
+
|
|
411
|
+
**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 `external/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.
|
|
412
|
+
|
|
413
|
+
## Activity Log Conventions
|
|
414
|
+
|
|
415
|
+
The `acq_deal_activity_log` table uses a `kind` field to distinguish how a state transition was initiated. Two values are relevant for CRM state changes:
|
|
416
|
+
|
|
417
|
+
- `state_change` -- written by workflow steps (e.g. `crm-send-booking-link.ts` transitioning to `discovery_link_sent`). Carries an `action_taken` payload identifying the workflow.
|
|
418
|
+
- `state_changed_manually` -- written by the `PATCH /api/deals/:dealId/state` route when an operator edits `state_key` directly from the UI. Carries the user id and the before/after state. This is a pure column update with no workflow side-effects.
|
|
419
|
+
|
|
420
|
+
When reading the audit trail, use `kind` to distinguish automated pipeline progression from manual repair operations. Do not conflate the two when building reports or alerting rules.
|
|
421
|
+
|
|
397
422
|
## Verify
|
|
398
423
|
|
|
399
424
|
Run the relevant checks from the project root:
|
|
@@ -58,7 +58,9 @@ Read the generated contracts before changing typed boundaries:
|
|
|
58
58
|
|
|
59
59
|
`node_modules/@elevasis/sdk/reference/scaffold/reference/contracts.md`
|
|
60
60
|
|
|
61
|
-
Look for the **CRM Platform Primitives** section. It includes deal stages, deal rows, task shapes, API schemas, action definitions, and the focused CRM workflow adapter map. The broader acquisition/list adapter maps live under **Lead Gen Platform Primitives**.
|
|
61
|
+
Look for the **CRM Platform Primitives** section. It includes deal stages, deal rows, task shapes, API schemas, action definitions, and the focused CRM workflow adapter map. The broader acquisition/list adapter maps live under **Lead Gen Platform Primitives**.
|
|
62
|
+
|
|
63
|
+
Deal list and detail responses include a server-derived `priority` object. Use `deal.priority.bucketKey`, `rank`, `label`, `reason`, `latestActivityAt`, and `nextActionAt` when composing custom deal workspaces or workflow-side follow-up logic instead of re-deriving priority from `updated_at`.
|
|
62
64
|
|
|
63
65
|
## 1. Extend CRM Navigation or Sidebar
|
|
64
66
|
|
|
@@ -192,13 +194,15 @@ export const followUpStaleDealsWorkflow: WorkflowDefinition = {
|
|
|
192
194
|
outputSchema,
|
|
193
195
|
next: null,
|
|
194
196
|
handler: async (input) => {
|
|
195
|
-
const deals = await crm.listDeals({ stage: input.stage })
|
|
196
|
-
|
|
197
|
-
for (const deal of deals) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
197
|
+
const deals = await crm.listDeals({ stage: input.stage })
|
|
198
|
+
|
|
199
|
+
for (const deal of deals) {
|
|
200
|
+
if (!['follow_up_due', 'stale'].includes(deal.priority.bucketKey)) continue
|
|
201
|
+
|
|
202
|
+
await crm.createDealTask({
|
|
203
|
+
dealId: deal.id,
|
|
204
|
+
title: 'Follow up',
|
|
205
|
+
kind: 'email'
|
|
202
206
|
})
|
|
203
207
|
await crm.recordActivity({
|
|
204
208
|
dealId: deal.id,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Build and Extend Lead Gen
|
|
3
|
-
description: Map the lead-gen platform primitives available to SDK projects: shared UI pages, sidebar composition, data hooks, list/member state, artifacts,
|
|
3
|
+
description: Map the lead-gen platform primitives available to SDK projects: shared UI pages, sidebar composition, data hooks, list/member state, artifacts, workflow adapters, contracts, and org-model extension boundaries.
|
|
4
4
|
---
|
|
5
5
|
<!-- @generated by packages/sdk/scripts/copy-reference-docs.mjs -- DO NOT EDIT -->
|
|
6
6
|
<!-- Regenerate: pnpm scaffold:sync -->
|
|
@@ -15,7 +15,7 @@ Good trigger phrases:
|
|
|
15
15
|
- "Add a lead-gen reports page."
|
|
16
16
|
- "Build a campaign creator surface."
|
|
17
17
|
- "Customize the lead-gen sidebar."
|
|
18
|
-
- "Show artifacts
|
|
18
|
+
- "Show artifacts for a campaign."
|
|
19
19
|
- "Read or update lead-gen lists from a workflow."
|
|
20
20
|
- "Change the lead-gen lifecycle for this business."
|
|
21
21
|
|
|
@@ -23,42 +23,44 @@ Lead gen is a layered platform surface, not one component:
|
|
|
23
23
|
|
|
24
24
|
- **Organization OS:** prospecting semantics, feature gates, pipeline labels, and quick access live in the organization model.
|
|
25
25
|
- **Shared UI:** lead-gen overview, lists, list detail, companies, contacts, sidebars, and drawer components live in `@elevasis/ui`.
|
|
26
|
-
- **Headless hooks:** lists, companies, contacts, artifacts,
|
|
27
|
-
- **Acquisition substrate:** `acq_lists`, `acq_companies`, `acq_contacts`, `acq_artifacts`,
|
|
26
|
+
- **Headless hooks:** lists, companies, contacts, artifacts, list members, transitions, and derived actions live under `@elevasis/ui/hooks`.
|
|
27
|
+
- **Acquisition substrate:** `acq_lists`, `acq_companies`, `acq_contacts`, `acq_artifacts`, list members, list companies, telemetry, and stateful transition shapes are exposed through generated contracts.
|
|
28
28
|
- **Workflow adapters:** `acqDb` and `list` from `@elevasis/sdk/worker` let workflows read and mutate lead-gen data through platform tools.
|
|
29
29
|
- **Contracts:** generated contract docs expose the current lead-gen shapes in `node_modules/@elevasis/sdk/reference/scaffold/reference/contracts.md`.
|
|
30
30
|
|
|
31
31
|
## Decision Table
|
|
32
32
|
|
|
33
|
-
| User wants
|
|
34
|
-
|
|
|
35
|
-
| Change lead-gen feature availability, labels, quick access, or pipeline semantics | `core/config/organization-model.ts` plus `core/config/organization-model.examples.ts`
|
|
36
|
-
| Add lead-gen sidebar nav or a lead-gen route
|
|
37
|
-
| Wrap a shared lead-gen page with project chrome
|
|
38
|
-
| Build a custom campaign/list workspace
|
|
39
|
-
| Render artifacts
|
|
40
|
-
| Read or mutate lead-gen data inside a workflow
|
|
41
|
-
| Add a new persisted lead-gen field, artifact kind, or transition API
|
|
33
|
+
| User wants | Start here | Notes |
|
|
34
|
+
| --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
35
|
+
| Change lead-gen feature availability, labels, quick access, or pipeline semantics | `core/config/organization-model.ts` plus `core/config/organization-model.examples.ts` | Treat this as Organization OS work. Use the project's configure ceremony if available. |
|
|
36
|
+
| Add lead-gen sidebar nav or a lead-gen route | `@elevasis/ui/features/lead-gen` and `node_modules/@elevasis/sdk/reference/scaffold/ui/customization.md` | Prefer manifest/sidebar composition. Do not fork shared source first. |
|
|
37
|
+
| Wrap a shared lead-gen page with project chrome | `LeadGenOverviewPage`, `LeadGenListsPage`, `LeadGenListDetailPage`, `ListBuilderPage`, `LeadGenCompaniesPage`, `LeadGenContactsPage` | Keep route files thin and put project-specific behavior in local feature modules. |
|
|
38
|
+
| Build a custom campaign/list workspace | `ListBuilderPage`, `useLists`, `useList`, `useListProgress`, `useListExecutions`, `useWorkflowExecution`, `useExecutionSSE` from `@elevasis/ui` | Use the shared builder when possible; otherwise compose hooks for platform data and workflow execution. |
|
|
39
|
+
| Render artifacts or list-member detail | `LeadGenListDetailPage`, `useArtifacts`, `useCreateArtifact`, `useListMember` | Artifacts are a substrate primitive. Keep vertical-specific rendering local until there are repeated use cases. |
|
|
40
|
+
| Read or mutate lead-gen data inside a workflow | `acqDb` or `list` from `@elevasis/sdk/worker` | `organizationId` is injected server-side by the platform dispatcher. Do not pass it from workflow code. |
|
|
41
|
+
| Add a new persisted lead-gen field, artifact kind, or transition API | Platform/API migration work, not just scaffold work | Update DB, core schemas/types, API service/handlers, hooks, docs, and scaffold contracts together. |
|
|
42
42
|
|
|
43
43
|
## Published Lead-Gen Surfaces
|
|
44
44
|
|
|
45
|
-
| Surface
|
|
46
|
-
|
|
|
47
|
-
| `leadGenManifest`, `LEAD_GEN_ITEMS`, `LeadGenSidebar`, `LeadGenSidebarTop`, `LeadGenSidebarMiddle`
|
|
48
|
-
| `LeadGenOverviewPage`, `LeadGenListsPage`, `LeadGenListDetailPage`, `LeadGenCompaniesPage`, `LeadGenContactsPage`
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
53
|
-
| `
|
|
54
|
-
| `
|
|
55
|
-
| `
|
|
45
|
+
| Surface | Import from | Use for |
|
|
46
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | -------------------------------------------------------------------- |
|
|
47
|
+
| `leadGenManifest`, `LEAD_GEN_ITEMS`, `LeadGenSidebar`, `LeadGenSidebarTop`, `LeadGenSidebarMiddle` | `@elevasis/ui/features/lead-gen` | Feature registration and sidebar composition |
|
|
48
|
+
| `LeadGenOverviewPage`, `LeadGenListsPage`, `LeadGenListDetailPage`, `ListBuilderPage`, `LeadGenCompaniesPage`, `LeadGenContactsPage` | `@elevasis/ui/features/lead-gen` | Shared lead-gen pages you can route to or wrap |
|
|
49
|
+
| `ListActionsProvider`, `useListActions`, `ListBuilderWorkflow`, `ListBuilderRegistry`, MVP workflow form components | `@elevasis/ui/features/lead-gen` | List Builder workflow registry, run modal inputs, and project-owned action wiring |
|
|
50
|
+
| `LeadGenRouteShell`, `CompanyDetailModal`, `ContactDetailModal`, `LIST_TEMPLATE_OPTIONS`, `buildListConfig` | `@elevasis/ui/features/lead-gen` | Route shell helpers, detail modals, and list creation config helpers |
|
|
51
|
+
| `useLists`, `useList`, `useListsTelemetry`, `useListProgress`, `useListExecutions`, `useCreateList`, `useUpdateList`, `useUpdateListConfig`, `useDeleteList` | `@elevasis/ui/hooks` | Headless list and telemetry data access |
|
|
52
|
+
| `useWorkflowExecution`, `useExecutionSSE`, `useAddCompaniesToList`, `useRemoveCompaniesFromList`, `useAddContactsToList` | `@elevasis/ui/hooks` | List Builder workflow triggering, live execution tailing, and list membership mutations |
|
|
53
|
+
| `useCompanies`, `useCompany`, `useContacts`, `useContact` | `@elevasis/ui/hooks` | Acquisition company/contact data access |
|
|
54
|
+
| `useArtifacts`, `useCreateArtifact`, `useListMembers`, `useListMember` | `@elevasis/ui/hooks` | Lead-gen substrate data access |
|
|
55
|
+
| `useTransitionList`, `useTransitionListMember`, `useTransitionListCompany`, `useDeriveActions` | `@elevasis/ui/hooks` | Stateful transition mutations and contextual action derivation |
|
|
56
|
+
| `ElevasisUIProvider`, `ElevasisCoreProvider`, `useElevasisServices` | `@elevasis/ui/provider` | Provider setup, API access, organization context, and `listActions` registry injection |
|
|
57
|
+
| `acqDb`, `list` | `@elevasis/sdk/worker` | Workflow-side acquisition and list-scoped platform adapters |
|
|
56
58
|
|
|
57
59
|
Read the generated contracts before changing typed boundaries:
|
|
58
60
|
|
|
59
61
|
`node_modules/@elevasis/sdk/reference/scaffold/reference/contracts.md`
|
|
60
62
|
|
|
61
|
-
Look for the **Lead Gen Platform Primitives** section. It includes list shapes, company/contact shapes, list config, telemetry, artifacts,
|
|
63
|
+
Look for the **Lead Gen Platform Primitives** section. It includes list shapes, company/contact shapes, list config, telemetry, artifacts, list members, stateful pipeline definitions, and workflow adapter method maps.
|
|
62
64
|
|
|
63
65
|
## 1. Extend Lead-Gen Navigation or Sidebar
|
|
64
66
|
|
|
@@ -135,19 +137,90 @@ function ListDetailRoute() {
|
|
|
135
137
|
|
|
136
138
|
Use the same wrapping pattern for `LeadGenOverviewPage`, `LeadGenCompaniesPage`, and `LeadGenContactsPage`.
|
|
137
139
|
|
|
140
|
+
For the real-time List Builder workspace, add a thin route that passes the route param into `ListBuilderPage`:
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
144
|
+
import { ListBuilderPage } from '@elevasis/ui/features/lead-gen'
|
|
145
|
+
|
|
146
|
+
export const Route = createFileRoute('/lead-gen/list-builder/$listId')({
|
|
147
|
+
component: ListBuilderRoute
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
function ListBuilderRoute() {
|
|
151
|
+
const { listId } = Route.useParams()
|
|
152
|
+
return <ListBuilderPage listId={listId} />
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Register project workflow actions at the provider boundary. The shared UI owns the contract; each project owns workflow ids and form choices:
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
import {
|
|
160
|
+
CompanyCleanupForm,
|
|
161
|
+
EmailDiscoveryForm,
|
|
162
|
+
EmailVerificationForm,
|
|
163
|
+
WebsiteExtractForm,
|
|
164
|
+
type ListBuilderRegistry
|
|
165
|
+
} from '@elevasis/ui/features/lead-gen'
|
|
166
|
+
import { ElevasisUIProvider } from '@elevasis/ui/provider'
|
|
167
|
+
|
|
168
|
+
const listActions: ListBuilderRegistry = [
|
|
169
|
+
{
|
|
170
|
+
resourceId: 'lgn-04-email-discovery-workflow',
|
|
171
|
+
label: 'Email Discovery',
|
|
172
|
+
description: 'Discover contact email addresses for companies in the list.',
|
|
173
|
+
category: 'enrich',
|
|
174
|
+
stagesAffected: ['discovered'],
|
|
175
|
+
inputForm: EmailDiscoveryForm
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
resourceId: 'lgn-05-email-verification-workflow',
|
|
179
|
+
label: 'Email Verification',
|
|
180
|
+
description: 'Verify deliverability for contact emails in the list.',
|
|
181
|
+
category: 'enrich',
|
|
182
|
+
stagesAffected: ['verified'],
|
|
183
|
+
inputForm: EmailVerificationForm
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
resourceId: 'lgn-02-website-extract-workflow',
|
|
187
|
+
label: 'Website Extract',
|
|
188
|
+
description: 'Extract website intelligence for companies in the list.',
|
|
189
|
+
category: 'scrape',
|
|
190
|
+
stagesAffected: ['extracted'],
|
|
191
|
+
inputForm: WebsiteExtractForm
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
resourceId: 'lgn-company-cleanup-workflow',
|
|
195
|
+
label: 'Company Cleanup',
|
|
196
|
+
description: 'Normalize and clean company records for the list.',
|
|
197
|
+
category: 'utility',
|
|
198
|
+
stagesAffected: ['populated'],
|
|
199
|
+
inputForm: CompanyCleanupForm
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
|
|
203
|
+
export function App() {
|
|
204
|
+
return (
|
|
205
|
+
<ElevasisUIProvider listActions={listActions} {...providerProps}>
|
|
206
|
+
{children}
|
|
207
|
+
</ElevasisUIProvider>
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
138
212
|
## 3. Build a Custom Campaign Workspace
|
|
139
213
|
|
|
140
214
|
When the project needs custom layout or vertical-specific rendering, use the hooks directly:
|
|
141
215
|
|
|
142
216
|
```tsx
|
|
143
217
|
import { Badge, Button, Card, Group, Stack, Text } from '@mantine/core'
|
|
144
|
-
import { useArtifacts, useList, useListMembers,
|
|
218
|
+
import { useArtifacts, useList, useListMembers, useTransitionListMember } from '@elevasis/ui/hooks'
|
|
145
219
|
|
|
146
220
|
export function CampaignWorkspace({ listId }: { listId: string }) {
|
|
147
221
|
const listQuery = useList(listId)
|
|
148
222
|
const membersQuery = useListMembers({ listId })
|
|
149
223
|
const artifactsQuery = useArtifacts({ ownerKind: 'list', ownerId: listId })
|
|
150
|
-
const touchpointsQuery = useTouchpoints({ listId })
|
|
151
224
|
const transitionMember = useTransitionListMember()
|
|
152
225
|
|
|
153
226
|
const list = listQuery.data
|
|
@@ -167,7 +240,6 @@ export function CampaignWorkspace({ listId }: { listId: string }) {
|
|
|
167
240
|
|
|
168
241
|
<Card withBorder>
|
|
169
242
|
<Text size="sm">Artifacts: {artifactsQuery.data?.artifacts.length ?? 0}</Text>
|
|
170
|
-
<Text size="sm">Touchpoints: {touchpointsQuery.data?.touchpoints.length ?? 0}</Text>
|
|
171
243
|
</Card>
|
|
172
244
|
|
|
173
245
|
{firstMember ? (
|
|
@@ -190,7 +262,7 @@ export function CampaignWorkspace({ listId }: { listId: string }) {
|
|
|
190
262
|
}
|
|
191
263
|
```
|
|
192
264
|
|
|
193
|
-
Use `useArtifacts({ ownerKind, ownerId })` for durable JSON artifacts like audits, research summaries, snapshots, exports, or model outputs.
|
|
265
|
+
Use `useArtifacts({ ownerKind, ownerId })` for durable JSON artifacts like audits, research summaries, snapshots, exports, or model outputs.
|
|
194
266
|
|
|
195
267
|
## 4. Read and Mutate Lead-Gen Data in Workflows
|
|
196
268
|
|
|
@@ -277,7 +349,7 @@ The platform-side lead-gen stateful vocabulary is defined for:
|
|
|
277
349
|
|
|
278
350
|
The generated contracts expose `StatefulPipelineDefinition` and `LEAD_GEN_PIPELINE_DEFINITIONS` so downstream agents can inspect the current pipeline/stage/state vocabulary before adding UI labels or workflow transitions.
|
|
279
351
|
|
|
280
|
-
Changing persisted platform stages, adding new owner kinds, or extending artifact
|
|
352
|
+
Changing persisted platform stages, adding new owner kinds, or extending artifact schema requires coordinated core/API/UI updates. Relabeling, route wrapping, sidebar changes, and project-owned rendering usually stay in the downstream project.
|
|
281
353
|
|
|
282
354
|
## Verify
|
|
283
355
|
|