@elevasis/core 0.23.0 → 0.24.1

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 (243) hide show
  1. package/dist/index.d.ts +4343 -2690
  2. package/dist/index.js +1101 -156
  3. package/dist/knowledge/index.d.ts +574 -210
  4. package/dist/knowledge/index.js +104 -1
  5. package/dist/organization-model/index.d.ts +4343 -2690
  6. package/dist/organization-model/index.js +1101 -156
  7. package/dist/test-utils/index.d.ts +483 -109
  8. package/dist/test-utils/index.js +904 -144
  9. package/package.json +3 -3
  10. package/src/README.md +14 -14
  11. package/src/__tests__/publish.test.ts +24 -24
  12. package/src/__tests__/template-core-compatibility.test.ts +9 -12
  13. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +2137 -2093
  14. package/src/_gen/__tests__/scaffold-contracts.test.ts +30 -30
  15. package/src/auth/multi-tenancy/credentials/__tests__/encryption.test.ts +217 -217
  16. package/src/auth/multi-tenancy/credentials/server/encryption.ts +69 -69
  17. package/src/auth/multi-tenancy/credentials/server/kek-loader.ts +37 -37
  18. package/src/auth/multi-tenancy/index.ts +26 -26
  19. package/src/auth/multi-tenancy/invitations/api-schemas.ts +104 -104
  20. package/src/auth/multi-tenancy/memberships/api-schemas.ts +143 -143
  21. package/src/auth/multi-tenancy/memberships/index.ts +26 -26
  22. package/src/auth/multi-tenancy/memberships/membership.ts +130 -130
  23. package/src/auth/multi-tenancy/organizations/__tests__/api-schemas.test.ts +194 -194
  24. package/src/auth/multi-tenancy/organizations/api-schemas.ts +136 -136
  25. package/src/auth/multi-tenancy/permissions.test.ts +42 -42
  26. package/src/auth/multi-tenancy/permissions.ts +123 -123
  27. package/src/auth/multi-tenancy/role-management/api-schemas.ts +78 -78
  28. package/src/auth/multi-tenancy/role-management/index.ts +16 -16
  29. package/src/auth/multi-tenancy/theme-presets.ts +45 -45
  30. package/src/auth/multi-tenancy/types.ts +57 -57
  31. package/src/auth/multi-tenancy/users/api-schemas.ts +165 -165
  32. package/src/business/README.md +2 -2
  33. package/src/business/acquisition/activity-events.test.ts +250 -250
  34. package/src/business/acquisition/activity-events.ts +93 -93
  35. package/src/business/acquisition/api-schemas.test.ts +1883 -1843
  36. package/src/business/acquisition/api-schemas.ts +1492 -1497
  37. package/src/business/acquisition/build-templates.test.ts +240 -240
  38. package/src/business/acquisition/build-templates.ts +98 -98
  39. package/src/business/acquisition/crm-next-action.test.ts +262 -262
  40. package/src/business/acquisition/crm-next-action.ts +220 -220
  41. package/src/business/acquisition/crm-priority.test.ts +216 -216
  42. package/src/business/acquisition/crm-priority.ts +349 -349
  43. package/src/business/acquisition/crm-state-actions.test.ts +153 -153
  44. package/src/business/acquisition/deal-ownership.test.ts +351 -351
  45. package/src/business/acquisition/deal-ownership.ts +120 -120
  46. package/src/business/acquisition/derive-actions.test.ts +129 -104
  47. package/src/business/acquisition/derive-actions.ts +74 -84
  48. package/src/business/acquisition/index.ts +171 -170
  49. package/src/business/acquisition/ontology-validation.ts +309 -0
  50. package/src/business/acquisition/stateful.ts +30 -30
  51. package/src/business/acquisition/types.ts +396 -396
  52. package/src/business/clients/api-schemas.test.ts +115 -115
  53. package/src/business/clients/api-schemas.ts +158 -158
  54. package/src/business/clients/index.ts +1 -1
  55. package/src/business/crm/api-schemas.ts +40 -40
  56. package/src/business/crm/index.ts +1 -1
  57. package/src/business/deals/api-schemas.ts +87 -87
  58. package/src/business/deals/index.ts +1 -1
  59. package/src/business/index.ts +5 -5
  60. package/src/business/projects/types.ts +144 -144
  61. package/src/commands/queue/types/task.ts +15 -15
  62. package/src/execution/core/runner-types.ts +61 -61
  63. package/src/execution/core/sse-executions.ts +7 -7
  64. package/src/execution/engine/__tests__/fixtures/test-agents.ts +10 -10
  65. package/src/execution/engine/agent/core/__tests__/agent.test.ts +16 -16
  66. package/src/execution/engine/agent/core/__tests__/error-passthrough.test.ts +4 -4
  67. package/src/execution/engine/agent/core/types.ts +25 -25
  68. package/src/execution/engine/agent/index.ts +6 -6
  69. package/src/execution/engine/agent/reasoning/__tests__/request-builder.test.ts +24 -24
  70. package/src/execution/engine/index.ts +443 -443
  71. package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +298 -298
  72. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.test.ts +55 -55
  73. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +107 -107
  74. package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.test.ts +48 -48
  75. package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.ts +99 -99
  76. package/src/execution/engine/tools/integration/server/adapters/apollo/index.ts +1 -1
  77. package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +363 -363
  78. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.test.ts +162 -162
  79. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.test.ts +316 -316
  80. package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.test.ts +18 -18
  81. package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.ts +194 -194
  82. package/src/execution/engine/tools/integration/server/adapters/clickup/index.ts +7 -7
  83. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +204 -204
  84. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +105 -105
  85. package/src/execution/engine/tools/integration/server/adapters/google-calendar/google-calendar-adapter.ts +428 -428
  86. package/src/execution/engine/tools/integration/server/adapters/google-calendar/index.ts +2 -2
  87. package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -261
  88. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1474 -1474
  89. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +103 -103
  90. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.test.ts +88 -88
  91. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +141 -141
  92. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +76 -76
  93. package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-tools.ts +182 -182
  94. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +310 -310
  95. package/src/execution/engine/tools/integration/service.test.ts +239 -239
  96. package/src/execution/engine/tools/integration/service.ts +172 -172
  97. package/src/execution/engine/tools/integration/tool.ts +255 -255
  98. package/src/execution/engine/tools/lead-service-types.ts +1005 -1005
  99. package/src/execution/engine/tools/messages.ts +43 -43
  100. package/src/execution/engine/tools/platform/acquisition/company-tools.ts +7 -7
  101. package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +6 -6
  102. package/src/execution/engine/tools/platform/acquisition/list-tools.ts +6 -6
  103. package/src/execution/engine/tools/platform/acquisition/types.ts +280 -280
  104. package/src/execution/engine/tools/platform/email/types.ts +97 -97
  105. package/src/execution/engine/tools/registry.ts +704 -704
  106. package/src/execution/engine/tools/tool-maps.ts +831 -831
  107. package/src/execution/engine/tools/types.ts +234 -234
  108. package/src/execution/engine/workflow/types.ts +195 -197
  109. package/src/execution/external/__tests__/api-schemas.test.ts +127 -127
  110. package/src/execution/external/api-schemas.ts +40 -40
  111. package/src/execution/external/index.ts +1 -1
  112. package/src/index.ts +18 -18
  113. package/src/integrations/credentials/__tests__/api-schemas.test.ts +420 -420
  114. package/src/integrations/credentials/api-schemas.ts +146 -146
  115. package/src/integrations/credentials/schemas.ts +200 -200
  116. package/src/integrations/oauth/__tests__/provider-registry.test.ts +7 -7
  117. package/src/integrations/oauth/provider-registry.ts +74 -74
  118. package/src/integrations/oauth/server/credentials.ts +43 -43
  119. package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +327 -327
  120. package/src/integrations/webhook-endpoints/api-schemas.ts +103 -103
  121. package/src/integrations/webhook-endpoints/types.ts +58 -58
  122. package/src/knowledge/README.md +32 -32
  123. package/src/knowledge/__tests__/queries.test.ts +626 -535
  124. package/src/knowledge/format.ts +99 -99
  125. package/src/knowledge/index.ts +5 -5
  126. package/src/knowledge/published.ts +5 -5
  127. package/src/knowledge/queries.ts +269 -218
  128. package/src/operations/activities/api-schemas.ts +80 -80
  129. package/src/operations/activities/types.ts +64 -64
  130. package/src/organization-model/README.md +149 -149
  131. package/src/organization-model/__tests__/content-kinds-registry.test.ts +210 -210
  132. package/src/organization-model/__tests__/defaults.test.ts +168 -168
  133. package/src/organization-model/__tests__/domains/actions.test.ts +78 -56
  134. package/src/organization-model/__tests__/domains/customers.test.ts +299 -299
  135. package/src/organization-model/__tests__/domains/entities.test.ts +56 -56
  136. package/src/organization-model/__tests__/domains/goals.test.ts +493 -493
  137. package/src/organization-model/__tests__/domains/identity.test.ts +280 -280
  138. package/src/organization-model/__tests__/domains/navigation.test.ts +268 -268
  139. package/src/organization-model/__tests__/domains/offerings.test.ts +414 -414
  140. package/src/organization-model/__tests__/domains/policies.test.ts +323 -323
  141. package/src/organization-model/__tests__/domains/resource-mappings.test.ts +293 -293
  142. package/src/organization-model/__tests__/domains/resources.test.ts +387 -277
  143. package/src/organization-model/__tests__/domains/roles.test.ts +463 -463
  144. package/src/organization-model/__tests__/domains/statuses.test.ts +246 -246
  145. package/src/organization-model/__tests__/domains/systems.test.ts +209 -209
  146. package/src/organization-model/__tests__/domains/topology.test.ts +188 -0
  147. package/src/organization-model/__tests__/flatten-additive-merge.test.ts +362 -361
  148. package/src/organization-model/__tests__/foundation.test.ts +77 -77
  149. package/src/organization-model/__tests__/get-resources-for-system.test.ts +144 -144
  150. package/src/organization-model/__tests__/graph.test.ts +1312 -862
  151. package/src/organization-model/__tests__/icons.test.ts +10 -1
  152. package/src/organization-model/__tests__/knowledge.test.ts +251 -15
  153. package/src/organization-model/__tests__/lookup-helpers.test.ts +438 -438
  154. package/src/organization-model/__tests__/migration-helpers.test.ts +591 -591
  155. package/src/organization-model/__tests__/prospecting-ssot.test.ts +103 -103
  156. package/src/organization-model/__tests__/recursive-system-schema.test.ts +535 -506
  157. package/src/organization-model/__tests__/resolve.test.ts +274 -164
  158. package/src/organization-model/__tests__/schema.test.ts +844 -301
  159. package/src/organization-model/__tests__/surface-projection.test.ts +284 -284
  160. package/src/organization-model/catalogs/lead-gen.ts +144 -144
  161. package/src/organization-model/content-kinds/config.ts +36 -36
  162. package/src/organization-model/content-kinds/index.ts +76 -72
  163. package/src/organization-model/content-kinds/pipeline.ts +68 -68
  164. package/src/organization-model/content-kinds/registry.ts +44 -44
  165. package/src/organization-model/content-kinds/status.ts +71 -71
  166. package/src/organization-model/content-kinds/template.ts +83 -83
  167. package/src/organization-model/content-kinds/types.ts +117 -117
  168. package/src/organization-model/contracts.ts +27 -27
  169. package/src/organization-model/defaults.ts +42 -50
  170. package/src/organization-model/domains/actions.ts +333 -239
  171. package/src/organization-model/domains/customers.ts +78 -78
  172. package/src/organization-model/domains/entities.ts +144 -144
  173. package/src/organization-model/domains/goals.ts +83 -83
  174. package/src/organization-model/domains/knowledge.ts +117 -101
  175. package/src/organization-model/domains/navigation.ts +139 -139
  176. package/src/organization-model/domains/offerings.ts +71 -71
  177. package/src/organization-model/domains/policies.ts +102 -102
  178. package/src/organization-model/domains/projects.ts +14 -14
  179. package/src/organization-model/domains/prospecting.ts +395 -395
  180. package/src/organization-model/domains/resources.ts +202 -124
  181. package/src/organization-model/domains/roles.ts +96 -96
  182. package/src/organization-model/domains/sales.test.ts +218 -218
  183. package/src/organization-model/domains/sales.ts +380 -380
  184. package/src/organization-model/domains/shared.ts +63 -63
  185. package/src/organization-model/domains/statuses.ts +339 -339
  186. package/src/organization-model/domains/systems.ts +217 -172
  187. package/src/organization-model/domains/topology.ts +261 -0
  188. package/src/organization-model/foundation.ts +75 -75
  189. package/src/organization-model/graph/build.ts +1043 -867
  190. package/src/organization-model/graph/index.ts +4 -4
  191. package/src/organization-model/graph/link.ts +10 -10
  192. package/src/organization-model/graph/schema.ts +75 -68
  193. package/src/organization-model/graph/types.ts +71 -64
  194. package/src/organization-model/helpers.ts +289 -241
  195. package/src/organization-model/icons.ts +78 -66
  196. package/src/organization-model/index.ts +128 -125
  197. package/src/organization-model/migration-helpers.ts +247 -244
  198. package/src/organization-model/ontology.ts +658 -0
  199. package/src/organization-model/organization-graph.mdx +110 -90
  200. package/src/organization-model/organization-model.mdx +225 -213
  201. package/src/organization-model/published.ts +299 -222
  202. package/src/organization-model/resolve.ts +146 -91
  203. package/src/organization-model/schema.ts +818 -659
  204. package/src/organization-model/surface-projection.ts +212 -212
  205. package/src/organization-model/types.ts +179 -155
  206. package/src/platform/api/types.ts +38 -38
  207. package/src/platform/constants/versions.ts +3 -3
  208. package/src/platform/index.ts +23 -23
  209. package/src/platform/registry/__tests__/command-view.test.ts +10 -10
  210. package/src/platform/registry/__tests__/resource-link.test.ts +35 -35
  211. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +20 -20
  212. package/src/platform/registry/__tests__/resource-registry.nested-systems.test.ts +245 -245
  213. package/src/platform/registry/__tests__/resource-registry.test.ts +2053 -2053
  214. package/src/platform/registry/__tests__/validation.test.ts +1444 -1259
  215. package/src/platform/registry/command-view.ts +10 -10
  216. package/src/platform/registry/index.ts +103 -103
  217. package/src/platform/registry/resource-link.ts +32 -32
  218. package/src/platform/registry/resource-registry.ts +886 -886
  219. package/src/platform/registry/serialization.ts +295 -295
  220. package/src/platform/registry/serialized-types.ts +166 -166
  221. package/src/platform/registry/stats-types.ts +68 -68
  222. package/src/platform/registry/types.ts +425 -425
  223. package/src/platform/registry/validation.ts +876 -684
  224. package/src/platform/utils/__tests__/validation.test.ts +1084 -1084
  225. package/src/platform/utils/validation.ts +425 -425
  226. package/src/projects/api-schemas.test.ts +39 -39
  227. package/src/projects/api-schemas.ts +291 -291
  228. package/src/reference/_generated/contracts.md +2136 -2093
  229. package/src/reference/glossary.md +76 -76
  230. package/src/scaffold-registry/__tests__/index.test.ts +206 -206
  231. package/src/scaffold-registry/__tests__/schema.test.ts +166 -166
  232. package/src/scaffold-registry/index.ts +392 -392
  233. package/src/scaffold-registry/schema.ts +243 -243
  234. package/src/server.ts +289 -289
  235. package/src/supabase/database.types.ts +3 -0
  236. package/src/test-utils/README.md +37 -37
  237. package/src/test-utils/entities.ts +108 -108
  238. package/src/test-utils/fixtures/memberships.ts +82 -82
  239. package/src/test-utils/index.ts +12 -12
  240. package/src/test-utils/organization-model.ts +65 -65
  241. package/src/test-utils/published.ts +6 -6
  242. package/src/test-utils/rls/RLSTestContext.ts +588 -588
  243. package/src/test-utils/test-utils.test.ts +44 -44
@@ -1,1005 +1,1005 @@
1
- /**
2
- * Lead Service Types
3
- * CRUD operation types for the acquisition platform (lists, companies, contacts, deals)
4
- *
5
- * Implementation: apps/api/src/acquisition/lead-service.ts (LeadService class)
6
- */
7
-
8
- import type { Json } from '../../../supabase'
9
-
10
- // Re-export acquisition domain types from the authoritative source
11
- import type {
12
- AcqList,
13
- AcqCompany,
14
- AcqContact,
15
- AcqDealTask,
16
- AcqDealTaskKind,
17
- ListStatus,
18
- ScrapingConfig,
19
- IcpRubric,
20
- PipelineConfig,
21
- ProcessingState,
22
- ListTelemetry,
23
- DealDetail
24
- } from '../../../business/acquisition/types'
25
- import type { ListProgress, ProcessingStageStatus } from '../../../business/acquisition/api-schemas'
26
-
27
- export type {
28
- AcqList,
29
- AcqCompany,
30
- AcqContact,
31
- AcqDealTask,
32
- AcqDealTaskKind,
33
- ListStatus,
34
- ScrapingConfig,
35
- IcpRubric,
36
- PipelineConfig,
37
- ProcessingState,
38
- ProcessingStageStatus,
39
- ListTelemetry,
40
- DealDetail,
41
- ListProgress
42
- }
43
-
44
- // Pagination types
45
- export interface PaginationParams {
46
- limit: number
47
- offset: number
48
- }
49
-
50
- export interface PaginatedResult<T> {
51
- data: T[]
52
- total: number
53
- limit: number
54
- offset: number
55
- }
56
-
57
- // List params
58
- export interface CreateListParams {
59
- organizationId: string
60
- name: string
61
- description?: string
62
- type?: string
63
- batchIds?: string[]
64
- instantlyCampaignId?: string
65
- status?: ListStatus
66
- buildTemplateId?: string
67
- metadata?: Record<string, unknown>
68
- scrapingConfig?: ScrapingConfig
69
- icp?: IcpRubric
70
- pipelineConfig?: PipelineConfig
71
- }
72
-
73
- export interface UpdateListParams {
74
- name?: string
75
- description?: string
76
- batchIds?: string[]
77
- }
78
-
79
- export interface UpdateListStatusParams {
80
- organizationId: string
81
- listId: string
82
- status: ListStatus
83
- }
84
-
85
- // Company params
86
- export interface CreateCompanyParams {
87
- organizationId: string
88
- name: string
89
- domain?: string
90
- linkedinUrl?: string
91
- website?: string
92
- numEmployees?: number
93
- foundedYear?: number
94
- locationCity?: string
95
- locationState?: string
96
- category?: string
97
- source?: string
98
- batchId?: string
99
- verticalResearch?: string
100
- /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
101
- pipelineStatus?: unknown
102
- }
103
-
104
- export interface UpdateCompanyParams {
105
- name?: string
106
- domain?: string
107
- linkedinUrl?: string
108
- website?: string
109
- numEmployees?: number
110
- foundedYear?: number
111
- locationCity?: string
112
- locationState?: string
113
- category?: string
114
- segment?: string
115
- processingState?: ProcessingState
116
- /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
117
- pipelineStatus?: unknown
118
- enrichmentData?: Record<string, unknown>
119
- source?: string
120
- batchId?: string
121
- status?: 'active' | 'invalid'
122
- verticalResearch?: string | null
123
- /** Track A: flat qualification score column (null until a scoring rubric is defined) */
124
- qualificationScore?: number | null
125
- /** Track A: flat qualification signals jsonb */
126
- qualificationSignals?: Record<string, unknown> | null
127
- /** Track A: key identifying the rubric used for qualification */
128
- qualificationRubricKey?: string | null
129
- }
130
-
131
- export type UpsertCompanyParams = CreateCompanyParams
132
- // Upsert by domain - uses same fields as create
133
-
134
- export interface CompanyFilters {
135
- listId?: string // Filter to companies in a specific list (via acq_list_companies)
136
- search?: string
137
- domain?: string
138
- website?: string
139
- segment?: string
140
- category?: string
141
- processingState?: ProcessingState
142
- /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
143
- pipelineStatus?: unknown
144
- /** Exclude companies whose processing state contains this value (PostgREST NOT contains) */
145
- processingStateNot?: ProcessingState
146
- batchId?: string
147
- status?: 'active' | 'invalid'
148
- includeAll?: boolean
149
- excludeColumns?: Array<'enrichmentData' | 'processingState'>
150
- limit?: number
151
- }
152
-
153
- // Contact params
154
- export interface CreateContactParams {
155
- organizationId: string
156
- email: string
157
- companyId?: string
158
- firstName?: string
159
- lastName?: string
160
- linkedinUrl?: string
161
- title?: string
162
- source?: string
163
- sourceId?: string
164
- batchId?: string
165
- /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
166
- pipelineStatus?: unknown
167
- }
168
-
169
- export interface UpdateContactParams {
170
- companyId?: string
171
- emailValid?: 'VALID' | 'INVALID' | 'RISKY' | 'UNKNOWN'
172
- firstName?: string
173
- lastName?: string
174
- linkedinUrl?: string
175
- title?: string
176
- headline?: string
177
- filterReason?: string
178
- openingLine?: string
179
- processingState?: ProcessingState
180
- /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
181
- pipelineStatus?: unknown
182
- enrichmentData?: Record<string, unknown>
183
- status?: 'active' | 'invalid'
184
- }
185
-
186
- export type UpsertContactParams = CreateContactParams
187
- // Upsert by email - uses same fields as create
188
-
189
- export interface ContactFilters {
190
- listId?: string // Filter to contacts in a specific list (via acq_list_members)
191
- search?: string
192
- openingLineIsNull?: boolean // Filter to contacts without personalization
193
- processingState?: ProcessingState
194
- /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
195
- pipelineStatus?: unknown
196
- batchId?: string
197
- contactStatus?: 'active' | 'invalid' // Filter by contact status (soft-delete flag)
198
- }
199
-
200
- // Deal params (for acq_deals table)
201
- export interface UpsertDealParams {
202
- organizationId: string
203
- /** Contact email — dedupe key together with organization_id */
204
- contactEmail: string
205
- /** Optional contact ID for foreign key join */
206
- contactId?: string
207
- /** Campaign list that generated this deal (FK to acq_lists) */
208
- sourceListId?: string
209
- /** Deal origin: 'instantly', 'referral', 'inbound', 'manual' */
210
- sourceType?: 'instantly' | 'referral' | 'inbound' | 'manual'
211
- /** Optional discovery data JSONB to set on upsert */
212
- discoveryData?: unknown
213
- /** Optional proposal data JSONB to set on upsert */
214
- proposalData?: unknown
215
- /** Instantly email UUID used to hydrate the reply thread */
216
- instantlyThreadUuid?: string
217
- /** Instantly sender account for direction detection */
218
- instantlyEmailAccount?: string
219
- }
220
-
221
- export interface UpdateDiscoveryDataParams {
222
- organizationId: string
223
- contactEmail: string
224
- discoveryData: unknown
225
- submittedBy?: string
226
- }
227
-
228
- export interface UpdateProposalDataParams {
229
- organizationId: string
230
- contactEmail: string
231
- proposalData: unknown
232
- proposalPdfUrl?: string
233
- }
234
-
235
- export interface MarkProposalSentParams {
236
- organizationId: string
237
- contactEmail: string
238
- }
239
-
240
- export interface MarkProposalReviewedParams {
241
- organizationId: string
242
- contactEmail: string
243
- reviewedBy: string
244
- proposalData?: unknown
245
- }
246
-
247
- export interface UpdateCloseLostReasonParams {
248
- organizationId: string
249
- dealId: string
250
- reason: string
251
- }
252
-
253
- export interface UpdateFeesParams {
254
- organizationId: string
255
- contactEmail?: string
256
- dealId?: string
257
- initialFee?: number
258
- monthlyFee?: number
259
- }
260
-
261
- export interface CacheInstantlyThreadIdsParams {
262
- organizationId: string
263
- dealId: string
264
- instantlyThreadUuid: string
265
- instantlyEmailAccount: string
266
- }
267
-
268
- export interface TransitionItemParams {
269
- organizationId: string
270
- dealId: string
271
- pipelineKey: string
272
- stageKey: string
273
- stateKey?: string | null
274
- reason?: string
275
- expectedUpdatedAt?: string
276
- }
277
-
278
- export interface SetContactNurtureParams {
279
- organizationId: string
280
- contactEmail: string
281
- nurture?: boolean
282
- }
283
-
284
- export interface DeactivateContactsByCompanyParams {
285
- organizationId: string
286
- companyId: string
287
- }
288
-
289
- export interface DeactivateContactsByCompanyResult {
290
- deactivated: number
291
- }
292
-
293
- export interface CancelSchedulesAndHitlByEmailParams {
294
- organizationId: string
295
- email: string
296
- }
297
-
298
- export interface CancelHitlByDealIdParams {
299
- organizationId: string
300
- dealId: string
301
- }
302
-
303
- export interface ClearDealFieldsParams {
304
- organizationId: string
305
- contactEmail?: string
306
- dealId?: string
307
- fields: (
308
- | 'proposalPdfUrl'
309
- | 'proposalGeneratedAt'
310
- | 'initialFee'
311
- | 'monthlyFee'
312
- | 'closedLostReason'
313
- | 'closedLostAt'
314
- | 'discoveryData'
315
- | 'discoverySubmittedAt'
316
- )[]
317
- }
318
-
319
- export interface DeleteDealParams {
320
- organizationId: string
321
- dealId: string
322
- }
323
-
324
- export interface GetDealByIdParams {
325
- dealId: string
326
- organizationId: string
327
- }
328
-
329
- export interface GetContactByIdParams {
330
- contactId: string
331
- organizationId: string
332
- }
333
-
334
- export interface GetCompanyByIdParams {
335
- companyId: string
336
- organizationId: string
337
- }
338
-
339
- // Social monitoring params (acq_social_posts table)
340
- export interface UpsertSocialPostParams {
341
- organizationId: string
342
- platform: string
343
- platformPostId: string
344
- authorName: string
345
- authorUrl?: string | null
346
- postTitle: string
347
- postText: string
348
- postUrl: string
349
- engagementCount?: number
350
- commentsCount?: number
351
- postedAt: string
352
- metadata?: Record<string, unknown>
353
- relevanceScore?: number
354
- matchedKeywords?: string[]
355
- matchedQuery?: string | null
356
- initialDraft?: string | null
357
- finalResponse?: string | null
358
- sourceCategory?: string | null
359
- }
360
-
361
- export interface UpsertSocialPostsParams {
362
- organizationId: string
363
- posts: Omit<UpsertSocialPostParams, 'organizationId'>[]
364
- }
365
-
366
- export interface UpsertSocialPostsResult {
367
- inserted: number
368
- duplicatesSkipped: number
369
- }
370
-
371
- export interface AcqDeal {
372
- id: string
373
- organizationId: string
374
- contactEmail: string
375
- pipelineKey: string
376
- stageKey?: string | null
377
- stateKey?: string | null
378
- discoveryData?: Json | null
379
- proposalData?: Json | null
380
- proposalSentAt?: string | null
381
- proposalPdfUrl?: string | null
382
- signatureEnvelopeId?: string | null
383
- sourceListId?: string | null
384
- sourceType?: string | null
385
- activityLog: DealActivityEntry[]
386
- createdAt: Date
387
- updatedAt: Date
388
- }
389
-
390
- export interface DealActivityEntry {
391
- type: string
392
- title: string
393
- description?: string
394
- payload?: Record<string, unknown>
395
- occurredAt: string
396
- }
397
-
398
- export interface AcqDealNote {
399
- id: string
400
- dealId: string
401
- organizationId: string
402
- authorUserId: string | null
403
- body: string
404
- createdAt: string
405
- updatedAt: string
406
- }
407
-
408
- export interface CreateDealNoteParams {
409
- organizationId: string
410
- dealId: string
411
- body: string
412
- authorUserId?: string
413
- }
414
-
415
- export interface ListDealNotesParams {
416
- organizationId: string
417
- dealId: string
418
- }
419
-
420
- export interface CreateDealTaskParams {
421
- organizationId: string
422
- dealId: string
423
- title: string
424
- description?: string | null
425
- kind?: AcqDealTaskKind
426
- dueAt?: string | null
427
- assigneeUserId?: string | null
428
- createdByUserId?: string | null
429
- }
430
-
431
- export interface ListDealTasksParams {
432
- organizationId: string
433
- dealId: string
434
- }
435
-
436
- export interface ListDealTasksDueParams {
437
- organizationId: string
438
- assigneeUserId?: string | null
439
- /** Window filter: 'overdue' = past due, 'today' = due today only, 'today_and_overdue' (default) = both, 'upcoming' = future */
440
- window?: 'overdue' | 'today' | 'today_and_overdue' | 'upcoming'
441
- }
442
-
443
- export interface CompleteDealTaskParams {
444
- organizationId: string
445
- taskId: string
446
- completedByUserId: string | null
447
- }
448
-
449
- export interface RecordDealActivityParams {
450
- organizationId: string
451
- dealId: string
452
- type: string
453
- title: string
454
- description?: string
455
- payload?: Record<string, unknown>
456
- }
457
-
458
- export interface SetDealStateKeyParams {
459
- organizationId: string
460
- dealId: string
461
- stateKey: string
462
- }
463
-
464
- export interface TransitionDealParams {
465
- organizationId: string
466
- dealId: string
467
- toStage: string
468
- toState?: string
469
- }
470
-
471
- export interface LoadDealParams {
472
- organizationId: string
473
- dealId: string
474
- }
475
-
476
- // Deal analytics types (for /meta status and platform-status workflow)
477
-
478
- export interface DealStageSummary {
479
- stage: string
480
- count: number
481
- oldestUpdatedAt: string | null
482
- newestUpdatedAt: string | null
483
- }
484
-
485
- export interface StaleDeal {
486
- id: string
487
- contactEmail: string
488
- stageKey: string
489
- updatedAt: string
490
- daysStale: number
491
- }
492
-
493
- export interface DealPipelineAnalytics {
494
- totalDeals: number
495
- stageSummary: DealStageSummary[]
496
- staleDeals: StaleDeal[]
497
- recentActivity: AcqDeal[]
498
- }
499
-
500
- export interface DealAnalyticsParams {
501
- organizationId: string
502
- recentLimit?: number
503
- }
504
-
505
- export interface DealFilters {
506
- stage?: string
507
- search?: string
508
- limit?: number
509
- offset?: number
510
- }
511
-
512
- export interface AddContactsToListParams {
513
- organizationId: string
514
- listId: string
515
- contactIds: string[]
516
- }
517
-
518
- export interface AddContactsToListResult {
519
- added: number
520
- alreadyExisted: number
521
- }
522
-
523
- // List config/progress/executions params
524
- export interface UpdateListConfigParams {
525
- organizationId: string
526
- listId: string
527
- scrapingConfig?: ScrapingConfig
528
- icp?: IcpRubric
529
- pipelineConfig?: PipelineConfig
530
- }
531
-
532
- export interface UpdateCompanyStageParams {
533
- organizationId: string
534
- listId: string
535
- companyId: string
536
- stage: string
537
- status?: ProcessingStageStatus
538
- executionId?: string
539
- }
540
-
541
- export interface UpdateContactStageParams {
542
- organizationId: string
543
- listId: string
544
- contactId: string
545
- stage: string
546
- status?: ProcessingStageStatus
547
- executionId?: string
548
- }
549
-
550
- export interface ListPendingCompanyIdsParams {
551
- organizationId: string
552
- listId: string
553
- stageKey: string
554
- limit?: number
555
- }
556
-
557
- export interface ListPendingContactIdsParams {
558
- organizationId: string
559
- listId: string
560
- stageKey: string
561
- limit?: number
562
- }
563
-
564
- export interface AddCompaniesToListParams {
565
- organizationId: string
566
- listId: string
567
- companyIds: string[]
568
- }
569
-
570
- export interface AddCompaniesToListResult {
571
- added: number
572
- alreadyExisted: number
573
- }
574
-
575
- export interface RemoveCompaniesFromListParams {
576
- organizationId: string
577
- listId: string
578
- companyIds: string[]
579
- }
580
-
581
- export interface RemoveCompaniesFromListResult {
582
- removed: number
583
- }
584
-
585
- export interface RecordListExecutionParams {
586
- organizationId: string
587
- listId: string
588
- executionId: string
589
- configSnapshot?: Record<string, unknown>
590
- }
591
-
592
- export interface ListExecutionSummary {
593
- executionId: string
594
- resourceId: string
595
- status: string
596
- createdAt: string
597
- completedAt: string | null
598
- durationMs: number | null
599
- }
600
-
601
- // Bulk import (contacts)
602
- export interface BulkImportParams {
603
- organizationId: string
604
- contacts: CreateContactParams[]
605
- listId?: string
606
- }
607
-
608
- export interface BulkImportResult {
609
- created: number
610
- updated: number
611
- errors: Array<{ email: string; error: string }>
612
- }
613
-
614
- // Bulk import (companies)
615
- export interface BulkImportCompanyEntry {
616
- name: string
617
- domain: string
618
- website?: string
619
- locationCity?: string
620
- locationState?: string
621
- category?: string
622
- source?: string
623
- enrichmentData?: Record<string, unknown>
624
- processingState?: ProcessingState
625
- }
626
-
627
- export interface BulkImportCompaniesParams {
628
- organizationId: string
629
- batchId: string
630
- companies: BulkImportCompanyEntry[]
631
- }
632
-
633
- export interface BulkImportCompaniesResult {
634
- created: number
635
- skipped: number
636
- errors: Array<{ companyName: string; error: string }>
637
- }
638
-
639
- /**
640
- * Lead Service interface for acquisition platform tools.
641
- * Provides CRUD operations for lists, companies, and contacts.
642
- *
643
- * Implementation: apps/api/src/acquisition/lead-service.ts (LeadService class)
644
- *
645
- * Multi-tenancy: All operations require organizationId for tenant isolation.
646
- * All queries are filtered by organizationId via RLS policies.
647
- */
648
- export interface ILeadService {
649
- // List operations
650
- /**
651
- * Create a new list
652
- * @see LeadService.createList (apps/api/src/acquisition/lead-service.ts)
653
- */
654
- createList(params: CreateListParams): Promise<AcqList>
655
-
656
- /**
657
- * Update an existing list
658
- * @see LeadService.updateList (apps/api/src/acquisition/lead-service.ts)
659
- */
660
- updateList(id: string, params: UpdateListParams): Promise<AcqList>
661
-
662
- /**
663
- * Delete a list
664
- * @see LeadService.deleteList (apps/api/src/acquisition/lead-service.ts)
665
- */
666
- deleteList(id: string, organizationId: string): Promise<void>
667
-
668
- /**
669
- * Add contacts to a list (upsert — idempotent on re-runs)
670
- * @see LeadService.addContactsToList (apps/api/src/business/acquisition/lead-service.ts)
671
- */
672
- addContactsToList(params: AddContactsToListParams): Promise<AddContactsToListResult>
673
-
674
- /**
675
- * List all lists for an organization
676
- * @see LeadService.listLists (apps/api/src/acquisition/lead-service.ts)
677
- */
678
- listLists(organizationId: string): Promise<AcqList[]>
679
-
680
- /**
681
- * Get a single list by ID.
682
- */
683
- getList(id: string, organizationId: string): Promise<AcqList | null>
684
-
685
- /**
686
- * Deep-merge patch the jsonb `config` column. Patch keys at any depth
687
- * replace the corresponding subtree.
688
- */
689
- updateListConfig(params: UpdateListConfigParams): Promise<AcqList>
690
-
691
- /**
692
- * Add companies to a list via the acq_list_companies junction.
693
- * Idempotent on (list_id, company_id).
694
- */
695
- addCompaniesToList(params: AddCompaniesToListParams): Promise<AddCompaniesToListResult>
696
-
697
- /**
698
- * Remove companies from a list (delete junction rows only — company rows untouched).
699
- */
700
- removeCompaniesFromList(params: RemoveCompaniesFromListParams): Promise<RemoveCompaniesFromListResult>
701
-
702
- /**
703
- * Live org-wide list telemetry — computed on demand from acq_companies
704
- * and acq_contacts joined through the acq_list_companies / acq_list_members
705
- * junctions. Replaces the batch-scoped getBatchTelemetry.
706
- */
707
- getListsTelemetry(organizationId: string): Promise<ListTelemetry[]>
708
-
709
- /**
710
- * On-demand progress aggregation: COUNT(*) FILTER over processing_state flags,
711
- * keyed by the list's pipeline_config.stages[].key (Decision #4 + #7).
712
- */
713
- getListProgress(listId: string, organizationId: string): Promise<ListProgress | null>
714
-
715
- /**
716
- * Advance a company row within a list's explicit stage journey.
717
- */
718
- updateCompanyStage(params: UpdateCompanyStageParams): Promise<void>
719
-
720
- /**
721
- * Advance a contact row within a list's explicit stage journey.
722
- */
723
- updateContactStage(params: UpdateContactStageParams): Promise<void>
724
-
725
- /**
726
- * Return the company_ids in acq_list_companies for the given list where
727
- * processing_state[stageKey].status is NULL or NOT IN ('success', 'no_result').
728
- * Used by build-pipeline workflows to skip already-processed records.
729
- */
730
- listPendingCompanyIds(params: ListPendingCompanyIdsParams): Promise<string[]>
731
-
732
- /**
733
- * Return the contact_ids in acq_list_members for the given list where
734
- * processing_state[stageKey].status is NULL or NOT IN ('success', 'no_result').
735
- * Used by build-pipeline workflows to skip already-processed records.
736
- */
737
- listPendingContactIds(params: ListPendingContactIdsParams): Promise<string[]>
738
-
739
- /**
740
- * Per-list execution history — reads via the feature-owned
741
- * acq_list_executions junction, joined to execution_logs for details.
742
- */
743
- getListExecutions(listId: string, organizationId: string): Promise<ListExecutionSummary[]>
744
-
745
- /**
746
- * Write a junction row linking (listId, executionId). Called by the
747
- * workflow layer at execution start in Step 4. No-op if the row exists.
748
- */
749
- recordListExecution(params: RecordListExecutionParams): Promise<void>
750
-
751
- // Company operations
752
- /**
753
- * Create a new company
754
- * @see LeadService.createCompany (apps/api/src/acquisition/lead-service.ts)
755
- */
756
- createCompany(params: CreateCompanyParams): Promise<AcqCompany>
757
-
758
- /**
759
- * Update an existing company
760
- * @see LeadService.updateCompany (apps/api/src/acquisition/lead-service.ts)
761
- */
762
- updateCompany(id: string, params: UpdateCompanyParams): Promise<AcqCompany>
763
-
764
- /**
765
- * Upsert a company by domain
766
- * @see LeadService.upsertCompany (apps/api/src/acquisition/lead-service.ts)
767
- */
768
- upsertCompany(params: UpsertCompanyParams): Promise<AcqCompany>
769
-
770
- /**
771
- * Get a company by ID
772
- * @see LeadService.getCompany (apps/api/src/acquisition/lead-service.ts)
773
- */
774
- getCompany(id: string, organizationId: string): Promise<AcqCompany | null>
775
-
776
- /**
777
- * List companies with optional filters
778
- * @see LeadService.listCompanies (apps/api/src/acquisition/lead-service.ts)
779
- */
780
- listCompanies(organizationId: string, filters: CompanyFilters): Promise<AcqCompany[]>
781
-
782
- /**
783
- * Delete a company
784
- * @see LeadService.deleteCompany (apps/api/src/acquisition/lead-service.ts)
785
- */
786
- deleteCompany(id: string, organizationId: string): Promise<void>
787
-
788
- // Contact operations
789
- /**
790
- * Create a new contact
791
- * @see LeadService.createContact (apps/api/src/acquisition/lead-service.ts)
792
- */
793
- createContact(params: CreateContactParams): Promise<AcqContact>
794
-
795
- /**
796
- * Update an existing contact
797
- * @see LeadService.updateContact (apps/api/src/acquisition/lead-service.ts)
798
- */
799
- updateContact(id: string, params: UpdateContactParams): Promise<AcqContact>
800
-
801
- /**
802
- * Upsert a contact by email
803
- * @see LeadService.upsertContact (apps/api/src/acquisition/lead-service.ts)
804
- */
805
- upsertContact(params: UpsertContactParams): Promise<AcqContact>
806
-
807
- /**
808
- * Get a contact by ID
809
- * @see LeadService.getContact (apps/api/src/acquisition/lead-service.ts)
810
- */
811
- getContact(id: string, organizationId: string): Promise<AcqContact | null>
812
-
813
- /**
814
- * List contacts with pagination and filters
815
- * @see LeadService.listContacts (apps/api/src/acquisition/lead-service.ts)
816
- */
817
- listContacts(
818
- organizationId: string,
819
- filters: ContactFilters,
820
- pagination: PaginationParams
821
- ): Promise<PaginatedResult<AcqContact>>
822
-
823
- /**
824
- * Delete a contact
825
- * @see LeadService.deleteContact (apps/api/src/acquisition/lead-service.ts)
826
- */
827
- deleteContact(id: string, organizationId: string): Promise<void>
828
-
829
- /**
830
- * Bulk import contacts
831
- * @see LeadService.bulkImportContacts (apps/api/src/acquisition/lead-service.ts)
832
- */
833
- bulkImportContacts(params: BulkImportParams): Promise<BulkImportResult>
834
-
835
- /**
836
- * Bulk import companies with domain dedup (skips existing domains).
837
- * Inserts in batches using Supabase bulk insert + ON CONFLICT.
838
- * @see LeadService.bulkImportCompanies (apps/api/src/business/acquisition/lead-service.ts)
839
- */
840
- bulkImportCompanies(params: BulkImportCompaniesParams): Promise<BulkImportCompaniesResult>
841
-
842
- /**
843
- * Deactivate all active contacts belonging to a company.
844
- * Used by qualification workflow to cascade company disqualification to contacts.
845
- */
846
- deactivateContactsByCompany(params: DeactivateContactsByCompanyParams): Promise<DeactivateContactsByCompanyResult>
847
-
848
- /**
849
- * Get a contact by email address
850
- * Used for looking up existing leads when they reply to outreach
851
- * @see LeadService.getContactByEmail (apps/api/src/acquisition/lead-service.ts)
852
- */
853
- getContactByEmail(email: string, organizationId: string): Promise<AcqContact | null>
854
-
855
- // Deal operations (acq_deals table)
856
- /**
857
- * Upsert a deal by Attio Deal ID
858
- * Creates or updates acq_deals record linking Attio Deal to Supabase
859
- * @see LeadService.upsertDeal (apps/api/src/acquisition/lead-service.ts)
860
- */
861
- upsertDeal(params: UpsertDealParams): Promise<AcqDeal>
862
-
863
- /**
864
- * Get a deal by contact email
865
- * Used for looking up existing deals when leads book via email (fallback lookup)
866
- * @see LeadService.getDealByEmail (apps/api/src/acquisition/lead-service.ts)
867
- */
868
- getDealByEmail(email: string, organizationId: string): Promise<AcqDeal | null>
869
-
870
- /**
871
- * Get a deal by SignatureAPI envelope ID
872
- * Used by webhook handler to find deal when contract is signed
873
- * @see LeadService.getDealByEnvelopeId (apps/api/src/acquisition/lead-service.ts)
874
- */
875
- getDealByEnvelopeId(envelopeId: string, organizationId: string): Promise<AcqDeal | null>
876
-
877
- /**
878
- * Update deal with signature envelope ID
879
- * Called when proposal is sent via SignatureAPI
880
- * @see LeadService.updateDealEnvelopeId (apps/api/src/acquisition/lead-service.ts)
881
- */
882
- updateDealEnvelopeId(dealId: string, envelopeId: string, organizationId: string): Promise<AcqDeal | null>
883
-
884
- // Deal-sync operations (mirror deal-sync.ts utilities as server-side methods)
885
-
886
- getDealById(params: GetDealByIdParams): Promise<AcqDeal | null>
887
-
888
- getContactById(params: GetContactByIdParams): Promise<AcqContact | null>
889
-
890
- getCompanyById(params: GetCompanyByIdParams): Promise<AcqCompany | null>
891
-
892
- updateDiscoveryData(params: UpdateDiscoveryDataParams): Promise<void>
893
-
894
- updateProposalData(params: UpdateProposalDataParams): Promise<void>
895
-
896
- markProposalSent(params: MarkProposalSentParams): Promise<void>
897
-
898
- markProposalReviewed(params: MarkProposalReviewedParams): Promise<void>
899
-
900
- updateCloseLostReason(params: UpdateCloseLostReasonParams): Promise<void>
901
-
902
- updateFees(params: UpdateFeesParams): Promise<void>
903
-
904
- cacheInstantlyThreadIds(params: CacheInstantlyThreadIdsParams): Promise<void>
905
-
906
- transitionItem(params: TransitionItemParams): Promise<void>
907
-
908
- setContactNurture(params: SetContactNurtureParams): Promise<void>
909
-
910
- cancelSchedulesAndHitlByEmail(
911
- params: CancelSchedulesAndHitlByEmailParams
912
- ): Promise<{ schedulesCancelled: number; hitlDeleted: number }>
913
-
914
- cancelHitlByDealId(params: CancelHitlByDealIdParams): Promise<{ hitlDeleted: number }>
915
-
916
- clearDealFields(params: ClearDealFieldsParams): Promise<void>
917
-
918
- deleteDeal(params: DeleteDealParams): Promise<void>
919
-
920
- listDeals(organizationId: string, filters?: DealFilters): Promise<AcqDeal[]>
921
-
922
- getDealPipelineAnalytics(organizationId: string, recentLimit?: number): Promise<DealPipelineAnalytics>
923
-
924
- /**
925
- * Deep-merge enrichment data into a company or contact record.
926
- * Merges per source key rather than wholesale replacing the JSONB object.
927
- * @see LeadService.mergeEnrichmentData (apps/api/src/business/acquisition/lead-service.ts)
928
- */
929
- mergeEnrichmentData(
930
- id: string,
931
- orgId: string,
932
- table: 'acq_companies' | 'acq_contacts',
933
- data: Record<string, unknown>
934
- ): Promise<void>
935
-
936
- // Deal note operations (acq_deal_notes table)
937
- /**
938
- * Create a human-authored note on a deal
939
- * @see LeadService.createDealNote (apps/api/src/business/acquisition/lead-service.ts)
940
- */
941
- createDealNote(params: CreateDealNoteParams): Promise<AcqDealNote>
942
-
943
- /**
944
- * List notes for a deal, ordered by created_at DESC
945
- * @see LeadService.listDealNotes (apps/api/src/business/acquisition/lead-service.ts)
946
- */
947
- listDealNotes(params: ListDealNotesParams): Promise<AcqDealNote[]>
948
-
949
- // Deal task operations (acq_deal_tasks table)
950
- /**
951
- * Creates a new task attached to a deal.
952
- * @see LeadService.createDealTask (apps/api/src/business/acquisition/lead-service.ts)
953
- */
954
- createDealTask(params: CreateDealTaskParams): Promise<AcqDealTask>
955
-
956
- /**
957
- * Lists all tasks for a given deal, ordered by due date.
958
- * @see LeadService.listDealTasks (apps/api/src/business/acquisition/lead-service.ts)
959
- */
960
- listDealTasks(params: ListDealTasksParams): Promise<AcqDealTask[]>
961
-
962
- /**
963
- * Lists open (uncompleted) tasks within a date window across all deals.
964
- * @see LeadService.listDealTasksDue (apps/api/src/business/acquisition/lead-service.ts)
965
- */
966
- listDealTasksDue(params: ListDealTasksDueParams): Promise<AcqDealTask[]>
967
-
968
- /**
969
- * Marks a task as completed.
970
- * @see LeadService.completeDealTask (apps/api/src/business/acquisition/lead-service.ts)
971
- */
972
- completeDealTask(params: CompleteDealTaskParams): Promise<AcqDealTask>
973
-
974
- /**
975
- * Record a deal activity entry by deal ID.
976
- * Generic method for any activity type — used by SDK workflows.
977
- * @see LeadService.recordDealActivity (apps/api/src/business/acquisition/lead-service.ts)
978
- */
979
- recordDealActivity(params: RecordDealActivityParams): Promise<void>
980
-
981
- /**
982
- * Update the state_key on an acq_deals row.
983
- * @see LeadService.setDealStateKey (apps/api/src/business/acquisition/lead-service.ts)
984
- */
985
- setDealStateKey(params: SetDealStateKeyParams): Promise<{ ok: true }>
986
-
987
- /**
988
- * Transition a deal to a new stage, resolving pipeline_key automatically.
989
- * @see LeadService.transitionDeal (apps/api/src/business/acquisition/lead-service.ts)
990
- */
991
- transitionDeal(params: TransitionDealParams): Promise<{ deal: AcqDeal }>
992
-
993
- /**
994
- * Load a deal with its joined contact and company data.
995
- * @see LeadService.loadDeal (apps/api/src/business/acquisition/lead-service.ts)
996
- */
997
- loadDeal(params: LoadDealParams): Promise<DealDetail | null>
998
-
999
- // Social monitoring operations (acq_social_posts table)
1000
- /**
1001
- * Bulk upsert social posts (deduplicate by platform + platform_post_id)
1002
- * @see LeadService.upsertSocialPosts (apps/api/src/business/acquisition/lead-service.ts)
1003
- */
1004
- upsertSocialPosts(params: UpsertSocialPostsParams): Promise<UpsertSocialPostsResult>
1005
- }
1
+ /**
2
+ * Lead Service Types
3
+ * CRUD operation types for the acquisition platform (lists, companies, contacts, deals)
4
+ *
5
+ * Implementation: apps/api/src/acquisition/lead-service.ts (LeadService class)
6
+ */
7
+
8
+ import type { Json } from '../../../supabase'
9
+
10
+ // Re-export acquisition domain types from the authoritative source
11
+ import type {
12
+ AcqList,
13
+ AcqCompany,
14
+ AcqContact,
15
+ AcqDealTask,
16
+ AcqDealTaskKind,
17
+ ListStatus,
18
+ ScrapingConfig,
19
+ IcpRubric,
20
+ PipelineConfig,
21
+ ProcessingState,
22
+ ListTelemetry,
23
+ DealDetail
24
+ } from '../../../business/acquisition/types'
25
+ import type { ListProgress, ProcessingStageStatus } from '../../../business/acquisition/api-schemas'
26
+
27
+ export type {
28
+ AcqList,
29
+ AcqCompany,
30
+ AcqContact,
31
+ AcqDealTask,
32
+ AcqDealTaskKind,
33
+ ListStatus,
34
+ ScrapingConfig,
35
+ IcpRubric,
36
+ PipelineConfig,
37
+ ProcessingState,
38
+ ProcessingStageStatus,
39
+ ListTelemetry,
40
+ DealDetail,
41
+ ListProgress
42
+ }
43
+
44
+ // Pagination types
45
+ export interface PaginationParams {
46
+ limit: number
47
+ offset: number
48
+ }
49
+
50
+ export interface PaginatedResult<T> {
51
+ data: T[]
52
+ total: number
53
+ limit: number
54
+ offset: number
55
+ }
56
+
57
+ // List params
58
+ export interface CreateListParams {
59
+ organizationId: string
60
+ name: string
61
+ description?: string
62
+ type?: string
63
+ batchIds?: string[]
64
+ instantlyCampaignId?: string
65
+ status?: ListStatus
66
+ buildTemplateId?: string
67
+ metadata?: Record<string, unknown>
68
+ scrapingConfig?: ScrapingConfig
69
+ icp?: IcpRubric
70
+ pipelineConfig?: PipelineConfig
71
+ }
72
+
73
+ export interface UpdateListParams {
74
+ name?: string
75
+ description?: string
76
+ batchIds?: string[]
77
+ }
78
+
79
+ export interface UpdateListStatusParams {
80
+ organizationId: string
81
+ listId: string
82
+ status: ListStatus
83
+ }
84
+
85
+ // Company params
86
+ export interface CreateCompanyParams {
87
+ organizationId: string
88
+ name: string
89
+ domain?: string
90
+ linkedinUrl?: string
91
+ website?: string
92
+ numEmployees?: number
93
+ foundedYear?: number
94
+ locationCity?: string
95
+ locationState?: string
96
+ category?: string
97
+ source?: string
98
+ batchId?: string
99
+ verticalResearch?: string
100
+ /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
101
+ pipelineStatus?: unknown
102
+ }
103
+
104
+ export interface UpdateCompanyParams {
105
+ name?: string
106
+ domain?: string
107
+ linkedinUrl?: string
108
+ website?: string
109
+ numEmployees?: number
110
+ foundedYear?: number
111
+ locationCity?: string
112
+ locationState?: string
113
+ category?: string
114
+ segment?: string
115
+ processingState?: ProcessingState
116
+ /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
117
+ pipelineStatus?: unknown
118
+ enrichmentData?: Record<string, unknown>
119
+ source?: string
120
+ batchId?: string
121
+ status?: 'active' | 'invalid'
122
+ verticalResearch?: string | null
123
+ /** Track A: flat qualification score column (null until a scoring rubric is defined) */
124
+ qualificationScore?: number | null
125
+ /** Track A: flat qualification signals jsonb */
126
+ qualificationSignals?: Record<string, unknown> | null
127
+ /** Track A: key identifying the rubric used for qualification */
128
+ qualificationRubricKey?: string | null
129
+ }
130
+
131
+ export type UpsertCompanyParams = CreateCompanyParams
132
+ // Upsert by domain - uses same fields as create
133
+
134
+ export interface CompanyFilters {
135
+ listId?: string // Filter to companies in a specific list (via acq_list_companies)
136
+ search?: string
137
+ domain?: string
138
+ website?: string
139
+ segment?: string
140
+ category?: string
141
+ processingState?: ProcessingState
142
+ /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
143
+ pipelineStatus?: unknown
144
+ /** Exclude companies whose processing state contains this value (PostgREST NOT contains) */
145
+ processingStateNot?: ProcessingState
146
+ batchId?: string
147
+ status?: 'active' | 'invalid'
148
+ includeAll?: boolean
149
+ excludeColumns?: Array<'enrichmentData' | 'processingState'>
150
+ limit?: number
151
+ }
152
+
153
+ // Contact params
154
+ export interface CreateContactParams {
155
+ organizationId: string
156
+ email: string
157
+ companyId?: string
158
+ firstName?: string
159
+ lastName?: string
160
+ linkedinUrl?: string
161
+ title?: string
162
+ source?: string
163
+ sourceId?: string
164
+ batchId?: string
165
+ /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
166
+ pipelineStatus?: unknown
167
+ }
168
+
169
+ export interface UpdateContactParams {
170
+ companyId?: string
171
+ emailValid?: 'VALID' | 'INVALID' | 'RISKY' | 'UNKNOWN'
172
+ firstName?: string
173
+ lastName?: string
174
+ linkedinUrl?: string
175
+ title?: string
176
+ headline?: string
177
+ filterReason?: string
178
+ openingLine?: string
179
+ processingState?: ProcessingState
180
+ /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
181
+ pipelineStatus?: unknown
182
+ enrichmentData?: Record<string, unknown>
183
+ status?: 'active' | 'invalid'
184
+ }
185
+
186
+ export type UpsertContactParams = CreateContactParams
187
+ // Upsert by email - uses same fields as create
188
+
189
+ export interface ContactFilters {
190
+ listId?: string // Filter to contacts in a specific list (via acq_list_members)
191
+ search?: string
192
+ openingLineIsNull?: boolean // Filter to contacts without personalization
193
+ processingState?: ProcessingState
194
+ /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
195
+ pipelineStatus?: unknown
196
+ batchId?: string
197
+ contactStatus?: 'active' | 'invalid' // Filter by contact status (soft-delete flag)
198
+ }
199
+
200
+ // Deal params (for acq_deals table)
201
+ export interface UpsertDealParams {
202
+ organizationId: string
203
+ /** Contact email — dedupe key together with organization_id */
204
+ contactEmail: string
205
+ /** Optional contact ID for foreign key join */
206
+ contactId?: string
207
+ /** Campaign list that generated this deal (FK to acq_lists) */
208
+ sourceListId?: string
209
+ /** Deal origin: 'instantly', 'referral', 'inbound', 'manual' */
210
+ sourceType?: 'instantly' | 'referral' | 'inbound' | 'manual'
211
+ /** Optional discovery data JSONB to set on upsert */
212
+ discoveryData?: unknown
213
+ /** Optional proposal data JSONB to set on upsert */
214
+ proposalData?: unknown
215
+ /** Instantly email UUID used to hydrate the reply thread */
216
+ instantlyThreadUuid?: string
217
+ /** Instantly sender account for direction detection */
218
+ instantlyEmailAccount?: string
219
+ }
220
+
221
+ export interface UpdateDiscoveryDataParams {
222
+ organizationId: string
223
+ contactEmail: string
224
+ discoveryData: unknown
225
+ submittedBy?: string
226
+ }
227
+
228
+ export interface UpdateProposalDataParams {
229
+ organizationId: string
230
+ contactEmail: string
231
+ proposalData: unknown
232
+ proposalPdfUrl?: string
233
+ }
234
+
235
+ export interface MarkProposalSentParams {
236
+ organizationId: string
237
+ contactEmail: string
238
+ }
239
+
240
+ export interface MarkProposalReviewedParams {
241
+ organizationId: string
242
+ contactEmail: string
243
+ reviewedBy: string
244
+ proposalData?: unknown
245
+ }
246
+
247
+ export interface UpdateCloseLostReasonParams {
248
+ organizationId: string
249
+ dealId: string
250
+ reason: string
251
+ }
252
+
253
+ export interface UpdateFeesParams {
254
+ organizationId: string
255
+ contactEmail?: string
256
+ dealId?: string
257
+ initialFee?: number
258
+ monthlyFee?: number
259
+ }
260
+
261
+ export interface CacheInstantlyThreadIdsParams {
262
+ organizationId: string
263
+ dealId: string
264
+ instantlyThreadUuid: string
265
+ instantlyEmailAccount: string
266
+ }
267
+
268
+ export interface TransitionItemParams {
269
+ organizationId: string
270
+ dealId: string
271
+ pipelineKey: string
272
+ stageKey: string
273
+ stateKey?: string | null
274
+ reason?: string
275
+ expectedUpdatedAt?: string
276
+ }
277
+
278
+ export interface SetContactNurtureParams {
279
+ organizationId: string
280
+ contactEmail: string
281
+ nurture?: boolean
282
+ }
283
+
284
+ export interface DeactivateContactsByCompanyParams {
285
+ organizationId: string
286
+ companyId: string
287
+ }
288
+
289
+ export interface DeactivateContactsByCompanyResult {
290
+ deactivated: number
291
+ }
292
+
293
+ export interface CancelSchedulesAndHitlByEmailParams {
294
+ organizationId: string
295
+ email: string
296
+ }
297
+
298
+ export interface CancelHitlByDealIdParams {
299
+ organizationId: string
300
+ dealId: string
301
+ }
302
+
303
+ export interface ClearDealFieldsParams {
304
+ organizationId: string
305
+ contactEmail?: string
306
+ dealId?: string
307
+ fields: (
308
+ | 'proposalPdfUrl'
309
+ | 'proposalGeneratedAt'
310
+ | 'initialFee'
311
+ | 'monthlyFee'
312
+ | 'closedLostReason'
313
+ | 'closedLostAt'
314
+ | 'discoveryData'
315
+ | 'discoverySubmittedAt'
316
+ )[]
317
+ }
318
+
319
+ export interface DeleteDealParams {
320
+ organizationId: string
321
+ dealId: string
322
+ }
323
+
324
+ export interface GetDealByIdParams {
325
+ dealId: string
326
+ organizationId: string
327
+ }
328
+
329
+ export interface GetContactByIdParams {
330
+ contactId: string
331
+ organizationId: string
332
+ }
333
+
334
+ export interface GetCompanyByIdParams {
335
+ companyId: string
336
+ organizationId: string
337
+ }
338
+
339
+ // Social monitoring params (acq_social_posts table)
340
+ export interface UpsertSocialPostParams {
341
+ organizationId: string
342
+ platform: string
343
+ platformPostId: string
344
+ authorName: string
345
+ authorUrl?: string | null
346
+ postTitle: string
347
+ postText: string
348
+ postUrl: string
349
+ engagementCount?: number
350
+ commentsCount?: number
351
+ postedAt: string
352
+ metadata?: Record<string, unknown>
353
+ relevanceScore?: number
354
+ matchedKeywords?: string[]
355
+ matchedQuery?: string | null
356
+ initialDraft?: string | null
357
+ finalResponse?: string | null
358
+ sourceCategory?: string | null
359
+ }
360
+
361
+ export interface UpsertSocialPostsParams {
362
+ organizationId: string
363
+ posts: Omit<UpsertSocialPostParams, 'organizationId'>[]
364
+ }
365
+
366
+ export interface UpsertSocialPostsResult {
367
+ inserted: number
368
+ duplicatesSkipped: number
369
+ }
370
+
371
+ export interface AcqDeal {
372
+ id: string
373
+ organizationId: string
374
+ contactEmail: string
375
+ pipelineKey: string
376
+ stageKey?: string | null
377
+ stateKey?: string | null
378
+ discoveryData?: Json | null
379
+ proposalData?: Json | null
380
+ proposalSentAt?: string | null
381
+ proposalPdfUrl?: string | null
382
+ signatureEnvelopeId?: string | null
383
+ sourceListId?: string | null
384
+ sourceType?: string | null
385
+ activityLog: DealActivityEntry[]
386
+ createdAt: Date
387
+ updatedAt: Date
388
+ }
389
+
390
+ export interface DealActivityEntry {
391
+ type: string
392
+ title: string
393
+ description?: string
394
+ payload?: Record<string, unknown>
395
+ occurredAt: string
396
+ }
397
+
398
+ export interface AcqDealNote {
399
+ id: string
400
+ dealId: string
401
+ organizationId: string
402
+ authorUserId: string | null
403
+ body: string
404
+ createdAt: string
405
+ updatedAt: string
406
+ }
407
+
408
+ export interface CreateDealNoteParams {
409
+ organizationId: string
410
+ dealId: string
411
+ body: string
412
+ authorUserId?: string
413
+ }
414
+
415
+ export interface ListDealNotesParams {
416
+ organizationId: string
417
+ dealId: string
418
+ }
419
+
420
+ export interface CreateDealTaskParams {
421
+ organizationId: string
422
+ dealId: string
423
+ title: string
424
+ description?: string | null
425
+ kind?: AcqDealTaskKind
426
+ dueAt?: string | null
427
+ assigneeUserId?: string | null
428
+ createdByUserId?: string | null
429
+ }
430
+
431
+ export interface ListDealTasksParams {
432
+ organizationId: string
433
+ dealId: string
434
+ }
435
+
436
+ export interface ListDealTasksDueParams {
437
+ organizationId: string
438
+ assigneeUserId?: string | null
439
+ /** Window filter: 'overdue' = past due, 'today' = due today only, 'today_and_overdue' (default) = both, 'upcoming' = future */
440
+ window?: 'overdue' | 'today' | 'today_and_overdue' | 'upcoming'
441
+ }
442
+
443
+ export interface CompleteDealTaskParams {
444
+ organizationId: string
445
+ taskId: string
446
+ completedByUserId: string | null
447
+ }
448
+
449
+ export interface RecordDealActivityParams {
450
+ organizationId: string
451
+ dealId: string
452
+ type: string
453
+ title: string
454
+ description?: string
455
+ payload?: Record<string, unknown>
456
+ }
457
+
458
+ export interface SetDealStateKeyParams {
459
+ organizationId: string
460
+ dealId: string
461
+ stateKey: string
462
+ }
463
+
464
+ export interface TransitionDealParams {
465
+ organizationId: string
466
+ dealId: string
467
+ toStage: string
468
+ toState?: string
469
+ }
470
+
471
+ export interface LoadDealParams {
472
+ organizationId: string
473
+ dealId: string
474
+ }
475
+
476
+ // Deal analytics types (for /meta status and platform-status workflow)
477
+
478
+ export interface DealStageSummary {
479
+ stage: string
480
+ count: number
481
+ oldestUpdatedAt: string | null
482
+ newestUpdatedAt: string | null
483
+ }
484
+
485
+ export interface StaleDeal {
486
+ id: string
487
+ contactEmail: string
488
+ stageKey: string
489
+ updatedAt: string
490
+ daysStale: number
491
+ }
492
+
493
+ export interface DealPipelineAnalytics {
494
+ totalDeals: number
495
+ stageSummary: DealStageSummary[]
496
+ staleDeals: StaleDeal[]
497
+ recentActivity: AcqDeal[]
498
+ }
499
+
500
+ export interface DealAnalyticsParams {
501
+ organizationId: string
502
+ recentLimit?: number
503
+ }
504
+
505
+ export interface DealFilters {
506
+ stage?: string
507
+ search?: string
508
+ limit?: number
509
+ offset?: number
510
+ }
511
+
512
+ export interface AddContactsToListParams {
513
+ organizationId: string
514
+ listId: string
515
+ contactIds: string[]
516
+ }
517
+
518
+ export interface AddContactsToListResult {
519
+ added: number
520
+ alreadyExisted: number
521
+ }
522
+
523
+ // List config/progress/executions params
524
+ export interface UpdateListConfigParams {
525
+ organizationId: string
526
+ listId: string
527
+ scrapingConfig?: ScrapingConfig
528
+ icp?: IcpRubric
529
+ pipelineConfig?: PipelineConfig
530
+ }
531
+
532
+ export interface UpdateCompanyStageParams {
533
+ organizationId: string
534
+ listId: string
535
+ companyId: string
536
+ stage: string
537
+ status?: ProcessingStageStatus
538
+ executionId?: string
539
+ }
540
+
541
+ export interface UpdateContactStageParams {
542
+ organizationId: string
543
+ listId: string
544
+ contactId: string
545
+ stage: string
546
+ status?: ProcessingStageStatus
547
+ executionId?: string
548
+ }
549
+
550
+ export interface ListPendingCompanyIdsParams {
551
+ organizationId: string
552
+ listId: string
553
+ stageKey: string
554
+ limit?: number
555
+ }
556
+
557
+ export interface ListPendingContactIdsParams {
558
+ organizationId: string
559
+ listId: string
560
+ stageKey: string
561
+ limit?: number
562
+ }
563
+
564
+ export interface AddCompaniesToListParams {
565
+ organizationId: string
566
+ listId: string
567
+ companyIds: string[]
568
+ }
569
+
570
+ export interface AddCompaniesToListResult {
571
+ added: number
572
+ alreadyExisted: number
573
+ }
574
+
575
+ export interface RemoveCompaniesFromListParams {
576
+ organizationId: string
577
+ listId: string
578
+ companyIds: string[]
579
+ }
580
+
581
+ export interface RemoveCompaniesFromListResult {
582
+ removed: number
583
+ }
584
+
585
+ export interface RecordListExecutionParams {
586
+ organizationId: string
587
+ listId: string
588
+ executionId: string
589
+ configSnapshot?: Record<string, unknown>
590
+ }
591
+
592
+ export interface ListExecutionSummary {
593
+ executionId: string
594
+ resourceId: string
595
+ status: string
596
+ createdAt: string
597
+ completedAt: string | null
598
+ durationMs: number | null
599
+ }
600
+
601
+ // Bulk import (contacts)
602
+ export interface BulkImportParams {
603
+ organizationId: string
604
+ contacts: CreateContactParams[]
605
+ listId?: string
606
+ }
607
+
608
+ export interface BulkImportResult {
609
+ created: number
610
+ updated: number
611
+ errors: Array<{ email: string; error: string }>
612
+ }
613
+
614
+ // Bulk import (companies)
615
+ export interface BulkImportCompanyEntry {
616
+ name: string
617
+ domain: string
618
+ website?: string
619
+ locationCity?: string
620
+ locationState?: string
621
+ category?: string
622
+ source?: string
623
+ enrichmentData?: Record<string, unknown>
624
+ processingState?: ProcessingState
625
+ }
626
+
627
+ export interface BulkImportCompaniesParams {
628
+ organizationId: string
629
+ batchId: string
630
+ companies: BulkImportCompanyEntry[]
631
+ }
632
+
633
+ export interface BulkImportCompaniesResult {
634
+ created: number
635
+ skipped: number
636
+ errors: Array<{ companyName: string; error: string }>
637
+ }
638
+
639
+ /**
640
+ * Lead Service interface for acquisition platform tools.
641
+ * Provides CRUD operations for lists, companies, and contacts.
642
+ *
643
+ * Implementation: apps/api/src/acquisition/lead-service.ts (LeadService class)
644
+ *
645
+ * Multi-tenancy: All operations require organizationId for tenant isolation.
646
+ * All queries are filtered by organizationId via RLS policies.
647
+ */
648
+ export interface ILeadService {
649
+ // List operations
650
+ /**
651
+ * Create a new list
652
+ * @see LeadService.createList (apps/api/src/acquisition/lead-service.ts)
653
+ */
654
+ createList(params: CreateListParams): Promise<AcqList>
655
+
656
+ /**
657
+ * Update an existing list
658
+ * @see LeadService.updateList (apps/api/src/acquisition/lead-service.ts)
659
+ */
660
+ updateList(id: string, params: UpdateListParams): Promise<AcqList>
661
+
662
+ /**
663
+ * Delete a list
664
+ * @see LeadService.deleteList (apps/api/src/acquisition/lead-service.ts)
665
+ */
666
+ deleteList(id: string, organizationId: string): Promise<void>
667
+
668
+ /**
669
+ * Add contacts to a list (upsert — idempotent on re-runs)
670
+ * @see LeadService.addContactsToList (apps/api/src/business/acquisition/lead-service.ts)
671
+ */
672
+ addContactsToList(params: AddContactsToListParams): Promise<AddContactsToListResult>
673
+
674
+ /**
675
+ * List all lists for an organization
676
+ * @see LeadService.listLists (apps/api/src/acquisition/lead-service.ts)
677
+ */
678
+ listLists(organizationId: string): Promise<AcqList[]>
679
+
680
+ /**
681
+ * Get a single list by ID.
682
+ */
683
+ getList(id: string, organizationId: string): Promise<AcqList | null>
684
+
685
+ /**
686
+ * Deep-merge patch the jsonb `config` column. Patch keys at any depth
687
+ * replace the corresponding subtree.
688
+ */
689
+ updateListConfig(params: UpdateListConfigParams): Promise<AcqList>
690
+
691
+ /**
692
+ * Add companies to a list via the acq_list_companies junction.
693
+ * Idempotent on (list_id, company_id).
694
+ */
695
+ addCompaniesToList(params: AddCompaniesToListParams): Promise<AddCompaniesToListResult>
696
+
697
+ /**
698
+ * Remove companies from a list (delete junction rows only — company rows untouched).
699
+ */
700
+ removeCompaniesFromList(params: RemoveCompaniesFromListParams): Promise<RemoveCompaniesFromListResult>
701
+
702
+ /**
703
+ * Live org-wide list telemetry — computed on demand from acq_companies
704
+ * and acq_contacts joined through the acq_list_companies / acq_list_members
705
+ * junctions. Replaces the batch-scoped getBatchTelemetry.
706
+ */
707
+ getListsTelemetry(organizationId: string): Promise<ListTelemetry[]>
708
+
709
+ /**
710
+ * On-demand progress aggregation: COUNT(*) FILTER over processing_state flags,
711
+ * keyed by the list's pipeline_config.stages[].key (Decision #4 + #7).
712
+ */
713
+ getListProgress(listId: string, organizationId: string): Promise<ListProgress | null>
714
+
715
+ /**
716
+ * Advance a company row within a list's explicit stage journey.
717
+ */
718
+ updateCompanyStage(params: UpdateCompanyStageParams): Promise<void>
719
+
720
+ /**
721
+ * Advance a contact row within a list's explicit stage journey.
722
+ */
723
+ updateContactStage(params: UpdateContactStageParams): Promise<void>
724
+
725
+ /**
726
+ * Return the company_ids in acq_list_companies for the given list where
727
+ * processing_state[stageKey].status is NULL or NOT IN ('success', 'no_result').
728
+ * Used by build-pipeline workflows to skip already-processed records.
729
+ */
730
+ listPendingCompanyIds(params: ListPendingCompanyIdsParams): Promise<string[]>
731
+
732
+ /**
733
+ * Return the contact_ids in acq_list_members for the given list where
734
+ * processing_state[stageKey].status is NULL or NOT IN ('success', 'no_result').
735
+ * Used by build-pipeline workflows to skip already-processed records.
736
+ */
737
+ listPendingContactIds(params: ListPendingContactIdsParams): Promise<string[]>
738
+
739
+ /**
740
+ * Per-list execution history — reads via the feature-owned
741
+ * acq_list_executions junction, joined to execution_logs for details.
742
+ */
743
+ getListExecutions(listId: string, organizationId: string): Promise<ListExecutionSummary[]>
744
+
745
+ /**
746
+ * Write a junction row linking (listId, executionId). Called by the
747
+ * workflow layer at execution start in Step 4. No-op if the row exists.
748
+ */
749
+ recordListExecution(params: RecordListExecutionParams): Promise<void>
750
+
751
+ // Company operations
752
+ /**
753
+ * Create a new company
754
+ * @see LeadService.createCompany (apps/api/src/acquisition/lead-service.ts)
755
+ */
756
+ createCompany(params: CreateCompanyParams): Promise<AcqCompany>
757
+
758
+ /**
759
+ * Update an existing company
760
+ * @see LeadService.updateCompany (apps/api/src/acquisition/lead-service.ts)
761
+ */
762
+ updateCompany(id: string, params: UpdateCompanyParams): Promise<AcqCompany>
763
+
764
+ /**
765
+ * Upsert a company by domain
766
+ * @see LeadService.upsertCompany (apps/api/src/acquisition/lead-service.ts)
767
+ */
768
+ upsertCompany(params: UpsertCompanyParams): Promise<AcqCompany>
769
+
770
+ /**
771
+ * Get a company by ID
772
+ * @see LeadService.getCompany (apps/api/src/acquisition/lead-service.ts)
773
+ */
774
+ getCompany(id: string, organizationId: string): Promise<AcqCompany | null>
775
+
776
+ /**
777
+ * List companies with optional filters
778
+ * @see LeadService.listCompanies (apps/api/src/acquisition/lead-service.ts)
779
+ */
780
+ listCompanies(organizationId: string, filters: CompanyFilters): Promise<AcqCompany[]>
781
+
782
+ /**
783
+ * Delete a company
784
+ * @see LeadService.deleteCompany (apps/api/src/acquisition/lead-service.ts)
785
+ */
786
+ deleteCompany(id: string, organizationId: string): Promise<void>
787
+
788
+ // Contact operations
789
+ /**
790
+ * Create a new contact
791
+ * @see LeadService.createContact (apps/api/src/acquisition/lead-service.ts)
792
+ */
793
+ createContact(params: CreateContactParams): Promise<AcqContact>
794
+
795
+ /**
796
+ * Update an existing contact
797
+ * @see LeadService.updateContact (apps/api/src/acquisition/lead-service.ts)
798
+ */
799
+ updateContact(id: string, params: UpdateContactParams): Promise<AcqContact>
800
+
801
+ /**
802
+ * Upsert a contact by email
803
+ * @see LeadService.upsertContact (apps/api/src/acquisition/lead-service.ts)
804
+ */
805
+ upsertContact(params: UpsertContactParams): Promise<AcqContact>
806
+
807
+ /**
808
+ * Get a contact by ID
809
+ * @see LeadService.getContact (apps/api/src/acquisition/lead-service.ts)
810
+ */
811
+ getContact(id: string, organizationId: string): Promise<AcqContact | null>
812
+
813
+ /**
814
+ * List contacts with pagination and filters
815
+ * @see LeadService.listContacts (apps/api/src/acquisition/lead-service.ts)
816
+ */
817
+ listContacts(
818
+ organizationId: string,
819
+ filters: ContactFilters,
820
+ pagination: PaginationParams
821
+ ): Promise<PaginatedResult<AcqContact>>
822
+
823
+ /**
824
+ * Delete a contact
825
+ * @see LeadService.deleteContact (apps/api/src/acquisition/lead-service.ts)
826
+ */
827
+ deleteContact(id: string, organizationId: string): Promise<void>
828
+
829
+ /**
830
+ * Bulk import contacts
831
+ * @see LeadService.bulkImportContacts (apps/api/src/acquisition/lead-service.ts)
832
+ */
833
+ bulkImportContacts(params: BulkImportParams): Promise<BulkImportResult>
834
+
835
+ /**
836
+ * Bulk import companies with domain dedup (skips existing domains).
837
+ * Inserts in batches using Supabase bulk insert + ON CONFLICT.
838
+ * @see LeadService.bulkImportCompanies (apps/api/src/business/acquisition/lead-service.ts)
839
+ */
840
+ bulkImportCompanies(params: BulkImportCompaniesParams): Promise<BulkImportCompaniesResult>
841
+
842
+ /**
843
+ * Deactivate all active contacts belonging to a company.
844
+ * Used by qualification workflow to cascade company disqualification to contacts.
845
+ */
846
+ deactivateContactsByCompany(params: DeactivateContactsByCompanyParams): Promise<DeactivateContactsByCompanyResult>
847
+
848
+ /**
849
+ * Get a contact by email address
850
+ * Used for looking up existing leads when they reply to outreach
851
+ * @see LeadService.getContactByEmail (apps/api/src/acquisition/lead-service.ts)
852
+ */
853
+ getContactByEmail(email: string, organizationId: string): Promise<AcqContact | null>
854
+
855
+ // Deal operations (acq_deals table)
856
+ /**
857
+ * Upsert a deal by Attio Deal ID
858
+ * Creates or updates acq_deals record linking Attio Deal to Supabase
859
+ * @see LeadService.upsertDeal (apps/api/src/acquisition/lead-service.ts)
860
+ */
861
+ upsertDeal(params: UpsertDealParams): Promise<AcqDeal>
862
+
863
+ /**
864
+ * Get a deal by contact email
865
+ * Used for looking up existing deals when leads book via email (fallback lookup)
866
+ * @see LeadService.getDealByEmail (apps/api/src/acquisition/lead-service.ts)
867
+ */
868
+ getDealByEmail(email: string, organizationId: string): Promise<AcqDeal | null>
869
+
870
+ /**
871
+ * Get a deal by SignatureAPI envelope ID
872
+ * Used by webhook handler to find deal when contract is signed
873
+ * @see LeadService.getDealByEnvelopeId (apps/api/src/acquisition/lead-service.ts)
874
+ */
875
+ getDealByEnvelopeId(envelopeId: string, organizationId: string): Promise<AcqDeal | null>
876
+
877
+ /**
878
+ * Update deal with signature envelope ID
879
+ * Called when proposal is sent via SignatureAPI
880
+ * @see LeadService.updateDealEnvelopeId (apps/api/src/acquisition/lead-service.ts)
881
+ */
882
+ updateDealEnvelopeId(dealId: string, envelopeId: string, organizationId: string): Promise<AcqDeal | null>
883
+
884
+ // Deal-sync operations (mirror deal-sync.ts utilities as server-side methods)
885
+
886
+ getDealById(params: GetDealByIdParams): Promise<AcqDeal | null>
887
+
888
+ getContactById(params: GetContactByIdParams): Promise<AcqContact | null>
889
+
890
+ getCompanyById(params: GetCompanyByIdParams): Promise<AcqCompany | null>
891
+
892
+ updateDiscoveryData(params: UpdateDiscoveryDataParams): Promise<void>
893
+
894
+ updateProposalData(params: UpdateProposalDataParams): Promise<void>
895
+
896
+ markProposalSent(params: MarkProposalSentParams): Promise<void>
897
+
898
+ markProposalReviewed(params: MarkProposalReviewedParams): Promise<void>
899
+
900
+ updateCloseLostReason(params: UpdateCloseLostReasonParams): Promise<void>
901
+
902
+ updateFees(params: UpdateFeesParams): Promise<void>
903
+
904
+ cacheInstantlyThreadIds(params: CacheInstantlyThreadIdsParams): Promise<void>
905
+
906
+ transitionItem(params: TransitionItemParams): Promise<void>
907
+
908
+ setContactNurture(params: SetContactNurtureParams): Promise<void>
909
+
910
+ cancelSchedulesAndHitlByEmail(
911
+ params: CancelSchedulesAndHitlByEmailParams
912
+ ): Promise<{ schedulesCancelled: number; hitlDeleted: number }>
913
+
914
+ cancelHitlByDealId(params: CancelHitlByDealIdParams): Promise<{ hitlDeleted: number }>
915
+
916
+ clearDealFields(params: ClearDealFieldsParams): Promise<void>
917
+
918
+ deleteDeal(params: DeleteDealParams): Promise<void>
919
+
920
+ listDeals(organizationId: string, filters?: DealFilters): Promise<AcqDeal[]>
921
+
922
+ getDealPipelineAnalytics(organizationId: string, recentLimit?: number): Promise<DealPipelineAnalytics>
923
+
924
+ /**
925
+ * Deep-merge enrichment data into a company or contact record.
926
+ * Merges per source key rather than wholesale replacing the JSONB object.
927
+ * @see LeadService.mergeEnrichmentData (apps/api/src/business/acquisition/lead-service.ts)
928
+ */
929
+ mergeEnrichmentData(
930
+ id: string,
931
+ orgId: string,
932
+ table: 'acq_companies' | 'acq_contacts',
933
+ data: Record<string, unknown>
934
+ ): Promise<void>
935
+
936
+ // Deal note operations (acq_deal_notes table)
937
+ /**
938
+ * Create a human-authored note on a deal
939
+ * @see LeadService.createDealNote (apps/api/src/business/acquisition/lead-service.ts)
940
+ */
941
+ createDealNote(params: CreateDealNoteParams): Promise<AcqDealNote>
942
+
943
+ /**
944
+ * List notes for a deal, ordered by created_at DESC
945
+ * @see LeadService.listDealNotes (apps/api/src/business/acquisition/lead-service.ts)
946
+ */
947
+ listDealNotes(params: ListDealNotesParams): Promise<AcqDealNote[]>
948
+
949
+ // Deal task operations (acq_deal_tasks table)
950
+ /**
951
+ * Creates a new task attached to a deal.
952
+ * @see LeadService.createDealTask (apps/api/src/business/acquisition/lead-service.ts)
953
+ */
954
+ createDealTask(params: CreateDealTaskParams): Promise<AcqDealTask>
955
+
956
+ /**
957
+ * Lists all tasks for a given deal, ordered by due date.
958
+ * @see LeadService.listDealTasks (apps/api/src/business/acquisition/lead-service.ts)
959
+ */
960
+ listDealTasks(params: ListDealTasksParams): Promise<AcqDealTask[]>
961
+
962
+ /**
963
+ * Lists open (uncompleted) tasks within a date window across all deals.
964
+ * @see LeadService.listDealTasksDue (apps/api/src/business/acquisition/lead-service.ts)
965
+ */
966
+ listDealTasksDue(params: ListDealTasksDueParams): Promise<AcqDealTask[]>
967
+
968
+ /**
969
+ * Marks a task as completed.
970
+ * @see LeadService.completeDealTask (apps/api/src/business/acquisition/lead-service.ts)
971
+ */
972
+ completeDealTask(params: CompleteDealTaskParams): Promise<AcqDealTask>
973
+
974
+ /**
975
+ * Record a deal activity entry by deal ID.
976
+ * Generic method for any activity type — used by SDK workflows.
977
+ * @see LeadService.recordDealActivity (apps/api/src/business/acquisition/lead-service.ts)
978
+ */
979
+ recordDealActivity(params: RecordDealActivityParams): Promise<void>
980
+
981
+ /**
982
+ * Update the state_key on an acq_deals row.
983
+ * @see LeadService.setDealStateKey (apps/api/src/business/acquisition/lead-service.ts)
984
+ */
985
+ setDealStateKey(params: SetDealStateKeyParams): Promise<{ ok: true }>
986
+
987
+ /**
988
+ * Transition a deal to a new stage, resolving pipeline_key automatically.
989
+ * @see LeadService.transitionDeal (apps/api/src/business/acquisition/lead-service.ts)
990
+ */
991
+ transitionDeal(params: TransitionDealParams): Promise<{ deal: AcqDeal }>
992
+
993
+ /**
994
+ * Load a deal with its joined contact and company data.
995
+ * @see LeadService.loadDeal (apps/api/src/business/acquisition/lead-service.ts)
996
+ */
997
+ loadDeal(params: LoadDealParams): Promise<DealDetail | null>
998
+
999
+ // Social monitoring operations (acq_social_posts table)
1000
+ /**
1001
+ * Bulk upsert social posts (deduplicate by platform + platform_post_id)
1002
+ * @see LeadService.upsertSocialPosts (apps/api/src/business/acquisition/lead-service.ts)
1003
+ */
1004
+ upsertSocialPosts(params: UpsertSocialPostsParams): Promise<UpsertSocialPostsResult>
1005
+ }