115 lines
3.1 KiB
JavaScript
115 lines
3.1 KiB
JavaScript
|
|
const express = require('express');
|
||
|
|
const { prisma } = require('../utils/db');
|
||
|
|
const { authenticate } = require('../middleware/auth');
|
||
|
|
const matchingService = require('../services/matching');
|
||
|
|
const { SUGGESTION_STATUS } = require('../constants');
|
||
|
|
|
||
|
|
const router = express.Router();
|
||
|
|
|
||
|
|
// POST /api/admin/events/:slug/run-now - Trigger matching immediately for an event
|
||
|
|
router.post('/events/:slug/run-now', authenticate, async (req, res, next) => {
|
||
|
|
try {
|
||
|
|
const { slug } = req.params;
|
||
|
|
|
||
|
|
const event = await prisma.event.findUnique({
|
||
|
|
where: { slug },
|
||
|
|
select: { id: true, slug: true },
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!event) {
|
||
|
|
return res.status(404).json({ success: false, error: 'Event not found' });
|
||
|
|
}
|
||
|
|
|
||
|
|
const startedAt = new Date();
|
||
|
|
const runRow = await prisma.matchingRun.create({
|
||
|
|
data: {
|
||
|
|
eventId: event.id,
|
||
|
|
trigger: 'manual',
|
||
|
|
status: 'running',
|
||
|
|
startedAt,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
try {
|
||
|
|
const suggestions = await matchingService.runMatching(event.id);
|
||
|
|
await matchingService.saveMatchingResults(event.id, suggestions);
|
||
|
|
|
||
|
|
const notFoundCount = suggestions.filter(s => s.status === SUGGESTION_STATUS.NOT_FOUND).length;
|
||
|
|
const matchedCount = suggestions.filter(s => s.status === SUGGESTION_STATUS.PENDING).length;
|
||
|
|
|
||
|
|
await prisma.matchingRun.update({
|
||
|
|
where: { id: runRow.id },
|
||
|
|
data: {
|
||
|
|
status: 'success',
|
||
|
|
endedAt: new Date(),
|
||
|
|
matchedCount,
|
||
|
|
notFoundCount,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
return res.json({
|
||
|
|
success: true,
|
||
|
|
data: {
|
||
|
|
eventSlug: event.slug,
|
||
|
|
startedAt,
|
||
|
|
endedAt: new Date(),
|
||
|
|
matched: matchedCount,
|
||
|
|
notFound: notFoundCount,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
} catch (err) {
|
||
|
|
await prisma.matchingRun.update({
|
||
|
|
where: { id: runRow.id },
|
||
|
|
data: {
|
||
|
|
status: 'error',
|
||
|
|
endedAt: new Date(),
|
||
|
|
error: String(err?.message || err),
|
||
|
|
},
|
||
|
|
});
|
||
|
|
return res.status(500).json({ success: false, error: 'Matching failed', details: String(err?.message || err) });
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
next(error);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// GET /api/admin/events/:slug/matching-runs?limit=20 - List recent runs
|
||
|
|
router.get('/events/:slug/matching-runs', authenticate, async (req, res, next) => {
|
||
|
|
try {
|
||
|
|
const { slug } = req.params;
|
||
|
|
const limit = Math.min(parseInt(req.query.limit || '20', 10), 100);
|
||
|
|
|
||
|
|
const event = await prisma.event.findUnique({
|
||
|
|
where: { slug },
|
||
|
|
select: { id: true },
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!event) {
|
||
|
|
return res.status(404).json({ success: false, error: 'Event not found' });
|
||
|
|
}
|
||
|
|
|
||
|
|
const runs = await prisma.matchingRun.findMany({
|
||
|
|
where: { eventId: event.id },
|
||
|
|
orderBy: { startedAt: 'desc' },
|
||
|
|
take: limit,
|
||
|
|
select: {
|
||
|
|
id: true,
|
||
|
|
trigger: true,
|
||
|
|
status: true,
|
||
|
|
startedAt: true,
|
||
|
|
endedAt: true,
|
||
|
|
matchedCount: true,
|
||
|
|
notFoundCount: true,
|
||
|
|
error: true,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
res.json({ success: true, count: runs.length, data: runs });
|
||
|
|
} catch (error) {
|
||
|
|
next(error);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
module.exports = router;
|
||
|
|
|