PAR-112
0
FirmBalanceTaxListener bypasses the service layer (injects FirmAccountsMapper + holds tax-allocation logic)
Pending ReleaseLowUnassignedBusinessImprovement
Layering-rule violation found in a sweep against the new "entrypoint → service → mapper" rule (CLAUDE.md). Not a functional bug — behaviour is correct; this is maintainability/tech-debt.
File: business-rian/src/main/java/net/democracycraft/business/listeners/FirmBalanceTaxListener.java
Violations:
- The listener injects
FirmAccountsMapperdirectly (field at line 42, constructor param 50) and callsfirmAccountsMapper.listAccountsByFirm(firm.getFirmId())at line 112 — an event listener reaching the persistence layer, skipping the service layer. Every other DB read in this plugin goes through a*Service. - The per-account tax allocation algorithm lives in the listener:
buildFirmCollections(lines 109–174) does proportional split, 2dp settlement, and largest-account drift correction. That's business logic that belongs in a service, not an event handler.
Fix: expose account listing through a service (a read method on FirmAccountService/FirmService) and move the tax-collection computation into a FirmBalanceTaxService (interface + impl under services/, bound in BusinessModule). The listener should shrink to: on TaxCycleEvent (WEEKLY, enabled) → call the service → log the batch result.
Discovered alongside the CLAUDE.md layering-rules addition; filing for a later pass.
Comments
No comments yet.
Activity
- tesks changed status to Status → Pending Release
- tesks changed status to Status → In Progress
- paradaux description: Description updated
- paradaux changed status to Status → Planned
- tesks created the issue