Skip to main content

Care Practices: Lessons from Building a Personal ERP with AI

A non-coder's journey to build a custom ERP with AI reveals four pitfalls—from centralized accounting logic to version control—offering practical care practices for solo developers.

From Dream to Reality: A Personal ERP

For years, I dreamed of building my own ERP system. I studied computer science in college—operating systems, databases, software engineering—but after graduation, I barely wrote a line of code. The blueprint was in my head, but my fingers froze at the keyboard. The idea stayed just an idea.

Then I got tangled up with ERPs at work. I joined digital transformation projects at large companies, moved to a domestic ERP vendor, and later landed at a Big Four accounting firm. Through those years, I absorbed how business processes flow, how accounting entries are created, and the chaos that precedes a go-live. Slowly, a model of an ERP took shape in my mind: how transactions move, how vouchers are generated, how reports balance. But a model isn't code. Without programming skills, it remained just a mental diagram.

Then AI arrived, and the dream became real.

Start with the Business, Not the UI

My first instinct was to obsess over the interface—button placements, field validations, the whole visual polish. I thought that was the real craft. But as I dug in, I realized the core challenge was translating business actions into accounting language. A purchase receipt must record inventory and accounts payable. A production issue moves materials into work-in-progress. A sale confirms revenue and accounts receivable. Three different operations, each with its own debit-credit logic.

In my initial version, each module generated its own vouchers. Each business unit did its own math. It broke fast. Account balances didn't match. Purchasing said payables were one number, finance said another. Everyone was sure they were right.

So I re-architected. No module creates vouchers anymore. Instead, each module emits business events, and a centralized voucher engine translates them. For each document type, I defined a mapping rule: purchase receipt triggers debit inventory, credit payables. Every voucher flows into the same account balance table, from which the balance sheet and income statement are just read-only projections.

The essence of integrated financial and business operations isn't bolting modules together—it's a translation pipeline from business events to accounting language. Keep the translation rules centralized and configurable. Don't let each module speak its own dialect.

Stick to One AI Model

The code was written by AI, but I made a costly mistake early on. I thought, why not use different models for different modules? Let the strong ones do the heavy lifting. So model A wrote one module, model B wrote another. The result was a mess. Interfaces clashed, naming conventions diverged, error handling followed two different philosophies. Fixing A broke B, and fixing B broke A again. Bugs multiplied faster than features.

Even worse was letting different models take turns on the same logic. The context from the previous model was lost; the next one rewrote things based on its own understanding. The code looked plausible in isolation but fell apart when connected. Debugging was torture because every piece looked correct on its own.

After testing several, I settled on GLM5.2. From then on, one model generated the entire project. The style unified, and I could predict where things connected. When confusion arose, the same model's logic was consistent enough to continue.

Looking back, the biggest lesson is: don't be greedy. One model you're comfortable with beats three clever ones combined. If I'd learned that six months earlier, I'd have saved thousands of lines of code.

Version Control Is Non-Negotiable

In the early days, I didn't use Git properly—or at all. I saved files by date in folders with names like “final,” “final2,” “really final,” “final no more changes.” Then a major refactor broke the core voucher engine logic. I wanted to roll back, but there was no clean version. I had to rewrite everything from scratch.

This happened more than once. Each rewrite cost days of work and, worse, chipped away at my motivation. By the second rewrite, I started doubting whether I could finish at all. Plus, the token bills were piling up.

Finally, I adopted Git properly. I created a branch for each phase, kept the main branch for verified code, and let feature branches be the wild west. If something broke, I could revert in ten minutes. I also made a habit: before ending the day, I merged anything stable into main, leaving half-baked work on its branch overnight.

Without version discipline, a solo project is like coding on a cliff edge. You think you're saving time, but you're one misstep away from losing everything. When you're alone, there's no safety net—a crash is a real crash.

MCP: The Hidden Trap

Once the system ran, I moved to MCP (Model Context Protocol) to make it conversational. Traditional ERPs rely on menus and forms—click, click, click. I found that clunky. So I wrapped the core modules—purchasing, production, sales, finance—into MCP servers, each containing dozens of tools. Behind each tool is an API endpoint. From inventory checks to purchase orders to profit statements, every action became a standalone tool. I plugged them into WorkBuddy, and now I can just say, “Check stock for material X,” and the tool runs. No UI needed.

Tool granularity took trial and error. Too coarse, and one tool does ten things, confusing the conversation parser. Too fine, and you have dozens of similar-looking tools, overwhelming the caller. I settled on one action per tool, with clear names, so the dialogue understands what you want.

But the sneakiest pitfall was hiding in the MCP layer. Initially, I placed some calculation logic outside the API—things like line totals, tax amounts, document summaries—in the frontend. That worked fine in the UI because the browser executed the code. But when called via conversation, the dialogue layer only passes parameters and gets results; it doesn't run frontend calculations. So the data came back wrong. Voucher amounts didn't match, and reports diverged from actual business numbers.

This was the hardest bug to find. The UI showed correct numbers. Clicking into a document looked fine. Only the conversational interface returned errors. I compared the same transaction—UI vs. dialogue—and they didn't match. I stared at the screen, baffled.

I eventually upgraded the interfaces. All business calculations, no matter how small, moved into the backend. The frontend and dialogue layer only pass parameters and display results—they never touch the math. I also added a double-check: the same figure is computed via two independent paths, and if they disagree, the system blocks it from creating a voucher. It's a safety net for data integrity.

After that, the data finally stabilized. Numbers from the chat, the UI, and the reports all agree.

The lesson: MCP interfaces must be fully backend-driven. If the frontend does the math, a conversation call will silently lose it. Every calculation in an API must be robust enough to be invoked directly, because the dialogue won't compensate for missing frontend logic. Ironically, this forced me to make the APIs cleaner—a welcome side effect.

AI Gives Muscle, Not Judgment

Through this journey, I've come to a conclusion: AI loosens the reins on coding, but it doesn't loosen the reins on thinking through the business. Many people expect AI to figure out the system for them. In reality, AI writes the system; you still have to understand it. That gap is where the pitfalls live.

None of these four traps were one-and-done. Every reset came with a cost—time, morale, and those moments of staring at the screen doubting myself.

In the end, AI provides the muscle, but judgment is still yours. It didn't make development easier; it just made it possible for one person to shoulder the weight of enterprise software. The price is that you make every call alone, with no one to hit the brakes.

That long-held dream is now running in internal testing. It's not perfect—modules need polish, reports need tuning, and the chat occasionally mishears me. But it actually generates its own balance sheet now. And that's enough.

Share this article:

Comments (0)

No comments yet. Be the first to comment!