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