In software engineering, "Separation of Concerns" is a design principle that has stood the test of time. It dictates that a complex system should be divided into distinct parts, with each part addressing a separate concern. This prevents the creation of monolithic, tangled messes that are impossible to debug, maintain, or scale.
As we move into an era of sophisticated business automation and agentic workflows, this principle is more relevant than ever. Too often, automation scripts become sprawling monoliths where orchestration logic, business rules, and specific task implementations are all jumbled together. A small change in one part can have unforeseen consequences elsewhere, and identifying failures becomes a painful forensic exercise.
The solution? Applying a strict separation of concerns between what you are doing and how you are stringing those tasks together. On the .do platform, this principle is embodied by a perfect pair: the Action and the Workflow.
At the core of the .do platform is the action.do, the fundamental building block of automation.
An atomic action is the smallest, indivisible unit of work in your system. It's a self-contained, reusable function designed to perform a single, specific task and do it reliably. Think of it not as an entire process, but as a single workflow step.
Key characteristics of an action.do:
Consider this example of an action.do that enriches a user profile using a third-party service:
import { Do } from '@do-platform/sdk';
// Initialize the .do client with your API key
const-do = new Do(process.env.DO_API_KEY);
// Define a new atomic action to enrich user data
const enrichUserAction = await-do.action.create({
name: 'enrich-user-profile',
description: 'Fetches user data from Clearbit and updates the DB.',
inputs: {
email: 'string',
},
handler: async (inputs) => {
const userData = await clearbit.lookup(inputs.email);
const dbResult = await db.users.update({ email: inputs.email, data: userData });
return { success: true, userId: dbResult.id };
}
});
console.log('Action created:', enrichUserAction.id);
This enrich-user-profile action is a perfect atomic unit. It has a clear input (email), a specific job (call Clearbit, update the database), and a well-defined output. It doesn't know or care why it's being called; it just executes its task.
If actions are the specialized tools, the workflow.do agent is the blueprint and the master craftsman. A workflow's sole responsibility is to orchestrate a sequence of actions to accomplish a larger business goal.
The workflow manages:
Crucially, on the .do platform, actions cannot call other actions. This is by design. A workflow calls actions; actions execute tasks. This clear boundary is the key to enforcing separation of concerns and preventing a descent into nested, untraceable complexity. It's the core principle for building robust and scalable systems.
Separating "doing" from "orchestrating" isn't just an academic exercise. It delivers powerful, practical benefits for any business turning its processes into code.
Massive Reusability: The enrich-user-profile action defined above can be used in a new customer onboarding workflow, a support ticket escalation process, a data cleansing routine, and a targeted marketing campaign. You write the code once and reuse its capability everywhere.
Simplified Debugging: Imagine a 10-step onboarding process fails. Without separation, you'd be digging through a single, massive script. With the Action/Workflow model, the workflow log will pinpoint exactly which action failed—for example, send-welcome-email. You can go straight to that atomic unit, examine its specific inputs and logs, and fix the problem in isolation.
Enhanced Scalability: Your system may need to send thousands of emails per minute but only enrich a few hundred profiles. By decoupling these tasks into separate actions, you can scale the resources and infrastructure for each task independently.
True Business-as-Code: This model creates a clear, two-level view of your business processes. A workflow.do file becomes a high-level, almost human-readable definition of a business process, perfect for review by business analysts and product managers. The underlying action.do files contain the specific implementation details, which are the concern of the engineering team.
Think of it like this: you wouldn't build a house by melting down all your tools and materials into a single, giant block of "house stuff." You use distinct, reliable tools (hammers, saws) and distinct, standardized materials (bricks, lumber) according to a clear plan (the blueprint).
In automation, the same logic applies.
By embracing this separation of concerns, you move away from brittle scripts and toward a future of resilient, scalable, and understandable agentic workflows. You build a library of capabilities, not just a collection of automations.