LockMargin

Published: Apr 29, 2026 | Story begins: February 2026

The First Time I Dogfooded My Own Product

Last updated:

February 14, 2026. Valentine's Day. I was sitting in my apartment in Kharkiv, staring at a screen that showed:

Invoice #001
Client: [empty]
Amount: [empty]
Status: DRAFT

I had spent two months building LockMargin. I had a working database. I had a PDF exporter. I had a UI that didn't make me want to vomit. But I had never sent a real invoice from it.

Not a test invoice. Not a demo invoice. A real invoice to a real client who owed me real money.

The client was a German design agency. The project was a two-week consulting gig. The amount was €3,200. And the payment terms were 14 days.

I clicked "Create Invoice." The app froze for 3 seconds. Then it crashed.

What Broke

Bug #1: The Currency Symbol

I had hardcoded the currency symbol as "$". Because I'm American now, apparently. The client was German. The invoice showed:

Total: $3,200 EUR

Not "€3,200". Not "3,200 EUR". "$3,200 EUR". Three currency symbols in one line. I stared at the PDF for 10 seconds, then laughed. Then I cried a little.

Fix: I rewrote the currency formatter that night. Not just symbols — proper localization. Decimal separators. Thousands separators. Symbol placement before or after the number depending on the locale. It took 4 hours. I ate cold borscht at 2 AM.

Bug #2: The PDF Font

The PDF exported fine. I opened it. The client's name — "Müller & Schmidt Design" — rendered as "Mller & Schmidt Design". The umlaut disappeared. Because I had embedded a font that didn't support German characters.

I had tested with "John Smith" and "ABC Corp". I had never tested with a real European name.

Fix: Switched to a font with full Unicode support. Added test cases with names containing: ä, ö, ü, ñ, ç, ł, ø, and every other character I could find. The test file looks like a linguistic asylum now.

Bug #3: The VAT Presentation

Germany has 19% VAT. I knew this. I had implemented VAT calculation. The math was correct:

Subtotal: €2,689.08
VAT (19%): €510.92
Total: €3,200.00

But I had displayed it as a single line: "Total (incl. VAT): €3,200.00". No breakdown. No separate line item. No calculation methodology.

The German accountant replied with a 500-word email. Not angry — confused. She needed the VAT shown as a separate line item with the exact calculation method documented. For German tax purposes, the presentation matters as much as the numbers.

I had the numbers right. The presentation was wrong.

Fix: Added "VAT display mode" — inclusive vs. exclusive, with line-item breakdown. Added a note field for calculation methodology. Added country-specific invoice templates. Took 6 hours.

Bug #4: The Email Subject

I exported the PDF. I attached it to an email. I wrote:

Subject: Invoice

The client replied: "Which invoice? From which project? For what period?"

I had built an invoicing tool that generated perfect PDFs and left the email entirely to me. No template. No auto-subject. No client name in the filename.

Fix: Added email templates. Auto-subject: "Invoice #[number] — [project name] — [client name]". Auto-filename: "LockMargin_Invoice_001_MuellerSchmidt_2026-02-14.pdf". Added .eml export (Phase 1 of our Client Communication System).

What Worked

The Database Didn't Lose My Data

Despite the crash, despite the wrong currency, despite everything — when I reopened the app, the invoice was there. Draft status. All data intact. SQLite + WAL mode. Zero corruption. I had spent January agonizing over the database choice. In that moment, I stopped agonizing.

The PDF Looked Professional

Once I fixed the font, the PDF was clean. Header with my logo. Clean table. Proper totals. Terms and conditions footer. It looked like it came from software that cost $500/year, not software I had built in my kitchen.

The Client Paid

I sent the corrected invoice on February 15. The client paid on February 28. Fourteen days exactly. The money hit my account on March 1.

I opened LockMargin. I marked the invoice as "Paid." The dashboard updated. My "Outstanding" widget dropped from €3,200 to €0. My "Revenue This Month" widget jumped to €3,200.

I stared at that number for five minutes. Not because it was a lot of money. Because I had built the thing that showed it to me. And it worked.

What I Learned

You Can't Test Reality

I had 47 test cases. Unit tests. Integration tests. I had tested invoice creation, PDF export, database writes, currency formatting. I had not tested "send a real invoice to a real German client and get paid."

That test doesn't exist in any framework. You have to live it.

Dogfooding Is Not Optional

If I had waited until "v1.0" to use my own product, I would have shipped with "$3,200 EUR" and missing umlauts. Dogfooding isn't a nice-to-have. It's the only way to find the bugs that matter.

The Small Bugs Are the Big Bugs

The database architecture? Solid. The reactive engine? Flawless. The UI framework? Stable. What broke? A currency symbol. A font. An email subject line.

The infrastructure was fine. The details were broken. And details are what users see.

I Almost Deleted It Twice

The first time was when I saw "$3,200 EUR" on the invoice. I thought: "This is garbage. No one will trust this. I'm not a developer — I'm a fraud." I closed the laptop and didn't open it for 6 hours.

The second time was when the German accountant sent her 500-word email about VAT compliance. I thought: "I'm not qualified for this. I don't know German tax law. I should go back to consulting." I stared at the "Delete Project" button for 30 seconds.

I didn't delete it either time. I fixed it. Because I needed the €3,200. And because I was too stubborn to quit.

The Numbers

Metric Value
Time to first real invoice 2 months (Dec 2025 – Feb 2026)
Bugs found during dogfooding 4 critical, 12 minor
Time to fix critical bugs 14 hours total
Client payment time 14 days (exactly on terms)
My stress level, pre-fix 9/10
My stress level, post-payment 3/10
Times I almost deleted the project 2
Hours staring at "Paid" status 0.08 (5 minutes)

What's Next

Post #2: Why I Chose SQLite Over PostgreSQL — or how I learned that building secure software is not the same as thinking your software is secure.

Post #4: How We Test Encryption Without a Security Team — or how I learned that building secure software is not the same as thinking your software is secure.

Follow the entire series at Building LockMargin.

Try LockMargin

Standard is $49 one-time. No subscriptions. No cloud. Your data stays on your machine.

Download Free — No Account Needed Compare Pricing

About the Author

Vlad Shiyan — Founder & Developer of LockMargin

Vlad Shiyan

Founder & Developer

Kharkiv, Ukraine

Building LockMargin since December 2025. Offline-first invoicing for freelancers who are tired of subscriptions. Standard is $49 one-time.

Frequently Asked Questions

Do you really use LockMargin for your own invoices?

Yes. Every invoice since February 2026 has been sent from LockMargin. Every expense tracked. Every client managed. If it breaks, I feel it immediately.

How often do you find bugs now?

Fewer than at the start. The first month was brutal — 2-3 bugs per week. Now it's 1-2 per month, mostly edge cases. The product is stabilizing because I'm using it daily.

What if a client asks for a feature you don't have?

I add it. If one client needs it, others probably do too. That's how we built recurring invoices, multi-currency support, and the .eml export. Real requests, real priorities.

How do you handle updates without losing data?

SQLite file copy. Before every update, I copy the database file. If something breaks, I restore. Zero cloud sync needed. It takes 5 seconds.