Layering-rule violation found in a sweep against the "controller → service → mapper" rule (CLAUDE.md). Not a functional bug — behaviour is correct; this is maintainability/tech-debt.
File: treasury-rest-api/src/main/java/io/paradaux/treasuryrestapi/controller/AccountController.java
Violation: the controller injects AccountMapper and FirmMapper as fields (lines 33–34) and calls them directly:
getBalance → accountMapper.findBalance(accountId) (line 57)getAccountByPlayer → firmMapper.findPlayerUuidByName(...) (96), accountMapper.findPersonalAccountIdByOwner(...) (103), firmMapper.findPlayerNameByUuid(...) (109)The name→UUID→accountId→name resolution in getAccountByPlayer is multi-step orchestration sitting in the controller. (The getTransactions endpoint is already correct — it goes through TransactionService.)
Fix: move the mapper calls behind the service layer — a balance lookup on AccountService and a by-player resolver on AccountService/FirmService — so the controller only injects services, maps DTOs, and translates ApiException. Mirrors the TransactionService pattern already used in the same class.
Discovered alongside the CLAUDE.md layering-rules addition; filing for a later pass.