Roshan Kc

← All notes

Engineering · Strategy 9 min read

Business Logic First: Why We Don't Worry About the Perfect Tech Stack

Direct answer: We optimize for business logic first, not the perfect tech stack, because stack regret is cheaper than domain regret. AI coding tools make framework migration and boilerplate regeneration easier; messy data models and unclear invoicing rules still punish you for years — and no AI can fix those without deeply understanding your business first.

At MarginTop Solutions, founders regularly ask us which framework is "future-proof." We redirect: what money, compliance, and customer promises must the system never get wrong?

Stack regret vs. domain regret: what the data shows

There's no perfect study on this, but the pattern appears repeatedly across software engineering post-mortems. A Stripe engineering blog post on their billing system migration described spending months of senior engineering time cleaning up implicit pricing rules that existed only in a founder's head — not because they chose the wrong database, but because the billing rules had never been written down. Similar stories appear in every long-running SaaS company: Shopify's decade-long work to tease apart their monolith was fundamentally about domain clarity, not stack choice.

The asymmetry:

  • Stack migration (e.g., Express to NestJS, or adding TypeScript): typically 2–6 weeks of focused engineering time for a medium-sized codebase with decent test coverage. With AI tools, boilerplate and adapter conversion are faster than they've ever been.
  • Domain model migration (e.g., reconciling 3 years of invoicing edge cases, untangling implicit permission rules, correcting inconsistent multi-tenancy): typically 6–18 months of senior engineering time, touching production data under load, with business risk on every migration step.

The cost ratio is roughly 10:1 in favor of getting domain modeling right over getting stack choice right. That's why we spend more time in early engagements on data models and business rule documentation than on stack selection.

AI lowered the cost of stack regret further

The business-logic-first argument is stronger now than it was in 2019, because AI tools have changed the cost structure of stack migration:

  • Boilerplate CRUD, adapters, and test scaffolding can be regenerated faster than ever. Framework migration costs that used to take months take weeks.
  • Framework docs + AI coding tools shrink the "unknown API" tax when switching libraries.
  • What AI does not magically fix: contradictory business rules buried in Slack messages and spreadsheets. AI can generate an invoicing system fast; it cannot generate your invoicing rules without you knowing what they are.

That's why our Laravel default (why we chose Laravel) is a velocity bet, not a religion. See also how AI tools changed our velocity.

Where the real risk lives

  1. Data migrations you can't test safely. Renaming a table is easy. Reconciling five years of invoice states — some partially paid, some voided, some in an unknown status that a support ticket once resolved manually — is not. That migration touches production data, has no safe rollback, and takes a week of senior engineering time to de-risk properly.
  2. Implicit rules that exist only in human memory. "We always waive late fees for enterprise clients who've been with us over 18 months" is a business rule. If it's in a founder's head and not in code or documentation, it's a time bomb — usually triggered during a handoff, an audit, or an angry enterprise email.
  3. Partial truths in the UI. Screens that show numbers finance cannot defend in an audit. Reports generated from denormalized caches that diverged from source of truth six months ago. Dashboard metrics calculated differently between the app and the spreadsheet.

Concrete example: invoicing gets expensive fast

Suppose a B2B product needs invoices with tax, credit notes, partial payments, and multi-currency. Teams love debating GraphQL vs REST or Laravel vs Node. The expensive mistakes look like this — and they're all domain mistakes, not stack mistakes:

Domain mistake When it surfaces Cost to fix
Storing only "amount_due" without immutable line-item history First audit, or first disputed invoice Weeks of data reconstruction; some records unrecoverable
Allowing status transitions finance never approved (paid → draft) When a junior engineer "fixes" a customer issue in prod Accounting reconciliation; possible regulatory issue
Tax rate hardcoded in three different services When tax rates change (they always do) Hunt across codebase; risk of partial update causing inconsistency
No credit note / negative invoice model First customer refund request Schema migration in production; UI overhaul; accounting holes

Fixing any of these later means rewriting history under production load. Swapping Express for Nest, or Laravel for Nest, doesn't touch any of them.

What we actually do instead of stack-obsessing

In the first phase of any engagement, we do these things before writing much application code:

  1. Write down the invariants. What must always be true? What transitions are legally or financially disallowed? These belong in code as explicit guards, not implicit conventions.
  2. Model the lifecycle, not just the happy path. What does a fully paid invoice look like? A partially refunded one? A disputed one? If you can't answer these before you build, you're designing by accident.
  3. Identify the sources of truth. Which system is authoritative for price? For stock levels? For subscription status? Ambiguity here causes data divergence that's expensive to clean up later.
  4. Document implicit rules explicitly. Ask the founder: "Tell me about the exception cases you handle manually." Those manual exceptions are business rules waiting to be encoded — or disaster stories waiting to happen.

Only after we have clarity on those do we start making stack and framework choices — and by then, the choice is usually obvious from the constraints, not from preference.

Key takeaways

  • Stack migration costs 2–6 weeks with decent test coverage and modern AI tools. Domain model migration costs 6–18 months. Optimize accordingly.
  • AI makes boilerplate and framework migration faster — which makes the argument for business-logic-first even stronger, not weaker.
  • Implicit business rules, undocumented exceptions, and inconsistent sources of truth are the real technical debt that compounds over years.
  • Write down invariants, lifecycle models, and sources of truth before arguing about framework choice. The stack will become obvious from the constraints.

Building a product and want to start with a solid domain model? Get in touch — this is the conversation we have at the start of every engagement.