@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
@@ -0,0 +1,66 @@
1
+ // src/entities/contact.entity.ts
2
+ import {
3
+ defineEntity,
4
+ defineEntityEnum,
5
+ field,
6
+ index
7
+ } from "@contractspec/lib.schema";
8
+ var ContactStatusEnum = defineEntityEnum({
9
+ name: "ContactStatus",
10
+ values: ["LEAD", "PROSPECT", "CUSTOMER", "CHURNED", "ARCHIVED"],
11
+ schema: "crm",
12
+ description: "Status of a contact in the sales funnel."
13
+ });
14
+ var ContactEntity = defineEntity({
15
+ name: "Contact",
16
+ description: "An individual person in the CRM.",
17
+ schema: "crm",
18
+ map: "contact",
19
+ fields: {
20
+ id: field.id({ description: "Unique contact ID" }),
21
+ firstName: field.string({ description: "First name" }),
22
+ lastName: field.string({ description: "Last name" }),
23
+ email: field.email({ isOptional: true, isUnique: true }),
24
+ phone: field.string({ isOptional: true }),
25
+ companyId: field.string({
26
+ isOptional: true,
27
+ description: "Associated company"
28
+ }),
29
+ jobTitle: field.string({ isOptional: true }),
30
+ status: field.enum("ContactStatus", { default: "LEAD" }),
31
+ organizationId: field.foreignKey(),
32
+ ownerId: field.foreignKey({
33
+ description: "Sales rep who owns this contact"
34
+ }),
35
+ source: field.string({ isOptional: true, description: "Lead source" }),
36
+ linkedInUrl: field.url({ isOptional: true }),
37
+ twitterHandle: field.string({ isOptional: true }),
38
+ address: field.string({ isOptional: true }),
39
+ city: field.string({ isOptional: true }),
40
+ state: field.string({ isOptional: true }),
41
+ country: field.string({ isOptional: true }),
42
+ postalCode: field.string({ isOptional: true }),
43
+ notes: field.string({ isOptional: true }),
44
+ tags: field.string({ isArray: true }),
45
+ customFields: field.json({ isOptional: true }),
46
+ lastContactedAt: field.dateTime({ isOptional: true }),
47
+ nextFollowUpAt: field.dateTime({ isOptional: true }),
48
+ createdAt: field.createdAt(),
49
+ updatedAt: field.updatedAt(),
50
+ company: field.belongsTo("Company", ["companyId"], ["id"]),
51
+ deals: field.hasMany("Deal"),
52
+ tasks: field.hasMany("Task"),
53
+ activities: field.hasMany("Activity")
54
+ },
55
+ indexes: [
56
+ index.on(["organizationId", "status"]),
57
+ index.on(["organizationId", "ownerId"]),
58
+ index.on(["organizationId", "companyId"]),
59
+ index.on(["email"])
60
+ ],
61
+ enums: [ContactStatusEnum]
62
+ });
63
+ export {
64
+ ContactStatusEnum,
65
+ ContactEntity
66
+ };
@@ -0,0 +1,107 @@
1
+ // src/entities/deal.entity.ts
2
+ import {
3
+ defineEntity,
4
+ defineEntityEnum,
5
+ field,
6
+ index
7
+ } from "@contractspec/lib.schema";
8
+ var DealStatusEnum = defineEntityEnum({
9
+ name: "DealStatus",
10
+ values: ["OPEN", "WON", "LOST", "STALE"],
11
+ schema: "crm",
12
+ description: "Status of a deal."
13
+ });
14
+ var PipelineEntity = defineEntity({
15
+ name: "Pipeline",
16
+ description: "A sales pipeline with stages.",
17
+ schema: "crm",
18
+ map: "pipeline",
19
+ fields: {
20
+ id: field.id(),
21
+ name: field.string({ description: "Pipeline name" }),
22
+ description: field.string({ isOptional: true }),
23
+ organizationId: field.foreignKey(),
24
+ isDefault: field.boolean({ default: false }),
25
+ createdAt: field.createdAt(),
26
+ updatedAt: field.updatedAt(),
27
+ stages: field.hasMany("Stage"),
28
+ deals: field.hasMany("Deal")
29
+ }
30
+ });
31
+ var StageEntity = defineEntity({
32
+ name: "Stage",
33
+ description: "A stage within a sales pipeline.",
34
+ schema: "crm",
35
+ map: "stage",
36
+ fields: {
37
+ id: field.id(),
38
+ name: field.string({ description: "Stage name" }),
39
+ pipelineId: field.foreignKey(),
40
+ position: field.int({ description: "Order in pipeline" }),
41
+ probability: field.int({
42
+ default: 0,
43
+ description: "Win probability (0-100)"
44
+ }),
45
+ isWonStage: field.boolean({ default: false }),
46
+ isLostStage: field.boolean({ default: false }),
47
+ color: field.string({
48
+ isOptional: true,
49
+ description: "Stage color for UI"
50
+ }),
51
+ createdAt: field.createdAt(),
52
+ updatedAt: field.updatedAt(),
53
+ pipeline: field.belongsTo("Pipeline", ["pipelineId"], ["id"], {
54
+ onDelete: "Cascade"
55
+ }),
56
+ deals: field.hasMany("Deal")
57
+ },
58
+ indexes: [index.on(["pipelineId", "position"])]
59
+ });
60
+ var DealEntity = defineEntity({
61
+ name: "Deal",
62
+ description: "A sales opportunity/deal.",
63
+ schema: "crm",
64
+ map: "deal",
65
+ fields: {
66
+ id: field.id({ description: "Unique deal ID" }),
67
+ name: field.string({ description: "Deal name" }),
68
+ value: field.decimal({ description: "Deal value" }),
69
+ currency: field.string({ default: '"USD"' }),
70
+ pipelineId: field.foreignKey(),
71
+ stageId: field.foreignKey(),
72
+ status: field.enum("DealStatus", { default: "OPEN" }),
73
+ contactId: field.string({ isOptional: true }),
74
+ companyId: field.string({ isOptional: true }),
75
+ organizationId: field.foreignKey(),
76
+ ownerId: field.foreignKey({ description: "Deal owner" }),
77
+ expectedCloseDate: field.dateTime({ isOptional: true }),
78
+ closedAt: field.dateTime({ isOptional: true }),
79
+ lostReason: field.string({ isOptional: true }),
80
+ wonSource: field.string({ isOptional: true }),
81
+ notes: field.string({ isOptional: true }),
82
+ tags: field.string({ isArray: true }),
83
+ customFields: field.json({ isOptional: true }),
84
+ stagePosition: field.int({ default: 0 }),
85
+ createdAt: field.createdAt(),
86
+ updatedAt: field.updatedAt(),
87
+ pipeline: field.belongsTo("Pipeline", ["pipelineId"], ["id"]),
88
+ stage: field.belongsTo("Stage", ["stageId"], ["id"]),
89
+ contact: field.belongsTo("Contact", ["contactId"], ["id"]),
90
+ company: field.belongsTo("Company", ["companyId"], ["id"]),
91
+ tasks: field.hasMany("Task"),
92
+ activities: field.hasMany("Activity")
93
+ },
94
+ indexes: [
95
+ index.on(["organizationId", "status"]),
96
+ index.on(["pipelineId", "stageId", "stagePosition"]),
97
+ index.on(["ownerId", "status"]),
98
+ index.on(["expectedCloseDate"])
99
+ ],
100
+ enums: [DealStatusEnum]
101
+ });
102
+ export {
103
+ StageEntity,
104
+ PipelineEntity,
105
+ DealStatusEnum,
106
+ DealEntity
107
+ };
@@ -0,0 +1,343 @@
1
+ // src/entities/company.entity.ts
2
+ import {
3
+ defineEntity,
4
+ defineEntityEnum,
5
+ field,
6
+ index
7
+ } from "@contractspec/lib.schema";
8
+ var CompanySizeEnum = defineEntityEnum({
9
+ name: "CompanySize",
10
+ values: ["STARTUP", "SMALL", "MEDIUM", "LARGE", "ENTERPRISE"],
11
+ schema: "crm",
12
+ description: "Size category of a company."
13
+ });
14
+ var CompanyEntity = defineEntity({
15
+ name: "Company",
16
+ description: "A company/organization in the CRM.",
17
+ schema: "crm",
18
+ map: "company",
19
+ fields: {
20
+ id: field.id({ description: "Unique company ID" }),
21
+ name: field.string({ description: "Company name" }),
22
+ domain: field.string({ isOptional: true, description: "Website domain" }),
23
+ website: field.url({ isOptional: true }),
24
+ industry: field.string({ isOptional: true }),
25
+ size: field.enum("CompanySize", { isOptional: true }),
26
+ employeeCount: field.int({ isOptional: true }),
27
+ annualRevenue: field.decimal({ isOptional: true }),
28
+ organizationId: field.foreignKey(),
29
+ ownerId: field.foreignKey({ description: "Account owner" }),
30
+ phone: field.string({ isOptional: true }),
31
+ email: field.email({ isOptional: true }),
32
+ address: field.string({ isOptional: true }),
33
+ city: field.string({ isOptional: true }),
34
+ state: field.string({ isOptional: true }),
35
+ country: field.string({ isOptional: true }),
36
+ postalCode: field.string({ isOptional: true }),
37
+ linkedInUrl: field.url({ isOptional: true }),
38
+ description: field.string({ isOptional: true }),
39
+ tags: field.string({ isArray: true }),
40
+ customFields: field.json({ isOptional: true }),
41
+ createdAt: field.createdAt(),
42
+ updatedAt: field.updatedAt(),
43
+ contacts: field.hasMany("Contact"),
44
+ deals: field.hasMany("Deal")
45
+ },
46
+ indexes: [index.on(["organizationId", "ownerId"]), index.on(["domain"])],
47
+ enums: [CompanySizeEnum]
48
+ });
49
+
50
+ // src/entities/contact.entity.ts
51
+ import {
52
+ defineEntity as defineEntity2,
53
+ defineEntityEnum as defineEntityEnum2,
54
+ field as field2,
55
+ index as index2
56
+ } from "@contractspec/lib.schema";
57
+ var ContactStatusEnum = defineEntityEnum2({
58
+ name: "ContactStatus",
59
+ values: ["LEAD", "PROSPECT", "CUSTOMER", "CHURNED", "ARCHIVED"],
60
+ schema: "crm",
61
+ description: "Status of a contact in the sales funnel."
62
+ });
63
+ var ContactEntity = defineEntity2({
64
+ name: "Contact",
65
+ description: "An individual person in the CRM.",
66
+ schema: "crm",
67
+ map: "contact",
68
+ fields: {
69
+ id: field2.id({ description: "Unique contact ID" }),
70
+ firstName: field2.string({ description: "First name" }),
71
+ lastName: field2.string({ description: "Last name" }),
72
+ email: field2.email({ isOptional: true, isUnique: true }),
73
+ phone: field2.string({ isOptional: true }),
74
+ companyId: field2.string({
75
+ isOptional: true,
76
+ description: "Associated company"
77
+ }),
78
+ jobTitle: field2.string({ isOptional: true }),
79
+ status: field2.enum("ContactStatus", { default: "LEAD" }),
80
+ organizationId: field2.foreignKey(),
81
+ ownerId: field2.foreignKey({
82
+ description: "Sales rep who owns this contact"
83
+ }),
84
+ source: field2.string({ isOptional: true, description: "Lead source" }),
85
+ linkedInUrl: field2.url({ isOptional: true }),
86
+ twitterHandle: field2.string({ isOptional: true }),
87
+ address: field2.string({ isOptional: true }),
88
+ city: field2.string({ isOptional: true }),
89
+ state: field2.string({ isOptional: true }),
90
+ country: field2.string({ isOptional: true }),
91
+ postalCode: field2.string({ isOptional: true }),
92
+ notes: field2.string({ isOptional: true }),
93
+ tags: field2.string({ isArray: true }),
94
+ customFields: field2.json({ isOptional: true }),
95
+ lastContactedAt: field2.dateTime({ isOptional: true }),
96
+ nextFollowUpAt: field2.dateTime({ isOptional: true }),
97
+ createdAt: field2.createdAt(),
98
+ updatedAt: field2.updatedAt(),
99
+ company: field2.belongsTo("Company", ["companyId"], ["id"]),
100
+ deals: field2.hasMany("Deal"),
101
+ tasks: field2.hasMany("Task"),
102
+ activities: field2.hasMany("Activity")
103
+ },
104
+ indexes: [
105
+ index2.on(["organizationId", "status"]),
106
+ index2.on(["organizationId", "ownerId"]),
107
+ index2.on(["organizationId", "companyId"]),
108
+ index2.on(["email"])
109
+ ],
110
+ enums: [ContactStatusEnum]
111
+ });
112
+
113
+ // src/entities/deal.entity.ts
114
+ import {
115
+ defineEntity as defineEntity3,
116
+ defineEntityEnum as defineEntityEnum3,
117
+ field as field3,
118
+ index as index3
119
+ } from "@contractspec/lib.schema";
120
+ var DealStatusEnum = defineEntityEnum3({
121
+ name: "DealStatus",
122
+ values: ["OPEN", "WON", "LOST", "STALE"],
123
+ schema: "crm",
124
+ description: "Status of a deal."
125
+ });
126
+ var PipelineEntity = defineEntity3({
127
+ name: "Pipeline",
128
+ description: "A sales pipeline with stages.",
129
+ schema: "crm",
130
+ map: "pipeline",
131
+ fields: {
132
+ id: field3.id(),
133
+ name: field3.string({ description: "Pipeline name" }),
134
+ description: field3.string({ isOptional: true }),
135
+ organizationId: field3.foreignKey(),
136
+ isDefault: field3.boolean({ default: false }),
137
+ createdAt: field3.createdAt(),
138
+ updatedAt: field3.updatedAt(),
139
+ stages: field3.hasMany("Stage"),
140
+ deals: field3.hasMany("Deal")
141
+ }
142
+ });
143
+ var StageEntity = defineEntity3({
144
+ name: "Stage",
145
+ description: "A stage within a sales pipeline.",
146
+ schema: "crm",
147
+ map: "stage",
148
+ fields: {
149
+ id: field3.id(),
150
+ name: field3.string({ description: "Stage name" }),
151
+ pipelineId: field3.foreignKey(),
152
+ position: field3.int({ description: "Order in pipeline" }),
153
+ probability: field3.int({
154
+ default: 0,
155
+ description: "Win probability (0-100)"
156
+ }),
157
+ isWonStage: field3.boolean({ default: false }),
158
+ isLostStage: field3.boolean({ default: false }),
159
+ color: field3.string({
160
+ isOptional: true,
161
+ description: "Stage color for UI"
162
+ }),
163
+ createdAt: field3.createdAt(),
164
+ updatedAt: field3.updatedAt(),
165
+ pipeline: field3.belongsTo("Pipeline", ["pipelineId"], ["id"], {
166
+ onDelete: "Cascade"
167
+ }),
168
+ deals: field3.hasMany("Deal")
169
+ },
170
+ indexes: [index3.on(["pipelineId", "position"])]
171
+ });
172
+ var DealEntity = defineEntity3({
173
+ name: "Deal",
174
+ description: "A sales opportunity/deal.",
175
+ schema: "crm",
176
+ map: "deal",
177
+ fields: {
178
+ id: field3.id({ description: "Unique deal ID" }),
179
+ name: field3.string({ description: "Deal name" }),
180
+ value: field3.decimal({ description: "Deal value" }),
181
+ currency: field3.string({ default: '"USD"' }),
182
+ pipelineId: field3.foreignKey(),
183
+ stageId: field3.foreignKey(),
184
+ status: field3.enum("DealStatus", { default: "OPEN" }),
185
+ contactId: field3.string({ isOptional: true }),
186
+ companyId: field3.string({ isOptional: true }),
187
+ organizationId: field3.foreignKey(),
188
+ ownerId: field3.foreignKey({ description: "Deal owner" }),
189
+ expectedCloseDate: field3.dateTime({ isOptional: true }),
190
+ closedAt: field3.dateTime({ isOptional: true }),
191
+ lostReason: field3.string({ isOptional: true }),
192
+ wonSource: field3.string({ isOptional: true }),
193
+ notes: field3.string({ isOptional: true }),
194
+ tags: field3.string({ isArray: true }),
195
+ customFields: field3.json({ isOptional: true }),
196
+ stagePosition: field3.int({ default: 0 }),
197
+ createdAt: field3.createdAt(),
198
+ updatedAt: field3.updatedAt(),
199
+ pipeline: field3.belongsTo("Pipeline", ["pipelineId"], ["id"]),
200
+ stage: field3.belongsTo("Stage", ["stageId"], ["id"]),
201
+ contact: field3.belongsTo("Contact", ["contactId"], ["id"]),
202
+ company: field3.belongsTo("Company", ["companyId"], ["id"]),
203
+ tasks: field3.hasMany("Task"),
204
+ activities: field3.hasMany("Activity")
205
+ },
206
+ indexes: [
207
+ index3.on(["organizationId", "status"]),
208
+ index3.on(["pipelineId", "stageId", "stagePosition"]),
209
+ index3.on(["ownerId", "status"]),
210
+ index3.on(["expectedCloseDate"])
211
+ ],
212
+ enums: [DealStatusEnum]
213
+ });
214
+
215
+ // src/entities/task.entity.ts
216
+ import {
217
+ defineEntity as defineEntity4,
218
+ defineEntityEnum as defineEntityEnum4,
219
+ field as field4,
220
+ index as index4
221
+ } from "@contractspec/lib.schema";
222
+ var TaskTypeEnum = defineEntityEnum4({
223
+ name: "TaskType",
224
+ values: ["CALL", "EMAIL", "MEETING", "TODO", "FOLLOW_UP", "OTHER"],
225
+ schema: "crm",
226
+ description: "Type of CRM task."
227
+ });
228
+ var TaskPriorityEnum = defineEntityEnum4({
229
+ name: "TaskPriority",
230
+ values: ["LOW", "NORMAL", "HIGH", "URGENT"],
231
+ schema: "crm",
232
+ description: "Priority of a task."
233
+ });
234
+ var TaskStatusEnum = defineEntityEnum4({
235
+ name: "TaskStatus",
236
+ values: ["PENDING", "IN_PROGRESS", "COMPLETED", "CANCELLED"],
237
+ schema: "crm",
238
+ description: "Status of a task."
239
+ });
240
+ var TaskEntity = defineEntity4({
241
+ name: "Task",
242
+ description: "A task or follow-up activity.",
243
+ schema: "crm",
244
+ map: "task",
245
+ fields: {
246
+ id: field4.id(),
247
+ title: field4.string({ description: "Task title" }),
248
+ description: field4.string({ isOptional: true }),
249
+ type: field4.enum("TaskType", { default: "TODO" }),
250
+ priority: field4.enum("TaskPriority", { default: "NORMAL" }),
251
+ status: field4.enum("TaskStatus", { default: "PENDING" }),
252
+ dueDate: field4.dateTime({ isOptional: true }),
253
+ reminderAt: field4.dateTime({ isOptional: true }),
254
+ contactId: field4.string({ isOptional: true }),
255
+ dealId: field4.string({ isOptional: true }),
256
+ companyId: field4.string({ isOptional: true }),
257
+ organizationId: field4.foreignKey(),
258
+ assignedTo: field4.foreignKey({ description: "User assigned to this task" }),
259
+ createdBy: field4.foreignKey(),
260
+ completedAt: field4.dateTime({ isOptional: true }),
261
+ completedBy: field4.string({ isOptional: true }),
262
+ createdAt: field4.createdAt(),
263
+ updatedAt: field4.updatedAt(),
264
+ contact: field4.belongsTo("Contact", ["contactId"], ["id"]),
265
+ deal: field4.belongsTo("Deal", ["dealId"], ["id"]),
266
+ company: field4.belongsTo("Company", ["companyId"], ["id"])
267
+ },
268
+ indexes: [
269
+ index4.on(["organizationId", "assignedTo", "status"]),
270
+ index4.on(["dueDate", "status"]),
271
+ index4.on(["contactId"]),
272
+ index4.on(["dealId"])
273
+ ],
274
+ enums: [TaskTypeEnum, TaskPriorityEnum, TaskStatusEnum]
275
+ });
276
+ var ActivityEntity = defineEntity4({
277
+ name: "Activity",
278
+ description: "An activity/interaction logged in the CRM.",
279
+ schema: "crm",
280
+ map: "activity",
281
+ fields: {
282
+ id: field4.id(),
283
+ type: field4.enum("TaskType"),
284
+ subject: field4.string(),
285
+ description: field4.string({ isOptional: true }),
286
+ contactId: field4.string({ isOptional: true }),
287
+ dealId: field4.string({ isOptional: true }),
288
+ companyId: field4.string({ isOptional: true }),
289
+ organizationId: field4.foreignKey(),
290
+ performedBy: field4.foreignKey(),
291
+ outcome: field4.string({ isOptional: true }),
292
+ occurredAt: field4.dateTime(),
293
+ duration: field4.int({
294
+ isOptional: true,
295
+ description: "Duration in minutes"
296
+ }),
297
+ createdAt: field4.createdAt(),
298
+ contact: field4.belongsTo("Contact", ["contactId"], ["id"]),
299
+ deal: field4.belongsTo("Deal", ["dealId"], ["id"]),
300
+ company: field4.belongsTo("Company", ["companyId"], ["id"])
301
+ },
302
+ indexes: [
303
+ index4.on(["contactId", "occurredAt"]),
304
+ index4.on(["dealId", "occurredAt"])
305
+ ]
306
+ });
307
+ // src/entities/index.ts
308
+ var crmPipelineSchemaContribution = {
309
+ moduleId: "@contractspec/example.crm-pipeline",
310
+ entities: [
311
+ CompanyEntity,
312
+ ContactEntity,
313
+ DealEntity,
314
+ PipelineEntity,
315
+ StageEntity,
316
+ TaskEntity,
317
+ ActivityEntity
318
+ ],
319
+ enums: [
320
+ CompanySizeEnum,
321
+ ContactStatusEnum,
322
+ DealStatusEnum,
323
+ TaskTypeEnum,
324
+ TaskPriorityEnum,
325
+ TaskStatusEnum
326
+ ]
327
+ };
328
+ export {
329
+ crmPipelineSchemaContribution,
330
+ TaskTypeEnum,
331
+ TaskStatusEnum,
332
+ TaskPriorityEnum,
333
+ TaskEntity,
334
+ StageEntity,
335
+ PipelineEntity,
336
+ DealStatusEnum,
337
+ DealEntity,
338
+ ContactStatusEnum,
339
+ ContactEntity,
340
+ CompanySizeEnum,
341
+ CompanyEntity,
342
+ ActivityEntity
343
+ };
@@ -0,0 +1,99 @@
1
+ // src/entities/task.entity.ts
2
+ import {
3
+ defineEntity,
4
+ defineEntityEnum,
5
+ field,
6
+ index
7
+ } from "@contractspec/lib.schema";
8
+ var TaskTypeEnum = defineEntityEnum({
9
+ name: "TaskType",
10
+ values: ["CALL", "EMAIL", "MEETING", "TODO", "FOLLOW_UP", "OTHER"],
11
+ schema: "crm",
12
+ description: "Type of CRM task."
13
+ });
14
+ var TaskPriorityEnum = defineEntityEnum({
15
+ name: "TaskPriority",
16
+ values: ["LOW", "NORMAL", "HIGH", "URGENT"],
17
+ schema: "crm",
18
+ description: "Priority of a task."
19
+ });
20
+ var TaskStatusEnum = defineEntityEnum({
21
+ name: "TaskStatus",
22
+ values: ["PENDING", "IN_PROGRESS", "COMPLETED", "CANCELLED"],
23
+ schema: "crm",
24
+ description: "Status of a task."
25
+ });
26
+ var TaskEntity = defineEntity({
27
+ name: "Task",
28
+ description: "A task or follow-up activity.",
29
+ schema: "crm",
30
+ map: "task",
31
+ fields: {
32
+ id: field.id(),
33
+ title: field.string({ description: "Task title" }),
34
+ description: field.string({ isOptional: true }),
35
+ type: field.enum("TaskType", { default: "TODO" }),
36
+ priority: field.enum("TaskPriority", { default: "NORMAL" }),
37
+ status: field.enum("TaskStatus", { default: "PENDING" }),
38
+ dueDate: field.dateTime({ isOptional: true }),
39
+ reminderAt: field.dateTime({ isOptional: true }),
40
+ contactId: field.string({ isOptional: true }),
41
+ dealId: field.string({ isOptional: true }),
42
+ companyId: field.string({ isOptional: true }),
43
+ organizationId: field.foreignKey(),
44
+ assignedTo: field.foreignKey({ description: "User assigned to this task" }),
45
+ createdBy: field.foreignKey(),
46
+ completedAt: field.dateTime({ isOptional: true }),
47
+ completedBy: field.string({ isOptional: true }),
48
+ createdAt: field.createdAt(),
49
+ updatedAt: field.updatedAt(),
50
+ contact: field.belongsTo("Contact", ["contactId"], ["id"]),
51
+ deal: field.belongsTo("Deal", ["dealId"], ["id"]),
52
+ company: field.belongsTo("Company", ["companyId"], ["id"])
53
+ },
54
+ indexes: [
55
+ index.on(["organizationId", "assignedTo", "status"]),
56
+ index.on(["dueDate", "status"]),
57
+ index.on(["contactId"]),
58
+ index.on(["dealId"])
59
+ ],
60
+ enums: [TaskTypeEnum, TaskPriorityEnum, TaskStatusEnum]
61
+ });
62
+ var ActivityEntity = defineEntity({
63
+ name: "Activity",
64
+ description: "An activity/interaction logged in the CRM.",
65
+ schema: "crm",
66
+ map: "activity",
67
+ fields: {
68
+ id: field.id(),
69
+ type: field.enum("TaskType"),
70
+ subject: field.string(),
71
+ description: field.string({ isOptional: true }),
72
+ contactId: field.string({ isOptional: true }),
73
+ dealId: field.string({ isOptional: true }),
74
+ companyId: field.string({ isOptional: true }),
75
+ organizationId: field.foreignKey(),
76
+ performedBy: field.foreignKey(),
77
+ outcome: field.string({ isOptional: true }),
78
+ occurredAt: field.dateTime(),
79
+ duration: field.int({
80
+ isOptional: true,
81
+ description: "Duration in minutes"
82
+ }),
83
+ createdAt: field.createdAt(),
84
+ contact: field.belongsTo("Contact", ["contactId"], ["id"]),
85
+ deal: field.belongsTo("Deal", ["dealId"], ["id"]),
86
+ company: field.belongsTo("Company", ["companyId"], ["id"])
87
+ },
88
+ indexes: [
89
+ index.on(["contactId", "occurredAt"]),
90
+ index.on(["dealId", "occurredAt"])
91
+ ]
92
+ });
93
+ export {
94
+ TaskTypeEnum,
95
+ TaskStatusEnum,
96
+ TaskPriorityEnum,
97
+ TaskEntity,
98
+ ActivityEntity
99
+ };
@@ -0,0 +1,31 @@
1
+ // src/events/contact.event.ts
2
+ import { ScalarTypeEnum, defineSchemaModel } from "@contractspec/lib.schema";
3
+ import { defineEvent } from "@contractspec/lib.contracts";
4
+ var ContactCreatedPayload = defineSchemaModel({
5
+ name: "ContactCreatedPayload",
6
+ description: "Payload when a contact is created",
7
+ fields: {
8
+ contactId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
9
+ email: { type: ScalarTypeEnum.EmailAddress(), isOptional: true },
10
+ organizationId: {
11
+ type: ScalarTypeEnum.String_unsecure(),
12
+ isOptional: false
13
+ },
14
+ ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
15
+ createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
16
+ }
17
+ });
18
+ var ContactCreatedEvent = defineEvent({
19
+ meta: {
20
+ key: "contact.created",
21
+ version: "1.0.0",
22
+ description: "A new contact has been created.",
23
+ stability: "stable",
24
+ owners: ["@crm-team"],
25
+ tags: ["contact", "created"]
26
+ },
27
+ payload: ContactCreatedPayload
28
+ });
29
+ export {
30
+ ContactCreatedEvent
31
+ };