import { uploadFile } from './services/storage.js'; import pg from 'pg'; const { Pool } = pg; const pool = new Pool({ connectionString: process.env.DATABASE_URL }); async function run() { try { console.log("Starting presence photo migration to MinIO..."); // 1. Buscar registros com fotos base64 no PostgreSQL const { rows } = await pool.query( "SELECT id, foto FROM frequencias WHERE foto LIKE 'data:image%'" ); console.log(`Found ${rows.length} base64 photos in PostgreSQL table 'frequencias'.`); for (const row of rows) { try { const base64Data = row.foto; const match = base64Data.match(/^data:image\/([a-zA-Z0-9+]+);base64,(.+)$/); if (!match) { console.log(`[Warning] Invalid base64 format for id ${row.id}`); continue; } const ext = match[1] === 'jpeg' ? 'jpg' : match[1]; const base64Str = match[2]; const buffer = Buffer.from(base64Str, 'base64'); const fileName = `frequencia_${row.id}.${ext}`; const contentType = `image/${match[1]}`; console.log(`Uploading ${fileName} to MinIO bucket 'presenca'...`); const relativeUrl = await uploadFile('presenca', fileName, buffer, contentType); console.log(`Uploaded to MinIO: ${relativeUrl}`); // Atualiza a linha na tabela frequencias await pool.query( "UPDATE frequencias SET foto = $1 WHERE id = $2", [relativeUrl, row.id] ); console.log(`Updated SQL row for ID: ${row.id}`); } catch (err) { console.error(`Error migrating record ${row.id}:`, err.message); } } // 2. Sincronizar com o cache JSON do school_data console.log("Syncing school_data JSON cache..."); const { rows: schoolDataRows } = await pool.query( "SELECT data FROM school_data WHERE id = 1" ); if (schoolDataRows[0] && schoolDataRows[0].data) { const schoolData = schoolDataRows[0].data; if (Array.isArray(schoolData.attendance)) { let updatedCount = 0; schoolData.attendance = schoolData.attendance.map(a => { if (a.photo && a.photo.startsWith('data:image')) { const match = a.photo.match(/^data:image\/([a-zA-Z0-9+]+);base64,(.+)$/); if (match) { const ext = match[1] === 'jpeg' ? 'jpg' : match[1]; const fileName = `frequencia_${a.id}.${ext}`; a.photo = `/storage/presenca/${fileName}`; updatedCount++; } } return a; }); if (updatedCount > 0) { schoolData.lastUpdated = new Date().toISOString(); await pool.query( "UPDATE school_data SET data = $1 WHERE id = 1", [JSON.stringify(schoolData)] ); console.log(`Successfully updated ${updatedCount} entries in school_data.data JSON.`); } else { console.log("No base64 photos found in school_data.data JSON."); } } else { console.log("school_data.data.attendance is not an array or does not exist."); } } else { console.log("No school_data record found or data is empty."); } console.log("Migration complete!"); } catch (err) { console.error("Migration failed:", err); } finally { await pool.end(); } } run();