Engineering Notes

Defining ERP domain boundaries before modules start to scale

How Businext ERP separates each business area — CRM, inventory, sales, finance, human resources and suppliers — into independent modules mounted as FastAPI applications. The goal is to let each domain evolve without breaking the overall operation of the system.

Architecture Note

2026-03-09

8 min read

When an ERP becomes hard to change

An ERP does not become difficult to maintain when it grows in lines of code.
It becomes difficult when modules start depending on rules that actually belong to another business area.

That was the risk when designing Businext ERP.

In real enterprise systems, business areas are not isolated. Finance needs inventory context to validate certain events. Sales needs the financial state of the customer. Human resources manages permissions that affect the entire platform.

That interaction is normal.

The problem appears when those dependencies are resolved implicitly: direct joins across modules, duplicated business logic in multiple endpoints, or queries that reinterpret rules that should have a clear owner.

At that point the system still works, but it starts losing something more important than performance: clarity.

The scaling problem in ERP systems is not only technical

As an ERP grows, each business area expands its responsibility.

Finance does not only manage balances. It defines accounting periods, reconciliation semantics, and financial integrity.
Inventory does not only track stock. It controls operational movements that later impact reporting.
Sales does not only manage orders. It defines commitments, pricing rules, and customer lifecycle data.

If those responsibilities do not have clear boundaries, the system compensates with convenience.

Modules read tables from other modules.
Business rules get duplicated.
Conditional logic spreads across services.

The system still runs, but every change introduces uncertainty.

The architectural decision in Businext

From the beginning, Businext ERP was designed around business domains.

Each business area operates as an independent module:

CRM
HRM
SRM
PMS
EMS
RMS
IMS
SMS
AMS
EIS

In practice this is implemented as FastAPI applications mounted inside the same backend.

Each module exposes its own routes and services.

Each domain maintains its own engineering structure:

  • SQLAlchemy models
  • Pydantic schemas
  • API routers
  • domain services

This allows each domain to evolve within clear boundaries while still sharing the same production database.

Why domain boundaries are architecture

Separating domains is not just folder organization.

It is deciding who owns each business concept.

Finance owns accounting rules.
Sales can consult financial information but should not redefine accounting states.
Inventory owns stock movement rules.

Without those decisions, rules start leaking into queries, endpoints, and scripts.

That is how ERP systems become fragile.

Why direct table access usually starts the problem

In many internal systems, reading another module’s table seems harmless.

A developer needs one field.
They write a join.
Another endpoint copies it.
Later a rule changes in one place but not the other.

Efficiency slowly turns into distributed policy.

This is dangerous in ERP systems because many rules are not obvious from the database schema.

Those rules belong to the domain, not to persistence.

A practical model for defining boundaries

In Businext, a useful approach was asking four questions:

  • Which business area owns the rule
  • Which areas consume the result
  • What contract exists between them
  • What breaks if the contract is bypassed

This keeps architecture decisions grounded in business ownership.

The tradeoff: more explicit coordination

Clear boundaries do not reduce complexity.
They make it visible.

Some workflows require coordination across modules.
Designing explicit service contracts can feel slower than direct queries.

But in enterprise systems this prevents hidden coupling and large regression surfaces.

Operational effect

The biggest benefit was not aesthetic.

It was the ability to make changes with confidence.

Financial logic stayed isolated.
Inventory behavior remained predictable.
New features had to declare their dependencies explicitly.

That is what keeps an ERP maintainable.

Not the absence of complexity, but clear ownership of business rules.

Businext was not designed as microservices, but as a modular monolith where each business domain evolves inside a FastAPI application mounted within the same backend.

This is especially true when:

  • the ERP is still growing in modules;
  • multiple people touch the same platform over time;
  • accounting and operational workflows must stay consistent.

Operational effect

The strongest benefit was not aesthetic code quality. It was decision safety. Finance changes became easier to isolate. Inventory behavior stayed coherent. New features had to declare their dependencies instead of quietly inventing them.

That is what keeps an ERP maintainable. Not the absence of complexity, but the presence of explicit ownership.

If you are designing or refactoring a similar platform, a useful next step is to pair this boundary work with FastAPI service design around business transactions and with a broader view on ERP platform architecture.