hadi-bakhshi-portfolio-icon
Back to work

system.case

Razeman

An ERP-style internal platform unifying HR, finance, and operations into one modular system, replacing a fragmented landscape of disconnected tools across a holding company.

9 modules · thousands of users

ASP.NET CoreSQL ServerRedisReactEF Core

My role: Owned full-cycle design and development — architecture, backend, database design, and frontend — from initial module boundaries through production deployment.

UsersThousandsReactShared shellHostASP.NET CoreHRModuleFinanceModuleOps+6 modulesSQLSystem of recordRedisHot paths

Problem

A holding company ran day-to-day work across disconnected tools for HR, finance, and operations. Staff re-entered the same data in multiple systems, reporting required manual reconciliation, and each new process meant another siloed app. Leadership needed one platform that could grow module by module without rewriting the whole stack every time a department joined.

Constraints

Architecture

Razeman is a modular ASP.NET Core platform backed by SQL Server, with Redis for session and hot-path caching. Each organizational domain ships as a module with its own bounded context — shared infrastructure handles authentication, authorization, and cross-cutting concerns, while module APIs expose domain operations to a React frontend. New modules plug into the same host without forcing a rewrite of existing ones, keeping deployment and ownership boundaries clear as the platform grows.

Key decisions

Modular monolith over premature microservices

Nine domains shared strong transactional needs and a single ops team. A modular monolith kept deployment simple and cross-module workflows coherent, while still enforcing module boundaries so domains could evolve independently — avoiding the operational cost of nine services before the product had proven itself.

Ship modules independently, share the platform

HR, finance, and operations did not migrate together. The platform core (identity, permissions, shared UI shell) landed first; each module followed when that department was ready. That sequencing cut big-bang risk and let early modules validate patterns for later ones.

One source of truth per domain

Instead of syncing departmental tools forever, each module became the system of record for its domain. Cross-module reads go through explicit APIs rather than shared tables, so finance does not quietly depend on HR schema internals.

Redis for hot paths, SQL Server for truth

Operational dashboards and session-heavy flows needed low latency without compromising durable records. Redis absorbs repeated reads; SQL Server remains the authoritative store for audits, payroll-adjacent data, and reporting.

Trade-offs

Modular monolith vs microservices

A single deployable unit is simpler to operate and reason about, but a poorly bounded module can still couple the whole release. Mitigated with clear module ownership and avoiding shared database tables across domains.

Phased migration vs full cutover

Running old tools alongside Razeman during rollout meant temporary dual entry for some teams. Accepted the short-term friction to avoid a holding-wide freeze while nine modules were unfinished.

Impact