Review: Analytics dashboard: find winning conditions

review-1841-2026-07-09 Review

review needs-refinement

Verdict: NEEDS_REFINEMENT

Template Completeness

  • [x] Type -- Feature
  • [x] Lineage
  • [x] Repo
  • [x] User Story
  • [x] Context
  • [x] File Targets
  • [x] Feature Flag -- "None" (replaces existing dashboard, acceptable)
  • [x] Acceptance Criteria
  • [x] Test Expectations
  • [x] Constraints
  • [x] Checklist
  • [x] Related

Traceability

  • [x] story:bot-strategy label -- "Bot operator identifies winning conditions"
  • [ ] story note MISSING -- story-bots-bot-strategy listed as "(pending)" on project-botfire user-stories section. [SCOPE] Create story note story-bots-bot-strategy.
  • [x] arch:bots label -- bots architecture component
  • [ ] arch note MISSING -- search for arch-bots returned no results in pal-e-docs. [SCOPE] Create architecture note arch-bots for the bots component.
  • [x] Forgejo issue -- https://forgejo.tail5b443a.ts.net/ldraney/botfire/issues/5, open

File Targets

  • [x] app/controllers/dashboard_controller.rb -- verified: exists (2.5k), has data endpoint querying BotFire with joins to bot, trigger, market, game. Already accesses g.sport_type via join.
  • [x] app/services/scoreboard.rb -- verified: exists (3.0k), has bot_summary method with P&L, win/loss, stop-loss/take-profit counts. Good foundation to extend.
  • [x] db/migrate/ -- verified: directory exists with 13 migrations.
  • [ ] db/migrate/ -- ISSUE: Issue mentions adding sport_type to bot_fires, but sport_type already exists on games table and the controller already accesses it via join (g.sport_type). Clarify whether denormalization is intended or join-based computation suffices. [BODY]
  • [ ] db/migrate/ -- ISSUE: game_phase_at_entry is proposed but "game phase" is not defined in terms of existing data. The games table has period (string) and clock (string) fields. How to map these to early/mid/late across 5 different sports (each with different period structures -- innings, quarters, halves, periods) needs explicit definition. [BODY]
  • [x] app/views/dashboard/index.html.erb -- verified: exists (261 lines), live position monitoring dashboard with dark theme, summary cards, bot cards, open-positions table.

Repo Placement

OK -- issue filed on ldraney/botfire, all file targets in ldraney/botfire. Single-repo scope.

Dependencies

  • Board item #1839 (Rework Volatility Bot) -- in QA column, deployed. Generating the trade data this ticket will analyze. Not a blocker.
  • Board item #1840 (Rework Consensus Bot) -- in backlog, ON HOLD pending analytics. This ticket (#1841) is a prerequisite for #1840. Dependency direction is correct and documented in Related section ("Issue #2 -- Consensus Bot rework (ON HOLD until analytics prove what to amplify)").
  • No blockers for this ticket. Dependencies are documented.

Acceptance Criteria

8 acceptance criteria. Most are testable, with these concerns:
  • AC 3 (P&L by Game Phase) -- "early/mid/late" mapping from existing period/clock fields is undefined. Different sports have different period structures (innings, quarters, halves, periods). An agent cannot implement this without a definition.
  • AC 7 (Cross-filter) -- complex interactive behavior: "click a sport, price band, or game phase to filter all other views." Significant frontend engineering effort, especially with no chart libraries allowed.
  • AC 8 (Hypothesis Log) -- persistence mechanism undefined. Is this localStorage, a new DB table, or ephemeral? "Simple text area or section" is too vague for agent implementation.

Blast Radius

  • Dashboard changes are visually isolated (single page, no new routes).
  • Scoreboard service is used by bot services for console logging. Extending with analytics methods is additive and non-breaking.
  • BotFire model is used by 6 services (volatility_bot, consensus_bot, bot_engine, position_monitor, portfolio_grouper, scoreboard). Adding columns via migration is non-breaking.
  • No chart libraries constraint means all visualization (6+ chart types including line charts, bar charts, tables with breakeven lines) must be custom HTML/canvas. This is the highest-effort constraint.

Decomposition Assessment

NEEDS DECOMPOSITION -- fails the 5-minute rule on multiple criteria:
  • File targets: 3-4 files in 1 repo -- borderline acceptable.
  • Acceptance criteria: 8 criteria -- exceeds the >5 threshold.
  • Estimated agent work: Well over 15 minutes. Backend analytics endpoint + 6 chart views (all custom HTML/canvas, no libraries) + cross-filter interactivity + responsive design + hypothesis log + possible migration + tests. At minimum 3 separate agent passes.
Suggested decomposition into 3 sub-tickets:
  • Analytics backend + static tables (3pt) -- analytics endpoint with P&L breakdowns by sport, price band, game phase, exit reason. Static HTML tables with breakeven threshold. AC 1-5 data + display.
  • Cumulative P&L trend chart (2pt) -- custom canvas line chart per bot showing P&L over time. AC 6. Responsive.
  • Cross-filter + hypothesis log (3pt) -- AC 7-8: interactive filtering across all views and hypothesis persistence. Depends on tickets 1 and 2.

Recommendations

  • [DECOMPOSE] 8 AC across backend analytics + 6 custom chart types + cross-filter interactivity + hypothesis log. Route to skill-decompose-ticket.
  • [SCOPE] Create architecture note arch-bots for the bots component.
  • [SCOPE] Create story note story-bots-bot-strategy (currently listed as pending on project-botfire).
  • [BODY] Define "game phase" mapping: how do period and clock fields on the games table map to early/mid/late for each sport type (baseball innings, basketball quarters, football quarters, hockey periods, soccer halves)?
  • [BODY] Clarify sport_type migration: the field already exists on games table and is accessible via join. State explicitly whether denormalization to bot_fires is intended or join-based access suffices.
  • [BODY] Define hypothesis log persistence: localStorage, new DB table, or ephemeral?