Part of PAR-175 (firm sales commands). Parity with legacy /pb sales toggle <firm> + the chestshop-(buy|sale)-notify broadcasts.
When a ChestShop sale completes for a firm-owned shop, notify the firm's online staff in-game (e.g. "Steve bought 64x Cobblestone for $128 at Costco"), toggleable per firm.
Build on existing infra (verified):
net.democracycraft.business.services.FirmNotificationService (PAR-94, shipped) — notifyFirm(int firmId, String messageKey, Object... placeholders) / notifyFirmExcept(int firmId, UUID excluded, …), backed by FirmStaffService.getOnlineEmployees(...). Add a business.notify.sale.* message block.MarketListener.onTransaction calls MarketApi.recordSale but re-publishes nothing. This issue must first add a sale hook: either a new Bukkit event fired from MarketListener (carrying firmId/item/qty/price/customer) or a Treasury sale-feed callback. Resolve shop_firm_id → firm for routing. Do not poll the DB like the legacy plugin.firm_properties key-value table (firm_id, key, value, type, deleted_at) via a small service wrapper — avoids a firm table migration + Firm model/mapper change. Owner-gated toggle command (hibernia @Route("sales toggle <firm>")).Spam control (better than legacy): batch/rate-limit bursts (a busy shop can sell many times/min) — coalesce into a periodic digest or throttle per shop; cadence configurable.
Access: owner/admin for the toggle. Depends on: PAR-94 (done) + the new sale hook above.