@contractspec/example.crm-pipeline 1.44.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/.turbo/turbo-build$colon$bundle.log +97 -0
- package/.turbo/turbo-build.log +98 -0
- package/CHANGELOG.md +246 -0
- package/LICENSE +21 -0
- package/README.md +139 -0
- package/dist/crm-pipeline.feature.d.ts +12 -0
- package/dist/crm-pipeline.feature.d.ts.map +1 -0
- package/dist/crm-pipeline.feature.js +159 -0
- package/dist/crm-pipeline.feature.js.map +1 -0
- package/dist/deal/deal.enum.d.ts +14 -0
- package/dist/deal/deal.enum.d.ts.map +1 -0
- package/dist/deal/deal.enum.js +25 -0
- package/dist/deal/deal.enum.js.map +1 -0
- package/dist/deal/deal.operation.d.ts +513 -0
- package/dist/deal/deal.operation.d.ts.map +1 -0
- package/dist/deal/deal.operation.js +270 -0
- package/dist/deal/deal.operation.js.map +1 -0
- package/dist/deal/deal.schema.d.ts +300 -0
- package/dist/deal/deal.schema.d.ts.map +1 -0
- package/dist/deal/deal.schema.js +286 -0
- package/dist/deal/deal.schema.js.map +1 -0
- package/dist/deal/index.d.ts +4 -0
- package/dist/deal/index.js +5 -0
- package/dist/docs/crm-pipeline.docblock.d.ts +1 -0
- package/dist/docs/crm-pipeline.docblock.js +100 -0
- package/dist/docs/crm-pipeline.docblock.js.map +1 -0
- package/dist/docs/index.d.ts +1 -0
- package/dist/docs/index.js +1 -0
- package/dist/entities/company.entity.d.ts +40 -0
- package/dist/entities/company.entity.d.ts.map +1 -0
- package/dist/entities/company.entity.js +63 -0
- package/dist/entities/company.entity.js.map +1 -0
- package/dist/entities/contact.entity.d.ts +44 -0
- package/dist/entities/contact.entity.d.ts.map +1 -0
- package/dist/entities/contact.entity.js +78 -0
- package/dist/entities/contact.entity.js.map +1 -0
- package/dist/entities/deal.entity.d.ts +73 -0
- package/dist/entities/deal.entity.d.ts.map +1 -0
- package/dist/entities/deal.entity.js +120 -0
- package/dist/entities/deal.entity.js.map +1 -0
- package/dist/entities/index.d.ts +15 -0
- package/dist/entities/index.d.ts.map +1 -0
- package/dist/entities/index.js +33 -0
- package/dist/entities/index.js.map +1 -0
- package/dist/entities/task.entity.d.ts +65 -0
- package/dist/entities/task.entity.d.ts.map +1 -0
- package/dist/entities/task.entity.js +129 -0
- package/dist/entities/task.entity.js.map +1 -0
- package/dist/events/contact.event.d.ts +29 -0
- package/dist/events/contact.event.d.ts.map +1 -0
- package/dist/events/contact.event.js +45 -0
- package/dist/events/contact.event.js.map +1 -0
- package/dist/events/deal.event.d.ts +111 -0
- package/dist/events/deal.event.d.ts.map +1 -0
- package/dist/events/deal.event.js +172 -0
- package/dist/events/deal.event.js.map +1 -0
- package/dist/events/index.d.ts +4 -0
- package/dist/events/index.js +5 -0
- package/dist/events/task.event.d.ts +29 -0
- package/dist/events/task.event.d.ts.map +1 -0
- package/dist/events/task.event.js +45 -0
- package/dist/events/task.event.js.map +1 -0
- package/dist/example.d.ts +37 -0
- package/dist/example.d.ts.map +1 -0
- package/dist/example.js +46 -0
- package/dist/example.js.map +1 -0
- package/dist/handlers/deal.handlers.d.ts +94 -0
- package/dist/handlers/deal.handlers.d.ts.map +1 -0
- package/dist/handlers/deal.handlers.js +120 -0
- package/dist/handlers/deal.handlers.js.map +1 -0
- package/dist/handlers/index.d.ts +3 -0
- package/dist/handlers/index.js +4 -0
- package/dist/handlers/mock-data.d.ts +49 -0
- package/dist/handlers/mock-data.d.ts.map +1 -0
- package/dist/handlers/mock-data.js +188 -0
- package/dist/handlers/mock-data.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/operations/index.d.ts +5 -0
- package/dist/operations/index.js +6 -0
- package/dist/presentations/dashboard.presentation.d.ts +15 -0
- package/dist/presentations/dashboard.presentation.d.ts.map +1 -0
- package/dist/presentations/dashboard.presentation.js +59 -0
- package/dist/presentations/dashboard.presentation.js.map +1 -0
- package/dist/presentations/index.d.ts +3 -0
- package/dist/presentations/index.js +4 -0
- package/dist/presentations/pipeline.presentation.d.ts +23 -0
- package/dist/presentations/pipeline.presentation.d.ts.map +1 -0
- package/dist/presentations/pipeline.presentation.js +119 -0
- package/dist/presentations/pipeline.presentation.js.map +1 -0
- package/example.ts +1 -0
- package/package.json +105 -0
- package/src/crm-pipeline.feature.ts +96 -0
- package/src/deal/deal.enum.ts +21 -0
- package/src/deal/deal.operation.ts +291 -0
- package/src/deal/deal.schema.ts +154 -0
- package/src/deal/index.ts +26 -0
- package/src/docs/crm-pipeline.docblock.ts +98 -0
- package/src/docs/index.ts +1 -0
- package/src/entities/company.entity.ts +77 -0
- package/src/entities/contact.entity.ts +93 -0
- package/src/entities/deal.entity.ts +160 -0
- package/src/entities/index.ts +45 -0
- package/src/entities/task.entity.ts +137 -0
- package/src/events/contact.event.ts +31 -0
- package/src/events/deal.event.ts +104 -0
- package/src/events/index.ts +3 -0
- package/src/events/task.event.ts +28 -0
- package/src/example.ts +30 -0
- package/src/handlers/deal.handlers.ts +253 -0
- package/src/handlers/index.ts +27 -0
- package/src/handlers/mock-data.ts +198 -0
- package/src/index.ts +31 -0
- package/src/operations/index.ts +20 -0
- package/src/presentations/dashboard.presentation.ts +60 -0
- package/src/presentations/index.ts +2 -0
- package/src/presentations/pipeline.presentation.ts +118 -0
- package/tsconfig.json +10 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/tsdown.config.js +7 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { DealModel } from "../deal/deal.schema.js";
|
|
2
|
+
import { StabilityEnum } from "@contractspec/lib.contracts";
|
|
3
|
+
|
|
4
|
+
//#region src/presentations/pipeline.presentation.ts
|
|
5
|
+
/**
|
|
6
|
+
* Kanban board presentation for the sales pipeline.
|
|
7
|
+
*/
|
|
8
|
+
const PipelineKanbanPresentation = {
|
|
9
|
+
meta: {
|
|
10
|
+
key: "crm.pipeline.kanban",
|
|
11
|
+
version: 1,
|
|
12
|
+
title: "Pipeline Kanban",
|
|
13
|
+
description: "Kanban board view of deals organized by stage",
|
|
14
|
+
domain: "crm-pipeline",
|
|
15
|
+
owners: ["@crm-team"],
|
|
16
|
+
tags: [
|
|
17
|
+
"pipeline",
|
|
18
|
+
"kanban",
|
|
19
|
+
"deals"
|
|
20
|
+
],
|
|
21
|
+
stability: StabilityEnum.Experimental,
|
|
22
|
+
goal: "Visualize the sales pipeline status and deal distribution across stages.",
|
|
23
|
+
context: "Used in the sales dashboard and management reports."
|
|
24
|
+
},
|
|
25
|
+
source: {
|
|
26
|
+
type: "component",
|
|
27
|
+
framework: "react",
|
|
28
|
+
componentKey: "PipelineKanbanView",
|
|
29
|
+
props: DealModel
|
|
30
|
+
},
|
|
31
|
+
targets: ["react", "markdown"],
|
|
32
|
+
policy: { flags: ["crm.pipeline.enabled"] }
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* List view of deals with filtering.
|
|
36
|
+
*/
|
|
37
|
+
const DealListPresentation = {
|
|
38
|
+
meta: {
|
|
39
|
+
key: "crm.deal.list",
|
|
40
|
+
version: 1,
|
|
41
|
+
title: "Deal List",
|
|
42
|
+
description: "List view of deals with value, status, and owner info",
|
|
43
|
+
domain: "crm-pipeline",
|
|
44
|
+
owners: ["@crm-team"],
|
|
45
|
+
tags: ["deal", "list"],
|
|
46
|
+
stability: StabilityEnum.Experimental,
|
|
47
|
+
goal: "Search, filter, and review deal lists.",
|
|
48
|
+
context: "Standard view for deal management and bulk actions."
|
|
49
|
+
},
|
|
50
|
+
source: {
|
|
51
|
+
type: "component",
|
|
52
|
+
framework: "react",
|
|
53
|
+
componentKey: "DealListView",
|
|
54
|
+
props: DealModel
|
|
55
|
+
},
|
|
56
|
+
targets: [
|
|
57
|
+
"react",
|
|
58
|
+
"markdown",
|
|
59
|
+
"application/json"
|
|
60
|
+
],
|
|
61
|
+
policy: { flags: ["crm.deals.enabled"] }
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Deal detail presentation.
|
|
65
|
+
*/
|
|
66
|
+
const DealDetailPresentation = {
|
|
67
|
+
meta: {
|
|
68
|
+
key: "crm.deal.detail",
|
|
69
|
+
version: 1,
|
|
70
|
+
title: "Deal Details",
|
|
71
|
+
description: "Detailed view of a deal with activities, contacts, and history",
|
|
72
|
+
domain: "crm-pipeline",
|
|
73
|
+
owners: ["@crm-team"],
|
|
74
|
+
tags: ["deal", "detail"],
|
|
75
|
+
stability: StabilityEnum.Experimental,
|
|
76
|
+
goal: "Deep dive into deal details and historical activities.",
|
|
77
|
+
context: "The main workspace for managing a single deal execution."
|
|
78
|
+
},
|
|
79
|
+
source: {
|
|
80
|
+
type: "component",
|
|
81
|
+
framework: "react",
|
|
82
|
+
componentKey: "DealDetailView"
|
|
83
|
+
},
|
|
84
|
+
targets: ["react", "markdown"],
|
|
85
|
+
policy: { flags: ["crm.deals.enabled"] }
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Deal card for kanban board.
|
|
89
|
+
*/
|
|
90
|
+
const DealCardPresentation = {
|
|
91
|
+
meta: {
|
|
92
|
+
key: "crm.deal.card",
|
|
93
|
+
version: 1,
|
|
94
|
+
title: "Deal Card",
|
|
95
|
+
description: "Compact deal card for kanban board display",
|
|
96
|
+
domain: "crm-pipeline",
|
|
97
|
+
owners: ["@crm-team"],
|
|
98
|
+
tags: [
|
|
99
|
+
"deal",
|
|
100
|
+
"card",
|
|
101
|
+
"kanban"
|
|
102
|
+
],
|
|
103
|
+
stability: StabilityEnum.Experimental,
|
|
104
|
+
goal: "Provide a quick overview of deal status in the pipeline view.",
|
|
105
|
+
context: "Condensed representation used within the Pipeline Kanban board."
|
|
106
|
+
},
|
|
107
|
+
source: {
|
|
108
|
+
type: "component",
|
|
109
|
+
framework: "react",
|
|
110
|
+
componentKey: "DealCard",
|
|
111
|
+
props: DealModel
|
|
112
|
+
},
|
|
113
|
+
targets: ["react"],
|
|
114
|
+
policy: { flags: ["crm.deals.enabled"] }
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
//#endregion
|
|
118
|
+
export { DealCardPresentation, DealDetailPresentation, DealListPresentation, PipelineKanbanPresentation };
|
|
119
|
+
//# sourceMappingURL=pipeline.presentation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.presentation.js","names":["PipelineKanbanPresentation: PresentationSpec","DealListPresentation: PresentationSpec","DealDetailPresentation: PresentationSpec","DealCardPresentation: PresentationSpec"],"sources":["../../src/presentations/pipeline.presentation.ts"],"sourcesContent":["/**\n * Pipeline Presentation Descriptors\n */\nimport type { PresentationSpec } from '@contractspec/lib.contracts';\nimport { StabilityEnum } from '@contractspec/lib.contracts';\nimport { DealModel } from '../deal/deal.schema';\n\n/**\n * Kanban board presentation for the sales pipeline.\n */\nexport const PipelineKanbanPresentation: PresentationSpec = {\n meta: {\n key: 'crm.pipeline.kanban',\n version: 1,\n title: 'Pipeline Kanban',\n description: 'Kanban board view of deals organized by stage',\n domain: 'crm-pipeline',\n owners: ['@crm-team'],\n tags: ['pipeline', 'kanban', 'deals'],\n stability: StabilityEnum.Experimental,\n goal: 'Visualize the sales pipeline status and deal distribution across stages.',\n context: 'Used in the sales dashboard and management reports.',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'PipelineKanbanView',\n props: DealModel,\n },\n targets: ['react', 'markdown'],\n policy: {\n flags: ['crm.pipeline.enabled'],\n },\n};\n\n/**\n * List view of deals with filtering.\n */\nexport const DealListPresentation: PresentationSpec = {\n meta: {\n key: 'crm.deal.list',\n version: 1,\n title: 'Deal List',\n description: 'List view of deals with value, status, and owner info',\n domain: 'crm-pipeline',\n owners: ['@crm-team'],\n tags: ['deal', 'list'],\n stability: StabilityEnum.Experimental,\n goal: 'Search, filter, and review deal lists.',\n context: 'Standard view for deal management and bulk actions.',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'DealListView',\n props: DealModel,\n },\n targets: ['react', 'markdown', 'application/json'],\n policy: {\n flags: ['crm.deals.enabled'],\n },\n};\n\n/**\n * Deal detail presentation.\n */\nexport const DealDetailPresentation: PresentationSpec = {\n meta: {\n key: 'crm.deal.detail',\n version: 1,\n title: 'Deal Details',\n description:\n 'Detailed view of a deal with activities, contacts, and history',\n domain: 'crm-pipeline',\n owners: ['@crm-team'],\n tags: ['deal', 'detail'],\n stability: StabilityEnum.Experimental,\n goal: 'Deep dive into deal details and historical activities.',\n context: 'The main workspace for managing a single deal execution.',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'DealDetailView',\n },\n targets: ['react', 'markdown'],\n policy: {\n flags: ['crm.deals.enabled'],\n },\n};\n\n/**\n * Deal card for kanban board.\n */\nexport const DealCardPresentation: PresentationSpec = {\n meta: {\n key: 'crm.deal.card',\n version: 1,\n title: 'Deal Card',\n description: 'Compact deal card for kanban board display',\n domain: 'crm-pipeline',\n owners: ['@crm-team'],\n tags: ['deal', 'card', 'kanban'],\n stability: StabilityEnum.Experimental,\n goal: 'Provide a quick overview of deal status in the pipeline view.',\n context: 'Condensed representation used within the Pipeline Kanban board.',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'DealCard',\n props: DealModel,\n },\n targets: ['react'],\n policy: {\n flags: ['crm.deals.enabled'],\n },\n};\n"],"mappings":";;;;;;;AAUA,MAAaA,6BAA+C;CAC1D,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aAAa;EACb,QAAQ;EACR,QAAQ,CAAC,YAAY;EACrB,MAAM;GAAC;GAAY;GAAU;GAAQ;EACrC,WAAW,cAAc;EACzB,MAAM;EACN,SAAS;EACV;CACD,QAAQ;EACN,MAAM;EACN,WAAW;EACX,cAAc;EACd,OAAO;EACR;CACD,SAAS,CAAC,SAAS,WAAW;CAC9B,QAAQ,EACN,OAAO,CAAC,uBAAuB,EAChC;CACF;;;;AAKD,MAAaC,uBAAyC;CACpD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aAAa;EACb,QAAQ;EACR,QAAQ,CAAC,YAAY;EACrB,MAAM,CAAC,QAAQ,OAAO;EACtB,WAAW,cAAc;EACzB,MAAM;EACN,SAAS;EACV;CACD,QAAQ;EACN,MAAM;EACN,WAAW;EACX,cAAc;EACd,OAAO;EACR;CACD,SAAS;EAAC;EAAS;EAAY;EAAmB;CAClD,QAAQ,EACN,OAAO,CAAC,oBAAoB,EAC7B;CACF;;;;AAKD,MAAaC,yBAA2C;CACtD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aACE;EACF,QAAQ;EACR,QAAQ,CAAC,YAAY;EACrB,MAAM,CAAC,QAAQ,SAAS;EACxB,WAAW,cAAc;EACzB,MAAM;EACN,SAAS;EACV;CACD,QAAQ;EACN,MAAM;EACN,WAAW;EACX,cAAc;EACf;CACD,SAAS,CAAC,SAAS,WAAW;CAC9B,QAAQ,EACN,OAAO,CAAC,oBAAoB,EAC7B;CACF;;;;AAKD,MAAaC,uBAAyC;CACpD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aAAa;EACb,QAAQ;EACR,QAAQ,CAAC,YAAY;EACrB,MAAM;GAAC;GAAQ;GAAQ;GAAS;EAChC,WAAW,cAAc;EACzB,MAAM;EACN,SAAS;EACV;CACD,QAAQ;EACN,MAAM;EACN,WAAW;EACX,cAAc;EACd,OAAO;EACR;CACD,SAAS,CAAC,QAAQ;CAClB,QAAQ,EACN,OAAO,CAAC,oBAAoB,EAC7B;CACF"}
|
package/example.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './src/example';
|
package/package.json
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@contractspec/example.crm-pipeline",
|
|
3
|
+
"version": "1.44.0",
|
|
4
|
+
"description": "CRM Pipeline - Contacts, Companies, Deals, Tasks",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/index.js",
|
|
10
|
+
"./crm-pipeline.feature": "./dist/crm-pipeline.feature.js",
|
|
11
|
+
"./deal": "./dist/deal/index.js",
|
|
12
|
+
"./deal/deal.enum": "./dist/deal/deal.enum.js",
|
|
13
|
+
"./deal/deal.operation": "./dist/deal/deal.operation.js",
|
|
14
|
+
"./deal/deal.schema": "./dist/deal/deal.schema.js",
|
|
15
|
+
"./docs": "./dist/docs/index.js",
|
|
16
|
+
"./docs/crm-pipeline.docblock": "./dist/docs/crm-pipeline.docblock.js",
|
|
17
|
+
"./entities": "./dist/entities/index.js",
|
|
18
|
+
"./entities/company.entity": "./dist/entities/company.entity.js",
|
|
19
|
+
"./entities/contact.entity": "./dist/entities/contact.entity.js",
|
|
20
|
+
"./entities/deal.entity": "./dist/entities/deal.entity.js",
|
|
21
|
+
"./entities/task.entity": "./dist/entities/task.entity.js",
|
|
22
|
+
"./events": "./dist/events/index.js",
|
|
23
|
+
"./events/contact.event": "./dist/events/contact.event.js",
|
|
24
|
+
"./events/deal.event": "./dist/events/deal.event.js",
|
|
25
|
+
"./events/task.event": "./dist/events/task.event.js",
|
|
26
|
+
"./example": "./dist/example.js",
|
|
27
|
+
"./handlers": "./dist/handlers/index.js",
|
|
28
|
+
"./handlers/deal.handlers": "./dist/handlers/deal.handlers.js",
|
|
29
|
+
"./handlers/mock-data": "./dist/handlers/mock-data.js",
|
|
30
|
+
"./operations": "./dist/operations/index.js",
|
|
31
|
+
"./presentations": "./dist/presentations/index.js",
|
|
32
|
+
"./presentations/dashboard.presentation": "./dist/presentations/dashboard.presentation.js",
|
|
33
|
+
"./presentations/pipeline.presentation": "./dist/presentations/pipeline.presentation.js",
|
|
34
|
+
"./*": "./*"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
|
|
38
|
+
"publish:pkg:canary": "bun publish:pkg --tag canary",
|
|
39
|
+
"build": "bun build:types && bun build:bundle",
|
|
40
|
+
"build:bundle": "tsdown",
|
|
41
|
+
"build:types": "tsc --noEmit",
|
|
42
|
+
"dev": "bun build:bundle --watch",
|
|
43
|
+
"clean": "rimraf dist .turbo",
|
|
44
|
+
"lint": "bun lint:fix",
|
|
45
|
+
"lint:fix": "eslint src --fix",
|
|
46
|
+
"lint:check": "eslint src",
|
|
47
|
+
"test": "bun run"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@contractspec/lib.schema": "1.44.0",
|
|
51
|
+
"@contractspec/lib.contracts": "1.44.0",
|
|
52
|
+
"@contractspec/lib.bus": "1.44.0",
|
|
53
|
+
"@contractspec/lib.identity-rbac": "1.44.0",
|
|
54
|
+
"@contractspec/lib.jobs": "1.44.0",
|
|
55
|
+
"@contractspec/module.audit-trail": "1.44.0",
|
|
56
|
+
"@contractspec/module.notifications": "1.44.0",
|
|
57
|
+
"zod": "^4.1.13"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@contractspec/tool.tsdown": "1.44.0",
|
|
61
|
+
"@contractspec/tool.typescript": "1.44.0",
|
|
62
|
+
"tsdown": "^0.18.3",
|
|
63
|
+
"typescript": "^5.9.3"
|
|
64
|
+
},
|
|
65
|
+
"module": "./dist/index.js",
|
|
66
|
+
"publishConfig": {
|
|
67
|
+
"exports": {
|
|
68
|
+
".": "./dist/index.js",
|
|
69
|
+
"./contracts": "./dist/contracts/index.js",
|
|
70
|
+
"./crm-pipeline.feature": "./dist/crm-pipeline.feature.js",
|
|
71
|
+
"./deal": "./dist/deal/index.js",
|
|
72
|
+
"./deal/deal.contracts": "./dist/deal/deal.operations.js",
|
|
73
|
+
"./deal/deal.enum": "./dist/deal/deal.enum.js",
|
|
74
|
+
"./deal/deal.schema": "./dist/deal/deal.schema.js",
|
|
75
|
+
"./docs": "./dist/docs/index.js",
|
|
76
|
+
"./docs/crm-pipeline.docblock": "./dist/docs/crm-pipeline.docblock.js",
|
|
77
|
+
"./entities": "./dist/entities/index.js",
|
|
78
|
+
"./entities/company.entity": "./dist/entities/company.entity.js",
|
|
79
|
+
"./entities/contact.entity": "./dist/entities/contact.entity.js",
|
|
80
|
+
"./entities/deal.entity": "./dist/entities/deal.entity.js",
|
|
81
|
+
"./entities/task.entity": "./dist/entities/task.entity.js",
|
|
82
|
+
"./events": "./dist/events/index.js",
|
|
83
|
+
"./events/contact.event": "./dist/events/contact.event.js",
|
|
84
|
+
"./events/deal.event": "./dist/events/deal.event.js",
|
|
85
|
+
"./events/task.event": "./dist/events/task.event.js",
|
|
86
|
+
"./example": "./dist/example.js",
|
|
87
|
+
"./handlers": "./dist/handlers/index.js",
|
|
88
|
+
"./handlers/deal.handlers": "./dist/handlers/deal.handlers.js",
|
|
89
|
+
"./handlers/mock-data": "./dist/handlers/mock-data.js",
|
|
90
|
+
"./presentations": "./dist/presentations/index.js",
|
|
91
|
+
"./presentations/dashboard.presentation": "./dist/presentations/dashboard.presentation.js",
|
|
92
|
+
"./presentations/pipeline.presentation": "./dist/presentations/pipeline.presentation.js",
|
|
93
|
+
"./*": "./*"
|
|
94
|
+
},
|
|
95
|
+
"registry": "https://registry.npmjs.org/",
|
|
96
|
+
"access": "public"
|
|
97
|
+
},
|
|
98
|
+
"license": "MIT",
|
|
99
|
+
"repository": {
|
|
100
|
+
"type": "git",
|
|
101
|
+
"url": "https://github.com/lssm-tech/contractspec.git",
|
|
102
|
+
"directory": "packages/examples/crm-pipeline"
|
|
103
|
+
},
|
|
104
|
+
"homepage": "https://contractspec.io"
|
|
105
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CRM Pipeline Feature Module Specification
|
|
3
|
+
*
|
|
4
|
+
* Defines the feature module for CRM and sales pipeline capabilities.
|
|
5
|
+
*/
|
|
6
|
+
import type { FeatureModuleSpec } from '@contractspec/lib.contracts';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* CRM Pipeline feature module that bundles deal management,
|
|
10
|
+
* pipeline operations, and contact management into an installable feature.
|
|
11
|
+
*/
|
|
12
|
+
export const CrmPipelineFeature: FeatureModuleSpec = {
|
|
13
|
+
meta: {
|
|
14
|
+
key: 'crm-pipeline',
|
|
15
|
+
title: 'CRM Pipeline',
|
|
16
|
+
description:
|
|
17
|
+
'CRM and sales pipeline management with deals, contacts, and companies',
|
|
18
|
+
domain: 'crm',
|
|
19
|
+
owners: ['@crm-team'],
|
|
20
|
+
tags: ['crm', 'sales', 'pipeline', 'deals'],
|
|
21
|
+
stability: 'experimental',
|
|
22
|
+
version: 1,
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// All contract operations included in this feature
|
|
26
|
+
operations: [
|
|
27
|
+
// Deal operations
|
|
28
|
+
{ key: 'crm.deal.create', version: 1 },
|
|
29
|
+
{ key: 'crm.deal.move', version: 1 },
|
|
30
|
+
{ key: 'crm.deal.win', version: 1 },
|
|
31
|
+
{ key: 'crm.deal.lose', version: 1 },
|
|
32
|
+
{ key: 'crm.deal.list', version: 1 },
|
|
33
|
+
],
|
|
34
|
+
|
|
35
|
+
// Events emitted by this feature
|
|
36
|
+
events: [
|
|
37
|
+
// Deal events
|
|
38
|
+
{ key: 'deal.created', version: 1 },
|
|
39
|
+
{ key: 'deal.moved', version: 1 },
|
|
40
|
+
{ key: 'deal.won', version: 1 },
|
|
41
|
+
{ key: 'deal.lost', version: 1 },
|
|
42
|
+
|
|
43
|
+
// Contact events
|
|
44
|
+
{ key: 'contact.created', version: 1 },
|
|
45
|
+
|
|
46
|
+
// Task events
|
|
47
|
+
{ key: 'task.completed', version: 1 },
|
|
48
|
+
],
|
|
49
|
+
|
|
50
|
+
// Presentations associated with this feature
|
|
51
|
+
presentations: [
|
|
52
|
+
{ key: 'crm.dashboard', version: 1 },
|
|
53
|
+
{ key: 'crm.pipeline.kanban', version: 1 },
|
|
54
|
+
{ key: 'crm.deal.list', version: 1 },
|
|
55
|
+
{ key: 'crm.deal.detail', version: 1 },
|
|
56
|
+
{ key: 'crm.deal.card', version: 1 },
|
|
57
|
+
{ key: 'crm.pipeline.metrics', version: 1 },
|
|
58
|
+
],
|
|
59
|
+
|
|
60
|
+
// Link operations to their primary presentations
|
|
61
|
+
opToPresentation: [
|
|
62
|
+
{
|
|
63
|
+
op: { key: 'crm.deal.list', version: 1 },
|
|
64
|
+
pres: { key: 'crm.pipeline.kanban', version: 1 },
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
op: { key: 'crm.deal.move', version: 1 },
|
|
68
|
+
pres: { key: 'crm.pipeline.kanban', version: 1 },
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
|
|
72
|
+
// Target requirements for multi-surface rendering
|
|
73
|
+
presentationsTargets: [
|
|
74
|
+
{ key: 'crm.dashboard', version: 1, targets: ['react', 'markdown'] },
|
|
75
|
+
{ key: 'crm.pipeline.kanban', version: 1, targets: ['react', 'markdown'] },
|
|
76
|
+
{
|
|
77
|
+
key: 'crm.deal.list',
|
|
78
|
+
version: 1,
|
|
79
|
+
targets: ['react', 'markdown', 'application/json'],
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
key: 'crm.pipeline.metrics',
|
|
83
|
+
version: 1,
|
|
84
|
+
targets: ['react', 'markdown'],
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
|
|
88
|
+
// Capability requirements
|
|
89
|
+
capabilities: {
|
|
90
|
+
requires: [
|
|
91
|
+
{ key: 'identity', version: 1 },
|
|
92
|
+
{ key: 'audit-trail', version: 1 },
|
|
93
|
+
{ key: 'notifications', version: 1 },
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineEnum } from '@contractspec/lib.schema';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Deal status enum.
|
|
5
|
+
*/
|
|
6
|
+
export const DealStatusEnum = defineEnum('DealStatus', [
|
|
7
|
+
'OPEN',
|
|
8
|
+
'WON',
|
|
9
|
+
'LOST',
|
|
10
|
+
'STALE',
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Deal status filter enum.
|
|
15
|
+
*/
|
|
16
|
+
export const DealStatusFilterEnum = defineEnum('DealStatusFilter', [
|
|
17
|
+
'OPEN',
|
|
18
|
+
'WON',
|
|
19
|
+
'LOST',
|
|
20
|
+
'all',
|
|
21
|
+
]);
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineCommand,
|
|
3
|
+
defineQuery,
|
|
4
|
+
} from '@contractspec/lib.contracts/operations';
|
|
5
|
+
import {
|
|
6
|
+
DealModel,
|
|
7
|
+
CreateDealInputModel,
|
|
8
|
+
MoveDealInputModel,
|
|
9
|
+
DealMovedPayloadModel,
|
|
10
|
+
WinDealInputModel,
|
|
11
|
+
DealWonPayloadModel,
|
|
12
|
+
LoseDealInputModel,
|
|
13
|
+
DealLostPayloadModel,
|
|
14
|
+
ListDealsInputModel,
|
|
15
|
+
ListDealsOutputModel,
|
|
16
|
+
} from './deal.schema';
|
|
17
|
+
|
|
18
|
+
const OWNERS = ['@example.crm-pipeline'] as const;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Create a new deal.
|
|
22
|
+
*/
|
|
23
|
+
export const CreateDealContract = defineCommand({
|
|
24
|
+
meta: {
|
|
25
|
+
key: 'crm.deal.create',
|
|
26
|
+
version: 1,
|
|
27
|
+
stability: 'stable',
|
|
28
|
+
owners: [...OWNERS],
|
|
29
|
+
tags: ['crm', 'deal', 'create'],
|
|
30
|
+
description: 'Create a new deal in the pipeline.',
|
|
31
|
+
goal: 'Allow sales reps to create new opportunities.',
|
|
32
|
+
context: 'Deal creation UI, quick add.',
|
|
33
|
+
},
|
|
34
|
+
io: {
|
|
35
|
+
input: CreateDealInputModel,
|
|
36
|
+
output: DealModel,
|
|
37
|
+
},
|
|
38
|
+
policy: {
|
|
39
|
+
auth: 'user',
|
|
40
|
+
},
|
|
41
|
+
sideEffects: {
|
|
42
|
+
emits: [
|
|
43
|
+
{
|
|
44
|
+
key: 'deal.created',
|
|
45
|
+
version: 1,
|
|
46
|
+
when: 'Deal is created',
|
|
47
|
+
payload: DealModel,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
audit: ['deal.created'],
|
|
51
|
+
},
|
|
52
|
+
acceptance: {
|
|
53
|
+
scenarios: [
|
|
54
|
+
{
|
|
55
|
+
key: 'create-deal-happy-path',
|
|
56
|
+
given: ['User is authenticated'],
|
|
57
|
+
when: ['User creates a deal with valid data'],
|
|
58
|
+
then: ['Deal is created', 'DealCreated event is emitted'],
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
examples: [
|
|
62
|
+
{
|
|
63
|
+
key: 'create-basic-deal',
|
|
64
|
+
input: {
|
|
65
|
+
title: 'Big Corp Q3 License',
|
|
66
|
+
stageId: 'stage-lead',
|
|
67
|
+
value: 50000,
|
|
68
|
+
companyId: 'comp-123',
|
|
69
|
+
},
|
|
70
|
+
output: {
|
|
71
|
+
id: 'deal-789',
|
|
72
|
+
title: 'Big Corp Q3 License',
|
|
73
|
+
status: 'open',
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Move deal to a different stage.
|
|
82
|
+
*/
|
|
83
|
+
export const MoveDealContract = defineCommand({
|
|
84
|
+
meta: {
|
|
85
|
+
key: 'crm.deal.move',
|
|
86
|
+
version: 1,
|
|
87
|
+
stability: 'stable',
|
|
88
|
+
owners: [...OWNERS],
|
|
89
|
+
tags: ['crm', 'deal', 'move', 'kanban'],
|
|
90
|
+
description: 'Move a deal to a different stage.',
|
|
91
|
+
goal: 'Allow drag-and-drop stage movement in Kanban.',
|
|
92
|
+
context: 'Pipeline Kanban view.',
|
|
93
|
+
},
|
|
94
|
+
io: {
|
|
95
|
+
input: MoveDealInputModel,
|
|
96
|
+
output: DealModel,
|
|
97
|
+
},
|
|
98
|
+
policy: {
|
|
99
|
+
auth: 'user',
|
|
100
|
+
},
|
|
101
|
+
sideEffects: {
|
|
102
|
+
emits: [
|
|
103
|
+
{
|
|
104
|
+
key: 'deal.moved',
|
|
105
|
+
version: 1,
|
|
106
|
+
when: 'Deal stage changed',
|
|
107
|
+
payload: DealMovedPayloadModel,
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
audit: ['deal.moved'],
|
|
111
|
+
},
|
|
112
|
+
acceptance: {
|
|
113
|
+
scenarios: [
|
|
114
|
+
{
|
|
115
|
+
key: 'move-deal-happy-path',
|
|
116
|
+
given: ['Deal exists in stage A'],
|
|
117
|
+
when: ['User moves deal to stage B'],
|
|
118
|
+
then: ['Deal stage is updated', 'DealMoved event is emitted'],
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
examples: [
|
|
122
|
+
{
|
|
123
|
+
key: 'move-to-negotiation',
|
|
124
|
+
input: { dealId: 'deal-789', targetStageId: 'stage-negotiation' },
|
|
125
|
+
output: {
|
|
126
|
+
id: 'deal-789',
|
|
127
|
+
stageId: 'stage-negotiation',
|
|
128
|
+
movedAt: '2025-01-15T10:00:00Z',
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Mark deal as won.
|
|
137
|
+
*/
|
|
138
|
+
export const WinDealContract = defineCommand({
|
|
139
|
+
meta: {
|
|
140
|
+
key: 'crm.deal.win',
|
|
141
|
+
version: 1,
|
|
142
|
+
stability: 'stable',
|
|
143
|
+
owners: [...OWNERS],
|
|
144
|
+
tags: ['crm', 'deal', 'won'],
|
|
145
|
+
description: 'Mark a deal as won.',
|
|
146
|
+
goal: 'Close a deal as successful.',
|
|
147
|
+
context: 'Deal closing flow.',
|
|
148
|
+
},
|
|
149
|
+
io: {
|
|
150
|
+
input: WinDealInputModel,
|
|
151
|
+
output: DealModel,
|
|
152
|
+
},
|
|
153
|
+
policy: {
|
|
154
|
+
auth: 'user',
|
|
155
|
+
},
|
|
156
|
+
sideEffects: {
|
|
157
|
+
emits: [
|
|
158
|
+
{
|
|
159
|
+
key: 'deal.won',
|
|
160
|
+
version: 1,
|
|
161
|
+
when: 'Deal is won',
|
|
162
|
+
payload: DealWonPayloadModel,
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
audit: ['deal.won'],
|
|
166
|
+
},
|
|
167
|
+
acceptance: {
|
|
168
|
+
scenarios: [
|
|
169
|
+
{
|
|
170
|
+
key: 'win-deal-happy-path',
|
|
171
|
+
given: ['Deal is open'],
|
|
172
|
+
when: ['User marks deal as won'],
|
|
173
|
+
then: ['Deal status becomes WON', 'DealWon event is emitted'],
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
examples: [
|
|
177
|
+
{
|
|
178
|
+
key: 'mark-won',
|
|
179
|
+
input: {
|
|
180
|
+
dealId: 'deal-789',
|
|
181
|
+
actualValue: 52000,
|
|
182
|
+
note: 'Signed contract attached',
|
|
183
|
+
},
|
|
184
|
+
output: {
|
|
185
|
+
id: 'deal-789',
|
|
186
|
+
status: 'won',
|
|
187
|
+
closedAt: '2025-01-20T14:30:00Z',
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Mark deal as lost.
|
|
196
|
+
*/
|
|
197
|
+
export const LoseDealContract = defineCommand({
|
|
198
|
+
meta: {
|
|
199
|
+
key: 'crm.deal.lose',
|
|
200
|
+
version: 1,
|
|
201
|
+
stability: 'stable',
|
|
202
|
+
owners: [...OWNERS],
|
|
203
|
+
tags: ['crm', 'deal', 'lost'],
|
|
204
|
+
description: 'Mark a deal as lost.',
|
|
205
|
+
goal: 'Close a deal as unsuccessful.',
|
|
206
|
+
context: 'Deal closing flow.',
|
|
207
|
+
},
|
|
208
|
+
io: {
|
|
209
|
+
input: LoseDealInputModel,
|
|
210
|
+
output: DealModel,
|
|
211
|
+
},
|
|
212
|
+
policy: {
|
|
213
|
+
auth: 'user',
|
|
214
|
+
},
|
|
215
|
+
sideEffects: {
|
|
216
|
+
emits: [
|
|
217
|
+
{
|
|
218
|
+
key: 'deal.lost',
|
|
219
|
+
version: 1,
|
|
220
|
+
when: 'Deal is lost',
|
|
221
|
+
payload: DealLostPayloadModel,
|
|
222
|
+
},
|
|
223
|
+
],
|
|
224
|
+
audit: ['deal.lost'],
|
|
225
|
+
},
|
|
226
|
+
acceptance: {
|
|
227
|
+
scenarios: [
|
|
228
|
+
{
|
|
229
|
+
key: 'lose-deal-happy-path',
|
|
230
|
+
given: ['Deal is open'],
|
|
231
|
+
when: ['User marks deal as lost'],
|
|
232
|
+
then: ['Deal status becomes LOST', 'DealLost event is emitted'],
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
examples: [
|
|
236
|
+
{
|
|
237
|
+
key: 'mark-lost',
|
|
238
|
+
input: {
|
|
239
|
+
dealId: 'deal-789',
|
|
240
|
+
reason: 'competitor',
|
|
241
|
+
note: 'Went with cheaper option',
|
|
242
|
+
},
|
|
243
|
+
output: {
|
|
244
|
+
id: 'deal-789',
|
|
245
|
+
status: 'lost',
|
|
246
|
+
closedAt: '2025-01-21T09:00:00Z',
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* List deals in pipeline.
|
|
255
|
+
*/
|
|
256
|
+
export const ListDealsContract = defineQuery({
|
|
257
|
+
meta: {
|
|
258
|
+
key: 'crm.deal.list',
|
|
259
|
+
version: 1,
|
|
260
|
+
stability: 'stable',
|
|
261
|
+
owners: [...OWNERS],
|
|
262
|
+
tags: ['crm', 'deal', 'list'],
|
|
263
|
+
description: 'List deals with filters.',
|
|
264
|
+
goal: 'Show pipeline, deal lists, dashboards.',
|
|
265
|
+
context: 'Pipeline view, deal list.',
|
|
266
|
+
},
|
|
267
|
+
io: {
|
|
268
|
+
input: ListDealsInputModel,
|
|
269
|
+
output: ListDealsOutputModel,
|
|
270
|
+
},
|
|
271
|
+
policy: {
|
|
272
|
+
auth: 'user',
|
|
273
|
+
},
|
|
274
|
+
acceptance: {
|
|
275
|
+
scenarios: [
|
|
276
|
+
{
|
|
277
|
+
key: 'list-deals-happy-path',
|
|
278
|
+
given: ['User has access to deals'],
|
|
279
|
+
when: ['User lists deals'],
|
|
280
|
+
then: ['List of deals is returned'],
|
|
281
|
+
},
|
|
282
|
+
],
|
|
283
|
+
examples: [
|
|
284
|
+
{
|
|
285
|
+
key: 'list-filter-stage',
|
|
286
|
+
input: { stageId: 'stage-lead', limit: 20 },
|
|
287
|
+
output: { items: [], total: 5, hasMore: false },
|
|
288
|
+
},
|
|
289
|
+
],
|
|
290
|
+
},
|
|
291
|
+
});
|