import z from"@contractspec/lib.ui-link";import{ChevronRight as A}from"lucide-react";import{jsx as q,jsxs as y}from"react/jsx-runtime";function E(){return y("div",{className:"space-y-8",children:[y("div",{className:"space-y-4",children:[q("h1",{className:"font-bold text-4xl",children:"Workflows"}),y("p",{className:"text-muted-foreground",children:["A ",q("strong",{children:"WorkflowSpec"})," orchestrates multi-step processes. It defines the sequence of operations, handles failures with retries and compensation, and provides observability into long-running tasks."]})]}),y("div",{className:"space-y-4",children:[q("h2",{className:"font-bold text-2xl",children:"Core concepts"}),y("div",{className:"space-y-3",children:[y("div",{children:[q("h3",{className:"font-semibold text-lg",children:"Identifiers"}),y("p",{className:"text-muted-foreground",children:["Each workflow has a unique"," ",q("code",{className:"rounded bg-background/50 px-2 py-1",children:"workflowId"})," ","and a"," ",q("code",{className:"rounded bg-background/50 px-2 py-1",children:"version"}),". This allows you to run multiple versions of the same workflow simultaneously during migrations or A/B tests."]})]}),y("div",{children:[q("h3",{className:"font-semibold text-lg",children:"Steps"}),y("p",{className:"text-muted-foreground",children:["A workflow is composed of ",q("strong",{children:"steps"}),". Each step invokes a"," ",q(z,{href:"/docs/specs/capabilities",className:"text-violet-400 hover:text-violet-300",children:"CapabilitySpec"}),", passes inputs, and receives outputs. Steps can run sequentially or in parallel."]})]}),y("div",{children:[q("h3",{className:"font-semibold text-lg",children:"Transitions"}),y("p",{className:"text-muted-foreground",children:[q("strong",{children:"Transitions"}),' define the flow between steps. They can be conditional (e.g., "if payment succeeds, go to step 3; otherwise, go to step 5") or unconditional.']})]}),y("div",{children:[q("h3",{className:"font-semibold text-lg",children:"Retries"}),q("p",{className:"text-muted-foreground",children:"If a step fails, the workflow can retry it with exponential backoff. You specify the maximum number of retries and the backoff strategy in the spec."})]}),y("div",{children:[q("h3",{className:"font-semibold text-lg",children:"Compensation"}),y("p",{className:"text-muted-foreground",children:["When a workflow fails partway through,"," ",q("strong",{children:"compensation"})," steps undo the effects of completed steps (e.g., refunding a payment, releasing a reservation). This ensures consistency even in failure scenarios."]})]}),y("div",{children:[q("h3",{className:"font-semibold text-lg",children:"SLAs"}),q("p",{className:"text-muted-foreground",children:"You can define Service Level Agreements (SLAs) for each step or the entire workflow. If a step exceeds its SLA, the system can trigger alerts or escalations."})]})]})]}),y("div",{className:"space-y-4",children:[q("h2",{className:"font-bold text-2xl",children:"Example WorkflowSpec (TypeScript)"}),q("p",{className:"text-muted-foreground",children:"Here's a simplified example of a payment workflow in TypeScript:"}),y("p",{className:"text-muted-foreground text-sm",children:["For Vercel Workflow and other VM-evaluated runtimes, author workflow specs from"," ",q("code",{className:"rounded bg-background/50 px-2 py-1",children:"@contractspec/lib.contracts-spec/workflow/spec"})," ","rather than the broad workflow barrel."]}),q("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:q("pre",{children:`import { defineWorkflow } from '@contractspec/lib.contracts-spec/workflow/spec';
import { ValidatePaymentMethod, ChargePayment, SendEmail } from './specs';

export const PaymentFlow = defineWorkflow({
  meta: {
    key: 'payment.flow',
    version: '1.0.0',
    description: 'End-to-end payment processing',
    owners: ['team-payments'],
    tags: ['payments'],
    stability: 'stable',
  },
  steps: [
    {
      id: 'validate-payment',
      operation: ValidatePaymentMethod,
      inputs: (ctx, input) => ({
        userId: ctx.userId,
        paymentMethodId: input.paymentMethodId,
      }),
      retry: {
        maxAttempts: 3,
        backoff: 'exponential',
      },
      onSuccess: 'charge-payment',
      onFailure: 'notify-user',
    },
    {
      id: 'charge-payment',
      operation: ChargePayment,
      inputs: (ctx, input, steps) => ({
        amount: input.amount,
        paymentMethodId: input.paymentMethodId,
      }),
      compensation: 'refund-payment',
      onSuccess: 'send-receipt',
      onFailure: 'notify-admin',
    },
    {
      id: 'send-receipt',
      operation: SendEmail,
      inputs: (ctx, input, steps) => ({
        to: ctx.userEmail,
        template: 'payment-receipt',
        data: steps['charge-payment'].output,
      }),
    },
  ],
  sla: {
    maxDuration: 30000, // milliseconds
    alertOnBreach: true,
  },
});`})})]}),y("div",{className:"space-y-4",children:[q("h2",{className:"font-bold text-2xl",children:"Triggers"}),q("p",{className:"text-muted-foreground",children:"Workflows can be triggered in several ways:"}),y("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[y("li",{children:[q("strong",{children:"Manual invocation"})," – A user or system calls the workflow via an API endpoint."]}),y("li",{children:[q("strong",{children:"Event-driven"})," – The workflow starts automatically when a specific event occurs (e.g., a new order is created)."]}),y("li",{children:[q("strong",{children:"Scheduled"})," – The workflow runs on a cron schedule (e.g., nightly batch processing)."]}),y("li",{children:[q("strong",{children:"Chained"})," – One workflow can invoke another as a step."]})]})]}),y("div",{className:"space-y-4",children:[q("h2",{className:"font-bold text-2xl",children:"Monitoring and versioning"}),q("p",{className:"text-muted-foreground",children:"ContractSpec automatically instruments workflows with telemetry. You can view:"}),y("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[q("li",{children:"Real-time execution status for each step"}),q("li",{children:"Historical run data and success/failure rates"}),q("li",{children:"Latency distributions and SLA compliance"}),q("li",{children:"Compensation events and retry attempts"})]}),q("p",{className:"text-muted-foreground",children:"When you update a workflow, you increment its version. Running workflows continue on their original version, while new invocations use the latest version. This allows safe, zero-downtime deployments."})]}),y("div",{className:"space-y-4",children:[q("h2",{className:"font-bold text-2xl",children:"Best practices"}),y("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[q("li",{children:"Keep steps idempotent – they should be safe to retry without side effects."}),q("li",{children:"Define compensation for any step that modifies external state."}),q("li",{children:"Use meaningful step IDs that describe the operation."}),q("li",{children:"Set realistic SLAs and monitor them in production."}),q("li",{children:"Test failure scenarios locally before deploying."})]})]}),y("div",{className:"flex items-center gap-4 pt-4",children:[q(z,{href:"/docs/specs/capabilities",className:"btn-ghost",children:"Previous: Capabilities"}),y(z,{href:"/docs/safety",className:"btn-primary",children:["Next: Safety Features ",q(A,{size:16})]})]})]})}export{E as SpecsWorkflowsPage};
