An already-disbanded firm can be disbanded again, re-running the disband flow and spamming chat with the broadcast.
Technical notes — FirmServiceImpl.disbandFirm has no isArchived() guard, and FirmMapper.getFirmByName/getFirmById return rows regardless of is_archived. Guard disbandFirm with an already-archived check (and surface "firm already disbanded" in FirmCommands.disband) to make disband idempotent; optionally exclude archived firms from the name/id lookups. Confirmed via code read.
Fixed on develop (business-rian @ 0c6024c).
Change — disband is now idempotent:
FirmServiceImpl.disbandFirm throws BadCommandException("Firm already disbanded") when firm.getArchived() is true (before any account/archive work).FirmCommands.disband short-circuits with a new localized message business.firm.disband.already before the broadcast fires, so a repeat disband no longer spams chat.Left the getFirmByName/getFirmById lookups returning archived rows (other read paths — info views, explorer — rely on that); the explicit archived guard is the surgical fix.
Added unit test disbandFirm_alreadyArchived_throws (asserts no re-archive / no account work). FirmServiceImplTest green under JDK 21.
Code context —
business-rian/…/services/impl/FirmServiceImpl.disbandFirmhas noisArchived()guard, andFirmMapper.getFirmByName/getFirmByIdreturn rows regardless ofis_archived, so/firm disband <name>can be re-run on an already-disbanded firm — re-running the archive/withdraw flow and re-broadcasting the disband message (the chat spam).Fix: guard
disbandFirmwith an already-archived check (surface "firm already disbanded" inFirmCommands.disband) to make disband idempotent; optionally exclude archived firms from the name/id lookups. Confirmed via code read — dropped theUnconfirmedlabel.