@contractspec/example.crm-pipeline 3.7.6 → 3.7.10

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 (130) hide show
  1. package/.turbo/turbo-build.log +45 -42
  2. package/AGENTS.md +51 -33
  3. package/CHANGELOG.md +36 -0
  4. package/README.md +67 -148
  5. package/dist/browser/docs/crm-pipeline.docblock.js +1 -1
  6. package/dist/browser/docs/index.js +1 -1
  7. package/dist/browser/events/contact.event.js +1 -1
  8. package/dist/browser/events/deal.event.js +1 -1
  9. package/dist/browser/events/index.js +3 -3
  10. package/dist/browser/events/task.event.js +1 -1
  11. package/dist/browser/handlers/crm.handlers.js +13 -2
  12. package/dist/browser/handlers/index.js +13 -2
  13. package/dist/browser/index.js +680 -447
  14. package/dist/browser/ui/CrmDashboard.js +574 -352
  15. package/dist/browser/ui/CrmDealCard.js +5 -5
  16. package/dist/browser/ui/CrmPipelineBoard.js +13 -13
  17. package/dist/browser/ui/hooks/index.js +21 -10
  18. package/dist/browser/ui/hooks/useDealList.js +20 -9
  19. package/dist/browser/ui/hooks/useDealMutations.js +1 -1
  20. package/dist/browser/ui/index.js +683 -450
  21. package/dist/browser/ui/modals/CreateDealModal.js +12 -12
  22. package/dist/browser/ui/modals/DealActionsModal.js +21 -21
  23. package/dist/browser/ui/modals/index.js +33 -33
  24. package/dist/browser/ui/renderers/index.js +140 -118
  25. package/dist/browser/ui/renderers/pipeline.markdown.js +13 -2
  26. package/dist/browser/ui/renderers/pipeline.renderer.js +108 -97
  27. package/dist/browser/ui/tables/DealListTab.js +390 -0
  28. package/dist/deal/index.d.ts +2 -2
  29. package/dist/docs/crm-pipeline.docblock.js +1 -1
  30. package/dist/docs/index.js +1 -1
  31. package/dist/events/contact.event.js +1 -1
  32. package/dist/events/deal.event.js +1 -1
  33. package/dist/events/index.js +3 -3
  34. package/dist/events/task.event.js +1 -1
  35. package/dist/handlers/crm.handlers.d.ts +2 -0
  36. package/dist/handlers/crm.handlers.js +13 -2
  37. package/dist/handlers/index.d.ts +2 -2
  38. package/dist/handlers/index.js +13 -2
  39. package/dist/index.d.ts +3 -3
  40. package/dist/index.js +680 -447
  41. package/dist/node/docs/crm-pipeline.docblock.js +1 -1
  42. package/dist/node/docs/index.js +1 -1
  43. package/dist/node/events/contact.event.js +1 -1
  44. package/dist/node/events/deal.event.js +1 -1
  45. package/dist/node/events/index.js +3 -3
  46. package/dist/node/events/task.event.js +1 -1
  47. package/dist/node/handlers/crm.handlers.js +13 -2
  48. package/dist/node/handlers/index.js +13 -2
  49. package/dist/node/index.js +680 -447
  50. package/dist/node/ui/CrmDashboard.js +574 -352
  51. package/dist/node/ui/CrmDealCard.js +5 -5
  52. package/dist/node/ui/CrmPipelineBoard.js +13 -13
  53. package/dist/node/ui/hooks/index.js +21 -10
  54. package/dist/node/ui/hooks/useDealList.js +20 -9
  55. package/dist/node/ui/hooks/useDealMutations.js +1 -1
  56. package/dist/node/ui/index.js +683 -450
  57. package/dist/node/ui/modals/CreateDealModal.js +12 -12
  58. package/dist/node/ui/modals/DealActionsModal.js +21 -21
  59. package/dist/node/ui/modals/index.js +33 -33
  60. package/dist/node/ui/renderers/index.js +140 -118
  61. package/dist/node/ui/renderers/pipeline.markdown.js +13 -2
  62. package/dist/node/ui/renderers/pipeline.renderer.js +108 -97
  63. package/dist/node/ui/tables/DealListTab.js +390 -0
  64. package/dist/operations/index.d.ts +1 -1
  65. package/dist/ui/CrmDashboard.js +574 -352
  66. package/dist/ui/CrmDealCard.js +5 -5
  67. package/dist/ui/CrmPipelineBoard.js +13 -13
  68. package/dist/ui/hooks/index.d.ts +2 -2
  69. package/dist/ui/hooks/index.js +21 -10
  70. package/dist/ui/hooks/useDealList.d.ts +8 -2
  71. package/dist/ui/hooks/useDealList.js +20 -9
  72. package/dist/ui/hooks/useDealMutations.d.ts +9 -0
  73. package/dist/ui/hooks/useDealMutations.js +1 -1
  74. package/dist/ui/index.d.ts +3 -3
  75. package/dist/ui/index.js +683 -450
  76. package/dist/ui/modals/CreateDealModal.js +12 -12
  77. package/dist/ui/modals/DealActionsModal.js +21 -21
  78. package/dist/ui/modals/index.js +33 -33
  79. package/dist/ui/renderers/index.d.ts +1 -1
  80. package/dist/ui/renderers/index.js +140 -118
  81. package/dist/ui/renderers/pipeline.markdown.js +13 -2
  82. package/dist/ui/renderers/pipeline.renderer.d.ts +1 -1
  83. package/dist/ui/renderers/pipeline.renderer.js +108 -97
  84. package/dist/ui/tables/DealListTab.d.ts +20 -0
  85. package/dist/ui/tables/DealListTab.js +391 -0
  86. package/dist/ui/tables/DealListTab.smoke.test.d.ts +1 -0
  87. package/package.json +29 -14
  88. package/src/crm-pipeline.feature.ts +86 -86
  89. package/src/deal/deal.enum.ts +8 -8
  90. package/src/deal/deal.operation.ts +255 -255
  91. package/src/deal/deal.schema.ts +92 -92
  92. package/src/deal/deal.test-spec.ts +48 -48
  93. package/src/deal/index.ts +17 -19
  94. package/src/docs/crm-pipeline.docblock.ts +44 -44
  95. package/src/entities/company.entity.ts +52 -52
  96. package/src/entities/contact.entity.ts +67 -67
  97. package/src/entities/deal.entity.ts +134 -134
  98. package/src/entities/index.ts +27 -27
  99. package/src/entities/task.entity.ts +105 -105
  100. package/src/events/contact.event.ts +22 -22
  101. package/src/events/deal.event.ts +77 -77
  102. package/src/events/task.event.ts +19 -19
  103. package/src/example.ts +32 -32
  104. package/src/handlers/crm.handlers.ts +375 -357
  105. package/src/handlers/deal.handlers.ts +179 -179
  106. package/src/handlers/index.ts +18 -19
  107. package/src/handlers/mock-data.ts +167 -167
  108. package/src/index.ts +11 -11
  109. package/src/operations/index.ts +16 -16
  110. package/src/presentations/dashboard.presentation.ts +45 -45
  111. package/src/presentations/pipeline.presentation.ts +90 -90
  112. package/src/seeders/index.ts +26 -26
  113. package/src/shared/overlay-types.ts +23 -23
  114. package/src/ui/CrmDashboard.tsx +210 -279
  115. package/src/ui/CrmDealCard.tsx +64 -64
  116. package/src/ui/CrmPipelineBoard.tsx +105 -105
  117. package/src/ui/hooks/index.ts +3 -3
  118. package/src/ui/hooks/useDealList.ts +113 -85
  119. package/src/ui/hooks/useDealMutations.ts +151 -150
  120. package/src/ui/index.ts +5 -10
  121. package/src/ui/modals/CreateDealModal.tsx +217 -217
  122. package/src/ui/modals/DealActionsModal.tsx +390 -390
  123. package/src/ui/overlays/demo-overlays.ts +43 -43
  124. package/src/ui/renderers/index.ts +4 -3
  125. package/src/ui/renderers/pipeline.markdown.ts +165 -165
  126. package/src/ui/renderers/pipeline.renderer.tsx +17 -16
  127. package/src/ui/tables/DealListTab.smoke.test.tsx +149 -0
  128. package/src/ui/tables/DealListTab.tsx +276 -0
  129. package/tsconfig.json +7 -8
  130. 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';