> For the complete documentation index, see [llms.txt](https://rdeneau.gitbook.io/safe-clean-architecture/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://rdeneau.gitbook.io/safe-clean-architecture/domain-workflows/3-domain-workflow/5-conclusion.md).

# Conclusion

We have just seen how *Safe Clean Architecture* works with regard to features—in the sense of use cases, illustrated by practical examples taken from the demo application, *Shopfoo*.

* **Program:** The V4 `program`, based on the Tagless Final pattern, reduces the infrastructure to a single function type (`'ins -> Async<'ret>`) and a computation expression. It supports parallel execution via the applicative `let! ... and! ...` syntax and integrates undo/saga capabilities without modifying the core program type.
* **Instructions:** Each domain defines a single instruction interface inheriting `IProgramInstructions`. Adding a new instruction is a one-line interface member plus a one-line helper function—a dramatic reduction from V3's 5-step recipe.
* **Workflows:** Each workflow has its own file, making the file tree a map of supported features. Writing a workflow involves composing instructions using the `program` CE. Validation, error lifting, and parallel execution patterns are built into the CE's `Bind` overloads and applicative support.
* **Saga / Undo:** The saga pattern enables automatic rollback of completed commands when a workflow fails, with three strategies—`Reversible`, `Compensatable`, and `NotUndoable`. Workflow cancellation is supported as a first-class concept, distinct from failure. All of this operates in-process without a message bus.
* **Data:** The *Data* layer represents the application-driven exterior—the right side of the hexagon in *Ports and Adapters Architecture* terminology. This layer abstracts access to databases and external APIs, each isolated in their own module or folder.
* **API:** The `Api` class wires instructions to data-layer functions with undo strategies, then runs workflows through the saga runner. It is internal, abstracted by the API contract, and registered via dependency injection.

Since workflows are defined before the *Data* layer in the F# compilation order, the only way they can interact with it is through instructions. This makes workflows **pure**—effects are encoded in the type system and revealed only at the moment of execution—and independent of other layers, complying with *Clean Architecture*. This functional approach offers a different type of abstraction from the interfaces used in the object-oriented approach.

This architecture makes extensive use of F# capabilities: declaration order, computation expressions, interface-based polymorphism, and a combination of FP and OOP paradigms that few languages allow on the .NET platform.

{% hint style="info" %}
The migration from the V3 `program` to V4 was done without touching any workflow. This illustrates a key benefit of computation expressions: workflows are written against the CE syntax (`let!`, `return`…), not against the underlying implementation. When the `program` CE's internals change—here from V3 to V4—the call sites remain untouched as long as the CE contract is preserved. In other words, the CE acts as an abstraction barrier, decoupling *what* a workflow expresses from *how* it is executed.
{% endhint %}
