Paradaux
1

Autocomplete firms in commands (either member or online depending on command)

Re-add firm autocomplete in commands, in two forms: (1) all online/active firms (e.g. for paying into them), and (2) the firms the player is a proprietor or employee of.

Technical notesFirmPlayerResolver exists and is wired in CommanderModule, but it resolves players (FirmPlayer), not firms. Firm args are plain @Arg("firm") String resolved at runtime via FirmService.getFirmByNameOrId, so firms get no tab-completion. Add a FirmResolver implements ParameterResolver<Firm> (mirroring FirmPlayerResolver), bound in CommanderModule, with sender-aware suggestions() — all firms for pay-into, listOwnedOrMemberFirms(sender) for owned-firm contexts.

Comments

tesks · Jun 4, 2026, 9:56 AM

Code contextFirmPlayerResolver exists and is wired in CommanderModule, but it resolves players (FirmPlayer), not firms. Firm args are plain @Arg("firm") String resolved at runtime via FirmService.getFirmByNameOrId, so firms currently get no tab-completion.

Approach: add a FirmResolver implements ParameterResolver<Firm> (mirroring FirmPlayerResolver), bound in CommanderModule, with sender-aware suggestions() — all firms for pay-into contexts, listOwnedOrMemberFirms(sender) for owned-firm contexts (the two forms the description asks for).

tesks · Jun 5, 2026, 7:10 AM

Design (per the requested approach). Mirror FirmPlayerResolver but cache-backed. Hibernia resolves suggestions by parameter type (@Arg has no per-arg suggestion hook), so the "two forms" become two resolver types over one shared in-memory FirmSuggestionCache:

  • FirmName (default) → suggestions = firms the sender owns or is employed by (FirmService.listOwnedOrMemberFirms(uuid), cached per-player with a short TTL).
  • OnlineFirmName → suggestions = firms with an employee/proprietor online (union the cached firm-lists of Bukkit.getOnlinePlayers()).
  • Both resolve() accept any token (thin record FirmName(String value)), so a firm that matches neither form but still exists is usable — existence is checked downstream by the command's getFirmByNameOrId.

Cache: a @Singleton holding allFirmNames (refreshed on an interval from listAllActiveFirms) + a per-player firm-name cache (TTL ~30s via listOwnedOrMemberFirms); JDK ConcurrentHashMap (no Guava collections per repo rules). Register both resolvers in CommanderModule; migrate the relevant firm commands' String firmName args to FirmName/OnlineFirmName and call .value(). Tests for the cache + resolvers to hold the ≥95% gate. (Bonus: the resolver naturally prefers active firms, dovetailing with PAR-87.)

tesks · Jun 5, 2026, 7:30 AM

Implemented on develop (commit 3162fc9).

Design — two firm-name argument types backed by a short-TTL (30s) in-memory cache (FirmSuggestionCache) so tab-completion never hits the DB per keystroke:

  • FirmName (default): suggests firms the sender owns or is employed by; console falls back to all active firms.
  • OnlineFirmName (cross-firm targets): suggests firms with an employee or proprietor currently online — the union of each online player's firms, composed in the resolver so Bukkit stays out of the cache (keeps it unit-testable).

Either resolver still accepts any existing firm on resolve — suggestions are hints, not a whitelist, matching the requested third form.

Wiring — every firm-name command arg across Account / Misc / Firm / Request / Role / Staff / Tax now uses the right type. OnlineFirmName is used for pay business <firm> <target> and account pay business <firm> <accountId> <target> targets. firm create <name> left raw (completing existing names for a new firm would be wrong).

Bonus fix — caught a latent overflow in activeFirmNames(): the MIN_VALUE sentinel made now - activeAt overflow negative, so the first load never triggered (would have shipped an always-empty active-firm pool). Now guarded explicitly; covered by FirmSuggestionCacheTest.

Coverage gate (≥95%) green; 325 unit tests pass. Resolvers/commands are coverage-excluded by design; FirmSuggestionCache (in services/) is fully tested.

Activity

  • ParadauxIO linked a commit — Commit 3162fc9 — Add firm-name tab-completion resolvers (PAR-13)Jun 7, 2026, 2:49 PM
  • ParadauxIO changed status to Status → DoneJun 7, 2026, 2:49 PM
  • ParadauxIO linked a pull request — PR #6 merged — Release: develop → mainJun 7, 2026, 2:49 PM
  • ParadauxIO linked a pull request — PR #6 open — Release: develop → mainJun 7, 2026, 12:36 AM
  • ParadauxIO linked a pull request — PR #6 open — Release: develop → mainJun 6, 2026, 11:49 PM
  • ParadauxIO linked a pull request — PR #6 open — Release: develop → mainJun 6, 2026, 12:44 PM
  • ParadauxIO linked a pull request — PR #6 open — Release: develop → mainJun 6, 2026, 11:17 AM
  • ParadauxIO linked a pull request — PR #6 open — Release: develop → mainJun 6, 2026, 11:11 AM
  • ParadauxIO linked a pull request — PR #6 open — Release: develop → mainJun 5, 2026, 12:35 PM
  • tesks commentedJun 5, 2026, 7:30 AM
  • tesks changed status to Status → Pending ReleaseJun 5, 2026, 7:29 AM
  • ParadauxIO linked a commit — Commit 3162fc9 — Add firm-name tab-completion resolvers (PAR-13)Jun 5, 2026, 7:29 AM
  • tesks commentedJun 5, 2026, 7:10 AM
  • tesks changed status to Status → In ProgressJun 5, 2026, 7:10 AM
  • tesks description: Description updatedJun 4, 2026, 10:01 AM
  • tesks commentedJun 4, 2026, 9:56 AM
  • tesks assigned Assigned to rianJun 4, 2026, 9:26 AM