For years, I had a dream: build my own ERP system for an airline. Not just any ERP—one tailored to the messy reality of aviation operations, where procurement, maintenance, production, and sales all need to feed into a single financial picture. But I'm not a coder. I studied computer science in college, but after graduation, I rarely wrote a line of code. The blueprint was in my head; the keyboard just wouldn't cooperate.
My day job only deepened the obsession. I worked on digital transformation projects for major airlines, then joined a domestic ERP vendor, and later moved to a Big Four accounting firm. Through all that, I absorbed how business processes flow, how accounting entries are made, and the chaos that precedes a system go-live. Slowly, a complete ERP model took shape in my mind—how transactions should move, how vouchers should be generated. But a model in your head is just a model. Without code, it stays there.
Then AI showed up. And that dream became real.
Today, my system is in internal testing. Procurement orders, production issues, and sales invoices automatically generate accounting vouchers. Those vouchers roll into account balances, which then produce a balance sheet and income statement. Even better, I've wrapped the core modules as MCP (Model Context Protocol) servers, each with dozens of tools that map to ERP functions. Connected to WorkBuddy, I can just ask in chat: “Check inventory for part X” or “Create a purchase order” or “Pull the P&L.” No menus, no forms.
But this isn't a smooth-sailing story. I hit four major pitfalls, each one hard enough to make me want to delete everything and start over. Let me walk you through them, because if you're thinking of doing something similar, you might avoid a few bruises.
The First Trap: UI Before Substance
When I started, I poured most of my energy into the interface. Button placements, field dependencies—I thought that was the real craft. It wasn't until I actually built the thing that I realized the core isn't the UI. It's how a business document becomes accounting language.
Take a purchase receipt: it needs to record inventory and accounts payable. A production issue moves materials to work-in-progress. A sales confirmation triggers revenue and accounts receivable. Three different business actions, three different sets of debit-credit logic. My first version had each module generate its own vouchers—each department did its own accounting. It fell apart fast. Account balances didn't match. Procurement said payables were one number; finance said another. Everyone thought they were right.
So I changed the architecture. Modules no longer generate vouchers themselves; they emit business events. A centralized voucher engine translates those events into accounting entries. Each document type has a mapping rule: purchase receipt → debit inventory, credit payables. Sales confirmation → debit receivables, credit revenue. All vouchers write into a single account balance table, and the balance sheet and income statement are just read-only projections of that table.
The essence of integrated business and finance isn't bolting a finance module onto a business module. It's a translation pipeline from business actions to accounting language. The translation rules must be centralized and configurable, not scattered across modules. Once I did that, adding a new module was just a matter of plugging in a mapping. The vouchers generate themselves. No more begging finance to reconcile.
The Second Trap: Model Hopping
AI wrote the code, but I made a rookie mistake early on: I used different AI models for different modules. I thought I'd get the best of each—one for its strength in logic, another for its clean style. Instead, I got a mess. The interface styles clashed. Naming, structure, error handling—each model had its own temperament. Fixing one module broke another. Bugs multiplied faster than features.
Even sneakier was having multiple models take turns on the same logic. The second model didn't have the context of the first, so it rewrote things in its own way, and the logic got tangled. Each piece looked fine in isolation, but together they wouldn't run. Debugging was torture because every segment seemed correct on its own.
After testing a bunch, I settled on GLM5.2. From then on, one model wrote everything. The style became consistent, and when I had to change something, I knew where it connected. Even when things got messy, the model's own reasoning could pick up the thread. Looking back, the lesson is clear: when you're building with AI, don't be greedy. One model that works well is better than three that are collectively brilliant. If I'd learned that six months earlier, I'd have saved tens of thousands of lines of code.
The Third Trap: No Version Control
In the early days, I didn't use Git properly—or at all. I saved files with date-based names in folders: final, final2, true_final, true_final_dont_touch. Then one big refactor broke the voucher engine's core logic. I wanted to roll back, but there was no clean version to return to. I had to rewrite it.
That happened more than once. Each rewrite meant two or three days of work down the drain, and it chipped away at my morale. After the second rewrite, I started doubting I'd ever finish. And it burned tokens.
So I finally got serious about Git. Each phase gets its own branch; the main branch only holds verified code. Feature branches are for experimentation—break them, and you can switch back in ten minutes. I also made it a habit: before logging off, I merge the day's stable work into main, leaving unstable stuff on a branch overnight.
Without version discipline, a solo project is like writing code on a cliff. You think you're saving time, but one wrong move wipes out everything. A lone developer needs it even more, because there's no one to catch you when you fall.
The Fourth Trap: MCP-ifying Everything
Once the system ran, I wanted to make it conversational. Traditional ERP is all menus and forms—click, click, click. I found it clunky and slow. So I wrapped each core module—procurement, production, sales, finance—as an MCP server, each with dozens of tools that map to ERP functions. From checking stock to creating a purchase order to pulling a profit statement, every action became a standalone tool.
Tool granularity took some tuning. Too coarse, and a single tool does ten things, confusing the chat interface. Too fine, and you get dozens of similar-looking tools that confuse the caller. I ended up splitting by business action: one action, one tool, with plain names that made intent obvious.
But the sneakiest pitfall was hidden in the MCP layer. Early on, I put some calculations outside the backend interface—front-end logic for subtotals, taxes, document summaries. When the system ran in the UI, it worked fine, because the front end executed those calculations. But a conversational call doesn't run front-end code. It just sends parameters and gets results. So the numbers came out wrong. Voucher amounts didn't match, and the reports didn't align with the business.
This was the hardest bug to find. In the UI, everything looked perfect. Click a document, and the numbers were right. Only when I queried via chat did they differ. I stared at the same transaction, compared the UI view and the chat output, and saw two different numbers. I was baffled.
I did an interface overhaul. All business calculations, no matter how small, moved into the backend. The front end and chat layer only pass parameters and display results—they never touch the math. I also added a double-check in the backend: the same figure is calculated twice through two paths, and if they don't match, it's blocked from entering the voucher system. That's a double safety net for the data.
After that, the data was finally stable. The numbers you see in chat, the ones in the UI, and the totals in reports are finally the same.
The lesson: MCP interfaces must be fully backend. Any calculation done on the front end evaporates when called conversationally. Every computation in an interface has to survive being called directly by chat, because chat won't fill in missing front-end logic. In a way, conversational operation forced me to make the interfaces cleaner—an unexpected bonus.
The Real Takeaway
After this journey, I've got a firm belief: AI loosens the reins on writing code, but not on understanding the business. A lot of people think AI can figure out the system for them. It can't. AI can write the system, but the thinking—that's still on you. The gap between those two is where the pitfalls live.
None of these four traps did I get right on the first try. Each retry cost time, morale, and those moments staring at the screen wondering if I was in over my head. But in the end, AI gave me the muscle; I just had to supply the judgment. It didn't make development easier—it made it possible for one person to build something that feels enterprise-grade. The price is that every decision is yours alone, and there's no one to hit the brakes.
That dream I carried for years is now running in beta. It's not perfect. Modules need polish, reports need tuning, and the chat sometimes misunderstands me. But it really does generate a balance sheet on its own.
Comments (0)
Please sign in to post a comment.
Don't have an account? Create one
No comments yet. Be the first to comment!