@elevasis/core 0.18.0 → 0.20.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.
- package/dist/index.d.ts +82 -1
- package/dist/index.js +353 -171
- package/dist/knowledge/index.d.ts +44 -1
- package/dist/organization-model/index.d.ts +82 -1
- package/dist/organization-model/index.js +353 -171
- package/dist/test-utils/index.d.ts +41 -12
- package/dist/test-utils/index.js +352 -171
- package/package.json +4 -3
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +89 -69
- package/src/auth/multi-tenancy/organizations/__tests__/api-schemas.test.ts +194 -0
- package/src/auth/multi-tenancy/organizations/api-schemas.ts +136 -128
- package/src/business/acquisition/api-schemas.test.ts +199 -15
- package/src/business/acquisition/api-schemas.ts +116 -51
- package/src/business/acquisition/build-templates.test.ts +212 -0
- package/src/business/acquisition/derive-actions.test.ts +1 -1
- package/src/business/acquisition/types.ts +21 -38
- package/src/business/deals/api-schemas.ts +2 -2
- package/src/execution/engine/index.ts +436 -434
- package/src/execution/engine/tools/integration/server/adapters/google-calendar/google-calendar-adapter.ts +428 -0
- package/src/execution/engine/tools/integration/server/adapters/google-calendar/index.ts +2 -0
- package/src/execution/engine/tools/lead-service-types.ts +51 -9
- package/src/execution/engine/tools/platform/acquisition/company-tools.ts +7 -6
- package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +6 -5
- package/src/execution/engine/tools/platform/acquisition/types.ts +20 -9
- package/src/execution/engine/tools/registry.ts +700 -698
- package/src/execution/engine/tools/tool-maps.ts +10 -0
- package/src/execution/external/__tests__/api-schemas.test.ts +127 -0
- package/src/integrations/oauth/__tests__/provider-registry.test.ts +7 -6
- package/src/integrations/oauth/provider-registry.ts +74 -61
- package/src/integrations/oauth/server/credentials.ts +43 -39
- package/src/knowledge/__tests__/queries.test.ts +89 -0
- package/src/organization-model/__tests__/graph.test.ts +108 -2
- package/src/organization-model/__tests__/icons.test.ts +61 -0
- package/src/organization-model/__tests__/knowledge.test.ts +118 -1
- package/src/organization-model/__tests__/prospecting-ssot.test.ts +91 -0
- package/src/organization-model/__tests__/schema.test.ts +122 -0
- package/src/organization-model/__tests__/surface-projection.test.ts +174 -0
- package/src/organization-model/defaults.ts +8 -0
- package/src/organization-model/domains/knowledge.ts +9 -0
- package/src/organization-model/domains/prospecting.ts +347 -226
- package/src/organization-model/domains/sales.ts +40 -30
- package/src/organization-model/graph/build.ts +74 -0
- package/src/organization-model/graph/schema.ts +1 -0
- package/src/organization-model/graph/types.ts +1 -0
- package/src/organization-model/icons.ts +3 -0
- package/src/organization-model/schema.ts +63 -0
- package/src/organization-model/surface-projection.ts +218 -0
- package/src/organization-model/types.ts +9 -1
- package/src/platform/constants/versions.ts +1 -1
- package/src/platform/utils/__tests__/validation.test.ts +1084 -1083
- package/src/platform/utils/validation.ts +425 -425
- package/src/reference/_generated/contracts.md +89 -69
- package/src/server.ts +6 -0
- package/src/supabase/database.types.ts +6 -12
|
@@ -195,6 +195,18 @@ export type OrgKnowledgeNode = z.infer<typeof OrgKnowledgeNodeSchema>
|
|
|
195
195
|
export type OrgKnowledgeKind = z.infer<typeof OrgKnowledgeKindSchema>
|
|
196
196
|
```
|
|
197
197
|
|
|
198
|
+
### `KnowledgeSkillBinding`
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
export type KnowledgeSkillBinding = z.infer<typeof KnowledgeSkillBindingSchema>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### `KnowledgeDomainBinding`
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
export type KnowledgeDomainBinding = z.infer<typeof KnowledgeDomainBindingSchema>
|
|
208
|
+
```
|
|
209
|
+
|
|
198
210
|
### `OrganizationModelIconToken`
|
|
199
211
|
|
|
200
212
|
```typescript
|
|
@@ -866,7 +878,9 @@ export interface AcqCompany {
|
|
|
866
878
|
category: string | null
|
|
867
879
|
categoryPain: string | null
|
|
868
880
|
segment: string | null
|
|
869
|
-
|
|
881
|
+
processingState: CompanyProcessingState | null
|
|
882
|
+
/** @deprecated Use `processingState`. This legacy DB column has been removed; responses return null. */
|
|
883
|
+
pipelineStatus?: LegacyPipelineStatus | null
|
|
870
884
|
enrichmentData: CompanyEnrichmentData | null
|
|
871
885
|
source: string | null
|
|
872
886
|
batchId: string | null
|
|
@@ -906,7 +920,9 @@ export interface AcqContact {
|
|
|
906
920
|
openingLine: string | null
|
|
907
921
|
source: string | null
|
|
908
922
|
sourceId: string | null
|
|
909
|
-
|
|
923
|
+
processingState: ContactProcessingState | null
|
|
924
|
+
/** @deprecated Use `processingState`. This legacy DB column has been removed; responses return null. */
|
|
925
|
+
pipelineStatus?: LegacyPipelineStatus | null
|
|
910
926
|
enrichmentData: ContactEnrichmentData | null
|
|
911
927
|
/** Attio Person record ID - set when contact responds and is added to CRM */
|
|
912
928
|
attioPersonId: string | null
|
|
@@ -969,7 +985,7 @@ export interface DealContact {
|
|
|
969
985
|
title: string | null
|
|
970
986
|
headline: string | null
|
|
971
987
|
linkedin_url: string | null
|
|
972
|
-
|
|
988
|
+
processing_state: Record<string, unknown> | null
|
|
973
989
|
enrichment_data: Record<string, unknown> | null
|
|
974
990
|
company: {
|
|
975
991
|
id: string
|
|
@@ -1107,7 +1123,7 @@ export const DEFAULT_CRM_PRIORITY_RULE_CONFIG: CrmPriorityRuleConfig = {
|
|
|
1107
1123
|
### `DealStageSchema`
|
|
1108
1124
|
|
|
1109
1125
|
```typescript
|
|
1110
|
-
export const DealStageSchema =
|
|
1126
|
+
export const DealStageSchema = CrmStageKeySchema
|
|
1111
1127
|
```
|
|
1112
1128
|
|
|
1113
1129
|
### `AcqDealTaskKindSchema`
|
|
@@ -1199,7 +1215,7 @@ export const TransitionItemRequestSchema = z
|
|
|
1199
1215
|
.object({
|
|
1200
1216
|
pipelineKey: z.string().min(1),
|
|
1201
1217
|
stageKey: z.string().min(1),
|
|
1202
|
-
stateKey: z.string().nullable().optional(),
|
|
1218
|
+
stateKey: z.string().min(1).nullable().optional(),
|
|
1203
1219
|
reason: z.string().optional(),
|
|
1204
1220
|
expectedUpdatedAt: z.string().datetime().optional()
|
|
1205
1221
|
})
|
|
@@ -1242,7 +1258,7 @@ export const DealContactSummarySchema = z.object({
|
|
|
1242
1258
|
title: z.string().nullable(),
|
|
1243
1259
|
headline: z.string().nullable(),
|
|
1244
1260
|
linkedin_url: z.string().nullable(),
|
|
1245
|
-
|
|
1261
|
+
processing_state: ProcessingStateSchema.nullable(),
|
|
1246
1262
|
enrichment_data: z.record(z.string(), z.unknown()).nullable(),
|
|
1247
1263
|
company: z
|
|
1248
1264
|
.object({
|
|
@@ -1393,6 +1409,11 @@ export const DealTaskListResponseSchema = z.array(DealTaskResponseSchema)
|
|
|
1393
1409
|
|
|
1394
1410
|
```typescript
|
|
1395
1411
|
export const DealSchemas = {
|
|
1412
|
+
// Primitives
|
|
1413
|
+
CrmStageKey: CrmStageKeySchema,
|
|
1414
|
+
CrmStateKey: CrmStateKeySchema,
|
|
1415
|
+
DealStage: DealStageSchema,
|
|
1416
|
+
|
|
1396
1417
|
// Params
|
|
1397
1418
|
DealIdParams: DealIdParamsSchema,
|
|
1398
1419
|
DealTaskIdParams: DealTaskIdParamsSchema,
|
|
@@ -1405,7 +1426,7 @@ export const DealSchemas = {
|
|
|
1405
1426
|
// Request bodies
|
|
1406
1427
|
CreateDealNoteRequest: CreateDealNoteRequestSchema,
|
|
1407
1428
|
CreateDealTaskRequest: CreateDealTaskRequestSchema,
|
|
1408
|
-
TransitionItemRequest:
|
|
1429
|
+
TransitionItemRequest: CrmTransitionItemRequestSchema,
|
|
1409
1430
|
TransitionDealStateRequest: TransitionDealStateRequestSchema,
|
|
1410
1431
|
ExecuteActionParams: ExecuteActionParamsSchema,
|
|
1411
1432
|
ExecuteActionRequest: ExecuteActionRequestSchema,
|
|
@@ -1570,51 +1591,6 @@ export interface WebPost {
|
|
|
1570
1591
|
}
|
|
1571
1592
|
```
|
|
1572
1593
|
|
|
1573
|
-
### `CompanyPipelineStatus`
|
|
1574
|
-
|
|
1575
|
-
```typescript
|
|
1576
|
-
/**
|
|
1577
|
-
* Tracks pipeline status for a company across all processing stages.
|
|
1578
|
-
*/
|
|
1579
|
-
export interface CompanyPipelineStatus {
|
|
1580
|
-
acquired: boolean
|
|
1581
|
-
enrichment: {
|
|
1582
|
-
[source: string]: {
|
|
1583
|
-
status: 'pending' | 'complete' | 'failed' | 'skipped'
|
|
1584
|
-
completedAt?: string
|
|
1585
|
-
error?: string
|
|
1586
|
-
}
|
|
1587
|
-
}
|
|
1588
|
-
}
|
|
1589
|
-
```
|
|
1590
|
-
|
|
1591
|
-
### `ContactPipelineStatus`
|
|
1592
|
-
|
|
1593
|
-
```typescript
|
|
1594
|
-
/**
|
|
1595
|
-
* Tracks pipeline status for a contact across all processing stages.
|
|
1596
|
-
*/
|
|
1597
|
-
export interface ContactPipelineStatus {
|
|
1598
|
-
enrichment: {
|
|
1599
|
-
[source: string]: {
|
|
1600
|
-
status: 'pending' | 'complete' | 'failed' | 'skipped'
|
|
1601
|
-
completedAt?: string
|
|
1602
|
-
error?: string
|
|
1603
|
-
}
|
|
1604
|
-
}
|
|
1605
|
-
personalization: {
|
|
1606
|
-
status: 'pending' | 'complete' | 'failed' | 'skipped'
|
|
1607
|
-
completedAt?: string
|
|
1608
|
-
}
|
|
1609
|
-
outreach: {
|
|
1610
|
-
status: 'pending' | 'sent' | 'replied' | 'bounced' | 'opted-out'
|
|
1611
|
-
sentAt?: string
|
|
1612
|
-
channel?: string
|
|
1613
|
-
campaignId?: string
|
|
1614
|
-
}
|
|
1615
|
-
}
|
|
1616
|
-
```
|
|
1617
|
-
|
|
1618
1594
|
### `CompanyEnrichmentData`
|
|
1619
1595
|
|
|
1620
1596
|
```typescript
|
|
@@ -1730,7 +1706,9 @@ export interface AcqCompany {
|
|
|
1730
1706
|
category: string | null
|
|
1731
1707
|
categoryPain: string | null
|
|
1732
1708
|
segment: string | null
|
|
1733
|
-
|
|
1709
|
+
processingState: CompanyProcessingState | null
|
|
1710
|
+
/** @deprecated Use `processingState`. This legacy DB column has been removed; responses return null. */
|
|
1711
|
+
pipelineStatus?: LegacyPipelineStatus | null
|
|
1734
1712
|
enrichmentData: CompanyEnrichmentData | null
|
|
1735
1713
|
source: string | null
|
|
1736
1714
|
batchId: string | null
|
|
@@ -1770,7 +1748,9 @@ export interface AcqContact {
|
|
|
1770
1748
|
openingLine: string | null
|
|
1771
1749
|
source: string | null
|
|
1772
1750
|
sourceId: string | null
|
|
1773
|
-
|
|
1751
|
+
processingState: ContactProcessingState | null
|
|
1752
|
+
/** @deprecated Use `processingState`. This legacy DB column has been removed; responses return null. */
|
|
1753
|
+
pipelineStatus?: LegacyPipelineStatus | null
|
|
1774
1754
|
enrichmentData: ContactEnrichmentData | null
|
|
1775
1755
|
/** Attio Person record ID - set when contact responds and is added to CRM */
|
|
1776
1756
|
attioPersonId: string | null
|
|
@@ -2081,6 +2061,7 @@ export const ListCompaniesQuerySchema = z
|
|
|
2081
2061
|
website: z.string().trim().min(1).max(2048).optional(),
|
|
2082
2062
|
segment: z.string().trim().min(1).max(255).optional(),
|
|
2083
2063
|
category: z.string().trim().min(1).max(255).optional(),
|
|
2064
|
+
pipelineStatus: z.unknown().optional(),
|
|
2084
2065
|
batchId: z.string().trim().min(1).max(255).optional(),
|
|
2085
2066
|
status: AcqCompanyStatusSchema.optional(),
|
|
2086
2067
|
includeAll: QueryBooleanSchema.optional(),
|
|
@@ -2122,6 +2103,7 @@ export const CreateCompanyRequestSchema = z
|
|
|
2122
2103
|
category: z.string().trim().min(1).max(255).optional(),
|
|
2123
2104
|
source: z.string().trim().min(1).max(255).optional(),
|
|
2124
2105
|
batchId: z.string().trim().min(1).max(255).optional(),
|
|
2106
|
+
pipelineStatus: z.unknown().optional(),
|
|
2125
2107
|
verticalResearch: z.string().trim().min(1).max(5000).optional()
|
|
2126
2108
|
})
|
|
2127
2109
|
.strict()
|
|
@@ -2142,7 +2124,8 @@ export const UpdateCompanyRequestSchema = z
|
|
|
2142
2124
|
locationState: z.string().trim().min(1).max(255).optional(),
|
|
2143
2125
|
category: z.string().trim().min(1).max(255).optional(),
|
|
2144
2126
|
segment: z.string().trim().min(1).max(255).optional(),
|
|
2145
|
-
|
|
2127
|
+
processingState: CompanyProcessingStateSchema.optional(),
|
|
2128
|
+
pipelineStatus: z.unknown().optional(),
|
|
2146
2129
|
enrichmentData: z.record(z.string(), z.unknown()).optional(),
|
|
2147
2130
|
source: z.string().trim().min(1).max(255).optional(),
|
|
2148
2131
|
batchId: z.string().trim().min(1).max(255).optional(),
|
|
@@ -2162,6 +2145,7 @@ export const UpdateCompanyRequestSchema = z
|
|
|
2162
2145
|
data.locationState !== undefined ||
|
|
2163
2146
|
data.category !== undefined ||
|
|
2164
2147
|
data.segment !== undefined ||
|
|
2148
|
+
data.processingState !== undefined ||
|
|
2165
2149
|
data.pipelineStatus !== undefined ||
|
|
2166
2150
|
data.enrichmentData !== undefined ||
|
|
2167
2151
|
data.source !== undefined ||
|
|
@@ -2187,7 +2171,8 @@ export const CreateContactRequestSchema = z
|
|
|
2187
2171
|
title: z.string().trim().min(1).max(255).optional(),
|
|
2188
2172
|
source: z.string().trim().min(1).max(255).optional(),
|
|
2189
2173
|
sourceId: z.string().trim().min(1).max(255).optional(),
|
|
2190
|
-
batchId: z.string().trim().min(1).max(255).optional()
|
|
2174
|
+
batchId: z.string().trim().min(1).max(255).optional(),
|
|
2175
|
+
pipelineStatus: z.unknown().optional()
|
|
2191
2176
|
})
|
|
2192
2177
|
.strict()
|
|
2193
2178
|
```
|
|
@@ -2206,7 +2191,8 @@ export const UpdateContactRequestSchema = z
|
|
|
2206
2191
|
headline: z.string().trim().min(1).max(5000).optional(),
|
|
2207
2192
|
filterReason: z.string().trim().min(1).max(5000).optional(),
|
|
2208
2193
|
openingLine: z.string().trim().min(1).max(5000).optional(),
|
|
2209
|
-
|
|
2194
|
+
processingState: ContactProcessingStateSchema.optional(),
|
|
2195
|
+
pipelineStatus: z.unknown().optional(),
|
|
2210
2196
|
enrichmentData: z.record(z.string(), z.unknown()).optional(),
|
|
2211
2197
|
status: AcqContactStatusSchema.optional()
|
|
2212
2198
|
})
|
|
@@ -2222,6 +2208,7 @@ export const UpdateContactRequestSchema = z
|
|
|
2222
2208
|
data.headline !== undefined ||
|
|
2223
2209
|
data.filterReason !== undefined ||
|
|
2224
2210
|
data.openingLine !== undefined ||
|
|
2211
|
+
data.processingState !== undefined ||
|
|
2225
2212
|
data.pipelineStatus !== undefined ||
|
|
2226
2213
|
data.enrichmentData !== undefined ||
|
|
2227
2214
|
data.status !== undefined,
|
|
@@ -2248,7 +2235,8 @@ export const AcqCompanyResponseSchema = z.object({
|
|
|
2248
2235
|
category: z.string().nullable(),
|
|
2249
2236
|
categoryPain: z.string().nullable(),
|
|
2250
2237
|
segment: z.string().nullable(),
|
|
2251
|
-
|
|
2238
|
+
processingState: CompanyProcessingStateSchema.nullable(),
|
|
2239
|
+
pipelineStatus: z.unknown().nullable().optional(),
|
|
2252
2240
|
enrichmentData: z.record(z.string(), z.unknown()).nullable(),
|
|
2253
2241
|
source: z.string().nullable(),
|
|
2254
2242
|
batchId: z.string().nullable(),
|
|
@@ -2314,7 +2302,8 @@ export const AcqContactResponseSchema = z.object({
|
|
|
2314
2302
|
openingLine: z.string().nullable(),
|
|
2315
2303
|
source: z.string().nullable(),
|
|
2316
2304
|
sourceId: z.string().nullable(),
|
|
2317
|
-
|
|
2305
|
+
processingState: ContactProcessingStateSchema.nullable(),
|
|
2306
|
+
pipelineStatus: z.unknown().nullable().optional(),
|
|
2318
2307
|
enrichmentData: z.record(z.string(), z.unknown()).nullable(),
|
|
2319
2308
|
attioPersonId: z.string().nullable(),
|
|
2320
2309
|
batchId: z.string().nullable(),
|
|
@@ -2480,6 +2469,7 @@ export const AcqListCompanyResponseSchema = z.object({
|
|
|
2480
2469
|
|
|
2481
2470
|
```typescript
|
|
2482
2471
|
export const AcqCompanySchemas = {
|
|
2472
|
+
CompanyProcessingState: CompanyProcessingStateSchema,
|
|
2483
2473
|
CompanyIdParams: CompanyIdParamsSchema,
|
|
2484
2474
|
ListCompaniesQuery: ListCompaniesQuerySchema,
|
|
2485
2475
|
CreateCompanyRequest: CreateCompanyRequestSchema,
|
|
@@ -2494,6 +2484,7 @@ export const AcqCompanySchemas = {
|
|
|
2494
2484
|
|
|
2495
2485
|
```typescript
|
|
2496
2486
|
export const AcqContactSchemas = {
|
|
2487
|
+
ContactProcessingState: ContactProcessingStateSchema,
|
|
2497
2488
|
ContactIdParams: ContactIdParamsSchema,
|
|
2498
2489
|
ListContactsQuery: ListContactsQuerySchema,
|
|
2499
2490
|
CreateContactRequest: CreateContactRequestSchema,
|
|
@@ -2519,7 +2510,10 @@ export const AcqListSchemas = {
|
|
|
2519
2510
|
BuildPlanSnapshot: BuildPlanSnapshotSchema,
|
|
2520
2511
|
BuildPlanSnapshotStep: BuildPlanSnapshotStepSchema,
|
|
2521
2512
|
AcqListMetadata: AcqListMetadataSchema,
|
|
2513
|
+
LeadGenStageKey: LeadGenStageKeySchema,
|
|
2514
|
+
LeadGenCapabilityKey: LeadGenCapabilityKeySchema,
|
|
2522
2515
|
ProcessingStageStatus: ProcessingStageStatusSchema,
|
|
2516
|
+
ProcessingState: ProcessingStateSchema,
|
|
2523
2517
|
ListStageCounts: ListStageCountsSchema,
|
|
2524
2518
|
ListTelemetry: ListTelemetrySchema,
|
|
2525
2519
|
|
|
@@ -2563,7 +2557,7 @@ export const AcqSubstrateSchemas = {
|
|
|
2563
2557
|
ListCompanyIdParams: ListCompanyIdParamsSchema,
|
|
2564
2558
|
AcqListCompanyResponse: AcqListCompanyResponseSchema,
|
|
2565
2559
|
|
|
2566
|
-
// Transition (
|
|
2560
|
+
// Transition (generic stateful substrate)
|
|
2567
2561
|
TransitionItemRequest: TransitionItemRequestSchema
|
|
2568
2562
|
}
|
|
2569
2563
|
```
|
|
@@ -2631,6 +2625,8 @@ export interface StatefulStageDefinition {
|
|
|
2631
2625
|
/** Matches stage_key values written by workflow steps. */
|
|
2632
2626
|
stageKey: string
|
|
2633
2627
|
label: string
|
|
2628
|
+
/** UI color token. Consumers may map this to their design system. */
|
|
2629
|
+
color?: string
|
|
2634
2630
|
states: StatefulStateDefinition[]
|
|
2635
2631
|
}
|
|
2636
2632
|
```
|
|
@@ -2812,6 +2808,8 @@ export interface CreateCompanyParams {
|
|
|
2812
2808
|
source?: string
|
|
2813
2809
|
batchId?: string
|
|
2814
2810
|
verticalResearch?: string
|
|
2811
|
+
/** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
|
|
2812
|
+
pipelineStatus?: unknown
|
|
2815
2813
|
}
|
|
2816
2814
|
```
|
|
2817
2815
|
|
|
@@ -2829,7 +2827,9 @@ export interface UpdateCompanyParams {
|
|
|
2829
2827
|
locationState?: string
|
|
2830
2828
|
category?: string
|
|
2831
2829
|
segment?: string
|
|
2832
|
-
|
|
2830
|
+
processingState?: ProcessingState
|
|
2831
|
+
/** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
|
|
2832
|
+
pipelineStatus?: unknown
|
|
2833
2833
|
enrichmentData?: Record<string, unknown>
|
|
2834
2834
|
source?: string
|
|
2835
2835
|
batchId?: string
|
|
@@ -2837,7 +2837,7 @@ export interface UpdateCompanyParams {
|
|
|
2837
2837
|
verticalResearch?: string | null
|
|
2838
2838
|
/** Track A: flat qualification score column (null until a scoring rubric is defined) */
|
|
2839
2839
|
qualificationScore?: number | null
|
|
2840
|
-
/** Track A: flat qualification signals jsonb
|
|
2840
|
+
/** Track A: flat qualification signals jsonb */
|
|
2841
2841
|
qualificationSignals?: Record<string, unknown> | null
|
|
2842
2842
|
/** Track A: key identifying the rubric used for qualification */
|
|
2843
2843
|
qualificationRubricKey?: string | null
|
|
@@ -2860,13 +2860,15 @@ export interface CompanyFilters {
|
|
|
2860
2860
|
website?: string
|
|
2861
2861
|
segment?: string
|
|
2862
2862
|
category?: string
|
|
2863
|
-
|
|
2864
|
-
/**
|
|
2865
|
-
|
|
2863
|
+
processingState?: ProcessingState
|
|
2864
|
+
/** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
|
|
2865
|
+
pipelineStatus?: unknown
|
|
2866
|
+
/** Exclude companies whose processing state contains this value (PostgREST NOT contains) */
|
|
2867
|
+
processingStateNot?: ProcessingState
|
|
2866
2868
|
batchId?: string
|
|
2867
2869
|
status?: 'active' | 'invalid'
|
|
2868
2870
|
includeAll?: boolean
|
|
2869
|
-
excludeColumns?: Array<'enrichmentData' | '
|
|
2871
|
+
excludeColumns?: Array<'enrichmentData' | 'processingState'>
|
|
2870
2872
|
limit?: number
|
|
2871
2873
|
}
|
|
2872
2874
|
```
|
|
@@ -2885,6 +2887,8 @@ export interface CreateContactParams {
|
|
|
2885
2887
|
source?: string
|
|
2886
2888
|
sourceId?: string
|
|
2887
2889
|
batchId?: string
|
|
2890
|
+
/** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
|
|
2891
|
+
pipelineStatus?: unknown
|
|
2888
2892
|
}
|
|
2889
2893
|
```
|
|
2890
2894
|
|
|
@@ -2901,7 +2905,9 @@ export interface UpdateContactParams {
|
|
|
2901
2905
|
headline?: string
|
|
2902
2906
|
filterReason?: string
|
|
2903
2907
|
openingLine?: string
|
|
2904
|
-
|
|
2908
|
+
processingState?: ProcessingState
|
|
2909
|
+
/** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
|
|
2910
|
+
pipelineStatus?: unknown
|
|
2905
2911
|
enrichmentData?: Record<string, unknown>
|
|
2906
2912
|
status?: 'active' | 'invalid'
|
|
2907
2913
|
}
|
|
@@ -2920,7 +2926,9 @@ export interface ContactFilters {
|
|
|
2920
2926
|
listId?: string // Filter to contacts in a specific list (via acq_list_members)
|
|
2921
2927
|
search?: string
|
|
2922
2928
|
openingLineIsNull?: boolean // Filter to contacts without personalization
|
|
2923
|
-
|
|
2929
|
+
processingState?: ProcessingState
|
|
2930
|
+
/** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
|
|
2931
|
+
pipelineStatus?: unknown
|
|
2924
2932
|
batchId?: string
|
|
2925
2933
|
contactStatus?: 'active' | 'invalid' // Filter by contact status (soft-delete flag)
|
|
2926
2934
|
}
|
|
@@ -3119,7 +3127,7 @@ export interface BulkImportCompanyEntry {
|
|
|
3119
3127
|
category?: string
|
|
3120
3128
|
source?: string
|
|
3121
3129
|
enrichmentData?: Record<string, unknown>
|
|
3122
|
-
|
|
3130
|
+
processingState?: ProcessingState
|
|
3123
3131
|
}
|
|
3124
3132
|
```
|
|
3125
3133
|
|
|
@@ -3300,6 +3308,14 @@ export type ListToolMap = {
|
|
|
3300
3308
|
params: Omit<UpdateContactStageParams, 'organizationId'>
|
|
3301
3309
|
result: void
|
|
3302
3310
|
}
|
|
3311
|
+
listPendingCompanyIds: {
|
|
3312
|
+
params: Omit<ListPendingCompanyIdsParams, 'organizationId'>
|
|
3313
|
+
result: string[]
|
|
3314
|
+
}
|
|
3315
|
+
listPendingContactIds: {
|
|
3316
|
+
params: Omit<ListPendingContactIdsParams, 'organizationId'>
|
|
3317
|
+
result: string[]
|
|
3318
|
+
}
|
|
3303
3319
|
}
|
|
3304
3320
|
```
|
|
3305
3321
|
|
|
@@ -3335,6 +3351,10 @@ export const OrgKnowledgeNodeSchema = z.object({
|
|
|
3335
3351
|
* Each link emits a `governs` edge: knowledge-node -> target node.
|
|
3336
3352
|
*/
|
|
3337
3353
|
links: z.array(KnowledgeLinkSchema).default([]),
|
|
3354
|
+
/** Operator skill or command bindings relevant to this node. */
|
|
3355
|
+
skills: z.array(KnowledgeSkillBindingSchema).optional(),
|
|
3356
|
+
/** Domain key used to derive fast graph->skill registries. */
|
|
3357
|
+
domain: KnowledgeDomainBindingSchema.optional(),
|
|
3338
3358
|
/** Identifiers of the roles or members who own this knowledge node. */
|
|
3339
3359
|
ownerIds: z.array(ModelIdSchema).default([]),
|
|
3340
3360
|
/** ISO date string (YYYY-MM-DD or full ISO 8601) of last meaningful update. */
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { CreateOrganizationSchema, ListOrganizationsQuerySchema, UpdateOrganizationSchema } from '../api-schemas'
|
|
3
|
+
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// CreateOrganizationSchema
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
describe('CreateOrganizationSchema', () => {
|
|
9
|
+
it('accepts a minimal valid payload (name only)', () => {
|
|
10
|
+
expect(CreateOrganizationSchema.safeParse({ name: 'Acme Corp' }).success).toBe(true)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
it('accepts name at minimum length boundary (2 chars)', () => {
|
|
14
|
+
expect(CreateOrganizationSchema.safeParse({ name: 'AB' }).success).toBe(true)
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('accepts name at maximum length boundary (100 chars)', () => {
|
|
18
|
+
expect(CreateOrganizationSchema.safeParse({ name: 'A'.repeat(100) }).success).toBe(true)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('rejects name shorter than 2 characters', () => {
|
|
22
|
+
expect(CreateOrganizationSchema.safeParse({ name: 'A' }).success).toBe(false)
|
|
23
|
+
expect(CreateOrganizationSchema.safeParse({ name: '' }).success).toBe(false)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('rejects name longer than 100 characters', () => {
|
|
27
|
+
expect(CreateOrganizationSchema.safeParse({ name: 'A'.repeat(101) }).success).toBe(false)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('accepts names with letters, numbers, spaces, hyphens, and underscores', () => {
|
|
31
|
+
expect(CreateOrganizationSchema.safeParse({ name: 'My Org-123_Test' }).success).toBe(true)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('rejects names with disallowed characters (special symbols)', () => {
|
|
35
|
+
expect(CreateOrganizationSchema.safeParse({ name: 'Acme@Corp' }).success).toBe(false)
|
|
36
|
+
expect(CreateOrganizationSchema.safeParse({ name: 'Acme.Corp' }).success).toBe(false)
|
|
37
|
+
expect(CreateOrganizationSchema.safeParse({ name: 'Acme/Corp' }).success).toBe(false)
|
|
38
|
+
expect(CreateOrganizationSchema.safeParse({ name: 'Acme+Corp' }).success).toBe(false)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('accepts optional domainData array with valid entries', () => {
|
|
42
|
+
const result = CreateOrganizationSchema.safeParse({
|
|
43
|
+
name: 'Acme Corp',
|
|
44
|
+
domainData: [{ domain: 'acme.com', state: 'verified' }]
|
|
45
|
+
})
|
|
46
|
+
expect(result.success).toBe(true)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('accepts domainData up to 10 entries', () => {
|
|
50
|
+
const domains = Array.from({ length: 10 }, (_, i) => ({ domain: `domain${i}.com` }))
|
|
51
|
+
expect(CreateOrganizationSchema.safeParse({ name: 'Acme Corp', domainData: domains }).success).toBe(true)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('rejects domainData with more than 10 entries', () => {
|
|
55
|
+
const domains = Array.from({ length: 11 }, (_, i) => ({ domain: `domain${i}.com` }))
|
|
56
|
+
expect(CreateOrganizationSchema.safeParse({ name: 'Acme Corp', domainData: domains }).success).toBe(false)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('accepts optional metadata as a record under 10KB', () => {
|
|
60
|
+
const result = CreateOrganizationSchema.safeParse({
|
|
61
|
+
name: 'Acme Corp',
|
|
62
|
+
metadata: { plan: 'pro', region: 'us-west' }
|
|
63
|
+
})
|
|
64
|
+
expect(result.success).toBe(true)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('rejects metadata exceeding 10KB (10240 bytes)', () => {
|
|
68
|
+
// Build a metadata object whose JSON representation exceeds 10240 bytes
|
|
69
|
+
const largeValue = 'x'.repeat(10241)
|
|
70
|
+
const result = CreateOrganizationSchema.safeParse({
|
|
71
|
+
name: 'Acme Corp',
|
|
72
|
+
metadata: { big: largeValue }
|
|
73
|
+
})
|
|
74
|
+
expect(result.success).toBe(false)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
it('rejects unknown top-level fields (.strict() mode)', () => {
|
|
78
|
+
expect(CreateOrganizationSchema.safeParse({ name: 'Acme Corp', unknownField: 'value' }).success).toBe(false)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('rejects missing name field', () => {
|
|
82
|
+
expect(CreateOrganizationSchema.safeParse({}).success).toBe(false)
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// UpdateOrganizationSchema
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
|
|
90
|
+
describe('UpdateOrganizationSchema', () => {
|
|
91
|
+
it('rejects an empty object (at least one field required)', () => {
|
|
92
|
+
// UpdateOrganizationSchema is CreateOrganizationSchema.partial().strict().refine(...)
|
|
93
|
+
// The .refine() enforces the documented "at least one field" convention
|
|
94
|
+
// (see .claude/rules/core-package.md → "api-schemas.ts Pattern")
|
|
95
|
+
const result = UpdateOrganizationSchema.safeParse({})
|
|
96
|
+
expect(result.success).toBe(false)
|
|
97
|
+
if (!result.success) {
|
|
98
|
+
expect(result.error.issues[0].message).toMatch(/at least one field/i)
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it('accepts updating only name', () => {
|
|
103
|
+
expect(UpdateOrganizationSchema.safeParse({ name: 'New Name' }).success).toBe(true)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('accepts updating only domainData', () => {
|
|
107
|
+
expect(UpdateOrganizationSchema.safeParse({ domainData: [{ domain: 'newdomain.com' }] }).success).toBe(true)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('accepts updating only metadata', () => {
|
|
111
|
+
expect(UpdateOrganizationSchema.safeParse({ metadata: { key: 'value' } }).success).toBe(true)
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('applies same name validation as CreateOrganizationSchema when name is provided', () => {
|
|
115
|
+
// Too short
|
|
116
|
+
expect(UpdateOrganizationSchema.safeParse({ name: 'A' }).success).toBe(false)
|
|
117
|
+
// Too long
|
|
118
|
+
expect(UpdateOrganizationSchema.safeParse({ name: 'A'.repeat(101) }).success).toBe(false)
|
|
119
|
+
// Invalid charset
|
|
120
|
+
expect(UpdateOrganizationSchema.safeParse({ name: 'Bad@Name' }).success).toBe(false)
|
|
121
|
+
// Valid
|
|
122
|
+
expect(UpdateOrganizationSchema.safeParse({ name: 'Good Name-123' }).success).toBe(true)
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it('applies same domainData max-10 validation when provided', () => {
|
|
126
|
+
const tooMany = Array.from({ length: 11 }, (_, i) => ({ domain: `d${i}.com` }))
|
|
127
|
+
expect(UpdateOrganizationSchema.safeParse({ domainData: tooMany }).success).toBe(false)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('applies same metadata 10KB cap validation when provided', () => {
|
|
131
|
+
const largeValue = 'x'.repeat(10241)
|
|
132
|
+
expect(UpdateOrganizationSchema.safeParse({ metadata: { big: largeValue } }).success).toBe(false)
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('rejects unknown top-level fields (.strict() mode)', () => {
|
|
136
|
+
expect(UpdateOrganizationSchema.safeParse({ name: 'Valid Name', unknownField: 'bad' }).success).toBe(false)
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
// ---------------------------------------------------------------------------
|
|
141
|
+
// ListOrganizationsQuerySchema
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
|
|
144
|
+
describe('ListOrganizationsQuerySchema', () => {
|
|
145
|
+
it('accepts an empty query and applies default limit of 20', () => {
|
|
146
|
+
const result = ListOrganizationsQuerySchema.safeParse({})
|
|
147
|
+
expect(result.success).toBe(true)
|
|
148
|
+
if (result.success) {
|
|
149
|
+
expect(result.data.limit).toBe(20)
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
it('coerces limit from string "50" to number 50', () => {
|
|
154
|
+
const result = ListOrganizationsQuerySchema.safeParse({ limit: '50' })
|
|
155
|
+
expect(result.success).toBe(true)
|
|
156
|
+
if (result.success) expect(result.data.limit).toBe(50)
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
it('accepts limit at upper boundary (100)', () => {
|
|
160
|
+
const result = ListOrganizationsQuerySchema.safeParse({ limit: '100' })
|
|
161
|
+
expect(result.success).toBe(true)
|
|
162
|
+
if (result.success) expect(result.data.limit).toBe(100)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
it('accepts limit at lower boundary (1)', () => {
|
|
166
|
+
const result = ListOrganizationsQuerySchema.safeParse({ limit: '1' })
|
|
167
|
+
expect(result.success).toBe(true)
|
|
168
|
+
if (result.success) expect(result.data.limit).toBe(1)
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
it('rejects limit of 101 (above max 100)', () => {
|
|
172
|
+
expect(ListOrganizationsQuerySchema.safeParse({ limit: '101' }).success).toBe(false)
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
it('rejects limit of 0 (below min 1)', () => {
|
|
176
|
+
expect(ListOrganizationsQuerySchema.safeParse({ limit: '0' }).success).toBe(false)
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
it('accepts optional before cursor string', () => {
|
|
180
|
+
const result = ListOrganizationsQuerySchema.safeParse({ before: 'cursor_abc123' })
|
|
181
|
+
expect(result.success).toBe(true)
|
|
182
|
+
if (result.success) expect(result.data.before).toBe('cursor_abc123')
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
it('accepts optional after cursor string', () => {
|
|
186
|
+
const result = ListOrganizationsQuerySchema.safeParse({ after: 'cursor_xyz789' })
|
|
187
|
+
expect(result.success).toBe(true)
|
|
188
|
+
if (result.success) expect(result.data.after).toBe('cursor_xyz789')
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
it('accepts both before and after cursors together', () => {
|
|
192
|
+
expect(ListOrganizationsQuerySchema.safeParse({ before: 'a', after: 'b' }).success).toBe(true)
|
|
193
|
+
})
|
|
194
|
+
})
|