Paradaux

PAR-282

0

[chestshop] Migrate to a service/DAO architecture (strangler-fig away from the event-bus pipelines)

Pending ReleaseUnassignedChestShop

ChestShop is upstream's "Bukkit events as internal middleware" design: a single buy/sell is orchestrated across ~15 listeners coordinated only by @EventHandler(priority) ordering and a giant mutable PreTransactionEvent/TransactionEvent bag — no atomic boundary (ADT-4), untestable, the lone outlier vs. the monorepo's entrypoint→service→DAO. Persistence is SQLite/ORMlite via static God-classes (NameManager, ItemDatabase).

Strangler-fig migration (each phase ships independently, plugin works throughout). Storage stays SQLite for now behind storage-agnostic DAO interfaces (swap to shared MariaDB later = a new impl).

  • Phase 0 (done, PoC): Stood up the seam — a ChestShopModule (Guice), ItemCodeRepository (DAO interface) + SqliteItemCodeRepository (impl over the ORMlite items.db), and an ItemCodeService that owns the serialise/find-or-create/metadata-migration logic. Deleted the ItemDatabase God-class; callers go through ChestShop.itemCodes(). Faithful refactor (item codes byte-identical). Enables cleanly.
  • Phase 1 (next): TransactionService.execute(...) owning money+items+record atomically, collapsing the post-transaction listener chain.
  • Phase 2: ShopService for creation/removal. Phase 3: delete the dead event scaffolding. Account domain (NameManager/users.db) gets the same DAO/service treatment.

Resources

Comments

tesks · Jun 26, 2026, 6:30 PM

Phase 2 done (commit 7d0dc3f): account domain migrated. NameManager static God-class split into AccountRepository + SqliteAccountRepository (users.db persistence behind a storage-agnostic contract) and AccountService (@Singleton: caches, get-or-create, shortened-name allocation, admin/server-economy accounts, canUseName, load()), reached via ChestShop.accounts(). NameManager is now a thin Listener (the AccountQuery/AccountAccess events stay — Treasury integration points) plus a delegating static facade so the ~25 callers compile unchanged. Added AccountServiceTest (row-count + shortened-name disambiguation now unit-testable over a fake repo). Builds + tests green.

Remaining: ShopService for creation/removal (Phase 2-shops), migrate the ~25 callers off the NameManager facade and delete it, then delete the dead event scaffolding (Phase 3).

tesks · Jun 26, 2026, 7:28 PM

Phase 2-shops done (commit 2f8e28f): ShopService extracted. Shops have no ChestShop-owned persistence (sign+chest world state; only DB is Treasury's external MarketApi), so no repository — just a service owning the lifecycle money logic that was embedded in listeners: chargeCreationFee(player, signLines) (fee + server-economy credit + message, returns whether creation proceeds) and refundOnRemoval(destroyer, sign) (refund + server-economy debit + message). CreationFeeGetter and ShopRefundListener are now thin entrypoints delegating via ChestShop.shops(). Money still flows through the Currency*Event integration points. The 12-listener creation-validation pipeline + market sync stay as events (deliberately — integration/coordination, Phase 3). Builds + tests green.

Remaining: migrate the ~25 callers off the NameManager static facade and delete it (split its 2 @EventHandlers into a thin AccountListener); then Phase 3 — assess collapsing the internal-only validation scaffolding (PreShopCreationEvent pipeline) now that the money logic is out.

tesks · Jun 26, 2026, 7:40 PM

NameManager facade deleted (commit 5d68858): account-domain migration complete. The ~25 callers across the economy/sign-creation/removal/command paths now call AccountService directly via ChestShop.accounts(); the two account @EventHandlers moved to a thin AccountListener (registered in place of the old NameManager listener). Pure delegator removal, no behaviour change. Builds + tests green.

Remaining: Phase 3 — assess whether the now internal-only shop-creation validation scaffolding (PreShopCreationEvent + the 12 preshopcreation listeners) is worth collapsing into the ShopService, now that the money logic is out and the genuine integration events (AccountQuery/AccountAccess, Currency*, ShopCreated/Destroyed→Market) are clearly separated.

Activity

  • ParadauxIO linked a pull request — PR #2 open — Last major release
  • ParadauxIO linked a pull request — PR #2 open — Last major release
  • ParadauxIO linked a pull request — PR #2 open — Last major release
  • ParadauxIO linked a pull request — PR #2 open — Last major release
  • ParadauxIO linked a pull request — PR #2 open — Last major release
  • ParadauxIO linked a pull request — PR #2 open — Last major release
  • ParadauxIO linked a pull request — PR #2 open — Last major release
  • ParadauxIO linked a commit — Commit 0e659ef — Migrate logging to slf4j (@Slf4j); drop the shop file-log (PAR-309)
  • ParadauxIO linked a commit — Commit 30b408e — Refresh the ChestShopModule binding comment: the graph is fully acyclic (PAR-282)
  • ParadauxIO linked a commit — Commit 843ef1e — Dissolve the AccountService<->EconomyService cycle via a leaf BusinessAccountService (PAR-282)
  • ParadauxIO linked a commit — Commit 272e23f — Split ShopBlockUtil into a pure util + ShopBlockService, dissolving the ChestShopSign cycle (PAR-282)
  • ParadauxIO linked a commit — Commit e66ef05 — Split InventoryUtil into a pure util + InventoryService (PAR-282)
  • ParadauxIO linked a commit — Commit c17e659 — Split MaterialUtil into a pure util + MaterialService (PAR-282)
  • ParadauxIO linked a commit — Commit 6ee9d39 — Break the MaterialUtil<->InventoryUtil DI cycle: extract ShowItemHook (PAR-282)
  • ParadauxIO linked a commit — Commit 4564558 — Collapse small chestshop packages into model/ + utils/ (PAR-282)
  • ParadauxIO linked a commit — Commit 296eecf — Flatten the chestshop listeners package (PAR-282)
  • ParadauxIO linked a commit — Commit 107a2de — Port native Nexo/ItemsAdder custom-item support into ChestShop (PAR-291)
  • ParadauxIO linked a commit — Commit 44f218f — Delete the static Properties config mirror; route all config through injected ChestShopConfiguration (PAR-282)
  • ParadauxIO linked a commit — Commit f2ff580 — Move AdminBypass to permission/ and de-static TransactionService's singleton state (PAR-282)
  • ParadauxIO linked a commit — Commit 3fbbf7b — Re-home the economy providers and the persistence-row POJOs (PAR-282)
  • ParadauxIO linked a commit — Commit 0d2686c — Reorganise misleading names and relocate non-root classes (PAR-282)
  • ParadauxIO linked a commit — Commit 49f245c — Rename the events/ carriers to context/*Context — they aren't Bukkit events (PAR-282)
  • ParadauxIO linked a commit — Commit 492ce2a — Remove dead/deprecated code left after the service/DAO migration (PAR-282)
  • ParadauxIO linked a commit — Commit c6ed176 — Delete the static ChestShop.<service>() service-locator surface (PAR-282)
  • ParadauxIO linked a commit — Commit 3a4110a — Move the DB-backed item naming into ItemCodeService; MaterialUtil is now pure (PAR-282)
  • ParadauxIO linked a commit — Commit e143839 — Document MaterialUtil's item-code locator as the one principled DI boundary (PAR-282)
  • ParadauxIO linked a commit — Commit 0d0270a — Drop two more MaterialUtil locator hops: parseMaterial round-trip + Show message (PAR-282)
  • ParadauxIO linked a commit — Commit 5f214e5 — Move sign-format validation onto ChestShopSign; drop the isValid locator (PAR-282)
  • ParadauxIO linked a commit — Commit 65a2d43 — Move ChestShopSign's account predicates into AccountService (PAR-282)
  • ParadauxIO linked a commit — Commit b683825 — Fold ItemUtil into ItemService; inject the market helpers (PAR-282)
  • ParadauxIO linked a commit — Commit 52f7930 — Make Security an injected ProtectionService facade (PAR-282)
  • ParadauxIO linked a commit — Commit 9ce9422 — Inject the framework Message bean into ChestShop's DI-managed classes (PAR-282)
  • ParadauxIO linked a commit — Commit b123ab3 — Register ChestShop listeners via the framework ListenerManager (PAR-282)
  • ParadauxIO linked a commit — Commit 770803b — Inject services into the entrypoint listeners instead of the static locator (PAR-282)
  • ParadauxIO linked a commit — Commit c63665f — Fold the vestigial static Economy facade into EconomyService (PAR-282)
  • ParadauxIO linked a commit — Commit cfb18c9 — Delete the Permission enum; gate commands with @Permission directly (PAR-282)
  • ParadauxIO linked a commit — Commit 12eb1a8 — Inject services into the ChestShop commands instead of the static locator (PAR-282)
  • ParadauxIO linked a commit — Commit 37617c8 — Inject collaborators into the ChestShop services instead of the static locator (PAR-282)
  • ParadauxIO linked a commit — Commit bcd1315 — Migrate ChestShop persistence from ORMlite to MyBatis (still SQLite) (PAR-282)
  • tesks changed status to Status → Pending Release
  • ParadauxIO linked a commit — Commit a575b01 — Subsume the item-resolution pipeline into ItemService; delete the item event carriers (PAR-282)
  • ParadauxIO linked a commit — Commit a3181ec — Subsume the shop-creation validation pipeline into ShopService (PAR-282/PAR-288)
  • ParadauxIO linked a commit — Commit 05a870d — Subsume the pre-transaction validation pipeline into TransactionService (PAR-282/PAR-288)
  • ParadauxIO linked a commit — Commit f88f658 — Subsume the post-transaction reaction listeners into TransactionService (PAR-282)
  • ParadauxIO linked a commit — Commit d6f3117 — Subsume the post-shop-creation/removal reaction listeners into ShopService (PAR-282)
  • ParadauxIO linked a commit — Commit b33fe59 — Subsume the info listeners into InfoService; drop the ItemInfo/ShopInfo event carriers (PAR-282)
  • ParadauxIO linked a commit — Commit 09f5c46 — Close the highest-risk test-coverage gaps (ADT-50)
  • ParadauxIO linked a commit — Commit 5d68858 — Delete the NameManager facade; callers use ChestShop.accounts() (PAR-282)
  • ParadauxIO linked a commit — Commit 2f8e28f — Extract a ShopService for the shop-lifecycle money logic (PAR-282)
  • ParadauxIO linked a commit — Commit 7d0dc3f — Migrate the ChestShop account domain to a repository/service (PAR-282)
  • tesks commented
  • tesks commented
  • tesks commented
  • ParadauxIO linked a commit — Commit cd3a329 — Phase 1: ChestShop TransactionService owns the atomic goods+money legs (PAR-282)
  • ParadauxIO linked a commit — Commit a6254e3 — Phase 0: introduce ChestShop service/DAO layer for item codes (PAR-282)
  • tesks created the issue