ENGINEERING WORK 03 / LEGACY REFACTOR

Refactor the ownership of business logic, not the user’s entire workflow.

The issue was not another slow query. It was change risk: important calculations had accumulated across controllers, database views and helper methods.

CHANGE SURFACE SCATTERED → DEFINED caller contract preserved
01
PROBLEM

The same finance rules were becoming harder to reason about because data retrieval and calculation were fused.

A mature CRM had accumulated financial values through database views and controller-level orchestration. A faster retrieval path risked creating a second implementation of the same business rules if calculations were simply copied into the new controller method.

The goal was therefore not merely “make a fast version.” It was to separate reusable calculations from the particular data-access path that happened to call them.

BEFORE / COUPLED
Controller retrieval + finance calculations + formatting
Database view data + derived financial fields
Helper methods partial rule fragments
Caller depends on final array shape
→
AFTER / OWNED
Controller request + orchestration
Calculation boundary business rules + totals
Models / focused queries data access
Caller same output contract
02
CODE / EXTRACTION PATTERN

Make the calculation callable from both the legacy and optimized paths.

The important architectural move was to make the finance calculation independent from whichever query populated the input data.

BEFORE / REPRESENTATIVERules inside retrieval
public function getRecordFinance($recordId)
{
    $row = DB::table('legacy_finance_view')
        ->where('record_id', $recordId)
        ->first();

    // Retrieval and business calculations
    // are coupled to this one path.
    return [
        'revenue' => $row->revenue,
        'cost'    => $row->cost,
        'profit'  => $row->revenue - $row->cost,
    ];
}
AFTER / REPRESENTATIVEReusable calculation boundary
public function getOptimizedFinanceData($recordId)
{
    $inputs = $this->loadFinanceInputs($recordId);

    return $this->calculateFinance($inputs);
}

private function calculateFinance(array $inputs)
{
    return [
        'revenue' => $inputs['revenue'],
        'cost'    => $inputs['cost'],
        'profit'  => $inputs['revenue'] - $inputs['cost'],
    ];
}

Method names and domain identifiers are generalized, and the shown calculation body is simplified so proprietary finance rules are not published. The architectural point is that the new retrieval path did not need to invent a second business-rule implementation.

03
CHANGE STRATEGY

Preserve the contract while moving ownership underneath it.

01

Identified which calculations were already duplicated and which were merely called from multiple places.

02

Extracted reusable calculations rather than copying them into the new “fast” path.

03

Reduced reliance on database views where those views were acting as hidden business-logic containers.

04

Kept the existing caller contract so screens did not need a simultaneous rewrite.

05

Moved in small steps so old and new behavior could be compared during transition.

06

Left future changes with a clearer answer to “where does this rule belong?”

RESULT

The visible workflow stayed familiar. The change surface underneath became much clearer.

RULE OWNERSHIPDEFINED

Important calculations had a clearer application-level home.

REUSECENTRALIZED

Callers reused one implementation instead of reproducing the same decision.

USER BEHAVIORPRESERVED

The refactor targeted implementation structure rather than forcing a redesigned workflow.

FUTURE CHANGESAFER

Developers had fewer layers to inspect before changing an important rule.

ABOUT THIS ENGINEERING EXAMPLE

This example is based on production PHP/Laravel refactoring work. Proprietary calculation details are simplified, while the architectural concern and extraction strategy reflect the real implementation work.