@elevasis/core 0.15.0 → 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 (88) hide show
  1. package/dist/index.d.ts +1718 -19
  2. package/dist/index.js +369 -25
  3. package/dist/organization-model/index.d.ts +1718 -19
  4. package/dist/organization-model/index.js +369 -25
  5. package/dist/test-utils/index.d.ts +1108 -371
  6. package/dist/test-utils/index.js +357 -17
  7. package/package.json +5 -1
  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 +1109 -882
  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 +13 -4
  16. package/src/business/acquisition/api-schemas.test.ts +315 -4
  17. package/src/business/acquisition/api-schemas.ts +122 -8
  18. package/src/business/acquisition/build-templates.ts +44 -0
  19. package/src/business/acquisition/crm-next-action.test.ts +262 -0
  20. package/src/business/acquisition/crm-next-action.ts +220 -0
  21. package/src/business/acquisition/crm-priority.test.ts +216 -0
  22. package/src/business/acquisition/crm-priority.ts +349 -0
  23. package/src/business/acquisition/crm-state-actions.test.ts +151 -160
  24. package/src/business/acquisition/deal-ownership.test.ts +351 -0
  25. package/src/business/acquisition/deal-ownership.ts +120 -0
  26. package/src/business/acquisition/derive-actions.test.ts +101 -37
  27. package/src/business/acquisition/derive-actions.ts +102 -87
  28. package/src/business/acquisition/index.ts +10 -0
  29. package/src/business/acquisition/types.ts +400 -366
  30. package/src/business/crm/api-schemas.ts +40 -0
  31. package/src/business/crm/index.ts +1 -0
  32. package/src/business/deals/api-schemas.ts +79 -0
  33. package/src/business/deals/index.ts +1 -0
  34. package/src/business/projects/types.ts +124 -88
  35. package/src/execution/core/runner-types.ts +61 -80
  36. package/src/execution/engine/index.ts +4 -3
  37. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +105 -104
  38. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1474 -1473
  39. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +103 -102
  40. package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-tools.ts +182 -179
  41. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +310 -309
  42. package/src/execution/engine/tools/integration/tool.ts +255 -253
  43. package/src/execution/engine/tools/lead-service-types.ts +939 -924
  44. package/src/execution/engine/tools/messages.ts +43 -0
  45. package/src/execution/engine/tools/platform/acquisition/list-tools.ts +6 -5
  46. package/src/execution/engine/tools/platform/acquisition/types.ts +5 -2
  47. package/src/execution/engine/tools/platform/email/types.ts +97 -96
  48. package/src/execution/engine/tools/registry.ts +4 -3
  49. package/src/execution/engine/tools/tool-maps.ts +3 -1
  50. package/src/execution/engine/tools/types.ts +234 -233
  51. package/src/execution/engine/workflow/types.ts +195 -193
  52. package/src/execution/external/api-schemas.ts +40 -0
  53. package/src/execution/external/index.ts +1 -0
  54. package/src/knowledge/README.md +32 -0
  55. package/src/knowledge/__tests__/queries.test.ts +504 -0
  56. package/src/knowledge/format.ts +99 -0
  57. package/src/knowledge/index.ts +5 -0
  58. package/src/knowledge/queries.ts +256 -0
  59. package/src/organization-model/__tests__/defaults.test.ts +172 -172
  60. package/src/organization-model/__tests__/foundation.test.ts +7 -7
  61. package/src/organization-model/__tests__/icons.test.ts +27 -0
  62. package/src/organization-model/__tests__/knowledge.test.ts +214 -0
  63. package/src/organization-model/contracts.ts +17 -15
  64. package/src/organization-model/defaults.ts +74 -19
  65. package/src/organization-model/domains/knowledge.ts +53 -0
  66. package/src/organization-model/domains/navigation.ts +416 -399
  67. package/src/organization-model/domains/prospecting.ts +204 -1
  68. package/src/organization-model/domains/sales.test.ts +29 -0
  69. package/src/organization-model/domains/sales.ts +102 -0
  70. package/src/organization-model/domains/shared.ts +6 -5
  71. package/src/organization-model/foundation.ts +10 -6
  72. package/src/organization-model/graph/build.ts +209 -182
  73. package/src/organization-model/graph/schema.ts +37 -34
  74. package/src/organization-model/graph/types.ts +47 -31
  75. package/src/organization-model/icons.ts +81 -0
  76. package/src/organization-model/index.ts +8 -3
  77. package/src/organization-model/organization-model.mdx +1 -1
  78. package/src/organization-model/published.ts +103 -86
  79. package/src/organization-model/schema.ts +90 -85
  80. package/src/organization-model/types.ts +42 -35
  81. package/src/platform/constants/versions.ts +1 -1
  82. package/src/platform/index.ts +23 -27
  83. package/src/platform/registry/index.ts +0 -4
  84. package/src/platform/registry/resource-registry.ts +0 -77
  85. package/src/platform/registry/serialized-types.ts +148 -219
  86. package/src/platform/registry/stats-types.ts +60 -60
  87. package/src/reference/_generated/contracts.md +829 -595
  88. package/src/supabase/database.types.ts +2978 -2958
@@ -1,370 +1,404 @@
1
- import type { Database } from '../../supabase/database.types'
2
-
3
- // =============================================================================
4
- // Supabase-Generated Types (Re-exported from database.types)
5
- // =============================================================================
6
-
7
- /** Raw database row type for acq_lists table */
8
- export type AcqListRow = Database['public']['Tables']['acq_lists']['Row']
9
- /** Insert type for acq_lists table */
10
- export type AcqListInsert = Database['public']['Tables']['acq_lists']['Insert']
11
-
12
- /** Raw database row type for acq_companies table */
13
- export type AcqCompanyRow = Database['public']['Tables']['acq_companies']['Row']
14
- /** Insert type for acq_companies table */
15
- export type AcqCompanyInsert = Database['public']['Tables']['acq_companies']['Insert']
16
-
17
- /** Raw database row type for acq_contacts table */
18
- export type AcqContactRow = Database['public']['Tables']['acq_contacts']['Row']
19
- /** Insert type for acq_contacts table */
20
- export type AcqContactInsert = Database['public']['Tables']['acq_contacts']['Insert']
21
-
22
- /** Raw database row type for acq_deals table */
23
- export type AcqDealRow = Database['public']['Tables']['acq_deals']['Row']
24
- /** Insert type for acq_deals table */
25
- export type AcqDealInsert = Database['public']['Tables']['acq_deals']['Insert']
26
-
27
- /** Raw database row type for acq_deal_tasks table */
28
- export type AcqDealTaskRow = Database['public']['Tables']['acq_deal_tasks']['Row']
29
- /** Insert type for acq_deal_tasks table */
30
- export type AcqDealTaskInsert = Database['public']['Tables']['acq_deal_tasks']['Insert']
31
-
32
- // =============================================================================
33
- // Supporting Types
34
- // =============================================================================
35
-
36
- /**
37
- * Represents a web post from company website scraping.
38
- * Used for recent blog posts, news, or announcements.
39
- */
40
- export interface WebPost {
41
- /** ISO date string of when the post was published */
42
- date: string
43
- /** Title of the web post */
44
- title: string
45
- /** Brief summary of the post content */
46
- summary: string
47
- /** AI-generated insight about the post's relevance */
48
- aiInsight?: string
49
- }
50
-
51
- /**
52
- * Tracks pipeline status for a company across all processing stages.
53
- */
54
- export interface CompanyPipelineStatus {
55
- acquired: boolean
56
- enrichment: {
57
- [source: string]: {
58
- status: 'pending' | 'complete' | 'failed' | 'skipped'
59
- completedAt?: string
60
- error?: string
61
- }
62
- }
63
- }
64
-
65
- /**
66
- * Tracks pipeline status for a contact across all processing stages.
67
- */
68
- export interface ContactPipelineStatus {
69
- enrichment: {
70
- [source: string]: {
71
- status: 'pending' | 'complete' | 'failed' | 'skipped'
72
- completedAt?: string
73
- error?: string
74
- }
75
- }
76
- personalization: {
77
- status: 'pending' | 'complete' | 'failed' | 'skipped'
78
- completedAt?: string
79
- }
80
- outreach: {
81
- status: 'pending' | 'sent' | 'replied' | 'bounced' | 'opted-out'
82
- sentAt?: string
83
- channel?: string
84
- campaignId?: string
85
- }
86
- }
87
-
88
- /**
89
- * Enrichment data collected for a company from various sources.
90
- */
91
- export interface CompanyEnrichmentData {
92
- googleMaps?: {
93
- placeId?: string
94
- totalScore?: number
95
- reviewsCount?: number
96
- address?: string
97
- phone?: string
98
- categoryName?: string
99
- googleMapsUrl?: string
100
- scrapedAt?: string
101
- }
102
- websiteCrawl?: {
103
- companyDescription?: string
104
- services?: string[]
105
- specialties?: string[]
106
- staff?: Array<{ name: string; title?: string; email?: string }>
107
- automationGaps?: string[]
108
- targetAudience?: string
109
- category?: string
110
- segment?: string
111
- recentWin?: string
112
- emailCount?: number
113
- pageCount?: number
114
- totalChars?: number
115
- crawledAt?: string
116
- extractedAt?: string
117
- }
118
- website?: {
119
- missionVision?: string
120
- uniqueAttributes?: string
121
- coreOfferings?: string
122
- targetAudience?: string
123
- companyValues?: string
124
- businessDescription?: string
125
- recentPosts?: Array<{ date?: string; title?: string; summary?: string; aiInsight?: string }>
126
- }
127
- tomba?: {
128
- waterfallEmail?: {
129
- email: string
130
- name?: string
131
- title?: string
132
- department?: string
133
- } | null
134
- genericEmail?: string | null
135
- totalFound?: number
136
- searchedAt?: string
137
- }
138
- }
139
-
140
- /**
141
- * Enrichment data collected for a contact from various sources.
142
- */
143
- export interface ContactEnrichmentData {
144
- linkedin?: {
145
- summary?: string
146
- pastExperience?: string
147
- education?: string
148
- activity?: Array<{ date?: string; content?: string }>
149
- }
150
- }
151
-
152
- // =============================================================================
153
- // Domain Types (camelCase transformations of database rows)
154
- // =============================================================================
155
-
156
- export type ListStatus = 'draft' | 'enriching' | 'launched' | 'closing' | 'archived'
157
-
158
- export interface ScrapingConfig {
159
- source?: string
160
- query?: string
161
- filters?: Record<string, unknown>
162
- [key: string]: unknown
163
- }
164
-
165
- export interface IcpRubric {
166
- targetDescription?: string
167
- minReviewCount?: number
168
- minRating?: number
169
- excludeFranchises?: boolean
170
- customRules?: string
171
- qualificationRubricKey?: string | null
172
- [key: string]: unknown
173
- }
174
-
175
- export interface PipelineStage {
176
- key: string
177
- label?: string
178
- description?: string
179
- resourceId?: string
180
- inputTemplate?: Record<string, unknown>
181
- enabled?: boolean
182
- order?: number
183
- }
184
-
185
- export interface PipelineConfig {
186
- stages: PipelineStage[]
187
- }
188
-
189
- export interface AcqList {
190
- id: string
191
- organizationId: string
192
- name: string
193
- description: string | null
194
- batchIds: string[]
195
- instantlyCampaignId: string | null
196
- status: ListStatus
197
- scrapingConfig: ScrapingConfig
198
- icp: IcpRubric
199
- pipelineConfig: PipelineConfig
200
- metadata: Record<string, unknown>
201
- launchedAt: Date | null
202
- completedAt: Date | null
203
- createdAt: Date
204
- }
205
-
206
- /**
207
- * Company record in the acquisition database.
208
- * Contains enriched company data from various sources.
209
- * Transformed from AcqCompanyRow with camelCase properties.
210
- */
211
- export interface AcqCompany {
212
- id: string
213
- organizationId: string
214
- name: string
215
- domain: string | null
216
- linkedinUrl: string | null
217
- website: string | null
218
- numEmployees: number | null
219
- foundedYear: number | null
220
- locationCity: string | null
221
- locationState: string | null
222
- category: string | null
223
- categoryPain: string | null
224
- segment: string | null
225
- pipelineStatus: CompanyPipelineStatus | null
226
- enrichmentData: CompanyEnrichmentData | null
227
- source: string | null
228
- batchId: string | null
229
- status: 'active' | 'invalid'
230
- verticalResearch: string | null
231
- /** Track A: flat qualification score (null until a scoring rubric is defined). Added by W1 migration. */
232
- qualificationScore: number | null
233
- /** Track A: flat qualification signals jsonb preserving the result payload shape. Added by W1 migration. */
234
- qualificationSignals: Record<string, unknown> | null
235
- /** Track A: key identifying the rubric used for qualification. Added by W1 migration. */
236
- qualificationRubricKey: string | null
237
- createdAt: Date
238
- updatedAt: Date
239
- }
240
-
241
- /**
242
- * Contact record in the acquisition database.
243
- * Contains enriched contact data and personalization content.
244
- * Transformed from AcqContactRow with camelCase properties.
245
- */
246
- export interface AcqContact {
247
- id: string
248
- organizationId: string
249
- companyId: string | null
250
- email: string
251
- emailValid: 'VALID' | 'INVALID' | 'RISKY' | 'UNKNOWN' | null
252
- firstName: string | null
253
- lastName: string | null
254
- linkedinUrl: string | null
255
- title: string | null
256
- headline: string | null
257
- filterReason: string | null
258
- openingLine: string | null
259
- source: string | null
260
- sourceId: string | null
261
- pipelineStatus: ContactPipelineStatus | null
262
- enrichmentData: ContactEnrichmentData | null
263
- /** Attio Person record ID - set when contact responds and is added to CRM */
264
- attioPersonId: string | null
265
- batchId: string | null
266
- status: 'active' | 'invalid'
267
- createdAt: Date
268
- updatedAt: Date
269
- }
270
-
271
- // ─── Deal UI Types ───────────────────────────────────────────────────────────
272
-
273
- export type DealStage = 'interested' | 'proposal' | 'closing' | 'closed_won' | 'closed_lost' | 'nurturing'
274
-
275
- export interface KanbanStageConfig {
276
- color: string // Mantine color token (e.g. 'blue', 'teal')
277
- label?: string // Optional display label override
278
- }
279
-
280
- export type KanbanBoardConfig = Partial<Record<DealStage, KanbanStageConfig>>
281
-
282
- export interface DealContact {
283
- id: string
284
- first_name: string | null
285
- last_name: string | null
286
- email: string
287
- title: string | null
288
- headline: string | null
289
- linkedin_url: string | null
290
- pipeline_status: Record<string, unknown> | null
291
- enrichment_data: Record<string, unknown> | null
292
- company: {
293
- id: string
294
- name: string
295
- domain: string | null
296
- website: string | null
297
- linkedin_url: string | null
298
- segment: string | null
299
- category: string | null
300
- num_employees: number | null
301
- } | null
302
- }
303
-
304
- export interface DealFilters {
305
- stage?: DealStage
306
- search?: string
307
- limit?: number
308
- offset?: number
309
- }
310
-
311
- /** Deal list item with joined contact and company data */
312
- export interface DealListItem extends AcqDealRow {
313
- contact: DealContact | null
314
- }
315
-
316
- export type DealDetail = DealListItem
317
-
318
- /** Task kind options for a deal task (human follow-up action type) */
319
- export type AcqDealTaskKind = 'call' | 'email' | 'meeting' | 'other'
320
-
321
- /**
322
- * A CRM to-do item attached to a deal representing a human follow-up action.
323
- * Transformed from AcqDealTaskRow with camelCase properties.
324
- */
325
- export interface AcqDealTask {
326
- id: string
327
- organizationId: string
328
- dealId: string
329
- title: string
330
- description: string | null
331
- kind: AcqDealTaskKind
332
- dueAt: string | null
333
- assigneeUserId: string | null
334
- completedAt: string | null
335
- completedByUserId: string | null
336
- createdAt: string
337
- updatedAt: string
338
- createdByUserId: string | null
339
- }
340
-
341
- // ─── Progress / Telemetry Types ──────────────────────────────────────────────
342
-
343
- /**
1
+ import type { Database } from '../../supabase/database.types'
2
+ import type { PipelineStage } from './api-schemas'
3
+
4
+ // =============================================================================
5
+ // Supabase-Generated Types (Re-exported from database.types)
6
+ // =============================================================================
7
+
8
+ /** Raw database row type for acq_lists table */
9
+ export type AcqListRow = Database['public']['Tables']['acq_lists']['Row']
10
+ /** Insert type for acq_lists table */
11
+ export type AcqListInsert = Database['public']['Tables']['acq_lists']['Insert']
12
+
13
+ /** Raw database row type for acq_companies table */
14
+ export type AcqCompanyRow = Database['public']['Tables']['acq_companies']['Row']
15
+ /** Insert type for acq_companies table */
16
+ export type AcqCompanyInsert = Database['public']['Tables']['acq_companies']['Insert']
17
+
18
+ /** Raw database row type for acq_contacts table */
19
+ export type AcqContactRow = Database['public']['Tables']['acq_contacts']['Row']
20
+ /** Insert type for acq_contacts table */
21
+ export type AcqContactInsert = Database['public']['Tables']['acq_contacts']['Insert']
22
+
23
+ /** Raw database row type for acq_deals table */
24
+ export type AcqDealRow = Database['public']['Tables']['acq_deals']['Row']
25
+ /** Insert type for acq_deals table */
26
+ export type AcqDealInsert = Database['public']['Tables']['acq_deals']['Insert']
27
+
28
+ /** Raw database row type for acq_deal_tasks table */
29
+ export type AcqDealTaskRow = Database['public']['Tables']['acq_deal_tasks']['Row']
30
+ /** Insert type for acq_deal_tasks table */
31
+ export type AcqDealTaskInsert = Database['public']['Tables']['acq_deal_tasks']['Insert']
32
+
33
+ // =============================================================================
34
+ // Supporting Types
35
+ // =============================================================================
36
+
37
+ /**
38
+ * Represents a web post from company website scraping.
39
+ * Used for recent blog posts, news, or announcements.
40
+ */
41
+ export interface WebPost {
42
+ /** ISO date string of when the post was published */
43
+ date: string
44
+ /** Title of the web post */
45
+ title: string
46
+ /** Brief summary of the post content */
47
+ summary: string
48
+ /** AI-generated insight about the post's relevance */
49
+ aiInsight?: string
50
+ }
51
+
52
+ /**
53
+ * Tracks pipeline status for a company across all processing stages.
54
+ */
55
+ export interface CompanyPipelineStatus {
56
+ acquired: boolean
57
+ enrichment: {
58
+ [source: string]: {
59
+ status: 'pending' | 'complete' | 'failed' | 'skipped'
60
+ completedAt?: string
61
+ error?: string
62
+ }
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Tracks pipeline status for a contact across all processing stages.
68
+ */
69
+ export interface ContactPipelineStatus {
70
+ enrichment: {
71
+ [source: string]: {
72
+ status: 'pending' | 'complete' | 'failed' | 'skipped'
73
+ completedAt?: string
74
+ error?: string
75
+ }
76
+ }
77
+ personalization: {
78
+ status: 'pending' | 'complete' | 'failed' | 'skipped'
79
+ completedAt?: string
80
+ }
81
+ outreach: {
82
+ status: 'pending' | 'sent' | 'replied' | 'bounced' | 'opted-out'
83
+ sentAt?: string
84
+ channel?: string
85
+ campaignId?: string
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Enrichment data collected for a company from various sources.
91
+ */
92
+ export interface CompanyEnrichmentData {
93
+ googleMaps?: {
94
+ placeId?: string
95
+ totalScore?: number
96
+ reviewsCount?: number
97
+ address?: string
98
+ phone?: string
99
+ categoryName?: string
100
+ googleMapsUrl?: string
101
+ scrapedAt?: string
102
+ }
103
+ websiteCrawl?: {
104
+ companyDescription?: string
105
+ services?: string[]
106
+ specialties?: string[]
107
+ staff?: Array<{ name: string; title?: string; email?: string }>
108
+ automationGaps?: string[]
109
+ targetAudience?: string
110
+ category?: string
111
+ segment?: string
112
+ recentWin?: string
113
+ emailCount?: number
114
+ pageCount?: number
115
+ totalChars?: number
116
+ crawledAt?: string
117
+ extractedAt?: string
118
+ }
119
+ website?: {
120
+ missionVision?: string
121
+ uniqueAttributes?: string
122
+ coreOfferings?: string
123
+ targetAudience?: string
124
+ companyValues?: string
125
+ businessDescription?: string
126
+ recentPosts?: Array<{ date?: string; title?: string; summary?: string; aiInsight?: string }>
127
+ }
128
+ tomba?: {
129
+ waterfallEmail?: {
130
+ email: string
131
+ name?: string
132
+ title?: string
133
+ department?: string
134
+ } | null
135
+ genericEmail?: string | null
136
+ totalFound?: number
137
+ searchedAt?: string
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Enrichment data collected for a contact from various sources.
143
+ */
144
+ export interface ContactEnrichmentData {
145
+ linkedin?: {
146
+ summary?: string
147
+ pastExperience?: string
148
+ education?: string
149
+ activity?: Array<{ date?: string; content?: string }>
150
+ }
151
+ }
152
+
153
+ // =============================================================================
154
+ // Domain Types (camelCase transformations of database rows)
155
+ // =============================================================================
156
+
157
+ export type ListStatus = 'draft' | 'enriching' | 'launched' | 'closing' | 'archived'
158
+
159
+ export interface ScrapingConfig {
160
+ source?: string
161
+ query?: string
162
+ filters?: Record<string, unknown>
163
+ [key: string]: unknown
164
+ }
165
+
166
+ export interface IcpRubric {
167
+ targetDescription?: string
168
+ minReviewCount?: number
169
+ minRating?: number
170
+ excludeFranchises?: boolean
171
+ customRules?: string
172
+ qualificationRubricKey?: string | null
173
+ [key: string]: unknown
174
+ }
175
+
176
+ export interface PipelineConfig {
177
+ stages: PipelineStage[]
178
+ }
179
+
180
+ export type BuildPlanSnapshotPrimaryEntity = 'company' | 'contact'
181
+ export type BuildPlanSnapshotOutput = 'company' | 'contact' | 'export'
182
+ export type BuildPlanSnapshotDependencyMode = 'per-record-eligibility'
183
+
184
+ export interface BuildPlanSnapshotStep {
185
+ id: string
186
+ label: string
187
+ description?: string
188
+ primaryEntity: BuildPlanSnapshotPrimaryEntity
189
+ outputs: BuildPlanSnapshotOutput[]
190
+ stageKey: string
191
+ dependsOn?: string[]
192
+ dependencyMode: BuildPlanSnapshotDependencyMode
193
+ capabilityKey: string
194
+ defaultBatchSize: number
195
+ maxBatchSize: number
196
+ }
197
+
198
+ export interface BuildPlanSnapshot {
199
+ templateId: string
200
+ templateLabel: string
201
+ steps: BuildPlanSnapshotStep[]
202
+ }
203
+
204
+ export interface AcqListMetadata extends Record<string, unknown> {
205
+ buildPlanSnapshot?: BuildPlanSnapshot
206
+ }
207
+
208
+ export interface AcqList {
209
+ id: string
210
+ organizationId: string
211
+ name: string
212
+ description: string | null
213
+ batchIds: string[]
214
+ instantlyCampaignId: string | null
215
+ status: ListStatus
216
+ scrapingConfig: ScrapingConfig
217
+ icp: IcpRubric
218
+ pipelineConfig: PipelineConfig
219
+ metadata: AcqListMetadata
220
+ launchedAt: Date | null
221
+ completedAt: Date | null
222
+ createdAt: Date
223
+ }
224
+
225
+ /**
226
+ * Company record in the acquisition database.
227
+ * Contains enriched company data from various sources.
228
+ * Transformed from AcqCompanyRow with camelCase properties.
229
+ */
230
+ export interface AcqCompany {
231
+ id: string
232
+ organizationId: string
233
+ name: string
234
+ domain: string | null
235
+ linkedinUrl: string | null
236
+ website: string | null
237
+ numEmployees: number | null
238
+ foundedYear: number | null
239
+ locationCity: string | null
240
+ locationState: string | null
241
+ category: string | null
242
+ categoryPain: string | null
243
+ segment: string | null
244
+ pipelineStatus: CompanyPipelineStatus | null
245
+ enrichmentData: CompanyEnrichmentData | null
246
+ source: string | null
247
+ batchId: string | null
248
+ status: 'active' | 'invalid'
249
+ verticalResearch: string | null
250
+ /** Track A: flat qualification score (null until a scoring rubric is defined). Added by W1 migration. */
251
+ qualificationScore: number | null
252
+ /** Track A: flat qualification signals jsonb preserving the result payload shape. Added by W1 migration. */
253
+ qualificationSignals: Record<string, unknown> | null
254
+ /** Track A: key identifying the rubric used for qualification. Added by W1 migration. */
255
+ qualificationRubricKey: string | null
256
+ createdAt: Date
257
+ updatedAt: Date
258
+ }
259
+
260
+ /**
261
+ * Contact record in the acquisition database.
262
+ * Contains enriched contact data and personalization content.
263
+ * Transformed from AcqContactRow with camelCase properties.
264
+ */
265
+ export interface AcqContact {
266
+ id: string
267
+ organizationId: string
268
+ companyId: string | null
269
+ email: string
270
+ emailValid: 'VALID' | 'INVALID' | 'RISKY' | 'UNKNOWN' | null
271
+ firstName: string | null
272
+ lastName: string | null
273
+ linkedinUrl: string | null
274
+ title: string | null
275
+ headline: string | null
276
+ filterReason: string | null
277
+ openingLine: string | null
278
+ source: string | null
279
+ sourceId: string | null
280
+ pipelineStatus: ContactPipelineStatus | null
281
+ enrichmentData: ContactEnrichmentData | null
282
+ /** Attio Person record ID - set when contact responds and is added to CRM */
283
+ attioPersonId: string | null
284
+ batchId: string | null
285
+ status: 'active' | 'invalid'
286
+ createdAt: Date
287
+ updatedAt: Date
288
+ }
289
+
290
+ // ─── Deal UI Types ───────────────────────────────────────────────────────────
291
+
292
+ export type DealStage = 'interested' | 'proposal' | 'closing' | 'closed_won' | 'closed_lost' | 'nurturing'
293
+
294
+ export type DealPriorityBucketKey = 'needs_response' | 'follow_up_due' | 'waiting' | 'stale' | 'closed_low'
295
+
296
+ export interface DealPriority {
297
+ bucketKey: DealPriorityBucketKey
298
+ rank: number
299
+ label: string
300
+ color: string
301
+ reason: string
302
+ latestActivityAt: string | null
303
+ nextActionAt: string | null
304
+ }
305
+
306
+ export interface KanbanStageConfig {
307
+ color: string // Mantine color token (e.g. 'blue', 'teal')
308
+ label?: string // Optional display label override
309
+ }
310
+
311
+ export type KanbanBoardConfig = Partial<Record<DealStage, KanbanStageConfig>>
312
+
313
+ export interface DealContact {
314
+ id: string
315
+ first_name: string | null
316
+ last_name: string | null
317
+ email: string
318
+ title: string | null
319
+ headline: string | null
320
+ linkedin_url: string | null
321
+ pipeline_status: Record<string, unknown> | null
322
+ enrichment_data: Record<string, unknown> | null
323
+ company: {
324
+ id: string
325
+ name: string
326
+ domain: string | null
327
+ website: string | null
328
+ linkedin_url: string | null
329
+ segment: string | null
330
+ category: string | null
331
+ num_employees: number | null
332
+ } | null
333
+ }
334
+
335
+ export interface DealFilters {
336
+ stage?: DealStage
337
+ search?: string
338
+ limit?: number
339
+ offset?: number
340
+ }
341
+
342
+ /** Deal list item with joined contact and company data */
343
+ export interface DealListItem extends AcqDealRow {
344
+ priority: DealPriority
345
+ ownership: 'us' | 'them' | null
346
+ nextAction: string | null
347
+ contact: DealContact | null
348
+ }
349
+
350
+ export type DealDetail = DealListItem
351
+
352
+ /** Task kind options for a deal task (human follow-up action type) */
353
+ export type AcqDealTaskKind = 'call' | 'email' | 'meeting' | 'other'
354
+
355
+ /**
356
+ * A CRM to-do item attached to a deal representing a human follow-up action.
357
+ * Transformed from AcqDealTaskRow with camelCase properties.
358
+ */
359
+ export interface AcqDealTask {
360
+ id: string
361
+ organizationId: string
362
+ dealId: string
363
+ title: string
364
+ description: string | null
365
+ kind: AcqDealTaskKind
366
+ dueAt: string | null
367
+ assigneeUserId: string | null
368
+ completedAt: string | null
369
+ completedByUserId: string | null
370
+ createdAt: string
371
+ updatedAt: string
372
+ createdByUserId: string | null
373
+ }
374
+
375
+ // ─── Progress / Telemetry Types ──────────────────────────────────────────────
376
+
377
+ /**
344
378
  * Live-scan aggregate telemetry for a single list, computed on demand from
345
379
  * the list junction tables and current contact deliverability state.
346
380
  * `stageCounts` are attempted counts from list-row processing_state.
347
381
  */
348
- export interface ListTelemetry {
349
- listId: string
350
- totalCompanies: number
351
- totalContacts: number
352
- stageCounts: {
353
- populated: number
354
- extracted: number
355
- qualified: number
356
- discovered: number
357
- verified: number
358
- personalized: number
359
- uploaded: number
360
- }
361
- deliverability: {
362
- valid: number
363
- risky: number
364
- invalid: number
365
- unknown: number
366
- bounced: number
367
- }
368
- /** Reserved -- active workflow IDs associated with this list. */
369
- activeWorkflows?: string[]
370
- }
382
+ export interface ListTelemetry {
383
+ listId: string
384
+ totalCompanies: number
385
+ totalContacts: number
386
+ stageCounts: {
387
+ populated: number
388
+ extracted: number
389
+ qualified: number
390
+ discovered: number
391
+ verified: number
392
+ personalized: number
393
+ uploaded: number
394
+ }
395
+ deliverability: {
396
+ valid: number
397
+ risky: number
398
+ invalid: number
399
+ unknown: number
400
+ bounced: number
401
+ }
402
+ /** Reserved -- active workflow IDs associated with this list. */
403
+ activeWorkflows?: string[]
404
+ }