const db = require('../db/knex'); function parseTarget(value) { if (value == null) { return null; } const target = Number(value); if ( !Number.isInteger(target) || target <= 0 ) { throw new Error( 'Il limite deve essere un intero positivo', ); } return target; } async function selectPhotosWithoutJob(limit) { let query = db('photos as p') .leftJoin( 'face_scan_jobs as j', 'j.photo_id', 'p.id', ) .select('p.id') .whereNull('p.deleted_at') .whereNotNull('p.path') .where('p.path', '!=', '') .whereNull('j.photo_id') .andWhere((builder) => { builder .whereNull('p.mime_type') .orWhere( 'p.mime_type', 'like', 'image/%', ); }) .orderBy('p.created_at', 'asc') .orderBy('p.id', 'asc'); if (limit !== null) { query = query.limit(limit); } return query; } async function main() { const target = parseTarget(process.argv[2]); const existingResult = await db('face_scan_jobs') .count({ count: '*' }) .first(); const existingJobs = Number(existingResult?.count || 0); let slots = null; if (target !== null) { slots = Math.max( 0, target - existingJobs, ); } if (slots === 0) { console.log({ target_jobs: target, jobs_before: existingJobs, photos_selected: 0, jobs_inserted: 0, jobs_after: existingJobs, }); return; } const photos = await selectPhotosWithoutJob( slots, ); let inserted = 0; await db.transaction(async (trx) => { for (const photo of photos) { await trx('face_scan_jobs').insert({ photo_id: photo.id, status: 'pending', attempts: 0, faces_detected: null, execution_ms: null, applied_rotation: null, last_error: null, started_at: null, completed_at: null, created_at: trx.fn.now(), updated_at: trx.fn.now(), }); inserted += 1; } }); const finalResult = await db('face_scan_jobs') .count({ count: '*' }) .first(); const finalJobs = Number(finalResult?.count || 0); console.log({ target_jobs: target, jobs_before: existingJobs, photos_selected: photos.length, jobs_inserted: inserted, jobs_after: finalJobs, }); } main() .catch((error) => { console.error( '[enqueueFaceScanJobs] errore:', error.stack || error.message || error, ); process.exitCode = 1; }) .finally(async () => { await db.destroy(); });