From 2f6424617b5900d0e68e641238de6d0d3c831d59 Mon Sep 17 00:00:00 2001 From: m3taversal Date: Thu, 23 Apr 2026 12:22:12 +0100 Subject: [PATCH] feat: wire Timeline activity endpoint + surface source_channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /api/activity and /api/activity-feed were never registered in app.py — both files existed but neither route was reachable (confirmed 404 on VPS). Register both so Timeline and gamification feeds can consume them. Adds source_channel to /api/activity payload (both PR rows and audit events — audit rows return null since they aren't tied to a specific PR). Migration v22 already populated prs.source_channel on VPS with enum: telegram=2340, agent=698, maintenance=102, unknown=11, github=1. Co-Authored-By: Claude Opus 4.7 (1M context) --- diagnostics/activity_endpoint.py | 4 +++- diagnostics/app.py | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/diagnostics/activity_endpoint.py b/diagnostics/activity_endpoint.py index 7c6222d..36872fa 100644 --- a/diagnostics/activity_endpoint.py +++ b/diagnostics/activity_endpoint.py @@ -143,7 +143,7 @@ async def handle_activity(request): # Each PR generates events at created_at and merged_at timestamps pr_query = """ SELECT number, status, domain, agent, branch, source_path, - created_at, merged_at + created_at, merged_at, source_channel FROM prs WHERE {where_clause} ORDER BY COALESCE(merged_at, created_at) DESC @@ -189,6 +189,7 @@ async def handle_activity(request): 'description': description, 'status': row_dict['status'], 'pr_number': row_dict['number'], + 'source_channel': row_dict.get('source_channel') or 'unknown', }) # Source 2: Audit log events (secondary — pipeline-level) @@ -228,6 +229,7 @@ async def handle_activity(request): 'description': description, 'status': None, 'pr_number': None, + 'source_channel': None, # audit events not tied to a PR }) conn.close() diff --git a/diagnostics/app.py b/diagnostics/app.py index ee4059f..d167dba 100644 --- a/diagnostics/app.py +++ b/diagnostics/app.py @@ -2283,6 +2283,12 @@ def create_app() -> web.Application: # Response audit - cost tracking + reasoning traces app["db_path"] = str(DB_PATH) register_response_audit_routes(app) + # Timeline activity feed (per-PR + audit_log events for dashboard v2) + from activity_endpoint import handle_activity + app.router.add_get("/api/activity", handle_activity) + # Gamification activity feed (hot/recent/important sort) + from activity_feed_api import register as register_activity_feed + register_activity_feed(app) app.on_cleanup.append(_cleanup) return app