Transfer Evolution
This page is generated from the local transfer fixture and the current effect-analyzer implementation.
Every Mermaid block below comes from static analysis of the TypeScript source in apps/docs/samples/observability-transfer/evolution.
No code is executed. If the analyzer changes, rerun pnpm --dir apps/docs run generate:transfer-observability and this page will update.
Step 1: Validate input
Section titled “Step 1: Validate input”One operation. One possible failure. The type system already knows what can go wrong.
flowchart LR A["validated #lt;- deps.validateTransfer"] -->|ok| Done((Success)) A -->|err| AE["Validation"]
- Effects: 3
- Error paths: ValidationError
Raw effect-analyze output
Section titled “Raw effect-analyze output”createSendMoneyWorkflow (generator): 1. validated = Pipes deps.validateTransfer through: Calls deps.validateTransfer — collection
Error paths: ValidationError Concurrency: sequential (no parallelism)[ { "program": "createSendMoneyWorkflow", "stats": { "totalEffects": 3, "parallelCount": 0, "raceCount": 0, "errorHandlerCount": 0, "retryCount": 0, "timeoutCount": 0, "resourceCount": 0, "loopCount": 0, "conditionalCount": 0, "layerCount": 0, "interruptionCount": 0, "unknownCount": 0, "decisionCount": 0, "switchCount": 0, "tryCatchCount": 0, "terminalCount": 0, "opaqueCount": 0 } }]Step 2: + Fetch exchange rate
Section titled “Step 2: + Fetch exchange rate”A second step, a second way to fail. The error channel grows automatically.
flowchart LR A["validated #lt;- deps.validateTransfer"] -->|ok| B["rate #lt;- deps.fetchRate"] B -->|ok| Done((Success)) A -->|err| AE["Validation"] B -->|err| BE["RateUnavailable"]
- Effects: 5
- Error paths: RateUnavailableError, ValidationError
Raw effect-analyze output
Section titled “Raw effect-analyze output”createSendMoneyWorkflow (generator): 1. validated = Pipes deps.validateTransfer through: Calls deps.validateTransfer — collection 2. rate = Pipes deps.fetchRate through: Calls deps.fetchRate
Error paths: RateUnavailableError, ValidationError Concurrency: sequential (no parallelism)[ { "program": "createSendMoneyWorkflow", "stats": { "totalEffects": 5, "parallelCount": 0, "raceCount": 0, "errorHandlerCount": 0, "retryCount": 0, "timeoutCount": 0, "resourceCount": 0, "loopCount": 0, "conditionalCount": 0, "layerCount": 0, "interruptionCount": 0, "unknownCount": 0, "decisionCount": 0, "switchCount": 0, "tryCatchCount": 0, "terminalCount": 0, "opaqueCount": 0 } }]Step 3: + Check balance & convert
Section titled “Step 3: + Check balance & convert”Balance check introduces a new failure mode. The compiler tracks it, you don’t have to.
flowchart LR A["validated #lt;- deps.validateTransfer"] -->|ok| B["rate #lt;- deps.fetchRate"] B -->|ok| C["balance #lt;- deps.getBalance"] C -->|ok| D["converted #lt;- deps.convertCurrency"] D -->|ok| Done((Success)) A -->|err| AE["Validation"] B -->|err| BE["RateUnavailable"] D -->|err| DE["InsufficientFunds"]
- Effects: 9
- Error paths: InsufficientFundsError, RateUnavailableError, ValidationError
Raw effect-analyze output
Section titled “Raw effect-analyze output”createSendMoneyWorkflow (generator): 1. validated = Pipes deps.validateTransfer through: Calls deps.validateTransfer — collection 2. rate = Pipes deps.fetchRate through: Calls deps.fetchRate 3. balance = Pipes deps.getBalance through: Calls deps.getBalance 4. converted = Pipes deps.convertCurrency through: Calls deps.convertCurrency
Error paths: InsufficientFundsError, RateUnavailableError, ValidationError Concurrency: sequential (no parallelism)[ { "program": "createSendMoneyWorkflow", "stats": { "totalEffects": 9, "parallelCount": 0, "raceCount": 0, "errorHandlerCount": 0, "retryCount": 0, "timeoutCount": 0, "resourceCount": 0, "loopCount": 0, "conditionalCount": 0, "layerCount": 0, "interruptionCount": 0, "unknownCount": 0, "decisionCount": 0, "switchCount": 0, "tryCatchCount": 0, "terminalCount": 0, "opaqueCount": 0 } }]Step 4: + Execute transfer
Section titled “Step 4: + Execute transfer”The money moves. Two new failure modes from the external provider. Still zero runtime needed to see them.
flowchart LR A["validated #lt;- deps.validateTransfer"] -->|ok| B["rate #lt;- deps.fetchRate"] B -->|ok| C["balance #lt;- deps.getBalance"] C -->|ok| D["converted #lt;- deps.convertCurrency"] D -->|ok| E["transfer #lt;- deps.executeTransfer"] E -->|ok| Done((Success)) A -->|err| AE["Validation"] B -->|err| BE["RateUnavailable"] D -->|err| DE["InsufficientFunds"] E -->|err| EE["TransferRejected / ProviderUnavailable"]
- Effects: 11
- Error paths: InsufficientFundsError, ProviderUnavailableError, RateUnavailableError, TransferRejectedError, ValidationError
Raw effect-analyze output
Section titled “Raw effect-analyze output”createSendMoneyWorkflow (generator): 1. validated = Pipes deps.validateTransfer through: Calls deps.validateTransfer — collection 2. rate = Pipes deps.fetchRate through: Calls deps.fetchRate 3. balance = Pipes deps.getBalance through: Calls deps.getBalance 4. converted = Pipes deps.convertCurrency through: Calls deps.convertCurrency 5. transfer = Pipes deps.executeTransfer through: Calls deps.executeTransfer
Error paths: InsufficientFundsError, ProviderUnavailableError, RateUnavailableError, TransferRejectedError, ValidationError Concurrency: sequential (no parallelism)[ { "program": "createSendMoneyWorkflow", "stats": { "totalEffects": 11, "parallelCount": 0, "raceCount": 0, "errorHandlerCount": 0, "retryCount": 0, "timeoutCount": 0, "resourceCount": 0, "loopCount": 0, "conditionalCount": 0, "layerCount": 0, "interruptionCount": 0, "unknownCount": 0, "decisionCount": 0, "switchCount": 0, "tryCatchCount": 0, "terminalCount": 0, "opaqueCount": 0 } }]Step 5: + Send confirmation (complete)
Section titled “Step 5: + Send confirmation (complete)”The complete workflow. Six effects, six error channels, zero ambiguity. Every path is visible before a single line runs.
flowchart LR A["validated #lt;- deps.validateTransfer"] -->|ok| B["rate #lt;- deps.fetchRate"] B -->|ok| C["balance #lt;- deps.getBalance"] C -->|ok| D["converted #lt;- deps.convertCurrency"] D -->|ok| E["transfer #lt;- deps.executeTransfer"] E -->|ok| F["deps.sendConfirmation"] F -->|ok| Done((Success)) A -->|err| AE["Validation"] B -->|err| BE["RateUnavailable"] D -->|err| DE["InsufficientFunds"] E -->|err| EE["TransferRejected / ProviderUnavailable"] F -->|err| FE["ConfirmationFailed"]
- Effects: 13
- Error paths: ConfirmationFailedError, InsufficientFundsError, ProviderUnavailableError, RateUnavailableError, TransferRejectedError, ValidationError
Raw effect-analyze output
Section titled “Raw effect-analyze output”createSendMoneyWorkflow (generator): 1. validated = Pipes deps.validateTransfer through: Calls deps.validateTransfer — collection 2. rate = Pipes deps.fetchRate through: Calls deps.fetchRate 3. balance = Pipes deps.getBalance through: Calls deps.getBalance 4. converted = Pipes deps.convertCurrency through: Calls deps.convertCurrency 5. transfer = Pipes deps.executeTransfer through: Calls deps.executeTransfer 6. Pipes deps.sendConfirmation through: Calls deps.sendConfirmation
Error paths: ConfirmationFailedError, InsufficientFundsError, ProviderUnavailableError, RateUnavailableError, TransferRejectedError, ValidationError Concurrency: sequential (no parallelism)[ { "program": "createSendMoneyWorkflow", "stats": { "totalEffects": 13, "parallelCount": 0, "raceCount": 0, "errorHandlerCount": 0, "retryCount": 0, "timeoutCount": 0, "resourceCount": 0, "loopCount": 0, "conditionalCount": 0, "layerCount": 0, "interruptionCount": 0, "unknownCount": 0, "decisionCount": 0, "switchCount": 0, "tryCatchCount": 0, "terminalCount": 0, "opaqueCount": 0 } }]Related
Section titled “Related”- Transfer Observability for the narrative around implementation, review, testing, and communication.