Review: Per-bot live activity feed -- Turbo Streams
Verdict: NEEDS_REFINEMENT
Template Completeness
- [x] Type -- Feature
- [x] Lineage -- Sprint 4, depends on #26 and bots running
- [x] Repo -- ldraney/prediction-assistant
- [x] User Story -- Bot Marketplace
- [x] Context -- detailed background
- [x] File Targets -- 7 files listed
- [x] Feature Flag -- None (integral to UI)
- [x] Acceptance Criteria -- 10 criteria
- [x] Test Expectations -- listed
- [x] Constraints -- listed
- [x] Checklist -- 11 items
- [x] Related -- dependencies listed
All required sections present per
template-issue-feature.Traceability
- [x] story:bot-marketplace label -- Bot Marketplace user story
- [x] story note verified -- found in project-prediction-assistant user-stories section
- [x] arch:frontend label -- frontend component
- [ ] arch note MISSING -- [SCOPE] Create architecture note arch-frontend for component frontend
- [x] Forgejo issue -- #30, open
File Targets
- [x]
app/models/activity_log.rb-- EXISTS but schema diverges from AC (see Recommendations) - [x]
db/migrate/20260703200001_create_activity_logs.rb-- EXISTS, matches actual model - [ ]
app/channels/bot_activity_channel.rb-- does not exist yet, to be created - [ ]
app/views/bots/_activity_feed.html.erb-- does not exist yet, to be created - [ ]
app/views/activity_logs/_activity_log.html.erb-- does not exist yet, to be created - [x]
test/models/activity_log_test.rb-- EXISTS with full validation/scope coverage - [ ]
test/channels/bot_activity_channel_test.rb-- does not exist yet, to be created
Critical mismatch: AC #1 specifies fields that do not match the existing
ActivityLog model:- AC says
user_id-- no User model exists in the app, no user_id on ActivityLog or Strategy - AC says
bot_type-- actual field isbot_name - AC says action values
(order_placed, fill_received, position_opened, exit_triggered, error)-- actual values areplace_order, cancel_order, fill, partial_fill, error, dry_run, bulk_sweep - AC says
rationale(text) -- actual fields aremessage(text) +metadata(jsonb) - AC says
timestamp-- actual field iscreated_at(standard Rails timestamps)
Repo Placement
OK -- issue filed on ldraney/prediction-assistant, all file targets in that repo. Single-repo scope.
Dependencies
- #26 (Bot Detail pages) -- in validation column, merged. Show page exists at
app/views/bots/show.html.erb. SATISFIED. - #23 (OrderService) -- in validation column. Already creates ActivityLog entries via
ActivityLog.create!. SATISFIED. - #27 (Pregame Stacker) -- in validation column, merged. SATISFIED.
- #28 (Bulk Sweep) -- in validation column, merged. SATISFIED.
- #29 (Edge Learner) -- in backlog (sprint:6). NOT blocking -- feed works with whatever bots exist.
- #48 (Hotwire conversion) -- in validation column. Turbo/Stimulus/Action Cable are available. SATISFIED.
- Undocumented: User authentication model -- AC #6 says scope by user_id but no User model exists. Keycloak OIDC is integrated (#57, closed) but no Rails User model has been created. Action Cable Connection has no auth.
Acceptance Criteria
- AC #1 (model fields) -- STALE, model already exists with different schema. Needs update.
- AC #2 (Kalshi market link) -- testable, straightforward
- AC #3 (feed partial on detail page) -- testable, show.html.erb exists to embed it
- AC #4 (per-bot filtering) -- testable,
for_botscope exists - AC #5 (Turbo Streams real-time) -- testable, Action Cable + solid_cable configured
- AC #6 (channel scoped to user_id + strategy_id) -- PROBLEMATIC: no User model, no user_id. Must scope by strategy_id only for now.
- AC #7 (pagination) -- testable
- AC #8 (entry display: rationale) -- STALE: field is
message, notrationale - AC #9 (entries created by bots/OrderService) -- ALREADY MET: OrderService already creates ActivityLog entries
- AC #10 (reverse chronological) -- testable,
recentscope exists
Blast Radius
OrderServicealready creates ActivityLog entries -- addingafter_createbroadcast will fire on every trade execution across all bots- BulkSweepJob processes many markets rapidly -- broadcasting per-entry could flood the cable. Constraints section mentions throttling but no specific mechanism is prescribed
- Action Cable uses
solid_cable(database-backed pub/sub, not Redis) -- performance under high-frequency broadcasting should be monitored - No cross-user leakage concern currently since there is no multi-user model yet
Decomposition Assessment
7 file targets (3 already exist), 10 acceptance criteria (exceeds 5 threshold), 1 repo. Remaining work is 4 new files + 3 modifications. The work is standard Rails patterns (channel, partials, Turbo Streams wiring) that are boilerplate-heavy but not complex. At 2 story points the scope is reasonable for a single agent pass once the AC is corrected, provided AC #9 is marked as pre-existing. No decomposition needed after AC cleanup -- effective AC count drops to 7-8, and the remaining file creation is templated.
Recommendation
[BODY]Update AC #1 field list to match existing ActivityLog schema:strategy_id,bot_name(not bot_type),action(place_order, cancel_order, fill, partial_fill, error, dry_run, bulk_sweep),ticker,side,quantity,price,status(success, failure, dry_run, rejected),message(not rationale),metadata(jsonb). Removeuser_idandtimestamp.[BODY]Update AC #6: removeuser_idscoping -- scope BotActivityChannel tostrategy_idonly. User scoping is a future concern when User model lands.[BODY]Update AC #8: replace "rationale" with "message" to match actual schema.[BODY]Mark AC #9 as pre-existing (OrderService already writes to ActivityLog) or reframe as "verify existing integration".[SCOPE]Create architecture notearch-frontendfor component frontend.