@contractspec/example.crm-pipeline 1.57.0 โ†’ 1.59.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.
Files changed (259) hide show
  1. package/.turbo/turbo-build.log +148 -164
  2. package/.turbo/turbo-prebuild.log +1 -0
  3. package/CHANGELOG.md +39 -0
  4. package/dist/browser/crm-pipeline.feature.js +75 -0
  5. package/dist/browser/deal/deal.enum.js +18 -0
  6. package/dist/browser/deal/deal.operation.js +396 -0
  7. package/dist/browser/deal/deal.schema.js +141 -0
  8. package/dist/browser/deal/deal.test-spec.js +58 -0
  9. package/dist/browser/deal/index.js +408 -0
  10. package/dist/browser/docs/crm-pipeline.docblock.js +113 -0
  11. package/dist/browser/docs/index.js +113 -0
  12. package/dist/browser/entities/company.entity.js +52 -0
  13. package/dist/browser/entities/contact.entity.js +66 -0
  14. package/dist/browser/entities/deal.entity.js +107 -0
  15. package/dist/browser/entities/index.js +343 -0
  16. package/dist/browser/entities/task.entity.js +99 -0
  17. package/dist/browser/events/contact.event.js +31 -0
  18. package/dist/browser/events/deal.event.js +101 -0
  19. package/dist/browser/events/index.js +158 -0
  20. package/dist/browser/events/task.event.js +28 -0
  21. package/dist/browser/example.js +39 -0
  22. package/dist/browser/handlers/crm.handlers.js +160 -0
  23. package/dist/browser/handlers/deal.handlers.js +293 -0
  24. package/dist/browser/handlers/index.js +456 -0
  25. package/dist/browser/handlers/mock-data.js +165 -0
  26. package/dist/browser/index.js +3279 -0
  27. package/dist/browser/operations/index.js +407 -0
  28. package/dist/browser/presentations/dashboard.presentation.js +52 -0
  29. package/dist/browser/presentations/index.js +284 -0
  30. package/dist/browser/presentations/pipeline.presentation.js +233 -0
  31. package/dist/browser/seeders/index.js +22 -0
  32. package/dist/browser/shared/overlay-types.js +0 -0
  33. package/dist/browser/ui/CrmDashboard.js +1325 -0
  34. package/dist/browser/ui/CrmDealCard.js +50 -0
  35. package/dist/browser/ui/CrmPipelineBoard.js +160 -0
  36. package/dist/browser/ui/hooks/index.js +186 -0
  37. package/dist/browser/ui/hooks/useDealList.js +84 -0
  38. package/dist/browser/ui/hooks/useDealMutations.js +100 -0
  39. package/dist/browser/ui/index.js +1972 -0
  40. package/dist/browser/ui/modals/CreateDealModal.js +211 -0
  41. package/dist/browser/ui/modals/DealActionsModal.js +428 -0
  42. package/dist/browser/ui/modals/index.js +638 -0
  43. package/dist/browser/ui/overlays/demo-overlays.js +55 -0
  44. package/dist/browser/ui/overlays/index.js +55 -0
  45. package/dist/browser/ui/renderers/index.js +827 -0
  46. package/dist/browser/ui/renderers/pipeline.markdown.js +564 -0
  47. package/dist/browser/ui/renderers/pipeline.renderer.js +264 -0
  48. package/dist/crm-pipeline.feature.d.ts +1 -6
  49. package/dist/crm-pipeline.feature.d.ts.map +1 -1
  50. package/dist/crm-pipeline.feature.js +74 -164
  51. package/dist/deal/deal.enum.d.ts +2 -7
  52. package/dist/deal/deal.enum.d.ts.map +1 -1
  53. package/dist/deal/deal.enum.js +16 -22
  54. package/dist/deal/deal.operation.d.ts +444 -450
  55. package/dist/deal/deal.operation.d.ts.map +1 -1
  56. package/dist/deal/deal.operation.js +390 -263
  57. package/dist/deal/deal.schema.d.ts +251 -256
  58. package/dist/deal/deal.schema.d.ts.map +1 -1
  59. package/dist/deal/deal.schema.js +131 -275
  60. package/dist/deal/deal.test-spec.d.ts +2 -7
  61. package/dist/deal/deal.test-spec.d.ts.map +1 -1
  62. package/dist/deal/deal.test-spec.js +56 -62
  63. package/dist/deal/index.d.ts +7 -4
  64. package/dist/deal/index.d.ts.map +1 -0
  65. package/dist/deal/index.js +408 -4
  66. package/dist/docs/crm-pipeline.docblock.d.ts +2 -1
  67. package/dist/docs/crm-pipeline.docblock.d.ts.map +1 -0
  68. package/dist/docs/crm-pipeline.docblock.js +45 -51
  69. package/dist/docs/index.d.ts +2 -1
  70. package/dist/docs/index.d.ts.map +1 -0
  71. package/dist/docs/index.js +114 -1
  72. package/dist/entities/company.entity.d.ts +27 -32
  73. package/dist/entities/company.entity.d.ts.map +1 -1
  74. package/dist/entities/company.entity.js +51 -61
  75. package/dist/entities/contact.entity.d.ts +31 -36
  76. package/dist/entities/contact.entity.d.ts.map +1 -1
  77. package/dist/entities/contact.entity.js +65 -76
  78. package/dist/entities/deal.entity.d.ts +52 -57
  79. package/dist/entities/deal.entity.d.ts.map +1 -1
  80. package/dist/entities/deal.entity.js +104 -116
  81. package/dist/entities/index.d.ts +6 -10
  82. package/dist/entities/index.d.ts.map +1 -1
  83. package/dist/entities/index.js +342 -31
  84. package/dist/entities/task.entity.d.ts +42 -47
  85. package/dist/entities/task.entity.d.ts.map +1 -1
  86. package/dist/entities/task.entity.js +95 -124
  87. package/dist/events/contact.event.d.ts +21 -27
  88. package/dist/events/contact.event.d.ts.map +1 -1
  89. package/dist/events/contact.event.js +29 -42
  90. package/dist/events/deal.event.d.ts +100 -106
  91. package/dist/events/deal.event.d.ts.map +1 -1
  92. package/dist/events/deal.event.js +93 -163
  93. package/dist/events/index.d.ts +4 -4
  94. package/dist/events/index.d.ts.map +1 -0
  95. package/dist/events/index.js +158 -4
  96. package/dist/events/task.event.d.ts +21 -27
  97. package/dist/events/task.event.d.ts.map +1 -1
  98. package/dist/events/task.event.js +26 -42
  99. package/dist/example.d.ts +2 -6
  100. package/dist/example.d.ts.map +1 -1
  101. package/dist/example.js +38 -50
  102. package/dist/handlers/crm.handlers.d.ts +80 -78
  103. package/dist/handlers/crm.handlers.d.ts.map +1 -1
  104. package/dist/handlers/crm.handlers.js +155 -166
  105. package/dist/handlers/deal.handlers.d.ts +58 -63
  106. package/dist/handlers/deal.handlers.d.ts.map +1 -1
  107. package/dist/handlers/deal.handlers.js +279 -105
  108. package/dist/handlers/index.d.ts +10 -4
  109. package/dist/handlers/index.d.ts.map +1 -0
  110. package/dist/handlers/index.js +456 -4
  111. package/dist/handlers/mock-data.d.ts +38 -41
  112. package/dist/handlers/mock-data.d.ts.map +1 -1
  113. package/dist/handlers/mock-data.js +162 -184
  114. package/dist/index.d.ts +13 -42
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +3277 -53
  117. package/dist/node/crm-pipeline.feature.js +75 -0
  118. package/dist/node/deal/deal.enum.js +18 -0
  119. package/dist/node/deal/deal.operation.js +396 -0
  120. package/dist/node/deal/deal.schema.js +141 -0
  121. package/dist/node/deal/deal.test-spec.js +58 -0
  122. package/dist/node/deal/index.js +408 -0
  123. package/dist/node/docs/crm-pipeline.docblock.js +113 -0
  124. package/dist/node/docs/index.js +113 -0
  125. package/dist/node/entities/company.entity.js +52 -0
  126. package/dist/node/entities/contact.entity.js +66 -0
  127. package/dist/node/entities/deal.entity.js +107 -0
  128. package/dist/node/entities/index.js +343 -0
  129. package/dist/node/entities/task.entity.js +99 -0
  130. package/dist/node/events/contact.event.js +31 -0
  131. package/dist/node/events/deal.event.js +101 -0
  132. package/dist/node/events/index.js +158 -0
  133. package/dist/node/events/task.event.js +28 -0
  134. package/dist/node/example.js +39 -0
  135. package/dist/node/handlers/crm.handlers.js +160 -0
  136. package/dist/node/handlers/deal.handlers.js +293 -0
  137. package/dist/node/handlers/index.js +456 -0
  138. package/dist/node/handlers/mock-data.js +165 -0
  139. package/dist/node/index.js +3279 -0
  140. package/dist/node/operations/index.js +407 -0
  141. package/dist/node/presentations/dashboard.presentation.js +52 -0
  142. package/dist/node/presentations/index.js +284 -0
  143. package/dist/node/presentations/pipeline.presentation.js +233 -0
  144. package/dist/node/seeders/index.js +22 -0
  145. package/dist/node/shared/overlay-types.js +0 -0
  146. package/dist/node/ui/CrmDashboard.js +1325 -0
  147. package/dist/node/ui/CrmDealCard.js +50 -0
  148. package/dist/node/ui/CrmPipelineBoard.js +160 -0
  149. package/dist/node/ui/hooks/index.js +186 -0
  150. package/dist/node/ui/hooks/useDealList.js +84 -0
  151. package/dist/node/ui/hooks/useDealMutations.js +100 -0
  152. package/dist/node/ui/index.js +1972 -0
  153. package/dist/node/ui/modals/CreateDealModal.js +211 -0
  154. package/dist/node/ui/modals/DealActionsModal.js +428 -0
  155. package/dist/node/ui/modals/index.js +638 -0
  156. package/dist/node/ui/overlays/demo-overlays.js +55 -0
  157. package/dist/node/ui/overlays/index.js +55 -0
  158. package/dist/node/ui/renderers/index.js +827 -0
  159. package/dist/node/ui/renderers/pipeline.markdown.js +564 -0
  160. package/dist/node/ui/renderers/pipeline.renderer.js +264 -0
  161. package/dist/operations/index.d.ts +2 -5
  162. package/dist/operations/index.d.ts.map +1 -0
  163. package/dist/operations/index.js +407 -5
  164. package/dist/presentations/dashboard.presentation.d.ts +2 -7
  165. package/dist/presentations/dashboard.presentation.d.ts.map +1 -1
  166. package/dist/presentations/dashboard.presentation.js +51 -60
  167. package/dist/presentations/index.d.ts +3 -3
  168. package/dist/presentations/index.d.ts.map +1 -0
  169. package/dist/presentations/index.js +284 -3
  170. package/dist/presentations/pipeline.presentation.d.ts +4 -9
  171. package/dist/presentations/pipeline.presentation.d.ts.map +1 -1
  172. package/dist/presentations/pipeline.presentation.js +228 -116
  173. package/dist/seeders/index.d.ts +4 -8
  174. package/dist/seeders/index.d.ts.map +1 -1
  175. package/dist/seeders/index.js +21 -45
  176. package/dist/shared/overlay-types.d.ts +25 -28
  177. package/dist/shared/overlay-types.d.ts.map +1 -1
  178. package/dist/shared/overlay-types.js +1 -0
  179. package/dist/ui/CrmDashboard.d.ts +1 -6
  180. package/dist/ui/CrmDashboard.d.ts.map +1 -1
  181. package/dist/ui/CrmDashboard.js +1318 -296
  182. package/dist/ui/CrmDealCard.d.ts +8 -12
  183. package/dist/ui/CrmDealCard.d.ts.map +1 -1
  184. package/dist/ui/CrmDealCard.js +47 -45
  185. package/dist/ui/CrmPipelineBoard.d.ts +11 -20
  186. package/dist/ui/CrmPipelineBoard.d.ts.map +1 -1
  187. package/dist/ui/CrmPipelineBoard.js +157 -94
  188. package/dist/ui/hooks/index.d.ts +3 -3
  189. package/dist/ui/hooks/index.d.ts.map +1 -0
  190. package/dist/ui/hooks/index.js +185 -4
  191. package/dist/ui/hooks/useDealList.d.ts +28 -32
  192. package/dist/ui/hooks/useDealList.d.ts.map +1 -1
  193. package/dist/ui/hooks/useDealList.js +81 -90
  194. package/dist/ui/hooks/useDealMutations.d.ts +18 -22
  195. package/dist/ui/hooks/useDealMutations.d.ts.map +1 -1
  196. package/dist/ui/hooks/useDealMutations.js +97 -155
  197. package/dist/ui/index.d.ts +8 -14
  198. package/dist/ui/index.d.ts.map +1 -0
  199. package/dist/ui/index.js +1973 -15
  200. package/dist/ui/modals/CreateDealModal.d.ts +19 -29
  201. package/dist/ui/modals/CreateDealModal.d.ts.map +1 -1
  202. package/dist/ui/modals/CreateDealModal.js +209 -180
  203. package/dist/ui/modals/DealActionsModal.d.ts +31 -44
  204. package/dist/ui/modals/DealActionsModal.d.ts.map +1 -1
  205. package/dist/ui/modals/DealActionsModal.js +424 -367
  206. package/dist/ui/modals/index.d.ts +3 -3
  207. package/dist/ui/modals/index.d.ts.map +1 -0
  208. package/dist/ui/modals/index.js +638 -3
  209. package/dist/ui/overlays/demo-overlays.d.ts +10 -8
  210. package/dist/ui/overlays/demo-overlays.d.ts.map +1 -1
  211. package/dist/ui/overlays/demo-overlays.js +54 -66
  212. package/dist/ui/overlays/index.d.ts +2 -2
  213. package/dist/ui/overlays/index.d.ts.map +1 -0
  214. package/dist/ui/overlays/index.js +56 -3
  215. package/dist/ui/renderers/index.d.ts +3 -3
  216. package/dist/ui/renderers/index.d.ts.map +1 -0
  217. package/dist/ui/renderers/index.js +827 -3
  218. package/dist/ui/renderers/pipeline.markdown.d.ts +12 -11
  219. package/dist/ui/renderers/pipeline.markdown.d.ts.map +1 -1
  220. package/dist/ui/renderers/pipeline.markdown.js +560 -114
  221. package/dist/ui/renderers/pipeline.renderer.d.ts +9 -7
  222. package/dist/ui/renderers/pipeline.renderer.d.ts.map +1 -1
  223. package/dist/ui/renderers/pipeline.renderer.js +261 -24
  224. package/package.json +476 -90
  225. package/tsdown.config.js +1 -2
  226. package/.turbo/turbo-build$colon$bundle.log +0 -164
  227. package/dist/crm-pipeline.feature.js.map +0 -1
  228. package/dist/deal/deal.enum.js.map +0 -1
  229. package/dist/deal/deal.operation.js.map +0 -1
  230. package/dist/deal/deal.schema.js.map +0 -1
  231. package/dist/deal/deal.test-spec.js.map +0 -1
  232. package/dist/docs/crm-pipeline.docblock.js.map +0 -1
  233. package/dist/entities/company.entity.js.map +0 -1
  234. package/dist/entities/contact.entity.js.map +0 -1
  235. package/dist/entities/deal.entity.js.map +0 -1
  236. package/dist/entities/index.js.map +0 -1
  237. package/dist/entities/task.entity.js.map +0 -1
  238. package/dist/events/contact.event.js.map +0 -1
  239. package/dist/events/deal.event.js.map +0 -1
  240. package/dist/events/task.event.js.map +0 -1
  241. package/dist/example.js.map +0 -1
  242. package/dist/handlers/crm.handlers.js.map +0 -1
  243. package/dist/handlers/deal.handlers.js.map +0 -1
  244. package/dist/handlers/mock-data.js.map +0 -1
  245. package/dist/index.js.map +0 -1
  246. package/dist/presentations/dashboard.presentation.js.map +0 -1
  247. package/dist/presentations/pipeline.presentation.js.map +0 -1
  248. package/dist/seeders/index.js.map +0 -1
  249. package/dist/ui/CrmDashboard.js.map +0 -1
  250. package/dist/ui/CrmDealCard.js.map +0 -1
  251. package/dist/ui/CrmPipelineBoard.js.map +0 -1
  252. package/dist/ui/hooks/useDealList.js.map +0 -1
  253. package/dist/ui/hooks/useDealMutations.js.map +0 -1
  254. package/dist/ui/modals/CreateDealModal.js.map +0 -1
  255. package/dist/ui/modals/DealActionsModal.js.map +0 -1
  256. package/dist/ui/overlays/demo-overlays.js.map +0 -1
  257. package/dist/ui/renderers/pipeline.markdown.js.map +0 -1
  258. package/dist/ui/renderers/pipeline.renderer.js.map +0 -1
  259. package/tsconfig.tsbuildinfo +0 -1
@@ -1,164 +0,0 @@
1
- $ tsdown
2
- โ„น tsdown v0.20.3 powered by rolldown v1.0.0-rc.3
3
- โ„น config file: /home/runner/work/contractspec/contractspec/packages/examples/crm-pipeline/tsdown.config.js
4
- โ„น entry: src/crm-pipeline.feature.ts, src/example.ts, src/index.ts, src/deal/deal.enum.ts, src/deal/deal.operation.ts, src/deal/deal.schema.ts, src/deal/deal.test-spec.ts, src/deal/index.ts, src/docs/crm-pipeline.docblock.ts, src/docs/index.ts, src/entities/company.entity.ts, src/entities/contact.entity.ts, src/entities/deal.entity.ts, src/entities/index.ts, src/entities/task.entity.ts, src/events/contact.event.ts, src/events/deal.event.ts, src/events/index.ts, src/events/task.event.ts, src/handlers/crm.handlers.ts, src/handlers/deal.handlers.ts, src/handlers/index.ts, src/handlers/mock-data.ts, src/operations/index.ts, src/presentations/dashboard.presentation.ts, src/presentations/index.ts, src/presentations/pipeline.presentation.ts, src/seeders/index.ts, src/shared/overlay-types.ts, src/ui/CrmDashboard.tsx, src/ui/CrmDealCard.tsx, src/ui/CrmPipelineBoard.tsx, src/ui/index.ts, src/ui/hooks/index.ts, src/ui/hooks/useDealList.ts, src/ui/hooks/useDealMutations.ts, src/ui/modals/CreateDealModal.tsx, src/ui/modals/DealActionsModal.tsx, src/ui/modals/index.ts, src/ui/overlays/demo-overlays.ts, src/ui/overlays/index.ts, src/ui/renderers/index.ts, src/ui/renderers/pipeline.markdown.ts, src/ui/renderers/pipeline.renderer.tsx
5
- โ„น target: esnext
6
- โ„น tsconfig: tsconfig.json
7
- โ„น Build start
8
- โ„น Cleaning 166 files
9
- โ„น dist/ui/modals/DealActionsModal.js 12.27 kB โ”‚ gzip: 2.56 kB
10
- โ„น dist/ui/CrmDashboard.js  9.75 kB โ”‚ gzip: 2.51 kB
11
- โ„น dist/ui/modals/CreateDealModal.js  6.04 kB โ”‚ gzip: 1.84 kB
12
- โ„น dist/deal/deal.schema.js  5.86 kB โ”‚ gzip: 0.87 kB
13
- โ„น dist/deal/deal.operation.js  5.63 kB โ”‚ gzip: 1.47 kB
14
- โ„น dist/handlers/crm.handlers.js  5.59 kB โ”‚ gzip: 1.54 kB
15
- โ„น dist/index.js  4.72 kB โ”‚ gzip: 1.14 kB
16
- โ„น dist/ui/renderers/pipeline.markdown.js  4.50 kB โ”‚ gzip: 1.34 kB
17
- โ„น dist/handlers/mock-data.js  4.50 kB โ”‚ gzip: 1.09 kB
18
- โ„น dist/docs/crm-pipeline.docblock.js  4.36 kB โ”‚ gzip: 1.75 kB
19
- โ„น dist/ui/CrmPipelineBoard.js  3.88 kB โ”‚ gzip: 1.39 kB
20
- โ„น dist/events/deal.event.js  3.77 kB โ”‚ gzip: 0.67 kB
21
- โ„น dist/handlers/deal.handlers.js  3.73 kB โ”‚ gzip: 1.06 kB
22
- โ„น dist/entities/deal.entity.js  3.56 kB โ”‚ gzip: 1.05 kB
23
- โ„น dist/ui/hooks/useDealMutations.js  3.49 kB โ”‚ gzip: 0.80 kB
24
- โ„น dist/entities/task.entity.js  3.41 kB โ”‚ gzip: 0.98 kB
25
- โ„น dist/presentations/pipeline.presentation.js  3.23 kB โ”‚ gzip: 0.96 kB
26
- โ„น dist/crm-pipeline.feature.js  2.69 kB โ”‚ gzip: 0.71 kB
27
- โ„น dist/ui/hooks/useDealList.js  2.54 kB โ”‚ gzip: 1.03 kB
28
- โ„น dist/entities/contact.entity.js  2.38 kB โ”‚ gzip: 0.83 kB
29
- โ„น dist/entities/company.entity.js  1.97 kB โ”‚ gzip: 0.72 kB
30
- โ„น dist/ui/CrmDealCard.js  1.96 kB โ”‚ gzip: 0.91 kB
31
- โ„น dist/presentations/dashboard.presentation.js  1.67 kB โ”‚ gzip: 0.64 kB
32
- โ„น dist/deal/deal.test-spec.js  1.33 kB โ”‚ gzip: 0.43 kB
33
- โ„น dist/ui/overlays/demo-overlays.js  1.32 kB โ”‚ gzip: 0.51 kB
34
- โ„น dist/events/contact.event.js  1.09 kB โ”‚ gzip: 0.45 kB
35
- โ„น dist/events/task.event.js  1.07 kB โ”‚ gzip: 0.44 kB
36
- โ„น dist/entities/index.js  1.05 kB โ”‚ gzip: 0.39 kB
37
- โ„น dist/example.js  1.03 kB โ”‚ gzip: 0.54 kB
38
- โ„น dist/seeders/index.js  1.03 kB โ”‚ gzip: 0.50 kB
39
- โ„น dist/ui/index.js  1.03 kB โ”‚ gzip: 0.29 kB
40
- โ„น dist/ui/renderers/pipeline.renderer.js  0.90 kB โ”‚ gzip: 0.44 kB
41
- โ„น dist/operations/index.js  0.79 kB โ”‚ gzip: 0.23 kB
42
- โ„น dist/deal/index.js  0.78 kB โ”‚ gzip: 0.23 kB
43
- โ„น dist/handlers/index.js  0.60 kB โ”‚ gzip: 0.20 kB
44
- โ„น dist/deal/deal.enum.js  0.44 kB โ”‚ gzip: 0.24 kB
45
- โ„น dist/presentations/index.js  0.40 kB โ”‚ gzip: 0.15 kB
46
- โ„น dist/events/index.js  0.32 kB โ”‚ gzip: 0.14 kB
47
- โ„น dist/ui/renderers/index.js  0.26 kB โ”‚ gzip: 0.12 kB
48
- โ„น dist/ui/hooks/index.js  0.16 kB โ”‚ gzip: 0.10 kB
49
- โ„น dist/ui/modals/index.js  0.16 kB โ”‚ gzip: 0.09 kB
50
- โ„น dist/ui/overlays/index.js  0.15 kB โ”‚ gzip: 0.09 kB
51
- โ„น dist/docs/index.js  0.04 kB โ”‚ gzip: 0.06 kB
52
- โ„น dist/shared/overlay-types.js  0.00 kB โ”‚ gzip: 0.02 kB
53
- โ„น dist/ui/modals/DealActionsModal.js.map 17.99 kB โ”‚ gzip: 4.12 kB
54
- โ„น dist/handlers/crm.handlers.js.map 13.46 kB โ”‚ gzip: 3.36 kB
55
- โ„น dist/ui/CrmDashboard.js.map 13.33 kB โ”‚ gzip: 3.99 kB
56
- โ„น dist/ui/modals/CreateDealModal.js.map  9.71 kB โ”‚ gzip: 3.02 kB
57
- โ„น dist/deal/deal.operation.js.map  9.58 kB โ”‚ gzip: 2.06 kB
58
- โ„น dist/deal/deal.schema.js.map  8.70 kB โ”‚ gzip: 1.25 kB
59
- โ„น dist/ui/renderers/pipeline.markdown.js.map  8.65 kB โ”‚ gzip: 2.46 kB
60
- โ„น dist/handlers/deal.handlers.js.map  7.82 kB โ”‚ gzip: 2.05 kB
61
- โ„น dist/handlers/mock-data.js.map  7.43 kB โ”‚ gzip: 1.54 kB
62
- โ„น dist/ui/CrmPipelineBoard.js.map  6.91 kB โ”‚ gzip: 2.34 kB
63
- โ„น dist/ui/hooks/useDealMutations.js.map  6.85 kB โ”‚ gzip: 1.65 kB
64
- โ„น dist/entities/deal.entity.js.map  6.68 kB โ”‚ gzip: 1.76 kB
65
- โ„น dist/entities/task.entity.js.map  6.10 kB โ”‚ gzip: 1.56 kB
66
- โ„น dist/events/deal.event.js.map  5.88 kB โ”‚ gzip: 1.02 kB
67
- โ„น dist/docs/crm-pipeline.docblock.js.map  5.26 kB โ”‚ gzip: 1.97 kB
68
- โ„น dist/ui/hooks/useDealList.js.map  4.93 kB โ”‚ gzip: 1.83 kB
69
- โ„น dist/presentations/pipeline.presentation.js.map  4.69 kB โ”‚ gzip: 1.22 kB
70
- โ„น dist/crm-pipeline.feature.js.map  4.44 kB โ”‚ gzip: 1.21 kB
71
- โ„น dist/entities/contact.entity.js.map  4.32 kB โ”‚ gzip: 1.37 kB
72
- โ„น dist/entities/company.entity.js.map  3.58 kB โ”‚ gzip: 1.17 kB
73
- โ„น dist/ui/CrmDealCard.js.map  3.37 kB โ”‚ gzip: 1.49 kB
74
- โ„น dist/presentations/dashboard.presentation.js.map  2.40 kB โ”‚ gzip: 0.86 kB
75
- โ„น dist/deal/deal.test-spec.js.map  2.35 kB โ”‚ gzip: 0.63 kB
76
- โ„น dist/ui/overlays/demo-overlays.js.map  2.27 kB โ”‚ gzip: 0.84 kB
77
- โ„น dist/seeders/index.js.map  1.78 kB โ”‚ gzip: 0.84 kB
78
- โ„น dist/events/contact.event.js.map  1.65 kB โ”‚ gzip: 0.70 kB
79
- โ„น dist/ui/renderers/pipeline.renderer.js.map  1.62 kB โ”‚ gzip: 0.75 kB
80
- โ„น dist/events/task.event.js.map  1.61 kB โ”‚ gzip: 0.65 kB
81
- โ„น dist/example.js.map  1.56 kB โ”‚ gzip: 0.77 kB
82
- โ„น dist/entities/index.js.map  1.32 kB โ”‚ gzip: 0.49 kB
83
- โ„น dist/index.js.map  1.31 kB โ”‚ gzip: 0.54 kB
84
- โ„น dist/handlers/crm.handlers.d.ts.map  1.19 kB โ”‚ gzip: 0.39 kB
85
- โ„น dist/handlers/deal.handlers.d.ts.map  1.17 kB โ”‚ gzip: 0.39 kB
86
- โ„น dist/deal/deal.operation.d.ts.map  0.95 kB โ”‚ gzip: 0.25 kB
87
- โ„น dist/deal/deal.schema.d.ts.map  0.79 kB โ”‚ gzip: 0.25 kB
88
- โ„น dist/ui/modals/DealActionsModal.d.ts.map  0.72 kB โ”‚ gzip: 0.29 kB
89
- โ„น dist/deal/deal.enum.js.map  0.60 kB โ”‚ gzip: 0.32 kB
90
- โ„น dist/shared/overlay-types.d.ts.map  0.49 kB โ”‚ gzip: 0.22 kB
91
- โ„น dist/handlers/mock-data.d.ts.map  0.48 kB โ”‚ gzip: 0.24 kB
92
- โ„น dist/ui/modals/CreateDealModal.d.ts.map  0.48 kB โ”‚ gzip: 0.25 kB
93
- โ„น dist/events/deal.event.d.ts.map  0.45 kB โ”‚ gzip: 0.19 kB
94
- โ„น dist/ui/hooks/useDealMutations.d.ts.map  0.43 kB โ”‚ gzip: 0.24 kB
95
- โ„น dist/ui/CrmPipelineBoard.d.ts.map  0.37 kB โ”‚ gzip: 0.24 kB
96
- โ„น dist/entities/task.entity.d.ts.map  0.35 kB โ”‚ gzip: 0.20 kB
97
- โ„น dist/entities/deal.entity.d.ts.map  0.31 kB โ”‚ gzip: 0.19 kB
98
- โ„น dist/presentations/pipeline.presentation.d.ts.map  0.31 kB โ”‚ gzip: 0.18 kB
99
- โ„น dist/ui/hooks/useDealList.d.ts.map  0.27 kB โ”‚ gzip: 0.19 kB
100
- โ„น dist/ui/renderers/pipeline.markdown.d.ts.map  0.24 kB โ”‚ gzip: 0.17 kB
101
- โ„น dist/ui/CrmDealCard.d.ts.map  0.24 kB โ”‚ gzip: 0.18 kB
102
- โ„น dist/presentations/dashboard.presentation.d.ts.map  0.22 kB โ”‚ gzip: 0.16 kB
103
- โ„น dist/ui/overlays/demo-overlays.d.ts.map  0.21 kB โ”‚ gzip: 0.17 kB
104
- โ„น dist/entities/contact.entity.d.ts.map  0.20 kB โ”‚ gzip: 0.16 kB
105
- โ„น dist/entities/company.entity.d.ts.map  0.20 kB โ”‚ gzip: 0.16 kB
106
- โ„น dist/deal/deal.test-spec.d.ts.map  0.19 kB โ”‚ gzip: 0.15 kB
107
- โ„น dist/events/contact.event.d.ts.map  0.18 kB โ”‚ gzip: 0.15 kB
108
- โ„น dist/ui/renderers/pipeline.renderer.d.ts.map  0.18 kB โ”‚ gzip: 0.15 kB
109
- โ„น dist/events/task.event.d.ts.map  0.18 kB โ”‚ gzip: 0.15 kB
110
- โ„น dist/deal/deal.enum.d.ts.map  0.18 kB โ”‚ gzip: 0.15 kB
111
- โ„น dist/seeders/index.d.ts.map  0.17 kB โ”‚ gzip: 0.15 kB
112
- โ„น dist/crm-pipeline.feature.d.ts.map  0.16 kB โ”‚ gzip: 0.14 kB
113
- โ„น dist/index.d.ts.map  0.16 kB โ”‚ gzip: 0.13 kB
114
- โ„น dist/ui/CrmDashboard.d.ts.map  0.16 kB โ”‚ gzip: 0.14 kB
115
- โ„น dist/entities/index.d.ts.map  0.14 kB โ”‚ gzip: 0.13 kB
116
- โ„น dist/example.d.ts.map  0.13 kB โ”‚ gzip: 0.13 kB
117
- โ„น dist/deal/deal.operation.d.ts 14.01 kB โ”‚ gzip: 0.97 kB
118
- โ„น dist/deal/deal.schema.d.ts  8.12 kB โ”‚ gzip: 0.84 kB
119
- โ„น dist/index.d.ts  4.79 kB โ”‚ gzip: 1.16 kB
120
- โ„น dist/entities/deal.entity.d.ts  3.44 kB โ”‚ gzip: 0.55 kB
121
- โ„น dist/events/deal.event.d.ts  3.25 kB โ”‚ gzip: 0.42 kB
122
- โ„น dist/entities/task.entity.d.ts  2.90 kB โ”‚ gzip: 0.50 kB
123
- โ„น dist/handlers/deal.handlers.d.ts  2.40 kB โ”‚ gzip: 0.69 kB
124
- โ„น dist/handlers/crm.handlers.d.ts  2.18 kB โ”‚ gzip: 0.69 kB
125
- โ„น dist/entities/contact.entity.d.ts  2.10 kB โ”‚ gzip: 0.45 kB
126
- โ„น dist/entities/company.entity.d.ts  1.86 kB โ”‚ gzip: 0.42 kB
127
- โ„น dist/ui/modals/DealActionsModal.d.ts  1.14 kB โ”‚ gzip: 0.48 kB
128
- โ„น dist/ui/index.d.ts  1.11 kB โ”‚ gzip: 0.31 kB
129
- โ„น dist/handlers/mock-data.d.ts  1.04 kB โ”‚ gzip: 0.43 kB
130
- โ„น dist/shared/overlay-types.d.ts  1.00 kB โ”‚ gzip: 0.40 kB
131
- โ„น dist/ui/hooks/useDealList.d.ts  0.98 kB โ”‚ gzip: 0.47 kB
132
- โ„น dist/ui/hooks/useDealMutations.d.ts  0.96 kB โ”‚ gzip: 0.38 kB
133
- โ„น dist/events/contact.event.d.ts  0.92 kB โ”‚ gzip: 0.30 kB
134
- โ„น dist/events/task.event.d.ts  0.91 kB โ”‚ gzip: 0.30 kB
135
- โ„น dist/handlers/index.d.ts  0.91 kB โ”‚ gzip: 0.28 kB
136
- โ„น dist/entities/index.d.ts  0.85 kB โ”‚ gzip: 0.32 kB
137
- โ„น dist/presentations/pipeline.presentation.d.ts  0.83 kB โ”‚ gzip: 0.29 kB
138
- โ„น dist/operations/index.d.ts  0.79 kB โ”‚ gzip: 0.24 kB
139
- โ„น dist/deal/index.d.ts  0.78 kB โ”‚ gzip: 0.23 kB
140
- โ„น dist/ui/modals/CreateDealModal.d.ts  0.77 kB โ”‚ gzip: 0.39 kB
141
- โ„น dist/ui/renderers/pipeline.markdown.d.ts  0.70 kB โ”‚ gzip: 0.30 kB
142
- โ„น dist/ui/CrmPipelineBoard.d.ts  0.63 kB โ”‚ gzip: 0.34 kB
143
- โ„น dist/presentations/dashboard.presentation.d.ts  0.53 kB โ”‚ gzip: 0.23 kB
144
- โ„น dist/ui/overlays/demo-overlays.d.ts  0.52 kB โ”‚ gzip: 0.27 kB
145
- โ„น dist/deal/deal.enum.d.ts  0.48 kB โ”‚ gzip: 0.23 kB
146
- โ„น dist/crm-pipeline.feature.d.ts  0.44 kB โ”‚ gzip: 0.25 kB
147
- โ„น dist/presentations/index.d.ts  0.40 kB โ”‚ gzip: 0.15 kB
148
- โ„น dist/ui/CrmDealCard.d.ts  0.39 kB โ”‚ gzip: 0.25 kB
149
- โ„น dist/deal/deal.test-spec.d.ts  0.35 kB โ”‚ gzip: 0.19 kB
150
- โ„น dist/ui/renderers/pipeline.renderer.d.ts  0.33 kB โ”‚ gzip: 0.20 kB
151
- โ„น dist/events/index.d.ts  0.32 kB โ”‚ gzip: 0.14 kB
152
- โ„น dist/seeders/index.d.ts  0.28 kB โ”‚ gzip: 0.21 kB
153
- โ„น dist/ui/renderers/index.d.ts  0.26 kB โ”‚ gzip: 0.12 kB
154
- โ„น dist/example.d.ts  0.25 kB โ”‚ gzip: 0.17 kB
155
- โ„น dist/ui/hooks/index.d.ts  0.25 kB โ”‚ gzip: 0.11 kB
156
- โ„น dist/ui/CrmDashboard.d.ts  0.24 kB โ”‚ gzip: 0.17 kB
157
- โ„น dist/ui/modals/index.d.ts  0.16 kB โ”‚ gzip: 0.09 kB
158
- โ„น dist/ui/overlays/index.d.ts  0.14 kB โ”‚ gzip: 0.09 kB
159
- โ„น dist/docs/crm-pipeline.docblock.d.ts  0.01 kB โ”‚ gzip: 0.03 kB
160
- โ„น dist/docs/index.d.ts  0.01 kB โ”‚ gzip: 0.03 kB
161
- โ„น 152 files, total: 370.26 kB
162
- [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugin `tsdown:external`. See https://rolldown.rs/options/checks#plugintimings for more details.
163
-
164
- โœ” Build complete in 38811ms
@@ -1 +0,0 @@
1
- {"version":3,"file":"crm-pipeline.feature.js","names":[],"sources":["../src/crm-pipeline.feature.ts"],"sourcesContent":["/**\n * CRM Pipeline Feature Module Specification\n *\n * Defines the feature module for CRM and sales pipeline capabilities.\n */\nimport { defineFeature } from '@contractspec/lib.contracts';\n\n/**\n * CRM Pipeline feature module that bundles deal management,\n * pipeline operations, and contact management into an installable feature.\n */\nexport const CrmPipelineFeature = defineFeature({\n meta: {\n key: 'crm-pipeline',\n title: 'CRM Pipeline',\n description:\n 'CRM and sales pipeline management with deals, contacts, and companies',\n domain: 'crm',\n owners: ['@crm-team'],\n tags: ['crm', 'sales', 'pipeline', 'deals'],\n stability: 'experimental',\n version: '1.0.0',\n },\n\n // All contract operations included in this feature\n operations: [\n // Deal operations\n { key: 'crm.deal.create', version: '1.0.0' },\n { key: 'crm.deal.move', version: '1.0.0' },\n { key: 'crm.deal.win', version: '1.0.0' },\n { key: 'crm.deal.lose', version: '1.0.0' },\n { key: 'crm.deal.list', version: '1.0.0' },\n ],\n\n // Events emitted by this feature\n events: [\n // Deal events\n { key: 'deal.created', version: '1.0.0' },\n { key: 'deal.moved', version: '1.0.0' },\n { key: 'deal.won', version: '1.0.0' },\n { key: 'deal.lost', version: '1.0.0' },\n\n // Contact events\n { key: 'contact.created', version: '1.0.0' },\n\n // Task events\n { key: 'task.completed', version: '1.0.0' },\n ],\n\n // Presentations associated with this feature\n presentations: [\n { key: 'crm.dashboard', version: '1.0.0' },\n { key: 'crm.pipeline.kanban', version: '1.0.0' },\n { key: 'crm.deal.viewList', version: '1.0.0' },\n { key: 'crm.deal.detail', version: '1.0.0' },\n { key: 'crm.deal.card', version: '1.0.0' },\n { key: 'crm.pipeline.metrics', version: '1.0.0' },\n ],\n\n // Link operations to their primary presentations\n opToPresentation: [\n {\n op: { key: 'crm.deal.list', version: '1.0.0' },\n pres: { key: 'crm.pipeline.kanban', version: '1.0.0' },\n },\n {\n op: { key: 'crm.deal.move', version: '1.0.0' },\n pres: { key: 'crm.pipeline.kanban', version: '1.0.0' },\n },\n ],\n\n // Target requirements for multi-surface rendering\n presentationsTargets: [\n { key: 'crm.dashboard', version: '1.0.0', targets: ['react', 'markdown'] },\n {\n key: 'crm.pipeline.kanban',\n version: '1.0.0',\n targets: ['react', 'markdown'],\n },\n {\n key: 'crm.deal.viewList',\n version: '1.0.0',\n targets: ['react', 'markdown', 'application/json'],\n },\n {\n key: 'crm.pipeline.metrics',\n version: '1.0.0',\n targets: ['react', 'markdown'],\n },\n ],\n\n // Capability requirements\n capabilities: {\n requires: [\n { key: 'identity', version: '1.0.0' },\n { key: 'audit-trail', version: '1.0.0' },\n { key: 'notifications', version: '1.0.0' },\n ],\n },\n});\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,qBAAqB,cAAc;CAC9C,MAAM;EACJ,KAAK;EACL,OAAO;EACP,aACE;EACF,QAAQ;EACR,QAAQ,CAAC,YAAY;EACrB,MAAM;GAAC;GAAO;GAAS;GAAY;GAAQ;EAC3C,WAAW;EACX,SAAS;EACV;CAGD,YAAY;EAEV;GAAE,KAAK;GAAmB,SAAS;GAAS;EAC5C;GAAE,KAAK;GAAiB,SAAS;GAAS;EAC1C;GAAE,KAAK;GAAgB,SAAS;GAAS;EACzC;GAAE,KAAK;GAAiB,SAAS;GAAS;EAC1C;GAAE,KAAK;GAAiB,SAAS;GAAS;EAC3C;CAGD,QAAQ;EAEN;GAAE,KAAK;GAAgB,SAAS;GAAS;EACzC;GAAE,KAAK;GAAc,SAAS;GAAS;EACvC;GAAE,KAAK;GAAY,SAAS;GAAS;EACrC;GAAE,KAAK;GAAa,SAAS;GAAS;EAGtC;GAAE,KAAK;GAAmB,SAAS;GAAS;EAG5C;GAAE,KAAK;GAAkB,SAAS;GAAS;EAC5C;CAGD,eAAe;EACb;GAAE,KAAK;GAAiB,SAAS;GAAS;EAC1C;GAAE,KAAK;GAAuB,SAAS;GAAS;EAChD;GAAE,KAAK;GAAqB,SAAS;GAAS;EAC9C;GAAE,KAAK;GAAmB,SAAS;GAAS;EAC5C;GAAE,KAAK;GAAiB,SAAS;GAAS;EAC1C;GAAE,KAAK;GAAwB,SAAS;GAAS;EAClD;CAGD,kBAAkB,CAChB;EACE,IAAI;GAAE,KAAK;GAAiB,SAAS;GAAS;EAC9C,MAAM;GAAE,KAAK;GAAuB,SAAS;GAAS;EACvD,EACD;EACE,IAAI;GAAE,KAAK;GAAiB,SAAS;GAAS;EAC9C,MAAM;GAAE,KAAK;GAAuB,SAAS;GAAS;EACvD,CACF;CAGD,sBAAsB;EACpB;GAAE,KAAK;GAAiB,SAAS;GAAS,SAAS,CAAC,SAAS,WAAW;GAAE;EAC1E;GACE,KAAK;GACL,SAAS;GACT,SAAS,CAAC,SAAS,WAAW;GAC/B;EACD;GACE,KAAK;GACL,SAAS;GACT,SAAS;IAAC;IAAS;IAAY;IAAmB;GACnD;EACD;GACE,KAAK;GACL,SAAS;GACT,SAAS,CAAC,SAAS,WAAW;GAC/B;EACF;CAGD,cAAc,EACZ,UAAU;EACR;GAAE,KAAK;GAAY,SAAS;GAAS;EACrC;GAAE,KAAK;GAAe,SAAS;GAAS;EACxC;GAAE,KAAK;GAAiB,SAAS;GAAS;EAC3C,EACF;CACF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"deal.enum.js","names":[],"sources":["../../src/deal/deal.enum.ts"],"sourcesContent":["import { defineEnum } from '@contractspec/lib.schema';\n\n/**\n * Deal status enum.\n */\nexport const DealStatusEnum = defineEnum('DealStatus', [\n 'OPEN',\n 'WON',\n 'LOST',\n 'STALE',\n]);\n\n/**\n * Deal status filter enum.\n */\nexport const DealStatusFilterEnum = defineEnum('DealStatusFilter', [\n 'OPEN',\n 'WON',\n 'LOST',\n 'all',\n]);\n"],"mappings":";;;;;;AAKA,MAAa,iBAAiB,WAAW,cAAc;CACrD;CACA;CACA;CACA;CACD,CAAC;;;;AAKF,MAAa,uBAAuB,WAAW,oBAAoB;CACjE;CACA;CACA;CACA;CACD,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"deal.operation.js","names":[],"sources":["../../src/deal/deal.operation.ts"],"sourcesContent":["import {\n defineCommand,\n defineQuery,\n} from '@contractspec/lib.contracts/operations';\nimport {\n DealModel,\n CreateDealInputModel,\n MoveDealInputModel,\n DealMovedPayloadModel,\n WinDealInputModel,\n DealWonPayloadModel,\n LoseDealInputModel,\n DealLostPayloadModel,\n ListDealsInputModel,\n ListDealsOutputModel,\n} from './deal.schema';\n\nconst OWNERS = ['@example.crm-pipeline'] as const;\n\n/**\n * Create a new deal.\n */\nexport const CreateDealContract = defineCommand({\n meta: {\n key: 'crm.deal.create',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['crm', 'deal', 'create'],\n description: 'Create a new deal in the pipeline.',\n goal: 'Allow sales reps to create new opportunities.',\n context: 'Deal creation UI, quick add.',\n },\n io: {\n input: CreateDealInputModel,\n output: DealModel,\n },\n policy: {\n auth: 'user',\n },\n sideEffects: {\n emits: [\n {\n key: 'deal.created',\n version: '1.0.0',\n when: 'Deal is created',\n payload: DealModel,\n },\n ],\n audit: ['deal.created'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'create-deal-happy-path',\n given: ['User is authenticated'],\n when: ['User creates a deal with valid data'],\n then: ['Deal is created', 'DealCreated event is emitted'],\n },\n ],\n examples: [\n {\n key: 'create-basic-deal',\n input: {\n title: 'Big Corp Q3 License',\n stageId: 'stage-lead',\n value: 50000,\n companyId: 'comp-123',\n },\n output: {\n id: 'deal-789',\n title: 'Big Corp Q3 License',\n status: 'open',\n },\n },\n ],\n },\n});\n\n/**\n * Move deal to a different stage.\n */\nexport const MoveDealContract = defineCommand({\n meta: {\n key: 'crm.deal.move',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['crm', 'deal', 'move', 'kanban'],\n description: 'Move a deal to a different stage.',\n goal: 'Allow drag-and-drop stage movement in Kanban.',\n context: 'Pipeline Kanban view.',\n },\n io: {\n input: MoveDealInputModel,\n output: DealModel,\n },\n policy: {\n auth: 'user',\n },\n sideEffects: {\n emits: [\n {\n key: 'deal.moved',\n version: '1.0.0',\n when: 'Deal stage changed',\n payload: DealMovedPayloadModel,\n },\n ],\n audit: ['deal.moved'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'move-deal-happy-path',\n given: ['Deal exists in stage A'],\n when: ['User moves deal to stage B'],\n then: ['Deal stage is updated', 'DealMoved event is emitted'],\n },\n ],\n examples: [\n {\n key: 'move-to-negotiation',\n input: { dealId: 'deal-789', targetStageId: 'stage-negotiation' },\n output: {\n id: 'deal-789',\n stageId: 'stage-negotiation',\n movedAt: '2025-01-15T10:00:00Z',\n },\n },\n ],\n },\n});\n\n/**\n * Mark deal as won.\n */\nexport const WinDealContract = defineCommand({\n meta: {\n key: 'crm.deal.win',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['crm', 'deal', 'won'],\n description: 'Mark a deal as won.',\n goal: 'Close a deal as successful.',\n context: 'Deal closing flow.',\n },\n io: {\n input: WinDealInputModel,\n output: DealModel,\n },\n policy: {\n auth: 'user',\n },\n sideEffects: {\n emits: [\n {\n key: 'deal.won',\n version: '1.0.0',\n when: 'Deal is won',\n payload: DealWonPayloadModel,\n },\n ],\n audit: ['deal.won'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'win-deal-happy-path',\n given: ['Deal is open'],\n when: ['User marks deal as won'],\n then: ['Deal status becomes WON', 'DealWon event is emitted'],\n },\n ],\n examples: [\n {\n key: 'mark-won',\n input: {\n dealId: 'deal-789',\n actualValue: 52000,\n note: 'Signed contract attached',\n },\n output: {\n id: 'deal-789',\n status: 'won',\n closedAt: '2025-01-20T14:30:00Z',\n },\n },\n ],\n },\n});\n\n/**\n * Mark deal as lost.\n */\nexport const LoseDealContract = defineCommand({\n meta: {\n key: 'crm.deal.lose',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['crm', 'deal', 'lost'],\n description: 'Mark a deal as lost.',\n goal: 'Close a deal as unsuccessful.',\n context: 'Deal closing flow.',\n },\n io: {\n input: LoseDealInputModel,\n output: DealModel,\n },\n policy: {\n auth: 'user',\n },\n sideEffects: {\n emits: [\n {\n key: 'deal.lost',\n version: '1.0.0',\n when: 'Deal is lost',\n payload: DealLostPayloadModel,\n },\n ],\n audit: ['deal.lost'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'lose-deal-happy-path',\n given: ['Deal is open'],\n when: ['User marks deal as lost'],\n then: ['Deal status becomes LOST', 'DealLost event is emitted'],\n },\n ],\n examples: [\n {\n key: 'mark-lost',\n input: {\n dealId: 'deal-789',\n reason: 'competitor',\n note: 'Went with cheaper option',\n },\n output: {\n id: 'deal-789',\n status: 'lost',\n closedAt: '2025-01-21T09:00:00Z',\n },\n },\n ],\n },\n});\n\n/**\n * List deals in pipeline.\n */\nexport const ListDealsContract = defineQuery({\n meta: {\n key: 'crm.deal.list',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['crm', 'deal', 'list'],\n description: 'List deals with filters.',\n goal: 'Show pipeline, deal lists, dashboards.',\n context: 'Pipeline view, deal list.',\n },\n io: {\n input: ListDealsInputModel,\n output: ListDealsOutputModel,\n },\n policy: {\n auth: 'user',\n },\n acceptance: {\n scenarios: [\n {\n key: 'list-deals-happy-path',\n given: ['User has access to deals'],\n when: ['User lists deals'],\n then: ['List of deals is returned'],\n },\n ],\n examples: [\n {\n key: 'list-filter-stage',\n input: { stageId: 'stage-lead', limit: 20 },\n output: { items: [], total: 5, hasMore: false },\n },\n ],\n },\n});\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"deal.schema.js","names":[],"sources":["../../src/deal/deal.schema.ts"],"sourcesContent":["import { defineSchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';\nimport { DealStatusEnum, DealStatusFilterEnum } from './deal.enum';\n\n/**\n * A deal in the CRM pipeline.\n */\nexport const DealModel = defineSchemaModel({\n name: 'Deal',\n description: 'A deal in the CRM pipeline',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n value: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },\n currency: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n pipelineId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n stageId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n status: { type: DealStatusEnum, isOptional: false },\n contactId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n companyId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n expectedCloseDate: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n updatedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\n/**\n * Input for creating a deal.\n */\nexport const CreateDealInputModel = defineSchemaModel({\n name: 'CreateDealInput',\n description: 'Input for creating a deal',\n fields: {\n name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },\n value: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },\n currency: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n pipelineId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n stageId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n contactId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n companyId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n expectedCloseDate: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n },\n});\n\n/**\n * Input for moving a deal to another stage.\n */\nexport const MoveDealInputModel = defineSchemaModel({\n name: 'MoveDealInput',\n description: 'Input for moving a deal to another stage',\n fields: {\n dealId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n stageId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n position: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n },\n});\n\n/**\n * Payload for deal moved event.\n */\nexport const DealMovedPayloadModel = defineSchemaModel({\n name: 'DealMovedPayload',\n fields: {\n dealId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n fromStage: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n toStage: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n});\n\n/**\n * Input for marking a deal as won.\n */\nexport const WinDealInputModel = defineSchemaModel({\n name: 'WinDealInput',\n description: 'Input for marking a deal as won',\n fields: {\n dealId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n wonSource: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n notes: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n\n/**\n * Payload for deal won event.\n */\nexport const DealWonPayloadModel = defineSchemaModel({\n name: 'DealWonPayload',\n fields: {\n dealId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n value: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },\n },\n});\n\n/**\n * Input for marking a deal as lost.\n */\nexport const LoseDealInputModel = defineSchemaModel({\n name: 'LoseDealInput',\n description: 'Input for marking a deal as lost',\n fields: {\n dealId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n lostReason: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n notes: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n\n/**\n * Payload for deal lost event.\n */\nexport const DealLostPayloadModel = defineSchemaModel({\n name: 'DealLostPayload',\n fields: {\n dealId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n reason: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n});\n\n/**\n * Input for listing deals.\n */\nexport const ListDealsInputModel = defineSchemaModel({\n name: 'ListDealsInput',\n description: 'Input for listing deals',\n fields: {\n pipelineId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n stageId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n status: { type: DealStatusFilterEnum, isOptional: true },\n ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n search: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n limit: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n defaultValue: 20,\n },\n offset: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n defaultValue: 0,\n },\n },\n});\n\n/**\n * Output for listing deals.\n */\nexport const ListDealsOutputModel = defineSchemaModel({\n name: 'ListDealsOutput',\n description: 'Output for listing deals',\n fields: {\n deals: { type: DealModel, isArray: true, isOptional: false },\n total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n totalValue: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },\n },\n});\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"deal.test-spec.js","names":[],"sources":["../../src/deal/deal.test-spec.ts"],"sourcesContent":["import { defineTestSpec } from '@contractspec/lib.contracts';\n\nexport const dealListTest = defineTestSpec({\n meta: {\n key: 'test.crm.deal.list',\n version: '1.0.0',\n owners: ['@example.crm-pipeline'],\n description: 'Test for listing deals',\n stability: 'stable',\n tags: ['test'],\n },\n target: {\n type: 'operation',\n operation: { key: 'crm.deal.list', version: '1.0.0' },\n },\n scenarios: [\n {\n key: 'success',\n when: { operation: { key: 'crm.deal.list' } },\n then: [{ type: 'expectOutput', match: {} }],\n },\n {\n key: 'error',\n when: { operation: { key: 'crm.deal.list' } },\n then: [{ type: 'expectError' }],\n },\n ],\n});\n\nexport const dealMoveTest = defineTestSpec({\n meta: {\n key: 'test.crm.deal.move',\n version: '1.0.0',\n owners: ['@example.crm-pipeline'],\n description: 'Test for moving deal',\n stability: 'stable',\n tags: ['test'],\n },\n target: {\n type: 'operation',\n operation: { key: 'crm.deal.move', version: '1.0.0' },\n },\n scenarios: [\n {\n key: 'success',\n when: { operation: { key: 'crm.deal.move' } },\n then: [{ type: 'expectOutput', match: {} }],\n },\n {\n key: 'error',\n when: { operation: { key: 'crm.deal.move' } },\n then: [{ type: 'expectError' }],\n },\n ],\n});\n"],"mappings":";;;AAEA,MAAa,eAAe,eAAe;CACzC,MAAM;EACJ,KAAK;EACL,SAAS;EACT,QAAQ,CAAC,wBAAwB;EACjC,aAAa;EACb,WAAW;EACX,MAAM,CAAC,OAAO;EACf;CACD,QAAQ;EACN,MAAM;EACN,WAAW;GAAE,KAAK;GAAiB,SAAS;GAAS;EACtD;CACD,WAAW,CACT;EACE,KAAK;EACL,MAAM,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE;EAC7C,MAAM,CAAC;GAAE,MAAM;GAAgB,OAAO,EAAE;GAAE,CAAC;EAC5C,EACD;EACE,KAAK;EACL,MAAM,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE;EAC7C,MAAM,CAAC,EAAE,MAAM,eAAe,CAAC;EAChC,CACF;CACF,CAAC;AAEF,MAAa,eAAe,eAAe;CACzC,MAAM;EACJ,KAAK;EACL,SAAS;EACT,QAAQ,CAAC,wBAAwB;EACjC,aAAa;EACb,WAAW;EACX,MAAM,CAAC,OAAO;EACf;CACD,QAAQ;EACN,MAAM;EACN,WAAW;GAAE,KAAK;GAAiB,SAAS;GAAS;EACtD;CACD,WAAW,CACT;EACE,KAAK;EACL,MAAM,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE;EAC7C,MAAM,CAAC;GAAE,MAAM;GAAgB,OAAO,EAAE;GAAE,CAAC;EAC5C,EACD;EACE,KAAK;EACL,MAAM,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE;EAC7C,MAAM,CAAC,EAAE,MAAM,eAAe,CAAC;EAChC,CACF;CACF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"crm-pipeline.docblock.js","names":[],"sources":["../../src/docs/crm-pipeline.docblock.ts"],"sourcesContent":["import type { DocBlock } from '@contractspec/lib.contracts/docs';\nimport { registerDocBlocks } from '@contractspec/lib.contracts/docs';\n\nconst crmPipelineDocBlocks: DocBlock[] = [\n {\n id: 'docs.examples.crm-pipeline.goal',\n title: 'CRM Pipeline โ€” Goal',\n summary:\n 'Deals, stages, contacts, companies, and tasks with auditable stage movement.',\n kind: 'goal',\n visibility: 'public',\n route: '/docs/examples/crm-pipeline/goal',\n tags: ['crm', 'goal'],\n body: `## Why it matters\n- Regenerable CRM flow for deals/stages without code drift.\n- Ensures stage movement, tasks, and contacts stay aligned across surfaces.\n\n## Business/Product goal\n- Give sales teams a governed pipeline with auditable moves and notifications.\n- Allow experimentation (feature flags) on stage definitions and task flows.\n\n## Success criteria\n- Stage/state changes emit events and remain declarative in spec.\n- PII (contacts) is scoped/redacted in presentations.`,\n },\n {\n id: 'docs.examples.crm-pipeline.usage',\n title: 'CRM Pipeline โ€” Usage',\n summary: 'How to seed, extend, and regenerate the CRM pipeline.',\n kind: 'usage',\n visibility: 'public',\n route: '/docs/examples/crm-pipeline/usage',\n tags: ['crm', 'usage'],\n body: `## Setup\n1) Seed (if available) or create pipeline stages, deals, contacts, companies, tasks.\n2) Configure Notifications for stage changes/tasks; set policy.pii for contact data.\n\n## Extend & regenerate\n1) Adjust stage schema/order, deal fields, task fields in the spec.\n2) Regenerate to sync UI/API/events; ensure kanban/action buttons update.\n3) Use Feature Flags to trial new stages or SLA rules.\n\n## Guardrails\n- Emit events for stage moves and task completions; log to Audit Trail.\n- Keep required fields enforced in contracts; avoid freeform state.\n- Redact contact PII in markdown/JSON outputs.\n\n## Adoption narrative\n\n### Before\n- A CRM app with hand-written data models and handler logic.\n- Pipeline stage rules live in code and drift across UI/API/events.\n- Regeneration is risky because specs and implementations are not aligned.\n\n### After\n- Contracts define deals, stages, and tasks as the source of truth.\n- Regeneration keeps UI/API/events in sync when stages change.\n- Compliance surfaces (audits, notifications) stay consistent with specs.\n\n### Minimal adoption steps\n1) Add ContractSpec CLI and core libraries.\n2) Define one operation (for example, deal/create).\n3) Run contractspec build to generate handlers and types.\n4) Wire the generated handler into your existing router.\n5) Expand to events and presentations as you add surface areas.\n`,\n },\n {\n id: 'docs.examples.crm-pipeline.reference',\n title: 'CRM Pipeline โ€” Reference',\n summary:\n 'Entities, contracts, events, and presentations for the CRM template.',\n kind: 'reference',\n visibility: 'public',\n route: '/docs/examples/crm-pipeline',\n tags: ['crm', 'reference'],\n body: `## Entities\n- Contact, Company, Deal, Pipeline, Stage, Task.\n\n## Contracts\n- deal/create, stage/move, contact/company CRUD, task create/complete.\n\n## Events\n- deal.created, stage.moved, task.completed, contact.updated.\n\n## Presentations\n- Pipelines/kanban, deal detail, contact/company profiles, task lists.\n\n## Notes\n- Stage definitions should be declarative; enforce via spec and regeneration.\n- Use Notifications for deal/task updates; Audit Trail for state changes.`,\n },\n {\n id: 'docs.examples.crm-pipeline.constraints',\n title: 'CRM Pipeline โ€” Constraints & Safety',\n summary:\n 'Internal guardrails for stages, PII, and regeneration semantics in the CRM template.',\n kind: 'reference',\n visibility: 'internal',\n route: '/docs/examples/crm-pipeline/constraints',\n tags: ['crm', 'constraints', 'internal'],\n body: `## Constraints\n- Stage definitions/order must remain declarative; no imperative overrides in code.\n- Events to emit: deal.created, stage.moved, task.completed, contact.updated (minimum).\n- Regeneration should not alter stage semantics without explicit spec change.\n\n## PII\n- Mark contact/company PII (emails, phones) for redaction in presentations.\n- Ensure MCP/web outputs avoid raw PII when not needed.\n\n## Verification\n- Add fixtures for stage move rules and SLA/task changes.\n- Ensure Audit/Notifications remain wired for stage and task events.\n- Use Feature Flags for experimental stages/SLAs; default safe/off.`,\n },\n];\n\nregisterDocBlocks(crmPipelineDocBlocks);\n"],"mappings":";;;AAqHA,kBAlHyC;CACvC;EACE,IAAI;EACJ,OAAO;EACP,SACE;EACF,MAAM;EACN,YAAY;EACZ,OAAO;EACP,MAAM,CAAC,OAAO,OAAO;EACrB,MAAM;;;;;;;;;;;EAWP;CACD;EACE,IAAI;EACJ,OAAO;EACP,SAAS;EACT,MAAM;EACN,YAAY;EACZ,OAAO;EACP,MAAM,CAAC,OAAO,QAAQ;EACtB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCP;CACD;EACE,IAAI;EACJ,OAAO;EACP,SACE;EACF,MAAM;EACN,YAAY;EACZ,OAAO;EACP,MAAM,CAAC,OAAO,YAAY;EAC1B,MAAM;;;;;;;;;;;;;;;EAeP;CACD;EACE,IAAI;EACJ,OAAO;EACP,SACE;EACF,MAAM;EACN,YAAY;EACZ,OAAO;EACP,MAAM;GAAC;GAAO;GAAe;GAAW;EACxC,MAAM;;;;;;;;;;;;;EAaP;CACF,CAEsC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"company.entity.js","names":[],"sources":["../../src/entities/company.entity.ts"],"sourcesContent":["import {\n defineEntity,\n defineEntityEnum,\n field,\n index,\n} from '@contractspec/lib.schema';\n\n/**\n * Company size enum.\n */\nexport const CompanySizeEnum = defineEntityEnum({\n name: 'CompanySize',\n values: ['STARTUP', 'SMALL', 'MEDIUM', 'LARGE', 'ENTERPRISE'] as const,\n schema: 'crm',\n description: 'Size category of a company.',\n});\n\n/**\n * Company entity - organization/account.\n */\nexport const CompanyEntity = defineEntity({\n name: 'Company',\n description: 'A company/organization in the CRM.',\n schema: 'crm',\n map: 'company',\n fields: {\n id: field.id({ description: 'Unique company ID' }),\n\n // Basic info\n name: field.string({ description: 'Company name' }),\n domain: field.string({ isOptional: true, description: 'Website domain' }),\n website: field.url({ isOptional: true }),\n\n // Industry\n industry: field.string({ isOptional: true }),\n\n // Size\n size: field.enum('CompanySize', { isOptional: true }),\n employeeCount: field.int({ isOptional: true }),\n annualRevenue: field.decimal({ isOptional: true }),\n\n // Ownership\n organizationId: field.foreignKey(),\n ownerId: field.foreignKey({ description: 'Account owner' }),\n\n // Contact info\n phone: field.string({ isOptional: true }),\n email: field.email({ isOptional: true }),\n\n // Address\n address: field.string({ isOptional: true }),\n city: field.string({ isOptional: true }),\n state: field.string({ isOptional: true }),\n country: field.string({ isOptional: true }),\n postalCode: field.string({ isOptional: true }),\n\n // Social\n linkedInUrl: field.url({ isOptional: true }),\n\n // Notes\n description: field.string({ isOptional: true }),\n tags: field.string({ isArray: true }),\n\n // Custom fields\n customFields: field.json({ isOptional: true }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n contacts: field.hasMany('Contact'),\n deals: field.hasMany('Deal'),\n },\n indexes: [index.on(['organizationId', 'ownerId']), index.on(['domain'])],\n enums: [CompanySizeEnum],\n});\n"],"mappings":";;;;;;AAUA,MAAa,kBAAkB,iBAAiB;CAC9C,MAAM;CACN,QAAQ;EAAC;EAAW;EAAS;EAAU;EAAS;EAAa;CAC7D,QAAQ;CACR,aAAa;CACd,CAAC;;;;AAKF,MAAa,gBAAgB,aAAa;CACxC,MAAM;CACN,aAAa;CACb,QAAQ;CACR,KAAK;CACL,QAAQ;EACN,IAAI,MAAM,GAAG,EAAE,aAAa,qBAAqB,CAAC;EAGlD,MAAM,MAAM,OAAO,EAAE,aAAa,gBAAgB,CAAC;EACnD,QAAQ,MAAM,OAAO;GAAE,YAAY;GAAM,aAAa;GAAkB,CAAC;EACzE,SAAS,MAAM,IAAI,EAAE,YAAY,MAAM,CAAC;EAGxC,UAAU,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAG5C,MAAM,MAAM,KAAK,eAAe,EAAE,YAAY,MAAM,CAAC;EACrD,eAAe,MAAM,IAAI,EAAE,YAAY,MAAM,CAAC;EAC9C,eAAe,MAAM,QAAQ,EAAE,YAAY,MAAM,CAAC;EAGlD,gBAAgB,MAAM,YAAY;EAClC,SAAS,MAAM,WAAW,EAAE,aAAa,iBAAiB,CAAC;EAG3D,OAAO,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EACzC,OAAO,MAAM,MAAM,EAAE,YAAY,MAAM,CAAC;EAGxC,SAAS,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAC3C,MAAM,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EACxC,OAAO,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EACzC,SAAS,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAC3C,YAAY,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAG9C,aAAa,MAAM,IAAI,EAAE,YAAY,MAAM,CAAC;EAG5C,aAAa,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAC/C,MAAM,MAAM,OAAO,EAAE,SAAS,MAAM,CAAC;EAGrC,cAAc,MAAM,KAAK,EAAE,YAAY,MAAM,CAAC;EAG9C,WAAW,MAAM,WAAW;EAC5B,WAAW,MAAM,WAAW;EAG5B,UAAU,MAAM,QAAQ,UAAU;EAClC,OAAO,MAAM,QAAQ,OAAO;EAC7B;CACD,SAAS,CAAC,MAAM,GAAG,CAAC,kBAAkB,UAAU,CAAC,EAAE,MAAM,GAAG,CAAC,SAAS,CAAC,CAAC;CACxE,OAAO,CAAC,gBAAgB;CACzB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"contact.entity.js","names":[],"sources":["../../src/entities/contact.entity.ts"],"sourcesContent":["import {\n defineEntity,\n defineEntityEnum,\n field,\n index,\n} from '@contractspec/lib.schema';\n\n/**\n * Contact status enum.\n */\nexport const ContactStatusEnum = defineEntityEnum({\n name: 'ContactStatus',\n values: ['LEAD', 'PROSPECT', 'CUSTOMER', 'CHURNED', 'ARCHIVED'] as const,\n schema: 'crm',\n description: 'Status of a contact in the sales funnel.',\n});\n\n/**\n * Contact entity - individual person.\n */\nexport const ContactEntity = defineEntity({\n name: 'Contact',\n description: 'An individual person in the CRM.',\n schema: 'crm',\n map: 'contact',\n fields: {\n id: field.id({ description: 'Unique contact ID' }),\n\n // Basic info\n firstName: field.string({ description: 'First name' }),\n lastName: field.string({ description: 'Last name' }),\n email: field.email({ isOptional: true, isUnique: true }),\n phone: field.string({ isOptional: true }),\n\n // Company\n companyId: field.string({\n isOptional: true,\n description: 'Associated company',\n }),\n jobTitle: field.string({ isOptional: true }),\n\n // Status\n status: field.enum('ContactStatus', { default: 'LEAD' }),\n\n // Ownership\n organizationId: field.foreignKey(),\n ownerId: field.foreignKey({\n description: 'Sales rep who owns this contact',\n }),\n\n // Source\n source: field.string({ isOptional: true, description: 'Lead source' }),\n\n // Social\n linkedInUrl: field.url({ isOptional: true }),\n twitterHandle: field.string({ isOptional: true }),\n\n // Address\n address: field.string({ isOptional: true }),\n city: field.string({ isOptional: true }),\n state: field.string({ isOptional: true }),\n country: field.string({ isOptional: true }),\n postalCode: field.string({ isOptional: true }),\n\n // Notes\n notes: field.string({ isOptional: true }),\n tags: field.string({ isArray: true }),\n\n // Custom fields\n customFields: field.json({ isOptional: true }),\n\n // Engagement\n lastContactedAt: field.dateTime({ isOptional: true }),\n nextFollowUpAt: field.dateTime({ isOptional: true }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n company: field.belongsTo('Company', ['companyId'], ['id']),\n deals: field.hasMany('Deal'),\n tasks: field.hasMany('Task'),\n activities: field.hasMany('Activity'),\n },\n indexes: [\n index.on(['organizationId', 'status']),\n index.on(['organizationId', 'ownerId']),\n index.on(['organizationId', 'companyId']),\n index.on(['email']),\n ],\n enums: [ContactStatusEnum],\n});\n"],"mappings":";;;;;;AAUA,MAAa,oBAAoB,iBAAiB;CAChD,MAAM;CACN,QAAQ;EAAC;EAAQ;EAAY;EAAY;EAAW;EAAW;CAC/D,QAAQ;CACR,aAAa;CACd,CAAC;;;;AAKF,MAAa,gBAAgB,aAAa;CACxC,MAAM;CACN,aAAa;CACb,QAAQ;CACR,KAAK;CACL,QAAQ;EACN,IAAI,MAAM,GAAG,EAAE,aAAa,qBAAqB,CAAC;EAGlD,WAAW,MAAM,OAAO,EAAE,aAAa,cAAc,CAAC;EACtD,UAAU,MAAM,OAAO,EAAE,aAAa,aAAa,CAAC;EACpD,OAAO,MAAM,MAAM;GAAE,YAAY;GAAM,UAAU;GAAM,CAAC;EACxD,OAAO,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAGzC,WAAW,MAAM,OAAO;GACtB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,UAAU,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAG5C,QAAQ,MAAM,KAAK,iBAAiB,EAAE,SAAS,QAAQ,CAAC;EAGxD,gBAAgB,MAAM,YAAY;EAClC,SAAS,MAAM,WAAW,EACxB,aAAa,mCACd,CAAC;EAGF,QAAQ,MAAM,OAAO;GAAE,YAAY;GAAM,aAAa;GAAe,CAAC;EAGtE,aAAa,MAAM,IAAI,EAAE,YAAY,MAAM,CAAC;EAC5C,eAAe,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAGjD,SAAS,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAC3C,MAAM,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EACxC,OAAO,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EACzC,SAAS,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAC3C,YAAY,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAG9C,OAAO,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EACzC,MAAM,MAAM,OAAO,EAAE,SAAS,MAAM,CAAC;EAGrC,cAAc,MAAM,KAAK,EAAE,YAAY,MAAM,CAAC;EAG9C,iBAAiB,MAAM,SAAS,EAAE,YAAY,MAAM,CAAC;EACrD,gBAAgB,MAAM,SAAS,EAAE,YAAY,MAAM,CAAC;EAGpD,WAAW,MAAM,WAAW;EAC5B,WAAW,MAAM,WAAW;EAG5B,SAAS,MAAM,UAAU,WAAW,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC;EAC1D,OAAO,MAAM,QAAQ,OAAO;EAC5B,OAAO,MAAM,QAAQ,OAAO;EAC5B,YAAY,MAAM,QAAQ,WAAW;EACtC;CACD,SAAS;EACP,MAAM,GAAG,CAAC,kBAAkB,SAAS,CAAC;EACtC,MAAM,GAAG,CAAC,kBAAkB,UAAU,CAAC;EACvC,MAAM,GAAG,CAAC,kBAAkB,YAAY,CAAC;EACzC,MAAM,GAAG,CAAC,QAAQ,CAAC;EACpB;CACD,OAAO,CAAC,kBAAkB;CAC3B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"deal.entity.js","names":[],"sources":["../../src/entities/deal.entity.ts"],"sourcesContent":["import {\n defineEntity,\n defineEntityEnum,\n field,\n index,\n} from '@contractspec/lib.schema';\n\n/**\n * Deal status enum.\n */\nexport const DealStatusEnum = defineEntityEnum({\n name: 'DealStatus',\n values: ['OPEN', 'WON', 'LOST', 'STALE'] as const,\n schema: 'crm',\n description: 'Status of a deal.',\n});\n\n/**\n * Pipeline entity - sales pipeline definition.\n */\nexport const PipelineEntity = defineEntity({\n name: 'Pipeline',\n description: 'A sales pipeline with stages.',\n schema: 'crm',\n map: 'pipeline',\n fields: {\n id: field.id(),\n name: field.string({ description: 'Pipeline name' }),\n description: field.string({ isOptional: true }),\n\n // Ownership\n organizationId: field.foreignKey(),\n\n // Settings\n isDefault: field.boolean({ default: false }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n stages: field.hasMany('Stage'),\n deals: field.hasMany('Deal'),\n },\n});\n\n/**\n * Stage entity - pipeline stage.\n */\nexport const StageEntity = defineEntity({\n name: 'Stage',\n description: 'A stage within a sales pipeline.',\n schema: 'crm',\n map: 'stage',\n fields: {\n id: field.id(),\n name: field.string({ description: 'Stage name' }),\n pipelineId: field.foreignKey(),\n\n // Position\n position: field.int({ description: 'Order in pipeline' }),\n\n // Probability\n probability: field.int({\n default: 0,\n description: 'Win probability (0-100)',\n }),\n\n // Type\n isWonStage: field.boolean({ default: false }),\n isLostStage: field.boolean({ default: false }),\n\n // Settings\n color: field.string({\n isOptional: true,\n description: 'Stage color for UI',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n pipeline: field.belongsTo('Pipeline', ['pipelineId'], ['id'], {\n onDelete: 'Cascade',\n }),\n deals: field.hasMany('Deal'),\n },\n indexes: [index.on(['pipelineId', 'position'])],\n});\n\n/**\n * Deal entity - sales opportunity.\n */\nexport const DealEntity = defineEntity({\n name: 'Deal',\n description: 'A sales opportunity/deal.',\n schema: 'crm',\n map: 'deal',\n fields: {\n id: field.id({ description: 'Unique deal ID' }),\n name: field.string({ description: 'Deal name' }),\n\n // Value\n value: field.decimal({ description: 'Deal value' }),\n currency: field.string({ default: '\"USD\"' }),\n\n // Pipeline\n pipelineId: field.foreignKey(),\n stageId: field.foreignKey(),\n\n // Status\n status: field.enum('DealStatus', { default: 'OPEN' }),\n\n // Associations\n contactId: field.string({ isOptional: true }),\n companyId: field.string({ isOptional: true }),\n\n // Ownership\n organizationId: field.foreignKey(),\n ownerId: field.foreignKey({ description: 'Deal owner' }),\n\n // Timeline\n expectedCloseDate: field.dateTime({ isOptional: true }),\n closedAt: field.dateTime({ isOptional: true }),\n\n // Tracking\n lostReason: field.string({ isOptional: true }),\n wonSource: field.string({ isOptional: true }),\n\n // Notes\n notes: field.string({ isOptional: true }),\n tags: field.string({ isArray: true }),\n\n // Custom fields\n customFields: field.json({ isOptional: true }),\n\n // Position in stage (for Kanban)\n stagePosition: field.int({ default: 0 }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n pipeline: field.belongsTo('Pipeline', ['pipelineId'], ['id']),\n stage: field.belongsTo('Stage', ['stageId'], ['id']),\n contact: field.belongsTo('Contact', ['contactId'], ['id']),\n company: field.belongsTo('Company', ['companyId'], ['id']),\n tasks: field.hasMany('Task'),\n activities: field.hasMany('Activity'),\n },\n indexes: [\n index.on(['organizationId', 'status']),\n index.on(['pipelineId', 'stageId', 'stagePosition']),\n index.on(['ownerId', 'status']),\n index.on(['expectedCloseDate']),\n ],\n enums: [DealStatusEnum],\n});\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/entities/index.ts"],"sourcesContent":["export * from './company.entity';\nexport * from './contact.entity';\nexport * from './deal.entity';\nexport * from './task.entity';\n\nimport type { ModuleSchemaContribution } from '@contractspec/lib.schema';\nimport { CompanyEntity, CompanySizeEnum } from './company.entity';\nimport { ContactEntity, ContactStatusEnum } from './contact.entity';\nimport {\n DealEntity,\n PipelineEntity,\n StageEntity,\n DealStatusEnum,\n} from './deal.entity';\nimport {\n TaskEntity,\n ActivityEntity,\n TaskTypeEnum,\n TaskPriorityEnum,\n TaskStatusEnum,\n} from './task.entity';\n\n/**\n * CRM Pipeline schema contribution.\n */\nexport const crmPipelineSchemaContribution: ModuleSchemaContribution = {\n moduleId: '@contractspec/example.crm-pipeline',\n entities: [\n CompanyEntity,\n ContactEntity,\n DealEntity,\n PipelineEntity,\n StageEntity,\n TaskEntity,\n ActivityEntity,\n ],\n enums: [\n CompanySizeEnum,\n ContactStatusEnum,\n DealStatusEnum,\n TaskTypeEnum,\n TaskPriorityEnum,\n TaskStatusEnum,\n ],\n};\n"],"mappings":";;;;;;;;;AAyBA,MAAa,gCAA0D;CACrE,UAAU;CACV,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACD;CACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"task.entity.js","names":[],"sources":["../../src/entities/task.entity.ts"],"sourcesContent":["import {\n defineEntity,\n defineEntityEnum,\n field,\n index,\n} from '@contractspec/lib.schema';\n\n/**\n * Task type enum.\n */\nexport const TaskTypeEnum = defineEntityEnum({\n name: 'TaskType',\n values: ['CALL', 'EMAIL', 'MEETING', 'TODO', 'FOLLOW_UP', 'OTHER'] as const,\n schema: 'crm',\n description: 'Type of CRM task.',\n});\n\n/**\n * Task priority enum.\n */\nexport const TaskPriorityEnum = defineEntityEnum({\n name: 'TaskPriority',\n values: ['LOW', 'NORMAL', 'HIGH', 'URGENT'] as const,\n schema: 'crm',\n description: 'Priority of a task.',\n});\n\n/**\n * Task status enum.\n */\nexport const TaskStatusEnum = defineEntityEnum({\n name: 'TaskStatus',\n values: ['PENDING', 'IN_PROGRESS', 'COMPLETED', 'CANCELLED'] as const,\n schema: 'crm',\n description: 'Status of a task.',\n});\n\n/**\n * Task entity - follow-up activities.\n */\nexport const TaskEntity = defineEntity({\n name: 'Task',\n description: 'A task or follow-up activity.',\n schema: 'crm',\n map: 'task',\n fields: {\n id: field.id(),\n title: field.string({ description: 'Task title' }),\n description: field.string({ isOptional: true }),\n\n // Type and priority\n type: field.enum('TaskType', { default: 'TODO' }),\n priority: field.enum('TaskPriority', { default: 'NORMAL' }),\n status: field.enum('TaskStatus', { default: 'PENDING' }),\n\n // Schedule\n dueDate: field.dateTime({ isOptional: true }),\n reminderAt: field.dateTime({ isOptional: true }),\n\n // Associations (polymorphic)\n contactId: field.string({ isOptional: true }),\n dealId: field.string({ isOptional: true }),\n companyId: field.string({ isOptional: true }),\n\n // Ownership\n organizationId: field.foreignKey(),\n assignedTo: field.foreignKey({ description: 'User assigned to this task' }),\n createdBy: field.foreignKey(),\n\n // Completion\n completedAt: field.dateTime({ isOptional: true }),\n completedBy: field.string({ isOptional: true }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n contact: field.belongsTo('Contact', ['contactId'], ['id']),\n deal: field.belongsTo('Deal', ['dealId'], ['id']),\n company: field.belongsTo('Company', ['companyId'], ['id']),\n },\n indexes: [\n index.on(['organizationId', 'assignedTo', 'status']),\n index.on(['dueDate', 'status']),\n index.on(['contactId']),\n index.on(['dealId']),\n ],\n enums: [TaskTypeEnum, TaskPriorityEnum, TaskStatusEnum],\n});\n\n/**\n * Activity entity - interaction history.\n */\nexport const ActivityEntity = defineEntity({\n name: 'Activity',\n description: 'An activity/interaction logged in the CRM.',\n schema: 'crm',\n map: 'activity',\n fields: {\n id: field.id(),\n type: field.enum('TaskType'),\n subject: field.string(),\n description: field.string({ isOptional: true }),\n\n // Associations\n contactId: field.string({ isOptional: true }),\n dealId: field.string({ isOptional: true }),\n companyId: field.string({ isOptional: true }),\n\n // Ownership\n organizationId: field.foreignKey(),\n performedBy: field.foreignKey(),\n\n // Outcome\n outcome: field.string({ isOptional: true }),\n\n // Timing\n occurredAt: field.dateTime(),\n duration: field.int({\n isOptional: true,\n description: 'Duration in minutes',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n\n // Relations\n contact: field.belongsTo('Contact', ['contactId'], ['id']),\n deal: field.belongsTo('Deal', ['dealId'], ['id']),\n company: field.belongsTo('Company', ['companyId'], ['id']),\n },\n indexes: [\n index.on(['contactId', 'occurredAt']),\n index.on(['dealId', 'occurredAt']),\n ],\n});\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"contact.event.js","names":[],"sources":["../../src/events/contact.event.ts"],"sourcesContent":["import { ScalarTypeEnum, defineSchemaModel } from '@contractspec/lib.schema';\nimport { defineEvent } from '@contractspec/lib.contracts';\n\n// ============ Contact Event Payloads ============\n\nconst ContactCreatedPayload = defineSchemaModel({\n name: 'ContactCreatedPayload',\n description: 'Payload when a contact is created',\n fields: {\n contactId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n email: { type: ScalarTypeEnum.EmailAddress(), isOptional: true },\n organizationId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nexport const ContactCreatedEvent = defineEvent({\n meta: {\n key: 'contact.created',\n version: '1.0.0',\n description: 'A new contact has been created.',\n stability: 'stable',\n owners: ['@crm-team'],\n tags: ['contact', 'created'],\n },\n payload: ContactCreatedPayload,\n});\n"],"mappings":";;;;AAKA,MAAM,wBAAwB,kBAAkB;CAC9C,MAAM;CACN,aAAa;CACb,QAAQ;EACN,WAAW;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACxE,OAAO;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAM;EAChE,gBAAgB;GACd,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACtE,WAAW;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAO;EAClE;CACF,CAAC;AAEF,MAAa,sBAAsB,YAAY;CAC7C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,aAAa;EACb,WAAW;EACX,QAAQ,CAAC,YAAY;EACrB,MAAM,CAAC,WAAW,UAAU;EAC7B;CACD,SAAS;CACV,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"deal.event.js","names":[],"sources":["../../src/events/deal.event.ts"],"sourcesContent":["import { ScalarTypeEnum, defineSchemaModel } from '@contractspec/lib.schema';\nimport { defineEvent } from '@contractspec/lib.contracts';\n\n// ============ Deal Event Payloads ============\n\nconst DealCreatedPayload = defineSchemaModel({\n name: 'DealCreatedPayload',\n description: 'Payload when a deal is created',\n fields: {\n dealId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n value: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },\n pipelineId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n stageId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nconst DealMovedPayload = defineSchemaModel({\n name: 'DealMovedEventPayload',\n description: 'Payload when a deal is moved to another stage',\n fields: {\n dealId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n fromStageId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n toStageId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n movedBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n movedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nconst DealWonPayload = defineSchemaModel({\n name: 'DealWonEventPayload',\n description: 'Payload when a deal is won',\n fields: {\n dealId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n value: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },\n currency: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n contactId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n companyId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n wonAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nconst DealLostPayload = defineSchemaModel({\n name: 'DealLostEventPayload',\n description: 'Payload when a deal is lost',\n fields: {\n dealId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n value: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },\n reason: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n lostAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nexport const DealCreatedEvent = defineEvent({\n meta: {\n key: 'deal.created',\n version: '1.0.0',\n description: 'A new deal has been created.',\n stability: 'stable',\n owners: ['@crm-team'],\n tags: ['deal', 'created'],\n },\n payload: DealCreatedPayload,\n});\n\nexport const DealMovedEvent = defineEvent({\n meta: {\n key: 'deal.moved',\n version: '1.0.0',\n description: 'A deal has been moved to a different stage.',\n stability: 'stable',\n owners: ['@crm-team'],\n tags: ['deal', 'moved'],\n },\n payload: DealMovedPayload,\n});\n\nexport const DealWonEvent = defineEvent({\n meta: {\n key: 'deal.won',\n version: '1.0.0',\n description: 'A deal has been won.',\n stability: 'stable',\n owners: ['@crm-team'],\n tags: ['deal', 'won'],\n },\n payload: DealWonPayload,\n});\n\nexport const DealLostEvent = defineEvent({\n meta: {\n key: 'deal.lost',\n version: '1.0.0',\n description: 'A deal has been lost.',\n stability: 'stable',\n owners: ['@crm-team'],\n tags: ['deal', 'lost'],\n },\n payload: DealLostPayload,\n});\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"task.event.js","names":[],"sources":["../../src/events/task.event.ts"],"sourcesContent":["import { ScalarTypeEnum, defineSchemaModel } from '@contractspec/lib.schema';\nimport { defineEvent } from '@contractspec/lib.contracts';\n\n// ============ Task Event Payloads ============\n\nconst TaskCompletedPayload = defineSchemaModel({\n name: 'TaskCompletedPayload',\n description: 'Payload when a task is completed',\n fields: {\n taskId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n type: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n assignedTo: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n completedBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n completedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nexport const TaskCompletedEvent = defineEvent({\n meta: {\n key: 'task.completed',\n version: '1.0.0',\n description: 'A task has been completed.',\n stability: 'stable',\n owners: ['@crm-team'],\n tags: ['task', 'lifecycle'],\n },\n payload: TaskCompletedPayload,\n});\n"],"mappings":";;;;AAKA,MAAM,uBAAuB,kBAAkB;CAC7C,MAAM;CACN,aAAa;CACb,QAAQ;EACN,QAAQ;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACrE,MAAM;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACnE,YAAY;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACzE,aAAa;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EAC1E,aAAa;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAO;EACpE;CACF,CAAC;AAEF,MAAa,qBAAqB,YAAY;CAC5C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,aAAa;EACb,WAAW;EACX,QAAQ,CAAC,YAAY;EACrB,MAAM,CAAC,QAAQ,YAAY;EAC5B;CACD,SAAS;CACV,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"example.js","names":[],"sources":["../src/example.ts"],"sourcesContent":["import { defineExample } from '@contractspec/lib.contracts';\n\nconst example = defineExample({\n meta: {\n key: 'crm-pipeline',\n version: '1.0.0',\n title: 'CRM Pipeline',\n description:\n 'Sales CRM with contacts, companies, deals, pipelines, and tasks.',\n kind: 'template',\n visibility: 'public',\n stability: 'experimental',\n owners: ['@platform.core'],\n tags: ['crm', 'sales', 'pipeline', 'deals'],\n },\n docs: {\n rootDocId: 'docs.examples.crm-pipeline',\n },\n entrypoints: {\n packageName: '@contractspec/example.crm-pipeline',\n feature: './feature',\n contracts: './contracts',\n presentations: './presentations',\n handlers: './handlers',\n docs: './docs',\n },\n surfaces: {\n templates: true,\n sandbox: {\n enabled: true,\n modes: ['playground', 'specs', 'builder', 'markdown', 'evolution'],\n },\n studio: { enabled: true, installable: true },\n mcp: { enabled: true },\n },\n});\n\nexport default example;\n"],"mappings":";;;AAEA,MAAM,UAAU,cAAc;CAC5B,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,QAAQ,CAAC,iBAAiB;EAC1B,MAAM;GAAC;GAAO;GAAS;GAAY;GAAQ;EAC5C;CACD,MAAM,EACJ,WAAW,8BACZ;CACD,aAAa;EACX,aAAa;EACb,SAAS;EACT,WAAW;EACX,eAAe;EACf,UAAU;EACV,MAAM;EACP;CACD,UAAU;EACR,WAAW;EACX,SAAS;GACP,SAAS;GACT,OAAO;IAAC;IAAc;IAAS;IAAW;IAAY;IAAY;GACnE;EACD,QAAQ;GAAE,SAAS;GAAM,aAAa;GAAM;EAC5C,KAAK,EAAE,SAAS,MAAM;EACvB;CACF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"crm.handlers.js","names":[],"sources":["../../src/handlers/crm.handlers.ts"],"sourcesContent":["/**\n * Runtime-local CRM handlers\n *\n * These handlers work with the in-browser SQLite database\n * instead of in-memory mock arrays.\n */\nimport type { DatabasePort, DbRow } from '@contractspec/lib.runtime-sandbox';\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport { web } from '@contractspec/lib.runtime-sandbox';\nconst { generateId } = web;\n\n// ============ Types ============\n\nexport interface Deal {\n id: string;\n projectId: string;\n name: string;\n value: number;\n currency: string;\n pipelineId: string;\n stageId: string;\n status: 'OPEN' | 'WON' | 'LOST' | 'STALE';\n contactId?: string;\n companyId?: string;\n ownerId: string;\n expectedCloseDate?: Date;\n wonSource?: string;\n lostReason?: string;\n notes?: string;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface Stage {\n id: string;\n pipelineId: string;\n name: string;\n position: number;\n}\n\nexport interface CreateDealInput {\n name: string;\n value: number;\n currency?: string;\n pipelineId: string;\n stageId: string;\n contactId?: string;\n companyId?: string;\n expectedCloseDate?: Date;\n}\n\nexport interface MoveDealInput {\n dealId: string;\n stageId: string;\n}\n\nexport interface WinDealInput {\n dealId: string;\n wonSource?: string;\n notes?: string;\n}\n\nexport interface LoseDealInput {\n dealId: string;\n lostReason: string;\n notes?: string;\n}\n\nexport interface ListDealsInput {\n projectId: string;\n pipelineId?: string;\n stageId?: string;\n status?: 'OPEN' | 'WON' | 'LOST' | 'all';\n ownerId?: string;\n search?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface ListDealsOutput {\n deals: Deal[];\n total: number;\n totalValue: number;\n}\n\n// ============ Row Type ============\n\n// Note: We don't use DbRow generics here - just cast the results\n// to the expected types since we know the schema\n\ninterface DealRow {\n id: string;\n projectId: string;\n name: string;\n value: number;\n currency: string;\n pipelineId: string;\n stageId: string;\n status: string;\n contactId: string | null;\n companyId: string | null;\n ownerId: string;\n expectedCloseDate: string | null;\n wonSource: string | null;\n lostReason: string | null;\n notes: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface StageRow {\n id: string;\n pipelineId: string;\n name: string;\n position: number;\n}\n\nfunction rowToDeal(row: DealRow): Deal {\n return {\n id: row.id,\n projectId: row.projectId,\n name: row.name,\n value: row.value,\n currency: row.currency,\n pipelineId: row.pipelineId,\n stageId: row.stageId,\n status: row.status as Deal['status'],\n contactId: row.contactId ?? undefined,\n companyId: row.companyId ?? undefined,\n ownerId: row.ownerId,\n expectedCloseDate: row.expectedCloseDate\n ? new Date(row.expectedCloseDate)\n : undefined,\n wonSource: row.wonSource ?? undefined,\n lostReason: row.lostReason ?? undefined,\n notes: row.notes ?? undefined,\n createdAt: new Date(row.createdAt),\n updatedAt: new Date(row.updatedAt),\n };\n}\n\n// ============ Handler Factory ============\n\nexport function createCrmHandlers(db: DatabasePort) {\n /**\n * List deals with filtering\n */\n async function listDeals(input: ListDealsInput): Promise<ListDealsOutput> {\n const {\n projectId,\n pipelineId,\n stageId,\n status,\n ownerId,\n search,\n limit = 20,\n offset = 0,\n } = input;\n\n let whereClause = 'WHERE projectId = ?';\n const params: (string | number)[] = [projectId];\n\n if (pipelineId) {\n whereClause += ' AND pipelineId = ?';\n params.push(pipelineId);\n }\n\n if (stageId) {\n whereClause += ' AND stageId = ?';\n params.push(stageId);\n }\n\n if (status && status !== 'all') {\n whereClause += ' AND status = ?';\n params.push(status);\n }\n\n if (ownerId) {\n whereClause += ' AND ownerId = ?';\n params.push(ownerId);\n }\n\n if (search) {\n whereClause += ' AND name LIKE ?';\n params.push(`%${search}%`);\n }\n\n // Get total count\n const countResult = (\n await db.query(\n `SELECT COUNT(*) as count FROM crm_deal ${whereClause}`,\n params\n )\n ).rows as DbRow[];\n const total = (countResult[0]?.count as number) ?? 0;\n\n // Get total value\n const valueResult = (\n await db.query(\n `SELECT COALESCE(SUM(value), 0) as total FROM crm_deal ${whereClause}`,\n params\n )\n ).rows as DbRow[];\n const totalValue = (valueResult[0]?.total as number) ?? 0;\n\n // Get paginated deals\n const dealRows = (\n await db.query(\n `SELECT * FROM crm_deal ${whereClause} ORDER BY value DESC LIMIT ? OFFSET ?`,\n [...params, limit, offset]\n )\n ).rows as unknown as DealRow[];\n\n return {\n deals: dealRows.map(rowToDeal),\n total,\n totalValue,\n };\n }\n\n /**\n * Create a new deal\n */\n async function createDeal(\n input: CreateDealInput,\n context: { projectId: string; ownerId: string }\n ): Promise<Deal> {\n const id = generateId('deal');\n const now = new Date().toISOString();\n\n await db.execute(\n `INSERT INTO crm_deal (id, projectId, pipelineId, stageId, name, value, currency, status, contactId, companyId, ownerId, expectedCloseDate, createdAt, updatedAt)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n id,\n context.projectId,\n input.pipelineId,\n input.stageId,\n input.name,\n input.value,\n input.currency ?? 'USD',\n 'OPEN',\n input.contactId ?? null,\n input.companyId ?? null,\n context.ownerId,\n input.expectedCloseDate?.toISOString() ?? null,\n now,\n now,\n ]\n );\n\n const rows = (await db.query(`SELECT * FROM crm_deal WHERE id = ?`, [id]))\n .rows as unknown as DealRow[];\n\n if (!rows[0]) {\n throw new Error('Failed to create deal');\n }\n\n return rowToDeal(rows[0]);\n }\n\n /**\n * Move a deal to a different stage\n */\n async function moveDeal(input: MoveDealInput): Promise<Deal> {\n const now = new Date().toISOString();\n\n // Verify deal exists\n const existing = (\n await db.query(`SELECT * FROM crm_deal WHERE id = ?`, [input.dealId])\n ).rows as unknown as DealRow[];\n\n if (!existing[0]) {\n throw new Error('NOT_FOUND');\n }\n\n // Verify stage exists\n const stage = (\n await db.query(`SELECT * FROM crm_stage WHERE id = ?`, [input.stageId])\n ).rows as unknown as StageRow[];\n\n if (!stage[0]) {\n throw new Error('INVALID_STAGE');\n }\n\n await db.execute(\n `UPDATE crm_deal SET stageId = ?, updatedAt = ? WHERE id = ?`,\n [input.stageId, now, input.dealId]\n );\n\n const rows = (\n await db.query(`SELECT * FROM crm_deal WHERE id = ?`, [input.dealId])\n ).rows as unknown as DealRow[];\n\n return rowToDeal(rows[0]!);\n }\n\n /**\n * Mark a deal as won\n */\n async function winDeal(input: WinDealInput): Promise<Deal> {\n const now = new Date().toISOString();\n\n // Verify deal exists\n const existing = (\n await db.query(`SELECT * FROM crm_deal WHERE id = ?`, [input.dealId])\n ).rows as unknown as DealRow[];\n\n if (!existing[0]) {\n throw new Error('NOT_FOUND');\n }\n\n await db.execute(\n `UPDATE crm_deal SET status = 'WON', wonSource = ?, notes = ?, updatedAt = ? WHERE id = ?`,\n [input.wonSource ?? null, input.notes ?? null, now, input.dealId]\n );\n\n const rows = (\n await db.query(`SELECT * FROM crm_deal WHERE id = ?`, [input.dealId])\n ).rows as unknown as DealRow[];\n\n return rowToDeal(rows[0]!);\n }\n\n /**\n * Mark a deal as lost\n */\n async function loseDeal(input: LoseDealInput): Promise<Deal> {\n const now = new Date().toISOString();\n\n // Verify deal exists\n const existing = (\n await db.query(`SELECT * FROM crm_deal WHERE id = ?`, [input.dealId])\n ).rows as unknown as DealRow[];\n\n if (!existing[0]) {\n throw new Error('NOT_FOUND');\n }\n\n await db.execute(\n `UPDATE crm_deal SET status = 'LOST', lostReason = ?, notes = ?, updatedAt = ? WHERE id = ?`,\n [input.lostReason, input.notes ?? null, now, input.dealId]\n );\n\n const rows = (\n await db.query(`SELECT * FROM crm_deal WHERE id = ?`, [input.dealId])\n ).rows as unknown as DealRow[];\n\n return rowToDeal(rows[0]!);\n }\n\n /**\n * Get deals grouped by stage\n */\n async function getDealsByStage(input: {\n projectId: string;\n pipelineId: string;\n }): Promise<Record<string, Deal[]>> {\n const deals = (\n await db.query(\n `SELECT * FROM crm_deal WHERE projectId = ? AND pipelineId = ? AND status = 'OPEN' ORDER BY value DESC`,\n [input.projectId, input.pipelineId]\n )\n ).rows as unknown as DealRow[];\n\n const stages = (\n await db.query(\n `SELECT * FROM crm_stage WHERE pipelineId = ? ORDER BY position`,\n [input.pipelineId]\n )\n ).rows as unknown as StageRow[];\n\n const grouped: Record<string, Deal[]> = {};\n for (const stage of stages) {\n grouped[stage.id] = deals\n .filter((d) => d.stageId === stage.id)\n .map(rowToDeal);\n }\n\n return grouped;\n }\n\n /**\n * Get pipeline stages\n */\n async function getPipelineStages(input: {\n pipelineId: string;\n }): Promise<Stage[]> {\n const rows = (\n await db.query(\n `SELECT * FROM crm_stage WHERE pipelineId = ? ORDER BY position`,\n [input.pipelineId]\n )\n ).rows as unknown as StageRow[];\n\n return rows.map((row) => ({\n id: row.id,\n pipelineId: row.pipelineId,\n name: row.name,\n position: row.position,\n }));\n }\n\n return {\n listDeals,\n createDeal,\n moveDeal,\n winDeal,\n loseDeal,\n getDealsByStage,\n getPipelineStages,\n };\n}\n\nexport type CrmHandlers = ReturnType<typeof createCrmHandlers>;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"deal.handlers.js","names":[],"sources":["../../src/handlers/deal.handlers.ts"],"sourcesContent":["/**\n * Mock handlers for Deal contracts\n */\nimport { MOCK_DEALS, MOCK_STAGES } from './mock-data';\n\n// Types inferred from contract schemas\nexport interface Deal {\n id: string;\n name: string;\n value: number;\n currency: string;\n pipelineId: string;\n stageId: string;\n status: 'OPEN' | 'WON' | 'LOST' | 'STALE';\n contactId?: string;\n companyId?: string;\n ownerId: string;\n expectedCloseDate?: Date;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateDealInput {\n name: string;\n value: number;\n currency?: string;\n pipelineId: string;\n stageId: string;\n contactId?: string;\n companyId?: string;\n expectedCloseDate?: Date;\n}\n\nexport interface MoveDealInput {\n dealId: string;\n stageId: string;\n position?: number;\n}\n\nexport interface WinDealInput {\n dealId: string;\n wonSource?: string;\n notes?: string;\n}\n\nexport interface LoseDealInput {\n dealId: string;\n lostReason: string;\n notes?: string;\n}\n\nexport interface ListDealsInput {\n pipelineId?: string;\n stageId?: string;\n status?: 'OPEN' | 'WON' | 'LOST' | 'all';\n ownerId?: string;\n search?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface ListDealsOutput {\n deals: Deal[];\n total: number;\n totalValue: number;\n}\n\n/**\n * Mock handler for ListDealsContract\n */\nexport async function mockListDealsHandler(\n input: ListDealsInput\n): Promise<ListDealsOutput> {\n const {\n pipelineId,\n stageId,\n status,\n ownerId,\n search,\n limit = 20,\n offset = 0,\n } = input;\n\n let filtered = [...MOCK_DEALS];\n\n if (pipelineId) {\n filtered = filtered.filter((d) => d.pipelineId === pipelineId);\n }\n\n if (stageId) {\n filtered = filtered.filter((d) => d.stageId === stageId);\n }\n\n if (status && status !== 'all') {\n filtered = filtered.filter((d) => d.status === status);\n }\n\n if (ownerId) {\n filtered = filtered.filter((d) => d.ownerId === ownerId);\n }\n\n if (search) {\n const q = search.toLowerCase();\n filtered = filtered.filter((d) => d.name.toLowerCase().includes(q));\n }\n\n // Sort by value descending\n filtered.sort((a, b) => b.value - a.value);\n\n const total = filtered.length;\n const totalValue = filtered.reduce((sum, d) => sum + d.value, 0);\n const deals = filtered.slice(offset, offset + limit);\n\n return {\n deals,\n total,\n totalValue,\n };\n}\n\n/**\n * Mock handler for CreateDealContract\n */\nexport async function mockCreateDealHandler(\n input: CreateDealInput,\n context: { ownerId: string }\n): Promise<Deal> {\n const now = new Date();\n\n const deal: Deal = {\n id: `deal-${Date.now()}`,\n name: input.name,\n value: input.value,\n currency: input.currency ?? 'USD',\n pipelineId: input.pipelineId,\n stageId: input.stageId,\n status: 'OPEN',\n contactId: input.contactId,\n companyId: input.companyId,\n ownerId: context.ownerId,\n expectedCloseDate: input.expectedCloseDate,\n createdAt: now,\n updatedAt: now,\n };\n\n MOCK_DEALS.push(deal);\n\n return deal;\n}\n\n/**\n * Mock handler for MoveDealContract\n */\nexport async function mockMoveDealHandler(input: MoveDealInput): Promise<Deal> {\n const dealIndex = MOCK_DEALS.findIndex((d) => d.id === input.dealId);\n if (dealIndex === -1) {\n throw new Error('NOT_FOUND');\n }\n const deal = MOCK_DEALS[dealIndex];\n if (!deal) {\n throw new Error('NOT_FOUND');\n }\n\n const stage = MOCK_STAGES.find((s) => s.id === input.stageId);\n if (!stage) {\n throw new Error('INVALID_STAGE');\n }\n\n const updatedDeal: Deal = {\n ...deal,\n stageId: input.stageId,\n updatedAt: new Date(),\n };\n\n MOCK_DEALS[dealIndex] = updatedDeal;\n\n return updatedDeal;\n}\n\n/**\n * Mock handler for WinDealContract\n */\nexport async function mockWinDealHandler(input: WinDealInput): Promise<Deal> {\n const dealIndex = MOCK_DEALS.findIndex((d) => d.id === input.dealId);\n if (dealIndex === -1) {\n throw new Error('NOT_FOUND');\n }\n const deal = MOCK_DEALS[dealIndex];\n if (!deal) {\n throw new Error('NOT_FOUND');\n }\n\n const updatedDeal: Deal = {\n ...deal,\n status: 'WON' as const,\n updatedAt: new Date(),\n };\n\n MOCK_DEALS[dealIndex] = updatedDeal;\n\n return updatedDeal;\n}\n\n/**\n * Mock handler for LoseDealContract\n */\nexport async function mockLoseDealHandler(input: LoseDealInput): Promise<Deal> {\n const dealIndex = MOCK_DEALS.findIndex((d) => d.id === input.dealId);\n if (dealIndex === -1) {\n throw new Error('NOT_FOUND');\n }\n const deal = MOCK_DEALS[dealIndex];\n if (!deal) {\n throw new Error('NOT_FOUND');\n }\n\n const updatedDeal: Deal = {\n ...deal,\n status: 'LOST' as const,\n updatedAt: new Date(),\n };\n\n MOCK_DEALS[dealIndex] = updatedDeal;\n\n return updatedDeal;\n}\n\n/**\n * Get deals grouped by stage for Kanban view\n */\nexport async function mockGetDealsByStageHandler(input: {\n pipelineId: string;\n}): Promise<Record<string, Deal[]>> {\n const deals = MOCK_DEALS.filter(\n (d) => d.pipelineId === input.pipelineId && d.status === 'OPEN'\n );\n\n const grouped: Record<string, Deal[]> = {};\n for (const stage of MOCK_STAGES) {\n grouped[stage.id] = deals.filter((d) => d.stageId === stage.id);\n }\n\n return grouped;\n}\n\n/**\n * Get pipeline stages\n */\nexport async function mockGetPipelineStagesHandler(input: {\n pipelineId: string;\n}) {\n return MOCK_STAGES.filter((s) => s.pipelineId === input.pipelineId);\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"mock-data.js","names":[],"sources":["../../src/handlers/mock-data.ts"],"sourcesContent":["/**\n * Mock data for crm-pipeline handlers\n */\n\n// ============ Types for Mock Data ============\n\nexport interface MockDeal {\n id: string;\n name: string;\n value: number;\n currency: string;\n pipelineId: string;\n stageId: string;\n status: 'OPEN' | 'WON' | 'LOST' | 'STALE';\n contactId?: string;\n companyId?: string;\n ownerId: string;\n expectedCloseDate?: Date;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface MockStage {\n id: string;\n name: string;\n position: number;\n pipelineId: string;\n}\n\n// ============ Pipeline Stages Mock Data ============\n\nexport const MOCK_STAGES: MockStage[] = [\n { id: 'stage-1', name: 'Lead', position: 1, pipelineId: 'pipeline-1' },\n { id: 'stage-2', name: 'Qualified', position: 2, pipelineId: 'pipeline-1' },\n { id: 'stage-3', name: 'Proposal', position: 3, pipelineId: 'pipeline-1' },\n { id: 'stage-4', name: 'Negotiation', position: 4, pipelineId: 'pipeline-1' },\n { id: 'stage-5', name: 'Closed', position: 5, pipelineId: 'pipeline-1' },\n];\n\n// ============ Deal Mock Data ============\n\nexport const MOCK_DEALS: MockDeal[] = [\n {\n id: 'deal-1',\n name: 'Enterprise License - Acme Corp',\n value: 75000,\n currency: 'USD',\n pipelineId: 'pipeline-1',\n stageId: 'stage-3',\n status: 'OPEN',\n contactId: 'contact-1',\n companyId: 'company-1',\n ownerId: 'user-1',\n expectedCloseDate: new Date('2024-05-15T00:00:00Z'),\n createdAt: new Date('2024-02-01T10:00:00Z'),\n updatedAt: new Date('2024-04-10T14:30:00Z'),\n },\n {\n id: 'deal-2',\n name: 'Startup Plan - TechStart Inc',\n value: 12000,\n currency: 'USD',\n pipelineId: 'pipeline-1',\n stageId: 'stage-2',\n status: 'OPEN',\n contactId: 'contact-2',\n companyId: 'company-2',\n ownerId: 'user-2',\n expectedCloseDate: new Date('2024-04-30T00:00:00Z'),\n createdAt: new Date('2024-03-15T09:00:00Z'),\n updatedAt: new Date('2024-04-08T11:15:00Z'),\n },\n {\n id: 'deal-3',\n name: 'Professional Services - Global Ltd',\n value: 45000,\n currency: 'USD',\n pipelineId: 'pipeline-1',\n stageId: 'stage-4',\n status: 'OPEN',\n contactId: 'contact-3',\n companyId: 'company-3',\n ownerId: 'user-1',\n expectedCloseDate: new Date('2024-04-20T00:00:00Z'),\n createdAt: new Date('2024-01-20T08:00:00Z'),\n updatedAt: new Date('2024-04-12T16:45:00Z'),\n },\n {\n id: 'deal-4',\n name: 'Annual Contract - SmallBiz Co',\n value: 8500,\n currency: 'USD',\n pipelineId: 'pipeline-1',\n stageId: 'stage-1',\n status: 'OPEN',\n contactId: 'contact-4',\n companyId: 'company-4',\n ownerId: 'user-3',\n createdAt: new Date('2024-04-05T12:00:00Z'),\n updatedAt: new Date('2024-04-05T12:00:00Z'),\n },\n {\n id: 'deal-5',\n name: 'Custom Integration - MegaCorp',\n value: 125000,\n currency: 'USD',\n pipelineId: 'pipeline-1',\n stageId: 'stage-5',\n status: 'WON',\n contactId: 'contact-5',\n companyId: 'company-5',\n ownerId: 'user-1',\n expectedCloseDate: new Date('2024-03-31T00:00:00Z'),\n createdAt: new Date('2023-11-10T10:00:00Z'),\n updatedAt: new Date('2024-03-28T09:00:00Z'),\n },\n {\n id: 'deal-6',\n name: 'Pilot Project - NewCo',\n value: 5000,\n currency: 'USD',\n pipelineId: 'pipeline-1',\n stageId: 'stage-2',\n status: 'LOST',\n contactId: 'contact-6',\n companyId: 'company-6',\n ownerId: 'user-2',\n createdAt: new Date('2024-01-15T14:00:00Z'),\n updatedAt: new Date('2024-02-28T10:30:00Z'),\n },\n];\n\n// ============ Company Mock Data ============\n\nexport const MOCK_COMPANIES = [\n {\n id: 'company-1',\n name: 'Acme Corporation',\n domain: 'acme.com',\n industry: 'Technology',\n size: '1000-5000',\n website: 'https://acme.com',\n createdAt: new Date('2024-01-01T00:00:00Z'),\n },\n {\n id: 'company-2',\n name: 'TechStart Inc',\n domain: 'techstart.io',\n industry: 'Software',\n size: '10-50',\n website: 'https://techstart.io',\n createdAt: new Date('2024-02-15T00:00:00Z'),\n },\n {\n id: 'company-3',\n name: 'Global Ltd',\n domain: 'global.com',\n industry: 'Consulting',\n size: '500-1000',\n website: 'https://global.com',\n createdAt: new Date('2023-12-01T00:00:00Z'),\n },\n];\n\n// ============ Contact Mock Data ============\n\nexport const MOCK_CONTACTS = [\n {\n id: 'contact-1',\n firstName: 'John',\n lastName: 'Smith',\n email: 'john.smith@acme.com',\n phone: '+1-555-0101',\n title: 'VP of Engineering',\n companyId: 'company-1',\n createdAt: new Date('2024-01-05T00:00:00Z'),\n },\n {\n id: 'contact-2',\n firstName: 'Sarah',\n lastName: 'Johnson',\n email: 'sarah@techstart.io',\n phone: '+1-555-0102',\n title: 'CEO',\n companyId: 'company-2',\n createdAt: new Date('2024-02-20T00:00:00Z'),\n },\n {\n id: 'contact-3',\n firstName: 'Michael',\n lastName: 'Brown',\n email: 'michael.brown@global.com',\n phone: '+1-555-0103',\n title: 'CTO',\n companyId: 'company-3',\n createdAt: new Date('2023-12-10T00:00:00Z'),\n },\n];\n"],"mappings":"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"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["// CRM Pipeline Example\n// Demonstrates ContractSpec principles for a CRM application\n\nexport * from './entities';\nexport * from './operations';\nexport * from './events';\nexport * from './handlers';\nexport * from './presentations';\nexport * from './ui';\nexport * from './crm-pipeline.feature';\nexport { default as example } from './example';\nimport './docs';\n\n// Schema composition configuration\nimport { identityRbacSchemaContribution } from '@contractspec/lib.identity-rbac';\nimport { auditTrailSchemaContribution } from '@contractspec/module.audit-trail';\nimport { notificationsSchemaContribution } from '@contractspec/module.notifications';\nimport { crmPipelineSchemaContribution } from './entities';\n\n/**\n * Complete schema composition for CRM Pipeline.\n */\nexport const schemaComposition = {\n modules: [\n identityRbacSchemaContribution,\n auditTrailSchemaContribution,\n notificationsSchemaContribution,\n crmPipelineSchemaContribution,\n ],\n provider: 'postgresql' as const,\n outputPath: './prisma/schema/generated.prisma',\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,oBAAoB;CAC/B,SAAS;EACP;EACA;EACA;EACA;EACD;CACD,UAAU;CACV,YAAY;CACb"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard.presentation.js","names":[],"sources":["../../src/presentations/dashboard.presentation.ts"],"sourcesContent":["/**\n * CRM Dashboard Presentation Descriptor\n */\nimport { definePresentation, StabilityEnum } from '@contractspec/lib.contracts';\n\n/**\n * Main CRM dashboard presentation.\n */\nexport const CrmDashboardPresentation = definePresentation({\n meta: {\n key: 'crm.dashboard',\n version: '1.0.0',\n title: 'CRM Dashboard',\n description:\n 'Main CRM dashboard with pipeline overview, deal stats, and activities',\n domain: 'crm-pipeline',\n owners: ['@crm-team'],\n tags: ['dashboard', 'overview'],\n stability: StabilityEnum.Experimental,\n goal: 'Provide a high-level overview of CRM performance and active deals.',\n context: 'The landing page for CRM users.',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'CrmDashboard',\n },\n targets: ['react', 'markdown'],\n policy: {\n flags: ['crm.enabled'],\n },\n});\n\n/**\n * Pipeline metrics presentation.\n */\nexport const PipelineMetricsPresentation = definePresentation({\n meta: {\n key: 'crm.pipeline.metrics',\n version: '1.0.0',\n title: 'Pipeline Metrics',\n description: 'Pipeline metrics and forecasting view',\n domain: 'crm-pipeline',\n owners: ['@crm-team'],\n tags: ['pipeline', 'metrics', 'forecast'],\n stability: StabilityEnum.Experimental,\n goal: 'Track pipeline health and sales forecasts.',\n context: 'Data-intensive widget for sales managers.',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'PipelineMetricsView',\n },\n targets: ['react', 'markdown'],\n policy: {\n flags: ['crm.metrics.enabled'],\n },\n});\n"],"mappings":";;;;;;;;;AAQA,MAAa,2BAA2B,mBAAmB;CACzD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aACE;EACF,QAAQ;EACR,QAAQ,CAAC,YAAY;EACrB,MAAM,CAAC,aAAa,WAAW;EAC/B,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,cAAc,EACvB;CACF,CAAC;;;;AAKF,MAAa,8BAA8B,mBAAmB;CAC5D,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aAAa;EACb,QAAQ;EACR,QAAQ,CAAC,YAAY;EACrB,MAAM;GAAC;GAAY;GAAW;GAAW;EACzC,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,sBAAsB,EAC/B;CACF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"pipeline.presentation.js","names":[],"sources":["../../src/presentations/pipeline.presentation.ts"],"sourcesContent":["/**\n * Pipeline Presentation Descriptors\n */\nimport { definePresentation, 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 = definePresentation({\n meta: {\n key: 'crm.pipeline.kanban',\n version: '1.0.0',\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 = definePresentation({\n meta: {\n key: 'crm.deal.viewList',\n version: '1.0.0',\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 = definePresentation({\n meta: {\n key: 'crm.deal.detail',\n version: '1.0.0',\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 = definePresentation({\n meta: {\n key: 'crm.deal.card',\n version: '1.0.0',\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":";;;;;;;;;;AASA,MAAa,6BAA6B,mBAAmB;CAC3D,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,CAAC;;;;AAKF,MAAa,uBAAuB,mBAAmB;CACrD,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,CAAC;;;;AAKF,MAAa,yBAAyB,mBAAmB;CACvD,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,CAAC;;;;AAKF,MAAa,uBAAuB,mBAAmB;CACrD,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,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/seeders/index.ts"],"sourcesContent":["import type { DatabasePort } from '@contractspec/lib.runtime-sandbox';\n\nexport async function seedCrmPipeline(params: {\n projectId: string;\n db: DatabasePort;\n}) {\n const { projectId, db } = params;\n\n const existing = await db.query(\n `SELECT COUNT(*) as count FROM crm_pipeline WHERE \"projectId\" = $1`,\n [projectId]\n );\n if ((existing.rows[0]?.count as number) > 0) return;\n\n const pipelineId = 'pipeline_sales';\n await db.execute(\n `INSERT INTO crm_pipeline (id, \"projectId\", name) VALUES ($1, $2, $3)`,\n [pipelineId, projectId, 'Sales Pipeline']\n );\n\n const stages = [\n { id: 'stage_lead', name: 'Lead', position: 1 },\n { id: 'stage_contact', name: 'Contact Made', position: 2 },\n { id: 'stage_proposal', name: 'Proposal', position: 3 },\n { id: 'stage_negotiation', name: 'Negotiation', position: 4 },\n { id: 'stage_closed', name: 'Closed', position: 5 },\n ];\n\n for (const stage of stages) {\n await db.execute(\n `INSERT INTO crm_stage (id, \"pipelineId\", name, position) VALUES ($1, $2, $3, $4)`,\n [stage.id, pipelineId, stage.name, stage.position]\n );\n }\n}\n"],"mappings":";AAEA,eAAsB,gBAAgB,QAGnC;CACD,MAAM,EAAE,WAAW,OAAO;AAM1B,MAJiB,MAAM,GAAG,MACxB,qEACA,CAAC,UAAU,CACZ,EACa,KAAK,IAAI,QAAmB,EAAG;CAE7C,MAAM,aAAa;AACnB,OAAM,GAAG,QACP,wEACA;EAAC;EAAY;EAAW;EAAiB,CAC1C;AAUD,MAAK,MAAM,SARI;EACb;GAAE,IAAI;GAAc,MAAM;GAAQ,UAAU;GAAG;EAC/C;GAAE,IAAI;GAAiB,MAAM;GAAgB,UAAU;GAAG;EAC1D;GAAE,IAAI;GAAkB,MAAM;GAAY,UAAU;GAAG;EACvD;GAAE,IAAI;GAAqB,MAAM;GAAe,UAAU;GAAG;EAC7D;GAAE,IAAI;GAAgB,MAAM;GAAU,UAAU;GAAG;EACpD,CAGC,OAAM,GAAG,QACP,oFACA;EAAC,MAAM;EAAI;EAAY,MAAM;EAAM,MAAM;EAAS,CACnD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"CrmDashboard.js","names":[],"sources":["../../src/ui/CrmDashboard.tsx"],"sourcesContent":["'use client';\n\n/**\n * CRM Dashboard\n *\n * Fully integrated with ContractSpec example handlers\n * and design-system components.\n *\n * Commands wired:\n * - CreateDealContract -> Create Deal button + modal\n * - MoveDealContract -> Move deal between stages\n * - WinDealContract -> Mark deal as won\n * - LoseDealContract -> Mark deal as lost\n */\nimport { useCallback, useState } from 'react';\nimport {\n Button,\n ErrorState,\n LoaderBlock,\n StatCard,\n StatCardGroup,\n} from '@contractspec/lib.design-system';\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@contractspec/lib.ui-kit-web/ui/tabs';\nimport { type Deal, useDealList } from './hooks/useDealList';\nimport { useDealMutations } from './hooks/useDealMutations';\nimport { CrmPipelineBoard } from './CrmPipelineBoard';\nimport { CreateDealModal } from './modals/CreateDealModal';\nimport { DealActionsModal } from './modals/DealActionsModal';\n\n// type Tab = 'pipeline' | 'list' | 'metrics';\n\nfunction formatCurrency(value: number, currency = 'USD'): string {\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency,\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n }).format(value);\n}\n\nexport function CrmDashboard() {\n const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);\n const [selectedDeal, setSelectedDeal] = useState<Deal | null>(null);\n const [isDealActionsOpen, setIsDealActionsOpen] = useState(false);\n\n const { data, dealsByStage, stages, loading, error, stats, refetch } =\n useDealList();\n\n const mutations = useDealMutations({\n onSuccess: () => {\n refetch();\n },\n });\n\n const handleDealClick = useCallback(\n (dealId: string) => {\n // Find deal in data\n const deal = dealsByStage\n ? Object.values(dealsByStage)\n .flat()\n .find((d) => d.id === dealId)\n : null;\n\n if (deal) {\n setSelectedDeal(deal);\n setIsDealActionsOpen(true);\n }\n },\n [dealsByStage]\n );\n\n const handleDealMove = useCallback(\n async (dealId: string, toStageId: string) => {\n await mutations.moveDeal({ dealId, stageId: toStageId });\n },\n [mutations]\n );\n\n if (loading && !data) {\n return <LoaderBlock label=\"Loading CRM...\" />;\n }\n\n if (error) {\n return (\n <ErrorState\n title=\"Failed to load CRM\"\n description={error.message}\n onRetry={refetch}\n retryLabel=\"Retry\"\n />\n );\n }\n\n return (\n <div className=\"space-y-6\">\n {/* Header with Create Button */}\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-2xl font-bold\">CRM Pipeline</h2>\n <Button onClick={() => setIsCreateModalOpen(true)}>\n <span className=\"mr-2\">+</span> Create Deal\n </Button>\n </div>\n\n {/* Stats Row */}\n {stats && (\n <StatCardGroup>\n <StatCard\n label=\"Total Pipeline\"\n value={formatCurrency(stats.totalValue)}\n hint={`${stats.total} deals`}\n />\n <StatCard\n label=\"Open Deals\"\n value={formatCurrency(stats.openValue)}\n hint={`${stats.openCount} active`}\n />\n <StatCard\n label=\"Won\"\n value={formatCurrency(stats.wonValue)}\n hint={`${stats.wonCount} closed`}\n />\n <StatCard label=\"Lost\" value={stats.lostCount} hint=\"deals lost\" />\n </StatCardGroup>\n )}\n\n {/* Tabs */}\n <Tabs defaultValue=\"pipeline\" className=\"w-full\">\n <TabsList>\n <TabsTrigger value=\"pipeline\">\n <span className=\"mr-2\">๐Ÿ“Š</span>\n Pipeline\n </TabsTrigger>\n <TabsTrigger value=\"list\">\n <span className=\"mr-2\">๐Ÿ“‹</span>\n All Deals\n </TabsTrigger>\n <TabsTrigger value=\"metrics\">\n <span className=\"mr-2\">๐Ÿ“ˆ</span>\n Metrics\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"pipeline\" className=\"min-h-[400px]\">\n <CrmPipelineBoard\n dealsByStage={dealsByStage}\n stages={stages}\n onDealClick={handleDealClick}\n onDealMove={handleDealMove}\n />\n </TabsContent>\n\n <TabsContent value=\"list\" className=\"min-h-[400px]\">\n <DealListTab data={data} onDealClick={handleDealClick} />\n </TabsContent>\n\n <TabsContent value=\"metrics\" className=\"min-h-[400px]\">\n <MetricsTab stats={stats} />\n </TabsContent>\n </Tabs>\n\n {/* Create Deal Modal */}\n <CreateDealModal\n isOpen={isCreateModalOpen}\n onClose={() => setIsCreateModalOpen(false)}\n onSubmit={async (input) => {\n await mutations.createDeal(input);\n }}\n stages={stages}\n isLoading={mutations.createState.loading}\n />\n\n {/* Deal Actions Modal */}\n <DealActionsModal\n isOpen={isDealActionsOpen}\n deal={selectedDeal}\n stages={stages}\n onClose={() => {\n setIsDealActionsOpen(false);\n setSelectedDeal(null);\n }}\n onWin={async (input) => {\n await mutations.winDeal(input);\n }}\n onLose={async (input) => {\n await mutations.loseDeal(input);\n }}\n onMove={async (input) => {\n await mutations.moveDeal(input);\n refetch();\n }}\n isLoading={mutations.isLoading}\n />\n </div>\n );\n}\n\ninterface DealListTabProps {\n data: ReturnType<typeof useDealList>['data'];\n onDealClick?: (dealId: string) => void;\n}\n\nfunction DealListTab({ data, onDealClick }: DealListTabProps) {\n if (!data?.deals.length) {\n return (\n <div className=\"text-muted-foreground flex h-64 items-center justify-center\">\n No deals found\n </div>\n );\n }\n\n return (\n <div className=\"border-border rounded-lg border\">\n <table className=\"w-full\">\n <thead className=\"border-border bg-muted/30 border-b\">\n <tr>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">Deal</th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">Value</th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">Status</th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Expected Close\n </th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">Actions</th>\n </tr>\n </thead>\n <tbody className=\"divide-border divide-y\">\n {data.deals.map((deal: Deal) => (\n <tr key={deal.id} className=\"hover:bg-muted/50\">\n <td className=\"px-4 py-3\">\n <div className=\"font-medium\">{deal.name}</div>\n </td>\n <td className=\"px-4 py-3 font-mono\">\n {formatCurrency(deal.value, deal.currency)}\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${\n deal.status === 'WON'\n ? 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400'\n : deal.status === 'LOST'\n ? 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400'\n : 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400'\n }`}\n >\n {deal.status}\n </span>\n </td>\n <td className=\"text-muted-foreground px-4 py-3\">\n {deal.expectedCloseDate?.toLocaleDateString() ?? '-'}\n </td>\n <td className=\"px-4 py-3\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onPress={() => onDealClick?.(deal.id)}\n >\n Actions\n </Button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n\nfunction MetricsTab({\n stats,\n}: {\n stats: ReturnType<typeof useDealList>['stats'];\n}) {\n if (!stats) return null;\n\n return (\n <div className=\"space-y-6\">\n <div className=\"border-border bg-card rounded-xl border p-6\">\n <h3 className=\"mb-4 text-lg font-semibold\">Pipeline Overview</h3>\n <dl className=\"grid gap-4 sm:grid-cols-3\">\n <div>\n <dt className=\"text-muted-foreground text-sm\">Win Rate</dt>\n <dd className=\"text-2xl font-semibold\">\n {stats.total > 0\n ? ((stats.wonCount / stats.total) * 100).toFixed(0)\n : 0}\n %\n </dd>\n </div>\n <div>\n <dt className=\"text-muted-foreground text-sm\">Avg Deal Size</dt>\n <dd className=\"text-2xl font-semibold\">\n {formatCurrency(\n stats.total > 0 ? stats.totalValue / stats.total : 0\n )}\n </dd>\n </div>\n <div>\n <dt className=\"text-muted-foreground text-sm\">Conversion</dt>\n <dd className=\"text-2xl font-semibold\">\n {stats.wonCount} / {stats.total}\n </dd>\n </div>\n </dl>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"CrmDealCard.js","names":[],"sources":["../../src/ui/CrmDealCard.tsx"],"sourcesContent":["'use client';\n\n/**\n * CRM Deal Card - Individual deal card for kanban board\n */\nimport type { Deal } from './hooks/useDealList';\n\ninterface CrmDealCardProps {\n deal: Deal;\n onClick?: () => void;\n}\n\nfunction formatCurrency(value: number, currency: string): string {\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency,\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n }).format(value);\n}\n\nexport function CrmDealCard({ deal, onClick }: CrmDealCardProps) {\n const daysUntilClose = deal.expectedCloseDate\n ? Math.ceil(\n (deal.expectedCloseDate.getTime() - Date.now()) / (1000 * 60 * 60 * 24)\n )\n : null;\n\n return (\n <div\n onClick={onClick}\n className=\"border-border bg-card cursor-pointer rounded-lg border p-3 shadow-sm transition-shadow hover:shadow-md\"\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') onClick?.();\n }}\n >\n {/* Deal Name */}\n <h4 className=\"leading-snug font-medium\">{deal.name}</h4>\n\n {/* Deal Value */}\n <div className=\"text-primary mt-2 text-lg font-semibold\">\n {formatCurrency(deal.value, deal.currency)}\n </div>\n\n {/* Meta Info */}\n <div className=\"text-muted-foreground mt-3 flex items-center justify-between text-xs\">\n {/* Expected Close */}\n {daysUntilClose !== null && (\n <span\n className={\n daysUntilClose < 0\n ? 'text-red-500'\n : daysUntilClose <= 7\n ? 'text-yellow-600 dark:text-yellow-500'\n : ''\n }\n >\n {daysUntilClose < 0\n ? `${Math.abs(daysUntilClose)}d overdue`\n : daysUntilClose === 0\n ? 'Due today'\n : `${daysUntilClose}d left`}\n </span>\n )}\n\n {/* Status Badge */}\n <span\n className={`rounded px-1.5 py-0.5 text-xs font-medium ${\n deal.status === 'WON'\n ? 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400'\n : deal.status === 'LOST'\n ? 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400'\n : 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400'\n }`}\n >\n {deal.status}\n </span>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;AAYA,SAAS,eAAe,OAAe,UAA0B;AAC/D,QAAO,IAAI,KAAK,aAAa,SAAS;EACpC,OAAO;EACP;EACA,uBAAuB;EACvB,uBAAuB;EACxB,CAAC,CAAC,OAAO,MAAM;;AAGlB,SAAgB,YAAY,EAAE,MAAM,WAA6B;CAC/D,MAAM,iBAAiB,KAAK,oBACxB,KAAK,MACF,KAAK,kBAAkB,SAAS,GAAG,KAAK,KAAK,KAAK,MAAO,KAAK,KAAK,IACrE,GACD;AAEJ,QACE,qBAAC;EACU;EACT,WAAU;EACV,MAAK;EACL,UAAU;EACV,YAAY,MAAM;AAChB,OAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,IAAK,YAAW;;;GAIrD,oBAAC;IAAG,WAAU;cAA4B,KAAK;KAAU;GAGzD,oBAAC;IAAI,WAAU;cACZ,eAAe,KAAK,OAAO,KAAK,SAAS;KACtC;GAGN,qBAAC;IAAI,WAAU;eAEZ,mBAAmB,QAClB,oBAAC;KACC,WACE,iBAAiB,IACb,iBACA,kBAAkB,IAChB,yCACA;eAGP,iBAAiB,IACd,GAAG,KAAK,IAAI,eAAe,CAAC,aAC5B,mBAAmB,IACjB,cACA,GAAG,eAAe;MACnB,EAIT,oBAAC;KACC,WAAW,6CACT,KAAK,WAAW,QACZ,yEACA,KAAK,WAAW,SACd,iEACA;eAGP,KAAK;MACD;KACH;;GACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"CrmPipelineBoard.js","names":[],"sources":["../../src/ui/CrmPipelineBoard.tsx"],"sourcesContent":["'use client';\n\n/**\n * CRM Pipeline Board - Kanban-style deal board\n *\n * Features:\n * - Visual pipeline stages\n * - Deal cards with click actions\n * - Quick move dropdown per card\n * - Drag-and-drop ready (UI only, no lib dependency)\n */\nimport { useState } from 'react';\n// import { Button } from '@contractspec/lib.design-system';\nimport type { Deal } from './hooks/useDealList';\nimport { CrmDealCard } from './CrmDealCard';\n\ninterface CrmPipelineBoardProps {\n dealsByStage: Record<string, Deal[]>;\n stages: { id: string; name: string; position: number }[];\n onDealClick?: (dealId: string) => void;\n onDealMove?: (dealId: string, toStageId: string) => void;\n}\n\nfunction formatCurrency(value: number): string {\n if (value >= 1000000) return `$${(value / 1000000).toFixed(1)}M`;\n if (value >= 1000) return `$${(value / 1000).toFixed(0)}K`;\n return `$${value}`;\n}\n\nexport function CrmPipelineBoard({\n dealsByStage,\n stages,\n onDealClick,\n onDealMove,\n}: CrmPipelineBoardProps) {\n // Track which deal has the quick-move dropdown open\n const [quickMoveOpen, setQuickMoveOpen] = useState<string | null>(null);\n\n // Sort stages by position\n const sortedStages = [...stages].sort((a, b) => a.position - b.position);\n\n const handleQuickMove = (dealId: string, toStageId: string) => {\n onDealMove?.(dealId, toStageId);\n setQuickMoveOpen(null);\n };\n\n return (\n <div className=\"flex gap-4 overflow-x-auto pb-4\">\n {sortedStages.map((stage) => {\n const deals = dealsByStage[stage.id] ?? [];\n const stageValue = deals.reduce((sum, d) => sum + d.value, 0);\n\n return (\n <div\n key={stage.id}\n className=\"bg-muted/30 flex w-72 flex-shrink-0 flex-col rounded-lg\"\n >\n {/* Stage Header */}\n <div className=\"border-border flex items-center justify-between border-b px-3 py-2\">\n <div>\n <h3 className=\"font-medium\">{stage.name}</h3>\n <p className=\"text-muted-foreground text-xs\">\n {deals.length} deals ยท {formatCurrency(stageValue)}\n </p>\n </div>\n <span className=\"bg-muted flex h-6 w-6 items-center justify-center rounded-full text-xs font-medium\">\n {deals.length}\n </span>\n </div>\n\n {/* Deals Column */}\n <div className=\"flex flex-1 flex-col gap-2 p-2\">\n {deals.length === 0 ? (\n <div className=\"border-muted-foreground/20 text-muted-foreground flex h-24 items-center justify-center rounded-md border-2 border-dashed text-xs\">\n No deals\n </div>\n ) : (\n deals.map((deal) => (\n <div key={deal.id} className=\"group relative\">\n <CrmDealCard\n deal={deal}\n onClick={() => onDealClick?.(deal.id)}\n />\n\n {/* Quick Move Button */}\n {deal.status === 'OPEN' && onDealMove && (\n <div className=\"absolute top-1 right-1 opacity-0 transition-opacity group-hover:opacity-100\">\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n setQuickMoveOpen(\n quickMoveOpen === deal.id ? null : deal.id\n );\n }}\n className=\"bg-background border-border hover:bg-muted flex h-6 w-6 items-center justify-center rounded border text-xs shadow-sm\"\n title=\"Quick move\"\n >\n โžก๏ธ\n </button>\n\n {/* Quick Move Dropdown */}\n {quickMoveOpen === deal.id && (\n <div className=\"bg-card border-border absolute top-7 right-0 z-20 min-w-[140px] rounded-lg border py-1 shadow-lg\">\n <p className=\"text-muted-foreground px-3 py-1 text-xs font-medium\">\n Move to:\n </p>\n {sortedStages\n .filter((s) => s.id !== deal.stageId)\n .map((s) => (\n <button\n key={s.id}\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n handleQuickMove(deal.id, s.id);\n }}\n className=\"hover:bg-muted w-full px-3 py-1.5 text-left text-sm\"\n >\n {s.name}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n ))\n )}\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAuBA,SAAS,eAAe,OAAuB;AAC7C,KAAI,SAAS,IAAS,QAAO,KAAK,QAAQ,KAAS,QAAQ,EAAE,CAAC;AAC9D,KAAI,SAAS,IAAM,QAAO,KAAK,QAAQ,KAAM,QAAQ,EAAE,CAAC;AACxD,QAAO,IAAI;;AAGb,SAAgB,iBAAiB,EAC/B,cACA,QACA,aACA,cACwB;CAExB,MAAM,CAAC,eAAe,oBAAoB,SAAwB,KAAK;CAGvE,MAAM,eAAe,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,EAAE,WAAW,EAAE,SAAS;CAExE,MAAM,mBAAmB,QAAgB,cAAsB;AAC7D,eAAa,QAAQ,UAAU;AAC/B,mBAAiB,KAAK;;AAGxB,QACE,oBAAC;EAAI,WAAU;YACZ,aAAa,KAAK,UAAU;GAC3B,MAAM,QAAQ,aAAa,MAAM,OAAO,EAAE;GAC1C,MAAM,aAAa,MAAM,QAAQ,KAAK,MAAM,MAAM,EAAE,OAAO,EAAE;AAE7D,UACE,qBAAC;IAEC,WAAU;eAGV,qBAAC;KAAI,WAAU;gBACb,qBAAC,oBACC,oBAAC;MAAG,WAAU;gBAAe,MAAM;OAAU,EAC7C,qBAAC;MAAE,WAAU;;OACV,MAAM;OAAO;OAAU,eAAe,WAAW;;OAChD,IACA,EACN,oBAAC;MAAK,WAAU;gBACb,MAAM;OACF;MACH,EAGN,oBAAC;KAAI,WAAU;eACZ,MAAM,WAAW,IAChB,oBAAC;MAAI,WAAU;gBAAmI;OAE5I,GAEN,MAAM,KAAK,SACT,qBAAC;MAAkB,WAAU;iBAC3B,oBAAC;OACO;OACN,eAAe,cAAc,KAAK,GAAG;QACrC,EAGD,KAAK,WAAW,UAAU,cACzB,qBAAC;OAAI,WAAU;kBACb,oBAAC;QACC,MAAK;QACL,UAAU,MAAM;AACd,WAAE,iBAAiB;AACnB,0BACE,kBAAkB,KAAK,KAAK,OAAO,KAAK,GACzC;;QAEH,WAAU;QACV,OAAM;kBACP;SAEQ,EAGR,kBAAkB,KAAK,MACtB,qBAAC;QAAI,WAAU;mBACb,oBAAC;SAAE,WAAU;mBAAsD;UAE/D,EACH,aACE,QAAQ,MAAM,EAAE,OAAO,KAAK,QAAQ,CACpC,KAAK,MACJ,oBAAC;SAEC,MAAK;SACL,UAAU,MAAM;AACd,YAAE,iBAAiB;AACnB,0BAAgB,KAAK,IAAI,EAAE,GAAG;;SAEhC,WAAU;mBAET,EAAE;WARE,EAAE,GASA,CACT;SACA;QAEJ;QA9CA,KAAK,GAgDT,CACN;MAEA;MA3ED,MAAM,GA4EP;IAER;GACE"}