fix(sync): re-upload correto quando arquivo foi deletado do storage
continuous-integration/webhook Deploy concluído (VPS4)
continuous-integration/webhook Deploy concluído (VPS4)
- storage.js: adiciona fileExists() com HeadObject (sem baixar o arquivo) - check-image-exists: verifica existência física no storage, não só no banco; se registro existe mas arquivo não, apaga o registro órfão e retorna exists=false - send-image: mesma lógica — registro órfão é removido e re-upload prossegue - Remove migrate-to-wasabi.js do repositório Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
const { S3Client, GetObjectCommand, DeleteObjectCommand, PutObjectCommand } = require('@aws-sdk/client-s3');
|
||||
const { S3Client, GetObjectCommand, DeleteObjectCommand, PutObjectCommand, HeadObjectCommand } = require('@aws-sdk/client-s3');
|
||||
const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
|
||||
const { Upload } = require('@aws-sdk/lib-storage');
|
||||
const fs = require('fs').promises;
|
||||
@@ -369,12 +369,54 @@ async function getUploadPresignedUrl(filename, clinicName, clientName, patientNa
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifica se o arquivo existe no storage (local ou Wasabi) sem baixar o conteúdo.
|
||||
* Retorna true se encontrado em qualquer um dos dois lugares.
|
||||
*/
|
||||
async function fileExists(filename, clinicName = null, clientName = null, patientName = null) {
|
||||
// Verificar local primeiro
|
||||
const localPaths = [
|
||||
path.join(UPLOAD_DIR, filename),
|
||||
path.join(PROCESSED_DIR, filename),
|
||||
];
|
||||
for (const p of localPaths) {
|
||||
if (fsSync.existsSync(p)) return true;
|
||||
}
|
||||
|
||||
if (!s3 || !currentBucket) return false;
|
||||
|
||||
try {
|
||||
let clName = clinicName;
|
||||
let cName = clientName;
|
||||
let pName = patientName;
|
||||
|
||||
if (!cName || !pName) {
|
||||
try {
|
||||
const row = await db.get(
|
||||
'SELECT clinic_name, client_name, patient_name FROM images WHERE filename = $1 OR thumb_filename = $2 LIMIT 1',
|
||||
[filename, filename]
|
||||
);
|
||||
if (row) { clName = row.clinic_name; cName = row.client_name; pName = row.patient_name; }
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
const key = `${sanitizePathSegment(clName)}/${sanitizePathSegment(cName)}/${sanitizePathSegment(pName)}/${filename}`;
|
||||
await s3.send(new HeadObjectCommand({ Bucket: currentBucket, Key: key }));
|
||||
return true;
|
||||
} catch (e) {
|
||||
if (e.name === 'NotFound' || e.$metadata?.httpStatusCode === 404) return false;
|
||||
// Erro de rede/auth — assume não existe para forçar re-upload
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
loadConfigFromDb,
|
||||
saveImage,
|
||||
getImageBuffer,
|
||||
getImageUrl,
|
||||
deleteImage,
|
||||
fileExists,
|
||||
getDownloadPresignedUrl,
|
||||
getUploadPresignedUrl,
|
||||
isWasabiEnabled: () => !!(s3 && currentBucket),
|
||||
|
||||
Reference in New Issue
Block a user