@contractspec/example.crm-pipeline 3.7.5 → 3.7.7

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.
Files changed (106) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/AGENTS.md +51 -33
  3. package/CHANGELOG.md +16 -0
  4. package/README.md +66 -148
  5. package/dist/browser/events/contact.event.js +1 -1
  6. package/dist/browser/events/deal.event.js +1 -1
  7. package/dist/browser/events/index.js +3 -3
  8. package/dist/browser/events/task.event.js +1 -1
  9. package/dist/browser/index.js +293 -293
  10. package/dist/browser/ui/CrmDashboard.js +221 -221
  11. package/dist/browser/ui/CrmDealCard.js +5 -5
  12. package/dist/browser/ui/CrmPipelineBoard.js +13 -13
  13. package/dist/browser/ui/hooks/index.js +2 -2
  14. package/dist/browser/ui/hooks/useDealList.js +1 -1
  15. package/dist/browser/ui/hooks/useDealMutations.js +1 -1
  16. package/dist/browser/ui/index.js +290 -290
  17. package/dist/browser/ui/modals/CreateDealModal.js +12 -12
  18. package/dist/browser/ui/modals/DealActionsModal.js +21 -21
  19. package/dist/browser/ui/modals/index.js +33 -33
  20. package/dist/browser/ui/renderers/index.js +116 -116
  21. package/dist/browser/ui/renderers/pipeline.renderer.js +97 -97
  22. package/dist/deal/index.d.ts +2 -2
  23. package/dist/events/contact.event.js +1 -1
  24. package/dist/events/deal.event.js +1 -1
  25. package/dist/events/index.js +3 -3
  26. package/dist/events/task.event.js +1 -1
  27. package/dist/handlers/index.d.ts +2 -2
  28. package/dist/index.d.ts +3 -3
  29. package/dist/index.js +293 -293
  30. package/dist/node/events/contact.event.js +1 -1
  31. package/dist/node/events/deal.event.js +1 -1
  32. package/dist/node/events/index.js +3 -3
  33. package/dist/node/events/task.event.js +1 -1
  34. package/dist/node/index.js +293 -293
  35. package/dist/node/ui/CrmDashboard.js +221 -221
  36. package/dist/node/ui/CrmDealCard.js +5 -5
  37. package/dist/node/ui/CrmPipelineBoard.js +13 -13
  38. package/dist/node/ui/hooks/index.js +2 -2
  39. package/dist/node/ui/hooks/useDealList.js +1 -1
  40. package/dist/node/ui/hooks/useDealMutations.js +1 -1
  41. package/dist/node/ui/index.js +290 -290
  42. package/dist/node/ui/modals/CreateDealModal.js +12 -12
  43. package/dist/node/ui/modals/DealActionsModal.js +21 -21
  44. package/dist/node/ui/modals/index.js +33 -33
  45. package/dist/node/ui/renderers/index.js +116 -116
  46. package/dist/node/ui/renderers/pipeline.renderer.js +97 -97
  47. package/dist/operations/index.d.ts +1 -1
  48. package/dist/ui/CrmDashboard.js +221 -221
  49. package/dist/ui/CrmDealCard.js +5 -5
  50. package/dist/ui/CrmPipelineBoard.js +13 -13
  51. package/dist/ui/hooks/index.d.ts +2 -2
  52. package/dist/ui/hooks/index.js +2 -2
  53. package/dist/ui/hooks/useDealList.js +1 -1
  54. package/dist/ui/hooks/useDealMutations.d.ts +9 -0
  55. package/dist/ui/hooks/useDealMutations.js +1 -1
  56. package/dist/ui/index.d.ts +3 -3
  57. package/dist/ui/index.js +290 -290
  58. package/dist/ui/modals/CreateDealModal.js +12 -12
  59. package/dist/ui/modals/DealActionsModal.js +21 -21
  60. package/dist/ui/modals/index.js +33 -33
  61. package/dist/ui/renderers/index.d.ts +1 -1
  62. package/dist/ui/renderers/index.js +116 -116
  63. package/dist/ui/renderers/pipeline.renderer.d.ts +1 -1
  64. package/dist/ui/renderers/pipeline.renderer.js +97 -97
  65. package/package.json +14 -14
  66. package/src/crm-pipeline.feature.ts +86 -86
  67. package/src/deal/deal.enum.ts +8 -8
  68. package/src/deal/deal.operation.ts +255 -255
  69. package/src/deal/deal.schema.ts +92 -92
  70. package/src/deal/deal.test-spec.ts +48 -48
  71. package/src/deal/index.ts +17 -19
  72. package/src/docs/crm-pipeline.docblock.ts +43 -43
  73. package/src/entities/company.entity.ts +52 -52
  74. package/src/entities/contact.entity.ts +67 -67
  75. package/src/entities/deal.entity.ts +134 -134
  76. package/src/entities/index.ts +27 -27
  77. package/src/entities/task.entity.ts +105 -105
  78. package/src/events/contact.event.ts +22 -22
  79. package/src/events/deal.event.ts +77 -77
  80. package/src/events/task.event.ts +19 -19
  81. package/src/example.ts +32 -32
  82. package/src/handlers/crm.handlers.ts +358 -357
  83. package/src/handlers/deal.handlers.ts +179 -179
  84. package/src/handlers/index.ts +18 -19
  85. package/src/handlers/mock-data.ts +167 -167
  86. package/src/index.ts +11 -11
  87. package/src/operations/index.ts +16 -16
  88. package/src/presentations/dashboard.presentation.ts +45 -45
  89. package/src/presentations/pipeline.presentation.ts +90 -90
  90. package/src/seeders/index.ts +26 -26
  91. package/src/shared/overlay-types.ts +23 -23
  92. package/src/ui/CrmDashboard.tsx +256 -256
  93. package/src/ui/CrmDealCard.tsx +64 -64
  94. package/src/ui/CrmPipelineBoard.tsx +105 -105
  95. package/src/ui/hooks/index.ts +3 -3
  96. package/src/ui/hooks/useDealList.ts +85 -85
  97. package/src/ui/hooks/useDealMutations.ts +151 -150
  98. package/src/ui/index.ts +5 -10
  99. package/src/ui/modals/CreateDealModal.tsx +217 -217
  100. package/src/ui/modals/DealActionsModal.tsx +390 -390
  101. package/src/ui/overlays/demo-overlays.ts +43 -43
  102. package/src/ui/renderers/index.ts +4 -3
  103. package/src/ui/renderers/pipeline.markdown.ts +165 -165
  104. package/src/ui/renderers/pipeline.renderer.tsx +17 -16
  105. package/tsconfig.json +7 -8
  106. package/tsdown.config.js +7 -3
@@ -5,249 +5,249 @@ import { MOCK_DEALS, MOCK_STAGES } from './mock-data';
5
5
 
6
6
  // Types inferred from contract schemas
7
7
  export interface Deal {
8
- id: string;
9
- name: string;
10
- value: number;
11
- currency: string;
12
- pipelineId: string;
13
- stageId: string;
14
- status: 'OPEN' | 'WON' | 'LOST' | 'STALE';
15
- contactId?: string;
16
- companyId?: string;
17
- ownerId: string;
18
- expectedCloseDate?: Date;
19
- createdAt: Date;
20
- updatedAt: Date;
8
+ id: string;
9
+ name: string;
10
+ value: number;
11
+ currency: string;
12
+ pipelineId: string;
13
+ stageId: string;
14
+ status: 'OPEN' | 'WON' | 'LOST' | 'STALE';
15
+ contactId?: string;
16
+ companyId?: string;
17
+ ownerId: string;
18
+ expectedCloseDate?: Date;
19
+ createdAt: Date;
20
+ updatedAt: Date;
21
21
  }
22
22
 
23
23
  export interface CreateDealInput {
24
- name: string;
25
- value: number;
26
- currency?: string;
27
- pipelineId: string;
28
- stageId: string;
29
- contactId?: string;
30
- companyId?: string;
31
- expectedCloseDate?: Date;
24
+ name: string;
25
+ value: number;
26
+ currency?: string;
27
+ pipelineId: string;
28
+ stageId: string;
29
+ contactId?: string;
30
+ companyId?: string;
31
+ expectedCloseDate?: Date;
32
32
  }
33
33
 
34
34
  export interface MoveDealInput {
35
- dealId: string;
36
- stageId: string;
37
- position?: number;
35
+ dealId: string;
36
+ stageId: string;
37
+ position?: number;
38
38
  }
39
39
 
40
40
  export interface WinDealInput {
41
- dealId: string;
42
- wonSource?: string;
43
- notes?: string;
41
+ dealId: string;
42
+ wonSource?: string;
43
+ notes?: string;
44
44
  }
45
45
 
46
46
  export interface LoseDealInput {
47
- dealId: string;
48
- lostReason: string;
49
- notes?: string;
47
+ dealId: string;
48
+ lostReason: string;
49
+ notes?: string;
50
50
  }
51
51
 
52
52
  export interface ListDealsInput {
53
- pipelineId?: string;
54
- stageId?: string;
55
- status?: 'OPEN' | 'WON' | 'LOST' | 'all';
56
- ownerId?: string;
57
- search?: string;
58
- limit?: number;
59
- offset?: number;
53
+ pipelineId?: string;
54
+ stageId?: string;
55
+ status?: 'OPEN' | 'WON' | 'LOST' | 'all';
56
+ ownerId?: string;
57
+ search?: string;
58
+ limit?: number;
59
+ offset?: number;
60
60
  }
61
61
 
62
62
  export interface ListDealsOutput {
63
- deals: Deal[];
64
- total: number;
65
- totalValue: number;
63
+ deals: Deal[];
64
+ total: number;
65
+ totalValue: number;
66
66
  }
67
67
 
68
68
  /**
69
69
  * Mock handler for ListDealsContract
70
70
  */
71
71
  export async function mockListDealsHandler(
72
- input: ListDealsInput
72
+ input: ListDealsInput
73
73
  ): Promise<ListDealsOutput> {
74
- const {
75
- pipelineId,
76
- stageId,
77
- status,
78
- ownerId,
79
- search,
80
- limit = 20,
81
- offset = 0,
82
- } = input;
83
-
84
- let filtered = [...MOCK_DEALS];
85
-
86
- if (pipelineId) {
87
- filtered = filtered.filter((d) => d.pipelineId === pipelineId);
88
- }
89
-
90
- if (stageId) {
91
- filtered = filtered.filter((d) => d.stageId === stageId);
92
- }
93
-
94
- if (status && status !== 'all') {
95
- filtered = filtered.filter((d) => d.status === status);
96
- }
97
-
98
- if (ownerId) {
99
- filtered = filtered.filter((d) => d.ownerId === ownerId);
100
- }
101
-
102
- if (search) {
103
- const q = search.toLowerCase();
104
- filtered = filtered.filter((d) => d.name.toLowerCase().includes(q));
105
- }
106
-
107
- // Sort by value descending
108
- filtered.sort((a, b) => b.value - a.value);
109
-
110
- const total = filtered.length;
111
- const totalValue = filtered.reduce((sum, d) => sum + d.value, 0);
112
- const deals = filtered.slice(offset, offset + limit);
113
-
114
- return {
115
- deals,
116
- total,
117
- totalValue,
118
- };
74
+ const {
75
+ pipelineId,
76
+ stageId,
77
+ status,
78
+ ownerId,
79
+ search,
80
+ limit = 20,
81
+ offset = 0,
82
+ } = input;
83
+
84
+ let filtered = [...MOCK_DEALS];
85
+
86
+ if (pipelineId) {
87
+ filtered = filtered.filter((d) => d.pipelineId === pipelineId);
88
+ }
89
+
90
+ if (stageId) {
91
+ filtered = filtered.filter((d) => d.stageId === stageId);
92
+ }
93
+
94
+ if (status && status !== 'all') {
95
+ filtered = filtered.filter((d) => d.status === status);
96
+ }
97
+
98
+ if (ownerId) {
99
+ filtered = filtered.filter((d) => d.ownerId === ownerId);
100
+ }
101
+
102
+ if (search) {
103
+ const q = search.toLowerCase();
104
+ filtered = filtered.filter((d) => d.name.toLowerCase().includes(q));
105
+ }
106
+
107
+ // Sort by value descending
108
+ filtered.sort((a, b) => b.value - a.value);
109
+
110
+ const total = filtered.length;
111
+ const totalValue = filtered.reduce((sum, d) => sum + d.value, 0);
112
+ const deals = filtered.slice(offset, offset + limit);
113
+
114
+ return {
115
+ deals,
116
+ total,
117
+ totalValue,
118
+ };
119
119
  }
120
120
 
121
121
  /**
122
122
  * Mock handler for CreateDealContract
123
123
  */
124
124
  export async function mockCreateDealHandler(
125
- input: CreateDealInput,
126
- context: { ownerId: string }
125
+ input: CreateDealInput,
126
+ context: { ownerId: string }
127
127
  ): Promise<Deal> {
128
- const now = new Date();
129
-
130
- const deal: Deal = {
131
- id: `deal-${Date.now()}`,
132
- name: input.name,
133
- value: input.value,
134
- currency: input.currency ?? 'USD',
135
- pipelineId: input.pipelineId,
136
- stageId: input.stageId,
137
- status: 'OPEN',
138
- contactId: input.contactId,
139
- companyId: input.companyId,
140
- ownerId: context.ownerId,
141
- expectedCloseDate: input.expectedCloseDate,
142
- createdAt: now,
143
- updatedAt: now,
144
- };
145
-
146
- MOCK_DEALS.push(deal);
147
-
148
- return deal;
128
+ const now = new Date();
129
+
130
+ const deal: Deal = {
131
+ id: `deal-${Date.now()}`,
132
+ name: input.name,
133
+ value: input.value,
134
+ currency: input.currency ?? 'USD',
135
+ pipelineId: input.pipelineId,
136
+ stageId: input.stageId,
137
+ status: 'OPEN',
138
+ contactId: input.contactId,
139
+ companyId: input.companyId,
140
+ ownerId: context.ownerId,
141
+ expectedCloseDate: input.expectedCloseDate,
142
+ createdAt: now,
143
+ updatedAt: now,
144
+ };
145
+
146
+ MOCK_DEALS.push(deal);
147
+
148
+ return deal;
149
149
  }
150
150
 
151
151
  /**
152
152
  * Mock handler for MoveDealContract
153
153
  */
154
154
  export async function mockMoveDealHandler(input: MoveDealInput): Promise<Deal> {
155
- const dealIndex = MOCK_DEALS.findIndex((d) => d.id === input.dealId);
156
- if (dealIndex === -1) {
157
- throw new Error('NOT_FOUND');
158
- }
159
- const deal = MOCK_DEALS[dealIndex];
160
- if (!deal) {
161
- throw new Error('NOT_FOUND');
162
- }
163
-
164
- const stage = MOCK_STAGES.find((s) => s.id === input.stageId);
165
- if (!stage) {
166
- throw new Error('INVALID_STAGE');
167
- }
168
-
169
- const updatedDeal: Deal = {
170
- ...deal,
171
- stageId: input.stageId,
172
- updatedAt: new Date(),
173
- };
174
-
175
- MOCK_DEALS[dealIndex] = updatedDeal;
176
-
177
- return updatedDeal;
155
+ const dealIndex = MOCK_DEALS.findIndex((d) => d.id === input.dealId);
156
+ if (dealIndex === -1) {
157
+ throw new Error('NOT_FOUND');
158
+ }
159
+ const deal = MOCK_DEALS[dealIndex];
160
+ if (!deal) {
161
+ throw new Error('NOT_FOUND');
162
+ }
163
+
164
+ const stage = MOCK_STAGES.find((s) => s.id === input.stageId);
165
+ if (!stage) {
166
+ throw new Error('INVALID_STAGE');
167
+ }
168
+
169
+ const updatedDeal: Deal = {
170
+ ...deal,
171
+ stageId: input.stageId,
172
+ updatedAt: new Date(),
173
+ };
174
+
175
+ MOCK_DEALS[dealIndex] = updatedDeal;
176
+
177
+ return updatedDeal;
178
178
  }
179
179
 
180
180
  /**
181
181
  * Mock handler for WinDealContract
182
182
  */
183
183
  export async function mockWinDealHandler(input: WinDealInput): Promise<Deal> {
184
- const dealIndex = MOCK_DEALS.findIndex((d) => d.id === input.dealId);
185
- if (dealIndex === -1) {
186
- throw new Error('NOT_FOUND');
187
- }
188
- const deal = MOCK_DEALS[dealIndex];
189
- if (!deal) {
190
- throw new Error('NOT_FOUND');
191
- }
192
-
193
- const updatedDeal: Deal = {
194
- ...deal,
195
- status: 'WON' as const,
196
- updatedAt: new Date(),
197
- };
198
-
199
- MOCK_DEALS[dealIndex] = updatedDeal;
200
-
201
- return updatedDeal;
184
+ const dealIndex = MOCK_DEALS.findIndex((d) => d.id === input.dealId);
185
+ if (dealIndex === -1) {
186
+ throw new Error('NOT_FOUND');
187
+ }
188
+ const deal = MOCK_DEALS[dealIndex];
189
+ if (!deal) {
190
+ throw new Error('NOT_FOUND');
191
+ }
192
+
193
+ const updatedDeal: Deal = {
194
+ ...deal,
195
+ status: 'WON' as const,
196
+ updatedAt: new Date(),
197
+ };
198
+
199
+ MOCK_DEALS[dealIndex] = updatedDeal;
200
+
201
+ return updatedDeal;
202
202
  }
203
203
 
204
204
  /**
205
205
  * Mock handler for LoseDealContract
206
206
  */
207
207
  export async function mockLoseDealHandler(input: LoseDealInput): Promise<Deal> {
208
- const dealIndex = MOCK_DEALS.findIndex((d) => d.id === input.dealId);
209
- if (dealIndex === -1) {
210
- throw new Error('NOT_FOUND');
211
- }
212
- const deal = MOCK_DEALS[dealIndex];
213
- if (!deal) {
214
- throw new Error('NOT_FOUND');
215
- }
216
-
217
- const updatedDeal: Deal = {
218
- ...deal,
219
- status: 'LOST' as const,
220
- updatedAt: new Date(),
221
- };
222
-
223
- MOCK_DEALS[dealIndex] = updatedDeal;
224
-
225
- return updatedDeal;
208
+ const dealIndex = MOCK_DEALS.findIndex((d) => d.id === input.dealId);
209
+ if (dealIndex === -1) {
210
+ throw new Error('NOT_FOUND');
211
+ }
212
+ const deal = MOCK_DEALS[dealIndex];
213
+ if (!deal) {
214
+ throw new Error('NOT_FOUND');
215
+ }
216
+
217
+ const updatedDeal: Deal = {
218
+ ...deal,
219
+ status: 'LOST' as const,
220
+ updatedAt: new Date(),
221
+ };
222
+
223
+ MOCK_DEALS[dealIndex] = updatedDeal;
224
+
225
+ return updatedDeal;
226
226
  }
227
227
 
228
228
  /**
229
229
  * Get deals grouped by stage for Kanban view
230
230
  */
231
231
  export async function mockGetDealsByStageHandler(input: {
232
- pipelineId: string;
232
+ pipelineId: string;
233
233
  }): Promise<Record<string, Deal[]>> {
234
- const deals = MOCK_DEALS.filter(
235
- (d) => d.pipelineId === input.pipelineId && d.status === 'OPEN'
236
- );
234
+ const deals = MOCK_DEALS.filter(
235
+ (d) => d.pipelineId === input.pipelineId && d.status === 'OPEN'
236
+ );
237
237
 
238
- const grouped: Record<string, Deal[]> = {};
239
- for (const stage of MOCK_STAGES) {
240
- grouped[stage.id] = deals.filter((d) => d.stageId === stage.id);
241
- }
238
+ const grouped: Record<string, Deal[]> = {};
239
+ for (const stage of MOCK_STAGES) {
240
+ grouped[stage.id] = deals.filter((d) => d.stageId === stage.id);
241
+ }
242
242
 
243
- return grouped;
243
+ return grouped;
244
244
  }
245
245
 
246
246
  /**
247
247
  * Get pipeline stages
248
248
  */
249
249
  export async function mockGetPipelineStagesHandler(input: {
250
- pipelineId: string;
250
+ pipelineId: string;
251
251
  }) {
252
- return MOCK_STAGES.filter((s) => s.pipelineId === input.pipelineId);
252
+ return MOCK_STAGES.filter((s) => s.pipelineId === input.pipelineId);
253
253
  }
@@ -5,26 +5,25 @@
5
5
  * for use in demos, tests, and the sandbox environment.
6
6
  */
7
7
 
8
- // Mock data
9
- export * from './mock-data';
8
+ // Runtime handlers (PGLite)
9
+ export * from './crm.handlers';
10
10
 
11
11
  // Deal handlers
12
12
  export {
13
- mockListDealsHandler,
14
- mockCreateDealHandler,
15
- mockMoveDealHandler,
16
- mockWinDealHandler,
17
- mockLoseDealHandler,
18
- mockGetDealsByStageHandler,
19
- mockGetPipelineStagesHandler,
20
- type Deal,
21
- type CreateDealInput,
22
- type MoveDealInput,
23
- type WinDealInput,
24
- type LoseDealInput,
25
- type ListDealsInput,
26
- type ListDealsOutput,
13
+ type CreateDealInput,
14
+ type Deal,
15
+ type ListDealsInput,
16
+ type ListDealsOutput,
17
+ type LoseDealInput,
18
+ type MoveDealInput,
19
+ mockCreateDealHandler,
20
+ mockGetDealsByStageHandler,
21
+ mockGetPipelineStagesHandler,
22
+ mockListDealsHandler,
23
+ mockLoseDealHandler,
24
+ mockMoveDealHandler,
25
+ mockWinDealHandler,
26
+ type WinDealInput,
27
27
  } from './deal.handlers';
28
-
29
- // Runtime handlers (PGLite)
30
- export * from './crm.handlers';
28
+ // Mock data
29
+ export * from './mock-data';