Redesigning leave management so it’s hard to get wrong
Rebuilt a fragile, tangled HRM module into a strategy-driven design where a new leave type is one declarative policy file.
- 4 → 1
- files touched per new leave type
- 6 days
- from broken to redesigned
- 3
- clean layers: processor, logic, policy
The problem
Leave rules had been hardcoded into HRM with no clear design. Accrual, lapse, validation and payment logic were intertwined across central files. When a junior developer refactored it for API work, it broke.
Approach
- 01
Find the exact friction point
Instead of designing top-down, I started at the processor and located where rules and mechanics got tangled.
- 02
Separate layers under a strict type system
Split the module into processor, processing logic and policy, with types strict enough that invalid combinations fail early.
- 03
Extract reusable strategies
Accrual, lapse and payment became interchangeable strategies. A policy file now describes what a leave type wants, not how to compute it.
Outcome
Adding a leave type no longer needs edits to four central files, just one policy. Junior developers can extend the module safely.
What I took awayRefactor bottom-up. Build from the processor up to the policy and the pattern reveals itself. Top-down designs tend to be wrong or over-engineered.