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 && ( 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);