@elevasis/core 0.23.0 → 0.24.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 +1326 -552
- package/dist/index.js +869 -154
- package/dist/knowledge/index.d.ts +487 -209
- package/dist/knowledge/index.js +104 -1
- package/dist/organization-model/index.d.ts +1326 -552
- package/dist/organization-model/index.js +869 -154
- package/dist/test-utils/index.d.ts +357 -72
- package/dist/test-utils/index.js +795 -142
- package/package.json +5 -5
- package/src/README.md +14 -14
- package/src/__tests__/publish.test.ts +24 -24
- package/src/__tests__/template-core-compatibility.test.ts +9 -12
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +2102 -2096
- package/src/_gen/__tests__/scaffold-contracts.test.ts +30 -30
- package/src/auth/multi-tenancy/credentials/__tests__/encryption.test.ts +217 -217
- package/src/auth/multi-tenancy/credentials/server/encryption.ts +69 -69
- package/src/auth/multi-tenancy/credentials/server/kek-loader.ts +37 -37
- package/src/auth/multi-tenancy/index.ts +26 -26
- package/src/auth/multi-tenancy/invitations/api-schemas.ts +104 -104
- package/src/auth/multi-tenancy/memberships/api-schemas.ts +143 -143
- package/src/auth/multi-tenancy/memberships/index.ts +26 -26
- package/src/auth/multi-tenancy/memberships/membership.ts +130 -130
- package/src/auth/multi-tenancy/organizations/__tests__/api-schemas.test.ts +194 -194
- package/src/auth/multi-tenancy/organizations/api-schemas.ts +136 -136
- package/src/auth/multi-tenancy/permissions.test.ts +42 -42
- package/src/auth/multi-tenancy/permissions.ts +123 -123
- package/src/auth/multi-tenancy/role-management/api-schemas.ts +78 -78
- package/src/auth/multi-tenancy/role-management/index.ts +16 -16
- package/src/auth/multi-tenancy/theme-presets.ts +45 -45
- package/src/auth/multi-tenancy/types.ts +57 -57
- package/src/auth/multi-tenancy/users/api-schemas.ts +165 -165
- package/src/business/README.md +2 -2
- package/src/business/acquisition/activity-events.test.ts +250 -250
- package/src/business/acquisition/activity-events.ts +93 -93
- package/src/business/acquisition/api-schemas.test.ts +1883 -1843
- package/src/business/acquisition/api-schemas.ts +1492 -1497
- package/src/business/acquisition/build-templates.test.ts +240 -240
- package/src/business/acquisition/build-templates.ts +98 -98
- package/src/business/acquisition/crm-next-action.test.ts +262 -262
- package/src/business/acquisition/crm-next-action.ts +220 -220
- package/src/business/acquisition/crm-priority.test.ts +216 -216
- package/src/business/acquisition/crm-priority.ts +349 -349
- package/src/business/acquisition/crm-state-actions.test.ts +153 -153
- package/src/business/acquisition/deal-ownership.test.ts +351 -351
- package/src/business/acquisition/deal-ownership.ts +120 -120
- package/src/business/acquisition/derive-actions.test.ts +129 -104
- package/src/business/acquisition/derive-actions.ts +74 -84
- package/src/business/acquisition/index.ts +171 -170
- package/src/business/acquisition/ontology-validation.ts +309 -0
- package/src/business/acquisition/stateful.ts +30 -30
- package/src/business/acquisition/types.ts +396 -396
- package/src/business/clients/api-schemas.test.ts +115 -115
- package/src/business/clients/api-schemas.ts +158 -158
- package/src/business/clients/index.ts +1 -1
- package/src/business/crm/api-schemas.ts +40 -40
- package/src/business/crm/index.ts +1 -1
- package/src/business/deals/api-schemas.ts +87 -87
- package/src/business/deals/index.ts +1 -1
- package/src/business/index.ts +5 -5
- package/src/business/projects/types.ts +144 -144
- package/src/commands/queue/types/task.ts +15 -15
- package/src/execution/core/runner-types.ts +61 -61
- package/src/execution/core/sse-executions.ts +7 -7
- package/src/execution/engine/__tests__/fixtures/test-agents.ts +10 -10
- package/src/execution/engine/agent/core/__tests__/agent.test.ts +16 -16
- package/src/execution/engine/agent/core/__tests__/error-passthrough.test.ts +4 -4
- package/src/execution/engine/agent/core/types.ts +25 -25
- package/src/execution/engine/agent/index.ts +6 -6
- package/src/execution/engine/agent/reasoning/__tests__/request-builder.test.ts +24 -24
- package/src/execution/engine/index.ts +443 -443
- package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +298 -298
- package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.test.ts +55 -55
- package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +107 -107
- package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.test.ts +48 -48
- package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.ts +99 -99
- package/src/execution/engine/tools/integration/server/adapters/apollo/index.ts +1 -1
- package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +363 -363
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.test.ts +162 -162
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.test.ts +316 -316
- package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.test.ts +18 -18
- package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.ts +194 -194
- package/src/execution/engine/tools/integration/server/adapters/clickup/index.ts +7 -7
- package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +204 -204
- package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +105 -105
- package/src/execution/engine/tools/integration/server/adapters/google-calendar/google-calendar-adapter.ts +428 -428
- package/src/execution/engine/tools/integration/server/adapters/google-calendar/index.ts +2 -2
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -261
- package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1474 -1474
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +103 -103
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.test.ts +88 -88
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +141 -141
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +76 -76
- package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-tools.ts +182 -182
- package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +310 -310
- package/src/execution/engine/tools/integration/service.test.ts +239 -239
- package/src/execution/engine/tools/integration/service.ts +172 -172
- package/src/execution/engine/tools/integration/tool.ts +255 -255
- package/src/execution/engine/tools/lead-service-types.ts +1005 -1005
- package/src/execution/engine/tools/messages.ts +43 -43
- package/src/execution/engine/tools/platform/acquisition/company-tools.ts +7 -7
- package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +6 -6
- package/src/execution/engine/tools/platform/acquisition/list-tools.ts +6 -6
- package/src/execution/engine/tools/platform/acquisition/types.ts +280 -280
- package/src/execution/engine/tools/platform/email/types.ts +97 -97
- package/src/execution/engine/tools/registry.ts +704 -704
- package/src/execution/engine/tools/tool-maps.ts +831 -831
- package/src/execution/engine/tools/types.ts +234 -234
- package/src/execution/engine/workflow/types.ts +202 -202
- package/src/execution/external/__tests__/api-schemas.test.ts +127 -127
- package/src/execution/external/api-schemas.ts +40 -40
- package/src/execution/external/index.ts +1 -1
- package/src/index.ts +18 -18
- package/src/integrations/credentials/__tests__/api-schemas.test.ts +420 -420
- package/src/integrations/credentials/api-schemas.ts +146 -146
- package/src/integrations/credentials/schemas.ts +200 -200
- package/src/integrations/oauth/__tests__/provider-registry.test.ts +7 -7
- package/src/integrations/oauth/provider-registry.ts +74 -74
- package/src/integrations/oauth/server/credentials.ts +43 -43
- package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +327 -327
- package/src/integrations/webhook-endpoints/api-schemas.ts +103 -103
- package/src/integrations/webhook-endpoints/types.ts +58 -58
- package/src/knowledge/README.md +32 -32
- package/src/knowledge/__tests__/queries.test.ts +626 -535
- package/src/knowledge/format.ts +99 -99
- package/src/knowledge/index.ts +5 -5
- package/src/knowledge/published.ts +5 -5
- package/src/knowledge/queries.ts +269 -218
- package/src/operations/activities/api-schemas.ts +80 -80
- package/src/operations/activities/types.ts +64 -64
- package/src/organization-model/README.md +149 -149
- package/src/organization-model/__tests__/content-kinds-registry.test.ts +210 -210
- package/src/organization-model/__tests__/defaults.test.ts +168 -168
- package/src/organization-model/__tests__/domains/actions.test.ts +78 -56
- package/src/organization-model/__tests__/domains/customers.test.ts +299 -299
- package/src/organization-model/__tests__/domains/entities.test.ts +56 -56
- package/src/organization-model/__tests__/domains/goals.test.ts +493 -493
- package/src/organization-model/__tests__/domains/identity.test.ts +280 -280
- package/src/organization-model/__tests__/domains/navigation.test.ts +268 -268
- package/src/organization-model/__tests__/domains/offerings.test.ts +414 -414
- package/src/organization-model/__tests__/domains/policies.test.ts +323 -323
- package/src/organization-model/__tests__/domains/resource-mappings.test.ts +293 -293
- package/src/organization-model/__tests__/domains/resources.test.ts +382 -283
- package/src/organization-model/__tests__/domains/roles.test.ts +463 -463
- package/src/organization-model/__tests__/domains/statuses.test.ts +246 -246
- package/src/organization-model/__tests__/domains/systems.test.ts +209 -209
- package/src/organization-model/__tests__/flatten-additive-merge.test.ts +362 -361
- package/src/organization-model/__tests__/foundation.test.ts +77 -77
- package/src/organization-model/__tests__/get-resources-for-system.test.ts +144 -144
- package/src/organization-model/__tests__/graph.test.ts +1246 -887
- package/src/organization-model/__tests__/icons.test.ts +10 -1
- package/src/organization-model/__tests__/knowledge.test.ts +251 -15
- package/src/organization-model/__tests__/lookup-helpers.test.ts +438 -438
- package/src/organization-model/__tests__/migration-helpers.test.ts +591 -591
- package/src/organization-model/__tests__/prospecting-ssot.test.ts +103 -103
- package/src/organization-model/__tests__/recursive-system-schema.test.ts +535 -506
- package/src/organization-model/__tests__/resolve.test.ts +274 -164
- package/src/organization-model/__tests__/schema.test.ts +834 -301
- package/src/organization-model/__tests__/surface-projection.test.ts +284 -284
- package/src/organization-model/catalogs/lead-gen.ts +144 -144
- package/src/organization-model/content-kinds/config.ts +36 -36
- package/src/organization-model/content-kinds/index.ts +76 -72
- package/src/organization-model/content-kinds/pipeline.ts +68 -68
- package/src/organization-model/content-kinds/registry.ts +44 -44
- package/src/organization-model/content-kinds/status.ts +71 -71
- package/src/organization-model/content-kinds/template.ts +83 -83
- package/src/organization-model/content-kinds/types.ts +117 -117
- package/src/organization-model/contracts.ts +27 -27
- package/src/organization-model/defaults.ts +40 -50
- package/src/organization-model/domains/actions.ts +333 -239
- package/src/organization-model/domains/customers.ts +78 -78
- package/src/organization-model/domains/entities.ts +144 -144
- package/src/organization-model/domains/goals.ts +83 -83
- package/src/organization-model/domains/knowledge.ts +117 -101
- package/src/organization-model/domains/navigation.ts +139 -139
- package/src/organization-model/domains/offerings.ts +71 -71
- package/src/organization-model/domains/policies.ts +102 -102
- package/src/organization-model/domains/projects.ts +14 -14
- package/src/organization-model/domains/prospecting.ts +395 -395
- package/src/organization-model/domains/resources.ts +167 -132
- package/src/organization-model/domains/roles.ts +96 -96
- package/src/organization-model/domains/sales.test.ts +218 -218
- package/src/organization-model/domains/sales.ts +380 -380
- package/src/organization-model/domains/shared.ts +63 -63
- package/src/organization-model/domains/statuses.ts +339 -339
- package/src/organization-model/domains/systems.ts +217 -172
- package/src/organization-model/foundation.ts +75 -75
- package/src/organization-model/graph/build.ts +1016 -888
- package/src/organization-model/graph/index.ts +4 -4
- package/src/organization-model/graph/link.ts +10 -10
- package/src/organization-model/graph/schema.ts +76 -70
- package/src/organization-model/graph/types.ts +73 -67
- package/src/organization-model/helpers.ts +289 -241
- package/src/organization-model/icons.ts +78 -66
- package/src/organization-model/index.ts +130 -128
- package/src/organization-model/migration-helpers.ts +247 -244
- package/src/organization-model/ontology.ts +661 -0
- package/src/organization-model/organization-graph.mdx +110 -90
- package/src/organization-model/organization-model.mdx +226 -219
- package/src/organization-model/published.ts +289 -235
- package/src/organization-model/resolve.ts +146 -91
- package/src/organization-model/schema.ts +790 -671
- package/src/organization-model/surface-projection.ts +212 -212
- package/src/organization-model/types.ts +177 -167
- package/src/platform/api/types.ts +38 -38
- package/src/platform/constants/versions.ts +3 -3
- package/src/platform/index.ts +23 -23
- package/src/platform/registry/__tests__/command-view.test.ts +10 -10
- package/src/platform/registry/__tests__/resource-link.test.ts +35 -35
- package/src/platform/registry/__tests__/resource-registry.integration.test.ts +20 -20
- package/src/platform/registry/__tests__/resource-registry.nested-systems.test.ts +245 -245
- package/src/platform/registry/__tests__/resource-registry.test.ts +2053 -2053
- package/src/platform/registry/__tests__/validation.test.ts +1347 -1347
- package/src/platform/registry/command-view.ts +10 -10
- package/src/platform/registry/index.ts +103 -103
- package/src/platform/registry/resource-link.ts +32 -32
- package/src/platform/registry/resource-registry.ts +890 -890
- package/src/platform/registry/serialization.ts +295 -295
- package/src/platform/registry/serialized-types.ts +166 -166
- package/src/platform/registry/stats-types.ts +68 -68
- package/src/platform/registry/types.ts +425 -425
- package/src/platform/registry/validation.ts +745 -745
- package/src/platform/utils/__tests__/validation.test.ts +1084 -1084
- package/src/platform/utils/validation.ts +425 -425
- package/src/projects/api-schemas.test.ts +39 -39
- package/src/projects/api-schemas.ts +291 -291
- package/src/reference/_generated/contracts.md +2101 -2096
- package/src/reference/glossary.md +76 -76
- package/src/scaffold-registry/__tests__/index.test.ts +206 -206
- package/src/scaffold-registry/__tests__/schema.test.ts +166 -166
- package/src/scaffold-registry/index.ts +392 -392
- package/src/scaffold-registry/schema.ts +243 -243
- package/src/server.ts +289 -289
- package/src/supabase/database.types.ts +3153 -3153
- package/src/test-utils/README.md +37 -37
- package/src/test-utils/entities.ts +108 -108
- package/src/test-utils/fixtures/memberships.ts +82 -82
- package/src/test-utils/index.ts +12 -12
- package/src/test-utils/organization-model.ts +65 -65
- package/src/test-utils/published.ts +6 -6
- package/src/test-utils/rls/RLSTestContext.ts +588 -588
- package/src/test-utils/test-utils.test.ts +44 -44
|
@@ -1,202 +1,202 @@
|
|
|
1
|
-
// Import z for schema types
|
|
2
|
-
import type { z } from 'zod'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Workflow-specific type definitions
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { ExecutionContext } from '../base/types'
|
|
9
|
-
import type { ResourceDefinition } from '../../../platform/registry/types'
|
|
10
|
-
import type { WorkflowResourceEntry } from '../../../organization-model/domains/resources'
|
|
11
|
-
import type { ResourceMetricsConfig } from '../../../operations/observability/types'
|
|
12
|
-
import type { ExecutionInterface } from '../interface/types'
|
|
13
|
-
|
|
14
|
-
// Workflow configuration
|
|
15
|
-
export interface WorkflowConfig extends ResourceDefinition {
|
|
16
|
-
type: 'workflow'
|
|
17
|
-
/** OM descriptor backing canonical identity and governance metadata. */
|
|
18
|
-
resource?: WorkflowResourceEntry
|
|
19
|
-
/** Lead-gen action key for registry derivation (e.g. 'lead-gen.company.apollo-import') */
|
|
20
|
-
actionKey?: string
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type DescriptorBackedWorkflowConfig = Omit<WorkflowConfig, 'resourceId' | 'type' | 'resource'> & {
|
|
24
|
-
resource: WorkflowResourceEntry
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Workflow step definition
|
|
28
|
-
export interface WorkflowStepDefinition {
|
|
29
|
-
id: string
|
|
30
|
-
name: string
|
|
31
|
-
description: string
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Step handler function type
|
|
35
|
-
export type StepHandler = (input: unknown, context: ExecutionContext) => Promise<unknown>
|
|
36
|
-
|
|
37
|
-
// Step type for flow control
|
|
38
|
-
export const StepType = {
|
|
39
|
-
LINEAR: 'linear',
|
|
40
|
-
CONDITIONAL: 'conditional'
|
|
41
|
-
} as const
|
|
42
|
-
export type StepType = (typeof StepType)[keyof typeof StepType]
|
|
43
|
-
|
|
44
|
-
// Next step configuration types
|
|
45
|
-
export interface LinearNext {
|
|
46
|
-
type: 'linear'
|
|
47
|
-
target: string
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface ConditionalNext {
|
|
51
|
-
type: 'conditional'
|
|
52
|
-
routes: Array<{
|
|
53
|
-
condition: (data: unknown) => boolean
|
|
54
|
-
target: string
|
|
55
|
-
}>
|
|
56
|
-
default: string // Required to avoid ambiguity
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export type NextConfig =
|
|
60
|
-
| LinearNext // Go to specific step
|
|
61
|
-
| ConditionalNext // Conditional routing
|
|
62
|
-
| null // Explicitly end workflow
|
|
63
|
-
|
|
64
|
-
// Workflow step with graph-based flow
|
|
65
|
-
export interface WorkflowStep extends WorkflowStepDefinition {
|
|
66
|
-
handler: StepHandler
|
|
67
|
-
|
|
68
|
-
// I/O validation (BOTH REQUIRED for complete type safety)
|
|
69
|
-
inputSchema: z.ZodSchema // Validates input from previous step or workflow
|
|
70
|
-
outputSchema: z.ZodSchema // Validates output before next step
|
|
71
|
-
|
|
72
|
-
next: NextConfig // Required - explicit flow decision for every step
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Workflow definition - pure configuration without instance state
|
|
76
|
-
// Used by registry to define workflows that can be instantiated
|
|
77
|
-
export interface WorkflowDefinition {
|
|
78
|
-
config: WorkflowConfig
|
|
79
|
-
contract: import('../base/types').Contract
|
|
80
|
-
steps: Record<string, WorkflowStep>
|
|
81
|
-
entryPoint: string
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Metrics configuration for ROI calculations
|
|
85
|
-
* Optional: Only needed if tracking automation savings
|
|
86
|
-
*/
|
|
87
|
-
metricsConfig?: ResourceMetricsConfig
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Execution interface configuration (optional)
|
|
91
|
-
* If provided, workflow appears in Execution Runner UI
|
|
92
|
-
*/
|
|
93
|
-
interface?: ExecutionInterface
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Lead-gen processing stage this workflow implements (optional).
|
|
97
|
-
* Must match a key in the platform lead-gen stage catalog.
|
|
98
|
-
* Used by org-os graph derivation to surface workflow→stage edges and
|
|
99
|
-
* by pipeline_config validation to confirm each catalog stage has an
|
|
100
|
-
* implementing workflow before a list is activated.
|
|
101
|
-
*
|
|
102
|
-
* Example: stageImplemented: 'verified' on the email-verification workflow.
|
|
103
|
-
*/
|
|
104
|
-
stageImplemented?: string
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Workflow timeline and observability types
|
|
109
|
-
* Used for UI timeline visualization and backend processing
|
|
110
|
-
*/
|
|
111
|
-
|
|
112
|
-
import type { WorkflowLogMessage } from './logging'
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Workflow step state
|
|
116
|
-
* Aggregates step context events with timing and logs
|
|
117
|
-
*/
|
|
118
|
-
export interface StepState {
|
|
119
|
-
stepId: string
|
|
120
|
-
stepName: string
|
|
121
|
-
status: 'pending' | 'running' | 'completed' | 'failed'
|
|
122
|
-
|
|
123
|
-
// Timeline visualization timing
|
|
124
|
-
startTime?: number // From step-started context
|
|
125
|
-
endTime?: number // From step-completed/failed context
|
|
126
|
-
duration?: number // From step-completed/failed context
|
|
127
|
-
|
|
128
|
-
// Step data
|
|
129
|
-
input?: unknown
|
|
130
|
-
output?: unknown
|
|
131
|
-
error?: unknown
|
|
132
|
-
logs: WorkflowLogMessage[]
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Complete workflow execution data for node visualization
|
|
137
|
-
* Parsed from execution logs
|
|
138
|
-
*/
|
|
139
|
-
export interface WorkflowNodeVisualizerData {
|
|
140
|
-
steps: StepState[]
|
|
141
|
-
totalDuration: number
|
|
142
|
-
isRunning: boolean
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Step data extracted from execution logs
|
|
147
|
-
* Used to provide detailed step information in unified graph nodes
|
|
148
|
-
*/
|
|
149
|
-
export interface StepExecutionData {
|
|
150
|
-
/** Final execution status for this step */
|
|
151
|
-
status: 'pending' | 'running' | 'completed' | 'failed'
|
|
152
|
-
|
|
153
|
-
/** Step execution duration in milliseconds */
|
|
154
|
-
duration?: number
|
|
155
|
-
|
|
156
|
-
/** Step input data */
|
|
157
|
-
input?: unknown
|
|
158
|
-
|
|
159
|
-
/** Step output data */
|
|
160
|
-
output?: unknown
|
|
161
|
-
|
|
162
|
-
/** Error data if step failed */
|
|
163
|
-
error?: unknown
|
|
164
|
-
|
|
165
|
-
/** Log messages from this step (reserved for future use) */
|
|
166
|
-
logs?: unknown[]
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Execution path tracking state
|
|
171
|
-
*
|
|
172
|
-
* Tracks which steps have been executed and which edges were taken during workflow
|
|
173
|
-
* execution. This state is built from SSE execution log events and used to compute
|
|
174
|
-
* the visual dimming/highlighting of nodes and edges.
|
|
175
|
-
*
|
|
176
|
-
* Algorithm:
|
|
177
|
-
* - `executedSteps` provides O(1) lookup for "has this step been reached?"
|
|
178
|
-
* - `executedStepsOrdered` preserves execution order for edge inference
|
|
179
|
-
* - `takenEdges` comes from `conditional-route` SSE events + linear step inference
|
|
180
|
-
* - `currentStepId` tracks the actively running step for animation
|
|
181
|
-
* - `stepStatusMap` provides final status for each executed step
|
|
182
|
-
* - `stepDataMap` provides detailed execution data (duration, input, output, error)
|
|
183
|
-
*/
|
|
184
|
-
export interface ExecutionPathState {
|
|
185
|
-
/** Set of step IDs that have been executed (O(1) lookup) */
|
|
186
|
-
executedSteps: Set<string>
|
|
187
|
-
|
|
188
|
-
/** Step IDs in execution order (for inferring linear edges) */
|
|
189
|
-
executedStepsOrdered: string[]
|
|
190
|
-
|
|
191
|
-
/** Set of edge IDs that were traversed (format: "edge-{source}-{target}") */
|
|
192
|
-
takenEdges: Set<string>
|
|
193
|
-
|
|
194
|
-
/** Currently running step ID (undefined if no step is running) */
|
|
195
|
-
currentStepId?: string
|
|
196
|
-
|
|
197
|
-
/** Map of step IDs to their final execution status */
|
|
198
|
-
stepStatusMap?: Map<string, 'pending' | 'running' | 'completed' | 'failed'>
|
|
199
|
-
|
|
200
|
-
/** Map of step IDs to their execution data (duration, input, output, error) */
|
|
201
|
-
stepDataMap?: Map<string, StepExecutionData>
|
|
202
|
-
}
|
|
1
|
+
// Import z for schema types
|
|
2
|
+
import type { z } from 'zod'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Workflow-specific type definitions
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ExecutionContext } from '../base/types'
|
|
9
|
+
import type { ResourceDefinition } from '../../../platform/registry/types'
|
|
10
|
+
import type { WorkflowResourceEntry } from '../../../organization-model/domains/resources'
|
|
11
|
+
import type { ResourceMetricsConfig } from '../../../operations/observability/types'
|
|
12
|
+
import type { ExecutionInterface } from '../interface/types'
|
|
13
|
+
|
|
14
|
+
// Workflow configuration
|
|
15
|
+
export interface WorkflowConfig extends ResourceDefinition {
|
|
16
|
+
type: 'workflow'
|
|
17
|
+
/** OM descriptor backing canonical identity and governance metadata. */
|
|
18
|
+
resource?: WorkflowResourceEntry
|
|
19
|
+
/** Lead-gen action key for registry derivation (e.g. 'lead-gen.company.apollo-import') */
|
|
20
|
+
actionKey?: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type DescriptorBackedWorkflowConfig = Omit<WorkflowConfig, 'resourceId' | 'type' | 'resource'> & {
|
|
24
|
+
resource: WorkflowResourceEntry
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Workflow step definition
|
|
28
|
+
export interface WorkflowStepDefinition {
|
|
29
|
+
id: string
|
|
30
|
+
name: string
|
|
31
|
+
description: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Step handler function type
|
|
35
|
+
export type StepHandler = (input: unknown, context: ExecutionContext) => Promise<unknown>
|
|
36
|
+
|
|
37
|
+
// Step type for flow control
|
|
38
|
+
export const StepType = {
|
|
39
|
+
LINEAR: 'linear',
|
|
40
|
+
CONDITIONAL: 'conditional'
|
|
41
|
+
} as const
|
|
42
|
+
export type StepType = (typeof StepType)[keyof typeof StepType]
|
|
43
|
+
|
|
44
|
+
// Next step configuration types
|
|
45
|
+
export interface LinearNext {
|
|
46
|
+
type: 'linear'
|
|
47
|
+
target: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ConditionalNext {
|
|
51
|
+
type: 'conditional'
|
|
52
|
+
routes: Array<{
|
|
53
|
+
condition: (data: unknown) => boolean
|
|
54
|
+
target: string
|
|
55
|
+
}>
|
|
56
|
+
default: string // Required to avoid ambiguity
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type NextConfig =
|
|
60
|
+
| LinearNext // Go to specific step
|
|
61
|
+
| ConditionalNext // Conditional routing
|
|
62
|
+
| null // Explicitly end workflow
|
|
63
|
+
|
|
64
|
+
// Workflow step with graph-based flow
|
|
65
|
+
export interface WorkflowStep extends WorkflowStepDefinition {
|
|
66
|
+
handler: StepHandler
|
|
67
|
+
|
|
68
|
+
// I/O validation (BOTH REQUIRED for complete type safety)
|
|
69
|
+
inputSchema: z.ZodSchema // Validates input from previous step or workflow
|
|
70
|
+
outputSchema: z.ZodSchema // Validates output before next step
|
|
71
|
+
|
|
72
|
+
next: NextConfig // Required - explicit flow decision for every step
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Workflow definition - pure configuration without instance state
|
|
76
|
+
// Used by registry to define workflows that can be instantiated
|
|
77
|
+
export interface WorkflowDefinition {
|
|
78
|
+
config: WorkflowConfig
|
|
79
|
+
contract: import('../base/types').Contract
|
|
80
|
+
steps: Record<string, WorkflowStep>
|
|
81
|
+
entryPoint: string
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Metrics configuration for ROI calculations
|
|
85
|
+
* Optional: Only needed if tracking automation savings
|
|
86
|
+
*/
|
|
87
|
+
metricsConfig?: ResourceMetricsConfig
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Execution interface configuration (optional)
|
|
91
|
+
* If provided, workflow appears in Execution Runner UI
|
|
92
|
+
*/
|
|
93
|
+
interface?: ExecutionInterface
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Lead-gen processing stage this workflow implements (optional).
|
|
97
|
+
* Must match a key in the platform lead-gen stage catalog.
|
|
98
|
+
* Used by org-os graph derivation to surface workflow→stage edges and
|
|
99
|
+
* by pipeline_config validation to confirm each catalog stage has an
|
|
100
|
+
* implementing workflow before a list is activated.
|
|
101
|
+
*
|
|
102
|
+
* Example: stageImplemented: 'verified' on the email-verification workflow.
|
|
103
|
+
*/
|
|
104
|
+
stageImplemented?: string
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Workflow timeline and observability types
|
|
109
|
+
* Used for UI timeline visualization and backend processing
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
import type { WorkflowLogMessage } from './logging'
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Workflow step state
|
|
116
|
+
* Aggregates step context events with timing and logs
|
|
117
|
+
*/
|
|
118
|
+
export interface StepState {
|
|
119
|
+
stepId: string
|
|
120
|
+
stepName: string
|
|
121
|
+
status: 'pending' | 'running' | 'completed' | 'failed'
|
|
122
|
+
|
|
123
|
+
// Timeline visualization timing
|
|
124
|
+
startTime?: number // From step-started context
|
|
125
|
+
endTime?: number // From step-completed/failed context
|
|
126
|
+
duration?: number // From step-completed/failed context
|
|
127
|
+
|
|
128
|
+
// Step data
|
|
129
|
+
input?: unknown
|
|
130
|
+
output?: unknown
|
|
131
|
+
error?: unknown
|
|
132
|
+
logs: WorkflowLogMessage[]
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Complete workflow execution data for node visualization
|
|
137
|
+
* Parsed from execution logs
|
|
138
|
+
*/
|
|
139
|
+
export interface WorkflowNodeVisualizerData {
|
|
140
|
+
steps: StepState[]
|
|
141
|
+
totalDuration: number
|
|
142
|
+
isRunning: boolean
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Step data extracted from execution logs
|
|
147
|
+
* Used to provide detailed step information in unified graph nodes
|
|
148
|
+
*/
|
|
149
|
+
export interface StepExecutionData {
|
|
150
|
+
/** Final execution status for this step */
|
|
151
|
+
status: 'pending' | 'running' | 'completed' | 'failed'
|
|
152
|
+
|
|
153
|
+
/** Step execution duration in milliseconds */
|
|
154
|
+
duration?: number
|
|
155
|
+
|
|
156
|
+
/** Step input data */
|
|
157
|
+
input?: unknown
|
|
158
|
+
|
|
159
|
+
/** Step output data */
|
|
160
|
+
output?: unknown
|
|
161
|
+
|
|
162
|
+
/** Error data if step failed */
|
|
163
|
+
error?: unknown
|
|
164
|
+
|
|
165
|
+
/** Log messages from this step (reserved for future use) */
|
|
166
|
+
logs?: unknown[]
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Execution path tracking state
|
|
171
|
+
*
|
|
172
|
+
* Tracks which steps have been executed and which edges were taken during workflow
|
|
173
|
+
* execution. This state is built from SSE execution log events and used to compute
|
|
174
|
+
* the visual dimming/highlighting of nodes and edges.
|
|
175
|
+
*
|
|
176
|
+
* Algorithm:
|
|
177
|
+
* - `executedSteps` provides O(1) lookup for "has this step been reached?"
|
|
178
|
+
* - `executedStepsOrdered` preserves execution order for edge inference
|
|
179
|
+
* - `takenEdges` comes from `conditional-route` SSE events + linear step inference
|
|
180
|
+
* - `currentStepId` tracks the actively running step for animation
|
|
181
|
+
* - `stepStatusMap` provides final status for each executed step
|
|
182
|
+
* - `stepDataMap` provides detailed execution data (duration, input, output, error)
|
|
183
|
+
*/
|
|
184
|
+
export interface ExecutionPathState {
|
|
185
|
+
/** Set of step IDs that have been executed (O(1) lookup) */
|
|
186
|
+
executedSteps: Set<string>
|
|
187
|
+
|
|
188
|
+
/** Step IDs in execution order (for inferring linear edges) */
|
|
189
|
+
executedStepsOrdered: string[]
|
|
190
|
+
|
|
191
|
+
/** Set of edge IDs that were traversed (format: "edge-{source}-{target}") */
|
|
192
|
+
takenEdges: Set<string>
|
|
193
|
+
|
|
194
|
+
/** Currently running step ID (undefined if no step is running) */
|
|
195
|
+
currentStepId?: string
|
|
196
|
+
|
|
197
|
+
/** Map of step IDs to their final execution status */
|
|
198
|
+
stepStatusMap?: Map<string, 'pending' | 'running' | 'completed' | 'failed'>
|
|
199
|
+
|
|
200
|
+
/** Map of step IDs to their execution data (duration, input, output, error) */
|
|
201
|
+
stepDataMap?: Map<string, StepExecutionData>
|
|
202
|
+
}
|
|
@@ -1,127 +1,127 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { ExecuteAsyncEnvelopeSchema, GetExecutionsQuerySchema } from '../api-schemas'
|
|
3
|
-
|
|
4
|
-
// ---------------------------------------------------------------------------
|
|
5
|
-
// ExecuteAsyncEnvelopeSchema
|
|
6
|
-
// ---------------------------------------------------------------------------
|
|
7
|
-
|
|
8
|
-
describe('ExecuteAsyncEnvelopeSchema', () => {
|
|
9
|
-
it('accepts a minimal payload with only resourceId', () => {
|
|
10
|
-
const result = ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: 'my-workflow' })
|
|
11
|
-
expect(result.success).toBe(true)
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
it('accepts resourceId with optional input passthrough', () => {
|
|
15
|
-
const result = ExecuteAsyncEnvelopeSchema.safeParse({
|
|
16
|
-
resourceId: 'my-workflow',
|
|
17
|
-
input: { foo: 'bar', nested: { count: 5 } }
|
|
18
|
-
})
|
|
19
|
-
expect(result.success).toBe(true)
|
|
20
|
-
if (result.success) {
|
|
21
|
-
expect(result.data.resourceId).toBe('my-workflow')
|
|
22
|
-
expect(result.data.input).toEqual({ foo: 'bar', nested: { count: 5 } })
|
|
23
|
-
}
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
it('accepts any arbitrary input shape (unknown passthrough)', () => {
|
|
27
|
-
const result = ExecuteAsyncEnvelopeSchema.safeParse({
|
|
28
|
-
resourceId: 'some-resource',
|
|
29
|
-
input: [1, 2, 3]
|
|
30
|
-
})
|
|
31
|
-
expect(result.success).toBe(true)
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
it('accepts input as null (unknown type allows null)', () => {
|
|
35
|
-
const result = ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: 'r', input: null })
|
|
36
|
-
expect(result.success).toBe(true)
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
it('accepts payload without input field (input is optional)', () => {
|
|
40
|
-
const result = ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: 'r' })
|
|
41
|
-
expect(result.success).toBe(true)
|
|
42
|
-
if (result.success) {
|
|
43
|
-
expect(result.data.input).toBeUndefined()
|
|
44
|
-
}
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('rejects an empty resourceId (minLength 1)', () => {
|
|
48
|
-
expect(ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: '' }).success).toBe(false)
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
it('rejects a missing resourceId', () => {
|
|
52
|
-
expect(ExecuteAsyncEnvelopeSchema.safeParse({}).success).toBe(false)
|
|
53
|
-
expect(ExecuteAsyncEnvelopeSchema.safeParse({ input: { x: 1 } }).success).toBe(false)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it('rejects resourceId as a non-string type', () => {
|
|
57
|
-
expect(ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: 42 }).success).toBe(false)
|
|
58
|
-
expect(ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: null }).success).toBe(false)
|
|
59
|
-
})
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
// ---------------------------------------------------------------------------
|
|
63
|
-
// GetExecutionsQuerySchema
|
|
64
|
-
// ---------------------------------------------------------------------------
|
|
65
|
-
|
|
66
|
-
describe('GetExecutionsQuerySchema', () => {
|
|
67
|
-
it('accepts an empty query and applies default limit of 50', () => {
|
|
68
|
-
const result = GetExecutionsQuerySchema.safeParse({})
|
|
69
|
-
expect(result.success).toBe(true)
|
|
70
|
-
if (result.success) {
|
|
71
|
-
expect(result.data.limit).toBe(50)
|
|
72
|
-
}
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
it('coerces limit from string "10" to number 10', () => {
|
|
76
|
-
const result = GetExecutionsQuerySchema.safeParse({ limit: '10' })
|
|
77
|
-
expect(result.success).toBe(true)
|
|
78
|
-
if (result.success) expect(result.data.limit).toBe(10)
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
it('coerces limit from string "100" to number 100 (upper boundary)', () => {
|
|
82
|
-
const result = GetExecutionsQuerySchema.safeParse({ limit: '100' })
|
|
83
|
-
expect(result.success).toBe(true)
|
|
84
|
-
if (result.success) expect(result.data.limit).toBe(100)
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
it('coerces limit from string "1" to number 1 (lower boundary)', () => {
|
|
88
|
-
const result = GetExecutionsQuerySchema.safeParse({ limit: '1' })
|
|
89
|
-
expect(result.success).toBe(true)
|
|
90
|
-
if (result.success) expect(result.data.limit).toBe(1)
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
it('rejects limit of 101 (above max 100)', () => {
|
|
94
|
-
expect(GetExecutionsQuerySchema.safeParse({ limit: '101' }).success).toBe(false)
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
it('rejects limit of 0 (below min 1)', () => {
|
|
98
|
-
expect(GetExecutionsQuerySchema.safeParse({ limit: '0' }).success).toBe(false)
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
it('rejects a negative limit', () => {
|
|
102
|
-
expect(GetExecutionsQuerySchema.safeParse({ limit: '-1' }).success).toBe(false)
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
it('rejects a non-numeric string for limit', () => {
|
|
106
|
-
expect(GetExecutionsQuerySchema.safeParse({ limit: 'abc' }).success).toBe(false)
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
it('accepts status as an optional string filter', () => {
|
|
110
|
-
const result = GetExecutionsQuerySchema.safeParse({ status: 'running' })
|
|
111
|
-
expect(result.success).toBe(true)
|
|
112
|
-
if (result.success) expect(result.data.status).toBe('running')
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
it('accepts status as undefined (optional field omitted)', () => {
|
|
116
|
-
const result = GetExecutionsQuerySchema.safeParse({})
|
|
117
|
-
expect(result.success).toBe(true)
|
|
118
|
-
if (result.success) expect(result.data.status).toBeUndefined()
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
it('note: GetExecutionsQuerySchema does not have an offset field', () => {
|
|
122
|
-
// The schema only defines limit and status -- no offset field exists.
|
|
123
|
-
// Passing offset is neither rejected nor coerced (schema is not strict).
|
|
124
|
-
const result = GetExecutionsQuerySchema.safeParse({ limit: '10', offset: '5' })
|
|
125
|
-
expect(result.success).toBe(true)
|
|
126
|
-
})
|
|
127
|
-
})
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { ExecuteAsyncEnvelopeSchema, GetExecutionsQuerySchema } from '../api-schemas'
|
|
3
|
+
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// ExecuteAsyncEnvelopeSchema
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
describe('ExecuteAsyncEnvelopeSchema', () => {
|
|
9
|
+
it('accepts a minimal payload with only resourceId', () => {
|
|
10
|
+
const result = ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: 'my-workflow' })
|
|
11
|
+
expect(result.success).toBe(true)
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
it('accepts resourceId with optional input passthrough', () => {
|
|
15
|
+
const result = ExecuteAsyncEnvelopeSchema.safeParse({
|
|
16
|
+
resourceId: 'my-workflow',
|
|
17
|
+
input: { foo: 'bar', nested: { count: 5 } }
|
|
18
|
+
})
|
|
19
|
+
expect(result.success).toBe(true)
|
|
20
|
+
if (result.success) {
|
|
21
|
+
expect(result.data.resourceId).toBe('my-workflow')
|
|
22
|
+
expect(result.data.input).toEqual({ foo: 'bar', nested: { count: 5 } })
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('accepts any arbitrary input shape (unknown passthrough)', () => {
|
|
27
|
+
const result = ExecuteAsyncEnvelopeSchema.safeParse({
|
|
28
|
+
resourceId: 'some-resource',
|
|
29
|
+
input: [1, 2, 3]
|
|
30
|
+
})
|
|
31
|
+
expect(result.success).toBe(true)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('accepts input as null (unknown type allows null)', () => {
|
|
35
|
+
const result = ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: 'r', input: null })
|
|
36
|
+
expect(result.success).toBe(true)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('accepts payload without input field (input is optional)', () => {
|
|
40
|
+
const result = ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: 'r' })
|
|
41
|
+
expect(result.success).toBe(true)
|
|
42
|
+
if (result.success) {
|
|
43
|
+
expect(result.data.input).toBeUndefined()
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('rejects an empty resourceId (minLength 1)', () => {
|
|
48
|
+
expect(ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: '' }).success).toBe(false)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('rejects a missing resourceId', () => {
|
|
52
|
+
expect(ExecuteAsyncEnvelopeSchema.safeParse({}).success).toBe(false)
|
|
53
|
+
expect(ExecuteAsyncEnvelopeSchema.safeParse({ input: { x: 1 } }).success).toBe(false)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('rejects resourceId as a non-string type', () => {
|
|
57
|
+
expect(ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: 42 }).success).toBe(false)
|
|
58
|
+
expect(ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: null }).success).toBe(false)
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// GetExecutionsQuerySchema
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
describe('GetExecutionsQuerySchema', () => {
|
|
67
|
+
it('accepts an empty query and applies default limit of 50', () => {
|
|
68
|
+
const result = GetExecutionsQuerySchema.safeParse({})
|
|
69
|
+
expect(result.success).toBe(true)
|
|
70
|
+
if (result.success) {
|
|
71
|
+
expect(result.data.limit).toBe(50)
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it('coerces limit from string "10" to number 10', () => {
|
|
76
|
+
const result = GetExecutionsQuerySchema.safeParse({ limit: '10' })
|
|
77
|
+
expect(result.success).toBe(true)
|
|
78
|
+
if (result.success) expect(result.data.limit).toBe(10)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('coerces limit from string "100" to number 100 (upper boundary)', () => {
|
|
82
|
+
const result = GetExecutionsQuerySchema.safeParse({ limit: '100' })
|
|
83
|
+
expect(result.success).toBe(true)
|
|
84
|
+
if (result.success) expect(result.data.limit).toBe(100)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it('coerces limit from string "1" to number 1 (lower boundary)', () => {
|
|
88
|
+
const result = GetExecutionsQuerySchema.safeParse({ limit: '1' })
|
|
89
|
+
expect(result.success).toBe(true)
|
|
90
|
+
if (result.success) expect(result.data.limit).toBe(1)
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
it('rejects limit of 101 (above max 100)', () => {
|
|
94
|
+
expect(GetExecutionsQuerySchema.safeParse({ limit: '101' }).success).toBe(false)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('rejects limit of 0 (below min 1)', () => {
|
|
98
|
+
expect(GetExecutionsQuerySchema.safeParse({ limit: '0' }).success).toBe(false)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('rejects a negative limit', () => {
|
|
102
|
+
expect(GetExecutionsQuerySchema.safeParse({ limit: '-1' }).success).toBe(false)
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it('rejects a non-numeric string for limit', () => {
|
|
106
|
+
expect(GetExecutionsQuerySchema.safeParse({ limit: 'abc' }).success).toBe(false)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('accepts status as an optional string filter', () => {
|
|
110
|
+
const result = GetExecutionsQuerySchema.safeParse({ status: 'running' })
|
|
111
|
+
expect(result.success).toBe(true)
|
|
112
|
+
if (result.success) expect(result.data.status).toBe('running')
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it('accepts status as undefined (optional field omitted)', () => {
|
|
116
|
+
const result = GetExecutionsQuerySchema.safeParse({})
|
|
117
|
+
expect(result.success).toBe(true)
|
|
118
|
+
if (result.success) expect(result.data.status).toBeUndefined()
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('note: GetExecutionsQuerySchema does not have an offset field', () => {
|
|
122
|
+
// The schema only defines limit and status -- no offset field exists.
|
|
123
|
+
// Passing offset is neither rejected nor coerced (schema is not strict).
|
|
124
|
+
const result = GetExecutionsQuerySchema.safeParse({ limit: '10', offset: '5' })
|
|
125
|
+
expect(result.success).toBe(true)
|
|
126
|
+
})
|
|
127
|
+
})
|