@contractspec/example.crm-pipeline 3.7.6 → 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 (105) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/AGENTS.md +51 -33
  3. package/README.md +66 -148
  4. package/dist/browser/events/contact.event.js +1 -1
  5. package/dist/browser/events/deal.event.js +1 -1
  6. package/dist/browser/events/index.js +3 -3
  7. package/dist/browser/events/task.event.js +1 -1
  8. package/dist/browser/index.js +293 -293
  9. package/dist/browser/ui/CrmDashboard.js +221 -221
  10. package/dist/browser/ui/CrmDealCard.js +5 -5
  11. package/dist/browser/ui/CrmPipelineBoard.js +13 -13
  12. package/dist/browser/ui/hooks/index.js +2 -2
  13. package/dist/browser/ui/hooks/useDealList.js +1 -1
  14. package/dist/browser/ui/hooks/useDealMutations.js +1 -1
  15. package/dist/browser/ui/index.js +290 -290
  16. package/dist/browser/ui/modals/CreateDealModal.js +12 -12
  17. package/dist/browser/ui/modals/DealActionsModal.js +21 -21
  18. package/dist/browser/ui/modals/index.js +33 -33
  19. package/dist/browser/ui/renderers/index.js +116 -116
  20. package/dist/browser/ui/renderers/pipeline.renderer.js +97 -97
  21. package/dist/deal/index.d.ts +2 -2
  22. package/dist/events/contact.event.js +1 -1
  23. package/dist/events/deal.event.js +1 -1
  24. package/dist/events/index.js +3 -3
  25. package/dist/events/task.event.js +1 -1
  26. package/dist/handlers/index.d.ts +2 -2
  27. package/dist/index.d.ts +3 -3
  28. package/dist/index.js +293 -293
  29. package/dist/node/events/contact.event.js +1 -1
  30. package/dist/node/events/deal.event.js +1 -1
  31. package/dist/node/events/index.js +3 -3
  32. package/dist/node/events/task.event.js +1 -1
  33. package/dist/node/index.js +293 -293
  34. package/dist/node/ui/CrmDashboard.js +221 -221
  35. package/dist/node/ui/CrmDealCard.js +5 -5
  36. package/dist/node/ui/CrmPipelineBoard.js +13 -13
  37. package/dist/node/ui/hooks/index.js +2 -2
  38. package/dist/node/ui/hooks/useDealList.js +1 -1
  39. package/dist/node/ui/hooks/useDealMutations.js +1 -1
  40. package/dist/node/ui/index.js +290 -290
  41. package/dist/node/ui/modals/CreateDealModal.js +12 -12
  42. package/dist/node/ui/modals/DealActionsModal.js +21 -21
  43. package/dist/node/ui/modals/index.js +33 -33
  44. package/dist/node/ui/renderers/index.js +116 -116
  45. package/dist/node/ui/renderers/pipeline.renderer.js +97 -97
  46. package/dist/operations/index.d.ts +1 -1
  47. package/dist/ui/CrmDashboard.js +221 -221
  48. package/dist/ui/CrmDealCard.js +5 -5
  49. package/dist/ui/CrmPipelineBoard.js +13 -13
  50. package/dist/ui/hooks/index.d.ts +2 -2
  51. package/dist/ui/hooks/index.js +2 -2
  52. package/dist/ui/hooks/useDealList.js +1 -1
  53. package/dist/ui/hooks/useDealMutations.d.ts +9 -0
  54. package/dist/ui/hooks/useDealMutations.js +1 -1
  55. package/dist/ui/index.d.ts +3 -3
  56. package/dist/ui/index.js +290 -290
  57. package/dist/ui/modals/CreateDealModal.js +12 -12
  58. package/dist/ui/modals/DealActionsModal.js +21 -21
  59. package/dist/ui/modals/index.js +33 -33
  60. package/dist/ui/renderers/index.d.ts +1 -1
  61. package/dist/ui/renderers/index.js +116 -116
  62. package/dist/ui/renderers/pipeline.renderer.d.ts +1 -1
  63. package/dist/ui/renderers/pipeline.renderer.js +97 -97
  64. package/package.json +10 -10
  65. package/src/crm-pipeline.feature.ts +86 -86
  66. package/src/deal/deal.enum.ts +8 -8
  67. package/src/deal/deal.operation.ts +255 -255
  68. package/src/deal/deal.schema.ts +92 -92
  69. package/src/deal/deal.test-spec.ts +48 -48
  70. package/src/deal/index.ts +17 -19
  71. package/src/docs/crm-pipeline.docblock.ts +43 -43
  72. package/src/entities/company.entity.ts +52 -52
  73. package/src/entities/contact.entity.ts +67 -67
  74. package/src/entities/deal.entity.ts +134 -134
  75. package/src/entities/index.ts +27 -27
  76. package/src/entities/task.entity.ts +105 -105
  77. package/src/events/contact.event.ts +22 -22
  78. package/src/events/deal.event.ts +77 -77
  79. package/src/events/task.event.ts +19 -19
  80. package/src/example.ts +32 -32
  81. package/src/handlers/crm.handlers.ts +358 -357
  82. package/src/handlers/deal.handlers.ts +179 -179
  83. package/src/handlers/index.ts +18 -19
  84. package/src/handlers/mock-data.ts +167 -167
  85. package/src/index.ts +11 -11
  86. package/src/operations/index.ts +16 -16
  87. package/src/presentations/dashboard.presentation.ts +45 -45
  88. package/src/presentations/pipeline.presentation.ts +90 -90
  89. package/src/seeders/index.ts +26 -26
  90. package/src/shared/overlay-types.ts +23 -23
  91. package/src/ui/CrmDashboard.tsx +256 -256
  92. package/src/ui/CrmDealCard.tsx +64 -64
  93. package/src/ui/CrmPipelineBoard.tsx +105 -105
  94. package/src/ui/hooks/index.ts +3 -3
  95. package/src/ui/hooks/useDealList.ts +85 -85
  96. package/src/ui/hooks/useDealMutations.ts +151 -150
  97. package/src/ui/index.ts +5 -10
  98. package/src/ui/modals/CreateDealModal.tsx +217 -217
  99. package/src/ui/modals/DealActionsModal.tsx +390 -390
  100. package/src/ui/overlays/demo-overlays.ts +43 -43
  101. package/src/ui/renderers/index.ts +4 -3
  102. package/src/ui/renderers/pipeline.markdown.ts +165 -165
  103. package/src/ui/renderers/pipeline.renderer.tsx +17 -16
  104. package/tsconfig.json +7 -8
  105. 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';