Skip to main content

Managing the Evolution of Complex Business Apps

In high-scale enterprise environments—the kind traditionally dominated by SAP or custom-built Java monoliths—the biggest challenge isn't building a feature; it's evolving it over ten years.

Framework M is designed for this "Long Journey." We enable a progressive architectural roadmap that lets you scale without the need for a total rewrite:

Prototype $\rightarrow$ Modular Monolith $\rightarrow$ Progressively Decomposed Macroservices


Phase 1: Prototyping & "The Speed of Magic"​

In the early days of a project, you need the speed of a low-code platform.

  • Strategy: Use Pure Declarative Sync.
  • Workflow: Define your DocTypes, add fields, and run m migrate sync.
  • Outcome: You build 80% of your business logic (OOTB entities like Customer, Order, Invoice) in days, not months. The DeclarativeSyncEngine handles all additive changes (tables, columns, indexes) automatically.

Phase 2: Refactoring & The "Alembic Handshake"​

As the business model matures, you will inevitably need to change your mind. A column needs to be renamed, or a table needs to be split.

  • Strategy: Use the Dual-Track Handshake.
  • Workflow:
    1. Create an Alembic Patch to rename the column physically.
    2. Update the DocType code to the new name.
    3. Run m migrate all.
  • Outcome: The patch handles the transition, and the sync engine "seals" the new state by updating the checksum. This provides SAP-level auditability with Frappe-level development speed.

Phase 3: Handling Custom vs. OOTB Extensions​

In Framework M, you often extend "Out-of-the-Box" (OOTB) apps with custom logic.

  • Scenario: You add a custom_priority field to a core Ticket DocType.
  • Workflow: The core framework manages the Ticket table, but your custom app manages its own metadata decoration.
  • Migration: When the Core Framework updates the Ticket table in a new release, your custom app's m migrate sync will identify the structural change and ensure your custom fields remain intact. This is Modular Schema Management.

Phase 4: Complex Views & Enterprise Reporting​

Complex business apps often require SQL Views that aggregate data across many tables (e.g., joining SalesOrder, Inventory, and CustomerProfile).

  • Strategy: Use Migration Hooks.
  • Workflow: Implement after_sync in your app's migrations/__init__.py.
  • def after_sync(engine):
    with engine.begin() as conn:
    conn.execute(text("CREATE OR REPLACE VIEW sales_dashboard AS ..."))
  • Outcome: Your complex reporting layer is automatically re-synchronized every time the underlying DocTypes change. This eliminates the "broken report" syndrome common in large ERP systems.

The Zero-Downtime Journey (ZDM)​

For apps serving millions of users (like a national logistics platform), downtime is not an option. Framework M supports a 3-step ZDM evolution:

  1. Additive Step: Run m migrate sync. This adds new nullable columns. The old code still works because the new columns don't interfere.
  2. Application Rollout: Deploy the new code version. It begins writing to both old and new fields if necessary.
  3. Cleanup Step: Once all nodes are updated, run an Alembic Patch to drop the old column (using --allow-drop) and run a data-fix hook to enforce NOT NULL on the new fields.

Phase 5: Progressive Decomposition (Macroservices)​

As your application grows to a massive scale, even a clean modular monolith can become a burden. You may need to move your Inventory or Billing module into its own database and service.

  • The Promise: Because Framework M migrations are Decentralized (managed at the app level), you can literally "lift and shift" an app and its migration folder to a new repo/service.
  • Workflow:
    1. Provision a new database for the Macroservice.
    2. Point the App's DATABASE_URL to the new target.
    3. Run m migrate all on the new service.
  • Outcome: The DeclarativeSyncEngine rebuilds the schema in the new database instantly based on the existing DocTypes. You've successfully decomposed your system into a Macroservice while maintaining the exact same schema integrity and "magic" as the day you prototyped it.

Why this replaces SAP​

Unlike SAP, where schema changes often require massive "Transport Requests" and manual DDL coordination, Framework M treats the Database Schema as a Projected State of the Code.

You get the safety of a versioned ledger (Alembic) combined with the intelligence of a self-healing sync engine. This allows teams to iterate on complex business rules with the confidence that the database will always be a perfect reflection of the business logic.