feat(matching-runs): add per-run aggregate stats and UI display
- Admin list endpoint returns totalSuggestions, assignedCount, aggregatedNotFoundCount per run - UI: show Total/Matched/Not found columns using fresh aggregates - Add anchor link Run #ID and wording 'Pairs created in this run'
This commit is contained in:
@@ -104,6 +104,30 @@ router.get('/events/:slug/matching-runs', authenticate, async (req, res, next) =
|
||||
},
|
||||
});
|
||||
|
||||
// Aggregate fresh stats per run from recording_suggestions (origin_run_id)
|
||||
// Cheap and valuable: shows actual created pairs in this run.
|
||||
if (runs.length > 0) {
|
||||
const runIds = runs.map(r => r.id);
|
||||
// Single SQL query for all listed runs
|
||||
const placeholders = runIds.join(',');
|
||||
const aggRows = await prisma.$queryRawUnsafe(
|
||||
`SELECT origin_run_id AS "originRunId",
|
||||
COUNT(*)::int AS "totalSuggestions",
|
||||
COUNT(*) FILTER (WHERE recorder_id IS NOT NULL)::int AS "assignedCount",
|
||||
COUNT(*) FILTER (WHERE status = 'not_found')::int AS "notFoundCount"
|
||||
FROM recording_suggestions
|
||||
WHERE event_id = ${event.id} AND origin_run_id IN (${placeholders})
|
||||
GROUP BY origin_run_id`
|
||||
);
|
||||
const aggByRun = new Map(aggRows.map(r => [r.originRunId, r]));
|
||||
for (const r of runs) {
|
||||
const agg = aggByRun.get(r.id) || { totalSuggestions: 0, assignedCount: 0, notFoundCount: 0 };
|
||||
r.totalSuggestions = agg.totalSuggestions;
|
||||
r.assignedCount = agg.assignedCount;
|
||||
r.aggregatedNotFoundCount = agg.notFoundCount; // keep original notFoundCount for backward compat
|
||||
}
|
||||
}
|
||||
|
||||
res.json({ success: true, count: runs.length, data: runs });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
|
||||
Reference in New Issue
Block a user