Skip to content

feat: serverless worker create form wired to CreateWorkerDeployment API#3236

Draft
rossnelson wants to merge 11 commits intoworker-insightsfrom
serverless-workers-crud
Draft

feat: serverless worker create form wired to CreateWorkerDeployment API#3236
rossnelson wants to merge 11 commits intoworker-insightsfrom
serverless-workers-crud

Conversation

@rossnelson
Copy link
Copy Markdown
Collaborator

Summary

  • Add serverless worker CRUD pages under /workers/deployments/serverless/
  • Wire create form to CreateWorkerDeployment API: name → deploymentName, lambdaArn/iamRoleArn → computeConfig.provider.detailJson, min/maxInstances → computeConfig.scaler
  • Remove region field from form — parsed automatically from Lambda ARN (arn:aws:lambda:<region>:...)
  • Move ARN existence validation to submit (onUpdate handler) instead of a separate "Validate Connection" button — errors surface inline under the respective fields
  • Add ComputeProvider, ComputeScaler, CreateWorkerDeploymentRequest types
  • Add CapabilityGuard component and deployments empty state

Test plan

  • Create form renders with Name, Lambda ARN, IAM Role ARN fields
  • Zod format validation fires on submit for malformed ARNs
  • Lambda/IAM existence validation runs on submit, errors appear inline under the relevant field
  • Successful submit calls CreateWorkerDeployment with correct payload (region extracted from ARN)
  • Cancel navigates back to workers list
  • Scaling fields toggle correctly via "Show Scaling and Limits"

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
holocene Ready Ready Preview, Comment Apr 3, 2026 8:19pm

Request Review

localFilters = [
createFilter({
attribute,
type: 'Keyword',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Type 'string | null' is not assignable to type 'string | undefined'.

createFilter({
attribute,
parenthesis: localFilters.length ? ')' : '',
type: 'Keyword',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Type 'string | null' is not assignable to type 'string | undefined'.

};

const superform = superForm(initialData, {
SPA: true,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Type 'ClientValidationAdapter<{ name: string; lambdaArn: string; iamRoleArn: string; minInstances?: number | undefined; maxInstances?: number | undefined; }, { name: string; lambdaArn: string; iamRoleArn: string; minInstances?: number | undefined; maxInstances?: number | undefined; }>' is not assignable to type 'ClientValidationAdapter<Partial<{ name: string; lambdaArn: string; iamRoleArn: string; region: string; minInstances: undefined; maxInstances: undefined; }>, Record<string, unknown>> | ValidatorsOption<...> | undefined'.

? String($form.minInstances)
: ''}
oninput={(e) => {
const val = (e.currentTarget as HTMLInputElement).value;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Type 'number | undefined' is not assignable to type 'undefined'.

? String($form.maxInstances)
: ''}
oninput={(e) => {
const val = (e.currentTarget as HTMLInputElement).value;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Type 'number | undefined' is not assignable to type 'undefined'.


if (!filter || filter.value !== value) {
const newFilter: SearchAttributeFilter = createFilter({
attribute,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Type 'string | null | undefined' is not assignable to type 'string | undefined'.

/>
</div>
</div>
<CodecServerErrorBanner />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Type 'WorkflowExecution | null' is not assignable to type 'WorkflowExecution'.

{translate('workers.back-to-workers')}
</Link>
<span class="text-secondary">|</span>
<Link
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Type 'string | undefined' is not assignable to type 'string'.

</td>
<td>
<Link
class="inline-flex items-center gap-1"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Type 'string | undefined' is not assignable to type 'string'.

@temporal-cicd
Copy link
Copy Markdown
Contributor

temporal-cicd bot commented Mar 19, 2026

Warnings
⚠️

📊 Strict Mode: 42 errors in 11 files (3.9% of 1077 total)

src/lib/utilities/route-for-api.ts (8)
  • L68:48: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
  • L74:50: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
  • L76:4: Type 'string | null' is not assignable to type 'string'.
  • L103:8: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ namespace: string; workflowId: string; scheduleId: string; queue: string; queryType: string; signalName: string; updateName: string; batchJobId: string; runId: string; activityId: string; endpointId: string; deploymentName: string; version: string; workerInstanceKey: string; }'.
  • L103:38: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Partial'.
  • L105:8: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ namespace: string; workflowId: string; scheduleId: string; queue: string; queryType: string; signalName: string; updateName: string; batchJobId: string; runId: string; activityId: string; endpointId: string; deploymentName: string; version: string; workerInstanceKey: string; }'.
  • L105:57: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Partial'.
  • L191:16: This overload signature is not compatible with its implementation signature.
src/lib/stores/filters.ts (2)
  • L114:2: Argument of type 'StartStopNotifier<EventTypeCategory[] | null>' is not assignable to parameter of type 'StartStopNotifier<EventTypeCategory[] | undefined>'.
  • L130:13: Argument of type 'StartStopNotifier<("Scheduled" | "Unspecified" | "Open" | "New" | "Started" | "Initiated" | "Running" | "Completed" | "Fired" | "Signaled" | "Canceled" | "Failed" | "Terminated" | "TimedOut" | "CancelRequested")[] | null>' is not assignable to parameter of type 'StartStopNotifier<("Scheduled" | "Unspecified" | "Open" | "New" | "Started" | "Initiated" | "Running" | "Completed" | "Fired" | "Signaled" | "Canceled" | "Failed" | "Terminated" | "TimedOut" | "CancelRequested")[] | undefined>'.
src/lib/utilities/screaming-enums.ts (2)
  • L92:14: Type 'PendingNexusOperationState.PENDING_NEXUS_OPERATION_STATE_UNSPECIFIED | undefined' is not assignable to type 'PendingNexusOperationState'.
  • L99:14: Type 'CallbackState.CALLBACK_STATE_UNSPECIFIED | undefined' is not assignable to type 'CallbackState'.
src/lib/components/worker-table.svelte (6)
  • L69:12: Type 'number | null | undefined' is not assignable to type 'string | number'.
  • L69:24: 'workers.versioningInfo' is possibly 'null' or 'undefined'.
  • L75:5: Parameter 'poller' implicitly has an 'any' type.
  • L158:35: 'poller.taskQueueTypes' is possibly 'undefined'.
  • L165:35: 'poller.taskQueueTypes' is possibly 'undefined'.
  • L172:35: 'poller.taskQueueTypes' is possibly 'undefined'.
src/lib/components/workflow/filter-bar/dropdown-filter-chip.svelte (2)
  • L4:33: Could not find a declaration file for module 'date-fns-tz'. '/home/runner/work/ui/ui/node_modules/.pnpm/date-fns-tz@1.3.8_date-fns@2.30.0/node_modules/date-fns-tz/index.js' implicitly has an 'any' type.
  • L316:12: Type 'null' is not assignable to type 'string'.
src/lib/components/shared-search-attribute-filter/status-filter-chip.svelte (2)
  • L79:10: Type 'string | null' is not assignable to type 'string | undefined'.
  • L90:10: Type 'string | null' is not assignable to type 'string | undefined'.
src/lib/components/workers/serverless-worker-form/serverless-worker-create-form.svelte (3)
  • L48:4: Type 'ClientValidationAdapter<{ name: string; lambdaArn: string; iamRoleArn: string; minInstances?: number | undefined; maxInstances?: number | undefined; }, { name: string; lambdaArn: string; iamRoleArn: string; minInstances?: number | undefined; maxInstances?: number | undefined; }>' is not assignable to type 'ClientValidationAdapter<Partial<{ name: string; lambdaArn: string; iamRoleArn: string; region: string; minInstances: undefined; maxInstances: undefined; }>, Record<string, unknown>> | ValidatorsOption<...> | undefined'.
  • L180:20: Type 'number | undefined' is not assignable to type 'undefined'.
  • L193:20: Type 'number | undefined' is not assignable to type 'undefined'.
src/lib/components/workers/workers-table/workers-table-cell.svelte (1)
  • L44:8: Type 'string | null | undefined' is not assignable to type 'string | undefined'.
src/lib/layouts/workflow-header.svelte (6)
  • L135:37: Argument of type 'WorkflowExecution | null' is not assignable to parameter of type 'WorkflowExecution'.
  • L136:45: Argument of type 'WorkflowExecution | null' is not assignable to parameter of type 'WorkflowExecution'.
  • L141:13: Type 'WorkflowExecution | null' is not assignable to type 'WorkflowExecution'.
  • L167:9: Type 'WorkflowExecution | null' is not assignable to type 'WorkflowExecution'.
  • L175:20: Type 'WorkflowExecution | null' is not assignable to type 'WorkflowExecution'.
  • L231:12: Type 'string | undefined' is not assignable to type 'string'.
src/lib/layouts/workflow-run-layout.svelte (8)
  • L102:39: Type 'string | undefined' is not assignable to type 'string'.
  • L118:8: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
  • L153:6: Type 'WorkflowExecution | undefined' is not assignable to type 'WorkflowExecution | null'.
  • L167:4: Type 'undefined' is not assignable to type 'NetworkError | null'.
  • L170:18: No overload matches this call.
  • L179:28: Parameter 'fullHistory' implicitly has an 'any' type.
  • L179:41: Parameter 'pause' implicitly has an 'any' type.
  • L211:35: Argument of type 'null' is not assignable to parameter of type '((key: string, value: { eventHistory: WorkflowEvents; workflow: WorkflowExecution | null; workers: IDescribeTaskQueueResponse; workersLoaded: boolean; metadata: WorkflowMetadata | null; userMetadata: { ...; }; }) => { ...; }) | undefined'.
src/lib/pages/serverless-worker-detail.svelte (2)
  • L77:8: Type 'string | undefined' is not assignable to type 'string'.
  • L503:22: Type 'string | undefined' is not assignable to type 'string'.

Generated by 🚫 dangerJS against 5a3156d

Squashed 46 commits for clean rebase onto main.
…ypes

- Rewrite ComputeConfig types to scalingGroups map shape (real proto)
- Add deleteWorkerDeployment, deleteWorkerDeploymentVersion, createWorkerDeploymentVersion,
  validateWorkerDeploymentVersionComputeConfig, buildLambdaComputeConfig, decodeLambdaProviderDetails
- Fix route-for-api.ts: version route split to {deploymentName}/{buildId}; add versions POST,
  update-compute-config, validate-compute-config routes
- Add routeForWorkerDeploymentVersionCreate/Edit helpers
- Migrate delete-worker-modal to Svelte 5 onConfirm/onCancel callback props
- Wire compute-provider-picker to bindable prop with internal writable store sync
- New Create Version route + form (versions/create)
- New Edit Version route + form (versions/[buildId]/edit) with delete flow
- Deployment detail: replace header CTAs, remove compute cards, add Compute column,
  expandable rows, kebab menu; migrate $app/stores → $app/state
- Create deployment form: add Build ID field, two-call submit (createDeployment + createVersion),
  replace min/max instances with real scaling fields
- Update Zod schemas: createDeploymentSchema, createVersionSchema, editVersionSchema
- Update server go.mod to go.temporal.io/api v1.62.3-0.20260325221344 (adds CreateWorkerDeploymentVersion HTTP gateway)
…on table row

- Add namespace prop and derive workflowHref and editHref from it (removes $page.params dependency)
- Add expandable row showing Lambda ARN and IAM role ARN decoded from compute config
- Show compute provider type in compute column
- Replace go-to-workflows link with actions menu (Edit Version + Go to Workflows)
… worker form

- Create deployment → create version → validate compute config
- Rollback deployment if version creation fails (uses conflictToken)
- Rollback version then deployment if validation fails
- Route validate error message to lambdaArn/iamRoleArn field or form-level
- Treat Unimplemented (501) from validate endpoint as success
- Fix missing await on onSubmit in form component's onUpdate handler
- Show destructive delete button in deployment header when versionSummaries is empty
- Add DeleteDeploymentModal with type-DELETE confirmation
- Rollback navigates to deployments list on success
- Show inline error on delete failure
…s-lambda

- provider.type: 'lambda' -> 'aws-lambda' (server now validates against allowed types)
- scaler.type: 'lambda' -> 'no-sync' (valid scaling algorithm for invoke-based providers)
- provider details keys: {lambdaArn, iamRoleArn} -> {arn, role} (keys the aws-lambda provider reads)
- move form-level error above submit buttons so it's visible after submit
- Deployment list page with status badges and compute type indicators
- Deployment detail page with version table (build ID, status, compute, deployed date, actions)
- Version row expand: lazy-loads version details on demand using {#await} pattern, shows lambda ARN, IAM role, and scaler params for compute versions
- Actions menu: edit version, go to workflows, set as current, delete version
- Create/edit version forms with lambda compute config and scaler options
- Delete deployment/version with conflict token support
- i18n keys for all new strings
- Bump server go.mod for worker heartbeat support
- Drop {#each columns} loop from version-table-row, render cells directly
- Extract VersionComputeDetails sub-component for expanded row
- Add Config Status column (renders — until API returns data)
- Update context menu: Edit, Validate Connection, View Workflows, Delete
- Wire up Validate Connection to validateWorkerDeploymentVersionComputeConfig
- Add validate result modal with loading skeleton
- Fix compute badge rendering — in deployment list row
- Remove "Since [date]" from build status column (not in Figma design)
- Add i18n keys: edit, validate-connection, validate-connection-error/valid/invalid
- Extract VersionActionsMenu, ValidateConnectionModal, DeleteVersionModal,
  and DeploymentHeader from version-table-row and deployment page
- Add CapabilityGuard to Edit and Delete menu items in version actions
- Add CapabilityGuard to Create New Version and Delete Deployment buttons
- Enable editServerlessDeployment and deleteServerlessDeployment in DEV
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant