feat: add Max Battle (Dynamax) tracking alarms#137
Conversation
Code Review: PR !137 — Max Battle (Dynamax) Tracking AlarmsGrade: B+ (Approved with Conditions)
Critical Issues (2) — Must Fix Before Merge
Major Issues (4) — Should Fix
What's Good
VerdictApproved with conditions. Wire up the two TODO dialog stubs (C1, C2) and fix the edit dialog title (M4), then this is merge-ready. Full report saved as |
Full-stack implementation of a new alarm module for Dynamax/Gigantamax Max Battle tracking, proxied through PoracleNG's maxbattle CRUD API. Backend: - MaxBattle, MaxBattleCreate, MaxBattleUpdate models (9000 sentinel for "any") - IMaxBattleService/MaxBattleService with delete-then-create update pattern (PoracleNG maxbattle is insert-only, no upsert) - MaxBattleController with 8 REST endpoints at /api/maxbattles - Dashboard, Cleaning, AutoMapper, DI, and SettingsMigration integration - 26 new xUnit tests (service + controller + mapping) Frontend: - MaxBattle TypeScript models and MaxBattleService - List component with card grid, filter pills (level, move, gmax, form) - Add dialog with By Level / By Pokemon tabs, Gigantamax toggle - Edit dialog with settings and delivery tabs - Route (/max-battles), sidenav entry, dashboard card - Cleaning integration, admin settings (disable_maxbattles), help section - 7 Jest service tests Closes #118
- Connect openAddDialog() and editMaxBattle() to their dialog components - Fix edit dialog title to use MasterDataService.getPokemonName() instead of raw ID - Add "Any Level" (9000) option to edit dialog level select - Make levels arrays readonly in both add and edit dialogs - Fix ESLint import ordering
d56e64f to
95ea47e
Compare
- Fix duplicate "Any Level" in edit dialog (hardcoded + array both had 9000) - Add move name resolution to list filter pills via SettingsService/PoracleConfig - Add error logging to delete-then-create distance updates for atomicity recovery - Inject ILogger<MaxBattleService> for structured error logging - Fix line ending in cleaning.service.ts
Researched PoracleNG's maxbattle bot command and matching engine to
ensure the web UI mirrors how Poracle actually works.
Key fixes:
- Use correct battle levels: 1-5 (Dynamax), 7 (Gigantamax), 8 (Legendary
Gigantamax). No level 6 exists in PoracleNG.
- Add descriptive level labels matching PoracleNG util.json ("1 Star",
"5 Star (Legendary)", "Gigantamax", "Legendary Gigantamax")
- Remove standalone gmax toggle — gmax is inherent in levels 7/8 (level > 6
auto-sets gmax=1). A gmax toggle on levels 1-5 would never match.
- Remove evolution field from UI — always 9000, never used in PoracleNG
- Remove station_id field from UI — bot command doesn't expose it
- Remove move filter from add dialog — bot uses it rarely, keep UI simple
- By Pokemon tab: set level=9000 (any) matching bot behavior, remove level
selector that doesn't apply to pokemon-based tracking
- Add "Select All" button for level checkboxes (mirrors bot's "everything")
- Show auto_awesome icon for Gigantamax levels on alarm cards
- Simplify edit dialog: level-based alarms show level selector, pokemon-based
alarms show info text (no editable level)
- Derive gmax flag from level when creating alarms (levels 7/8 = gmax=1)
…mplates exist PoracleNG may not have maxbattle DTS templates configured. When no templates are found for an alarm type, the selector now shows template "1" (PoracleNG's default) instead of an empty dropdown. Also adds maxbattle to the preview color map.
Mirrors PoracleNG's !maxbattle <pokemon> gmax command behavior. When tracking a specific Pokemon, users can now toggle "Gigantamax only" to only receive notifications when that Pokemon appears in Gigantamax battles (levels 7/8), rather than any Max Battle tier. - Add gmax toggle to pokemon-based add dialog (By Pokemon tab) - Add gmax toggle to pokemon-based edit dialog (Settings tab) - For level-based alarms, gmax remains auto-derived from the level - Verified against PoracleNG's matching engine: gmax=0 matches all, gmax=1 requires battle_level > 6
Query the scanner DB's station table for distinct battle_pokemon_id values to limit the Pokemon selector in the Max Battle add dialog to species that have actually appeared in Max Battles. - Add RdmStationEntity mapping the station table (battle_pokemon_id only) - Add Stations DbSet to RdmScannerContext - Add GetMaxBattlePokemonIdsAsync() to IScannerService/RdmScannerService - Add GET /api/scanner/max-battle-pokemon endpoint (returns [] if scanner not configured — graceful fallback, no 404) - Add getMaxBattlePokemonIds() to frontend ScannerService - Add allowedIds input to PokemonSelectorComponent — when set, filters the Pokemon list to only those IDs (plus ID 0 for "All Pokemon") - Wire up in Max Battle add dialog: fetches IDs on init, passes to selector - Guards: scanner DB optional, endpoint returns empty on error, null allowedIds means "show all Pokemon" (no restriction)
Group battle encounter types together (Raids → Max Battles) instead of burying Max Battles at the bottom of the alarm list. New order reflects usage frequency and logical grouping: Pokemon → Raids → Max Battles → Quests → Invasions → Lures → Nests → Gyms → Fort Changes
Updated Code Review: PR !137 — Max Battle (Dynamax) Tracking AlarmsGrade: A (Approved)All critical and major issues from the initial review have been resolved across 7 follow-up commits. Status of All Previously Identified Issues
Additional Improvements Since Initial Review
Final Checks (All Passing)
Commit Summary (8 commits)
Verdict: APPROVEDNo remaining issues. Feature is complete, well-tested, and aligned with PoracleNG bot command semantics. Ready to merge. |
GH Pages (MkDocs): - features/alarms.md: Add Max Battle alarm type, filters table, battle levels reference, insert-only API note, scanner-based Pokemon filter - configuration/site-settings.md: Add disable_maxbattles setting - architecture/poracleng-proxy.md: Add maxbattle to proxy table with insert-only warning - architecture/backend.md: Add MaxBattleService to service listing - architecture/frontend.md: Add max-battles module to structure - index.md: Update features list to include Max Battles and Fort Changes In-app help: - Fix help section to use correct levels (1-5, 7, 8 — not 1-6) - Describe By Level and By Pokemon modes accurately - Document Gigantamax-only toggle behavior - Mention Select All and scanner-based filtering
Final Review: PR !137 — All Checks PassStatus: APPROVED
Commits (9)
Post-Merge Infrastructure Changes Applied
Related Issues Created
|
Summary
Full-stack implementation of a new alarm module for Dynamax/Gigantamax Max Battle tracking, proxied through PoracleNG's
maxbattleCRUD API. Closes #118.disable_maxbattles), help section, 7 Jest testsUpdateAsyncuses delete-then-create. Sentinel value9000= "any" for pokemon_id/level/move/evolution (differs from monster's0). Gmax field (0/1) for Gigantamax filtering.New files (19)
MaxBattle.cs,MaxBattleCreate.cs,MaxBattleUpdate.csIMaxBattleService.cs,MaxBattleService.csMaxBattleController.csMaxBattleServiceTests.cs,MaxBattleControllerTests.csmax-battle.service.ts,max-battle.service.spec.tsmax-battle-list.component.*,max-battle-add-dialog.component.*,max-battle-edit-dialog.component.*(9 files)Modified files (20)
DI registration, AutoMapper, DashboardCounts, DashboardService, CleaningService, CleaningController, SettingsMigrationService, models/index.ts, app.routes.ts, app.ts (sidenav), dashboard component, cleaning component/service, admin-settings, help-sections, and existing test files.
Test plan
dotnet build— 0 errors, 0 warningsdotnet test— 589 passed, 0 failedng build --configuration production— successnpm run lint— all files passnpx prettier --check— formattednpx jest— 468 passed, 0 faileddisable_maxbattles, verify nav item hides