feat: Add Ops Dashboard API endpoints - #23
Conversation
Backend: - GET /api/ops/events - Unified event stream from tasks & audit - GET /api/ops/tasks/history - Task history with duration & audit data - GET /api/ops/stats - Aggregated statistics (Admin only) Features: - Filter events by since, limit, agentId, type - Filter task history by status, assignee, includeAudit - Aggregate stats per agent with completion/stop rates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
@sentry review |
🤖 Auto-fixed by GitHub Actions
| if (agentId && entry.agent && entry.agent !== agentId) continue; | ||
|
|
||
| events.push({ | ||
| id: `audit-${entry.id}`, | ||
| type: "audit_decision", | ||
| timestamp: entry.created_at, | ||
| taskId: entry.task_id, | ||
| agentId: entry.agent, |
There was a problem hiding this comment.
Bug: Filtering by agentId on the /api/ops/events endpoint is non-functional because entry.agent is always undefined, as the audit_entries table lacks an agent column.
Severity: HIGH | Confidence: High
🔍 Detailed Analysis
The /api/ops/events endpoint attempts to filter audit decision events by agentId. This logic relies on the entry.agent property, which is sourced from the audit_entries database table. However, the audit_entries table schema does not include an agent column, causing entry.agent to always be undefined. As a result, the filtering condition entry.agent && entry.agent !== agentId is never met, and the feature fails silently, returning unfiltered results. Additionally, the agentId field in the response for these events is always undefined.
💡 Suggested Fix
Refactor the code to use the newer db.audit.list() function, which queries the audit_events table that correctly includes an agent_id. Alternatively, add an agent column to the audit_entries table and ensure it is populated when entries are created.
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: src/api/ops.ts#L149-L156
Potential issue: The `/api/ops/events` endpoint attempts to filter audit decision events
by `agentId`. This logic relies on the `entry.agent` property, which is sourced from the
`audit_entries` database table. However, the `audit_entries` table schema does not
include an `agent` column, causing `entry.agent` to always be `undefined`. As a result,
the filtering condition `entry.agent && entry.agent !== agentId` is never met, and the
feature fails silently, returning unfiltered results. Additionally, the `agentId` field
in the response for these events is always `undefined`.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 507408
Summary
/api/ops/*endpoints for the Ops DashboardNew Endpoints
GET /api/ops/eventsGET /api/ops/tasks/historyGET /api/ops/statsQuery Parameters
Events:
since- ISO timestamp (default: 24h ago)limit- max events (default: 100, max: 500)agentId- filter by agenttype- filter by event typeTasks History:
limit- max tasks (default: 50, max: 200)status- filter by statusassignee- filter by agentincludeAudit- include audit entriesTest plan
🤖 Generated with Claude Code