From 57df0f80a229ff899e77051c648e223ed20c561d Mon Sep 17 00:00:00 2001 From: Dean Rie Date: Sat, 24 Oct 2026 18:11:49 +0300 Subject: [PATCH 1/2] Judge a stuck scan by updated_at, like the recovery cron and the rescan tool getStuckScans() treated a pending or scanning plugin as stuck once its created_at was older than 15 minutes. The recover-stuck-scans cron, added to use "the same 15-min staleness threshold getStuckScans uses", and the MCP rescan_plugin guard both measure from updated_at, which the plugins_set_updated_at trigger bumps on every status write. So a re-scan of any plugin older than 15 minutes showed up in the admin Stuck tab and in list_moderation_queue scan_issues the moment it was queued, while the cron left it alone, and the rescan tool refused to re-queue it as in progress. The query now uses updated_at, so the three agree. --- apps/cursor/src/data/queries.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/cursor/src/data/queries.ts b/apps/cursor/src/data/queries.ts index 86e2f64e..db2b731c 100644 --- a/apps/cursor/src/data/queries.ts +++ b/apps/cursor/src/data/queries.ts @@ -538,11 +538,15 @@ export async function getStuckScans() { const supabase = await createClient(); const fifteenMinutesAgo = new Date(Date.now() - 15 * 60 * 1000).toISOString(); + // A scan counts as stuck 15 minutes after the row last changed, the same + // test the recover-stuck-scans cron and the MCP rescan tool apply. Every + // status write bumps updated_at through the plugins_set_updated_at trigger, + // so a fresh re-scan of an old plugin is not stuck until that time passes. const { data, error } = await supabase .from("plugins") .select("*, plugin_components(*)") .or( - `scan_status.eq.error,and(scan_status.in.(pending,scanning),created_at.lt.${fifteenMinutesAgo})`, + `scan_status.eq.error,and(scan_status.in.(pending,scanning),updated_at.lt.${fifteenMinutesAgo})`, ) .order("created_at", { ascending: false }) .limit(200); From a68e41a0b43b91dc43f15f4a9d88487e3e562cbf Mon Sep 17 00:00:00 2001 From: Dean Rie Date: Mon, 26 Oct 2026 12:50:20 +0300 Subject: [PATCH 2/2] Show the stuck card's last change time, the value the stuck rule now reads --- apps/cursor/src/app/admin/plugins/stuck-scan-list.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/cursor/src/app/admin/plugins/stuck-scan-list.tsx b/apps/cursor/src/app/admin/plugins/stuck-scan-list.tsx index f2f01d49..bd788efe 100644 --- a/apps/cursor/src/app/admin/plugins/stuck-scan-list.tsx +++ b/apps/cursor/src/app/admin/plugins/stuck-scan-list.tsx @@ -61,7 +61,7 @@ function StuckCard({ plugin }: { plugin: PluginRow }) {
- created {new Date(plugin.created_at).toLocaleString()} + last change {new Date(plugin.updated_at).toLocaleString()} {plugin.scan_run_id && (