feat(gastown): show admin bead failure reasons#3432
Conversation
| sql: SqlStorage, | ||
| filter: BeadFilter | ||
| ): BeadWithFailureReason[] { | ||
| return listBeads(sql, filter).map(bead => attachFailureReason(sql, bead)); |
There was a problem hiding this comment.
WARNING: N+1 query pattern — one extra SQL query per bead
listBeadsWithFailureReasons calls attachFailureReason for every bead, and attachFailureReason calls failureReasonForBead which issues its own SQL query (SELECT metadata FROM bead_events WHERE bead_id = ? AND event_type = 'status_changed' AND new_value = 'failed' LIMIT 1). With the default limit of 200 beads, this results in up to 201 SQL queries for a single adminListBeads call.
This is a Durable Object SQLite context so the queries are local/in-process, but it still generates significant per-bead overhead. Consider a single bulk query joining beads with bead_events filtered to the latest failed status-change event per bead, using MAX(created_at) or a window function, to fetch all failure reasons in one pass.
Code Review SummaryStatus: 1 Issue Found | Recommendation: Address before merge Executive SummaryThe Overview
Issue Details (click to expand)WARNING
Other Observations (not in diff)
Files Reviewed (7 files)
Fix these issues in Kilo Cloud Reviewed by claude-sonnet-4.6 · 634,278 tokens Review guidance: REVIEW.md from base branch |
Summary
Failed Gastown beads previously gave admins little actionable context, especially after later audit events could bury the original failure metadata. This adds failure-reason plumbing from the Town DO through the admin tRPC/UI surfaces so admins can see the recorded failure message, code, source, and details directly in bead lists and inspectors.
Implementation notes
Verification
No separate manual browser verification was performed; this change was validated with targeted API/DO regression coverage.
Visual Changes
Admin bead list and inspector now show failure-reason fields for failed beads. Screenshots were not captured.
Reviewer Notes
Focus areas: the failure reason is reconstructed from the latest failed status-change event metadata rather than persisted on the bead row, matching the existing event-audit model and avoiding a schema change.