Legacy systems get a bad rap. They're often seen as monolithic, opaque tangled messes of code. When something goes wrong, the archaeological dig to find out what happened, why it happened, and who did it can take days. The temptation is to declare bankruptcy and start a "big bang" rewrite project. But we all know how those usually end: over budget, behind schedule, and with a whole new set of problems.
There's a better way.
Instead of tearing everything down, you can introduce a new layer of clarity, control, and observability on top of what you already have. By treating business operations as first-class citizens—as Verbs—you can incrementally modernize your application, starting today. This is the core principle of Verbs.do: integrate, don't rebuild.
Think about a critical action in your existing application, like processing a customer refund. Where does that logic live?
In many legacy systems, it's scattered.
When a customer complains they never received their refund, your investigation involves grep-ing through terabytes of inconsistent server logs, piecing together database timestamps, and hoping you can build a coherent timeline. You're not just debugging code; you're solving a mystery with no clues. This is the "What Just Happened?" problem, and it drains developer productivity and erodes business confidence.
Verbs.do introduces the concept of Actions as Code. A Verb is a standardized, explicit definition of a business action. It’s not a replacement for your existing logic—at least, not at first. It's a wrapper.
Imagine you have a complex piece of machinery. Instead of rewiring it immediately, you start by putting a clear, standardized control panel on the front. Each button is labeled: "Start Machine," "Run Diagnostic," "Emergency Stop." Pressing a button still triggers the old, complex wiring, but now the intent is recorded, clear, and standardized.
That's precisely what you do with Verbs.do. You identify a business action and wrap it in a Verb.
Let's stick with our ProcessRefund example. You don't need to refactor your entire refund module. You just need to announce that the action is happening.
First, you define the ProcessRefund action using the Verbs.do SDK. This definition lives centrally and serves as the single source of truth for what this action entails.
import { Verb } from 'verbs.do';
const processRefund = new Verb({
name: 'ProcessRefund',
description: 'An admin processes a monetary refund for an order.',
subject: { type: 'Admin' }, // Who is performing the action?
object: { type: 'Order' }, // What is it being performed on?
properties: {
amount: { type: 'number', description: 'The value of the refund.' },
reason: { type: 'string', description: 'The reason for the refund.' }
}
// We'll leave 'effects' empty for now. Our goal is the log!
});
Now, find the entry point to your existing, messy refund logic. It might be a controller or an API endpoint handler. The only change you're going to make is to add one line at the very beginning.
Before:
// in controllers/refund.controller.ts
async function handleRefundRequest(request) {
const { adminId, orderId, amount, reason } = request.body;
// --- Your existing, complex legacy code starts here ---
try {
legacyRefundLogic(orderId, amount, reason);
updateLegacyDatabase(orderId, 'refunded');
// ... and so on
} catch (error) {
// ... handle errors
}
// --- Your legacy code ends here ---
}
After:
// in controllers/refund.controller.ts
import { processRefund } from '../verbs'; // Import your central definition
async function handleRefundRequest(request) {
const { adminId, orderId, amount, reason } = request.body;
// 1. EXECUTE THE VERB
// This instantly creates a structured, immutable log of the intent.
await processRefund.execute({
subject: { id: adminId },
object: { id: orderId },
properties: { amount, reason }
});
// --- Your existing, complex legacy code runs UNCHANGED ---
try {
legacyRefundLogic(orderId, amount, reason);
updateLegacyDatabase(orderId, 'refunded');
// ... and so on
} catch (error) {
// You could even execute a 'RefundFailed' verb here
// ... handle errors
}
// --- Your legacy code ends here ---
}
With just a few lines of code, you've fundamentally improved your system:
This incremental approach provides a clear path forward. Once the ProcessRefund Verb is reliably logging every execution, you can take the next step.
Modernizing doesn't have to be a gamble. By layering a framework of Business-as-Code on top of your existing systems, you can bring order to chaos one Verb at a time.
Ready to bring clarity to your codebase? Visit Verbs.do and define your first action.