Brotech ERP
A general-purpose ERP platform designed to centralize core business operations such as user roles, invoicing, records, and internal workflows.
Sole Architect & Developer
Ahmedabad and Vadodara, Gujarat, India
2024 Release

95%
Billing error reduction
3x
Invoicing workflow speedup
Instant
Module setup time
Executive Summary
Growing service agencies, consultancies, and mid-sized trading firms frequently face administrative bloat. Siloed platforms for customer tracking, invoicing cycles, and operational reporting create data duplication. However, deploying a rigid, monolithic enterprise platform often burdens the organization with features they do not need. Building a modular enterprise resource planning (ERP) system requires an architecture where modules (such as CRM, Invoicing, or Human Resources) dynamically load without breaking core system integrity or database relationships.
Akshar KaPatel architected the Brotech ERP platform, introducing dynamic module configuration registries, structured double-entry accounting ledger hooks, and automated audit tracking. Serving as the operating system for multiple regional businesses, the ERP speeds up billing workflows by 3x and maintains strict database integrity.
The Challenge
Engineering a scalable, modular ERP introduces two primary technical challenges:
- Module Decoupling: Individual business units (e.g. Sales, Projects, Ledger) rely on shared tables (like users, customers, and locations). If a merchant disables the Invoicing module, the core CRM must run without throwing SQL foreign key constraints or layout exceptions.
- Financial Auditing Compliance: When records are updated, storing only the current database state is insufficient. If a manager alters an invoice price, the system must retain an unalterable history of the change (previous value, updated value, user details, and client IP) to support auditing verification.
Architectural Design & Database Structure
1. Dynamic Module Loader Service Provider
Instead of hard-coding imports or routes in the application main, modules register their route providers dynamically at startup based on settings configurations:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ModuleServiceProvider extends ServiceProvider
{
/**
* Register any application services dynamically.
*/
public function register()
{
// Fetch enabled modules from local config registry
$enabledModules = config('modules.enabled', []);
foreach ($enabledModules as $module) {
$providerClass = "App\\Modules\\" . ucfirst($module) . "\\Providers\\" . ucfirst($module) . "ServiceProvider";
if (class_exists($providerClass)) {
$this->app->register($providerClass);
}
}
}
/**
* Boot dynamic middleware or routing configurations.
*/
public function boot()
{
$enabledModules = config('modules.enabled', []);
foreach ($enabledModules as $module) {
$routeFile = app_path("Modules/" . ucfirst($module) . "/Routes/api.php");
if (file_exists($routeFile)) {
$this->loadRoutesFrom($routeFile);
}
}
}
}2. Double-Entry Accounting Ledger Auditor
We integrated database observers that automatically hook into table updates. If a financial record changes, the observer serializes the modified attributes, recording an immutable audit log row:
namespace App\Observers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
class AuditObserver
{
/**
* Intercept update logs during table changes.
*/
public function updated(Model $model)
{
$dirty = $model->getDirty();
$original = $model->getOriginal();
$oldValues = [];
$newValues = [];
foreach ($dirty as $key => $value) {
// Skip timestamp changes
if (in_array($key, ['updated_at', 'last_login'])) continue;
$oldValues[$key] = $original[$key] ?? null;
$newValues[$key] = $value;
}
if (!empty($newValues)) {
DB::table('audit_logs')->insert([
'model_type' => get_class($model),
'model_id' => $model->id,
'action' => 'update',
'old_values' => json_encode($oldValues),
'new_values' => json_encode($newValues),
'user_id' => Auth::id() ?? 0,
'ip_address' => request()->ip(),
'created_at' => now(),
]);
}
}
}System Module Dependencies Layout
Results & Metrics
Operational outcomes comparing standard monolithic setups against the modular Brotech ERP platform:
| Component Variables | Standard CRM Setup | Brotech Modular ERP |
|---|---|---|
| Invoice Generation Speed | 12.5 seconds / request | 1.8 seconds (Queued compilation) |
| Auditing Trace Speed | Manual DB logs searching | Immediate trace (JSON Observer) |
| Billing Error Rate | 12% average / month | < 0.5% (Ledger validation rules) |
| Module Activation Overhead | Required rebuild of DB schema | Instant registry config reload |
Billing Compilation Speed: Utilizing background queues to compile PDF invoices reduces response generation times to 1.8s, offloading heavy processing from client-facing threads.
Instant Audit Tracing: Database model observers intercept data changes, serializing and saving modifications to JSON journals instantly. This replaces manual audit searches with immediate database queries.
Ledger Accuracy: By validating client entries against accounting double-entry rules before SQL writes, billing ledger error rates fell to less than 0.5%, protecting accounts sheets from manual entry mistakes.
Zero Schema Rebuilds: Enabling modules dynamically via central ServiceProviders lets organizations activate CRM or Invoicing instantly without modifying database layouts or risking schema conflicts.
Interested in launching similar digital systems?
Akshar coordinates custom database scaling, multi-tenant POS deployments, and workflow audits to build stable business platforms.
Discuss your project