fix: include filename in search; add POST /cleanup-live to recover stuck live assets

This commit is contained in:
Zac Gaetano 2026-05-19 23:10:51 -04:00
parent 8a2ef38326
commit 16b8530d43

View file

@ -74,7 +74,8 @@ router.get('/', async (req, res, next) => {
}
if (search) {
query += ` AND (a.display_name ILIKE $${paramCount} OR a.notes ILIKE $${paramCount})`;
// Search display_name, filename, and notes — filename was previously omitted
query += ` AND (a.display_name ILIKE $${paramCount} OR a.filename ILIKE $${paramCount} OR a.notes ILIKE $${paramCount})`;
params.push(`%${search}%`);
paramCount++;
}
@ -203,6 +204,28 @@ router.post('/', async (req, res, next) => {
}
});
// POST /cleanup-live mark stuck 'live' assets as 'error'
//
// Recorder containers that crash without calling the stop callback leave
// assets permanently in 'live' status. This endpoint recovers them.
// Default age threshold: 4 hours. Accepts ?max_age_hours=N override.
router.post('/cleanup-live', async (req, res, next) => {
try {
const maxAgeHours = Math.max(1, parseInt(req.query.max_age_hours || '4', 10));
const result = await pool.query(
`UPDATE assets
SET status = 'error', updated_at = NOW()
WHERE status = 'live'
AND created_at < NOW() - ($1 * INTERVAL '1 hour')
RETURNING id, display_name, project_id, created_at`,
[maxAgeHours]
);
res.json({ cleaned: result.rowCount, assets: result.rows });
} catch (err) {
next(err);
}
});
// GET /:id - Single asset
router.get('/:id', async (req, res, next) => {
try {