fix: clean failed document uploads and surface filesystem errors

This commit is contained in:
2026-09-06 09:15:34 +03:00
parent 43dc4feb31
commit 37b10ce09a
4 changed files with 61 additions and 7 deletions
+2 -6
View File
@@ -969,17 +969,13 @@ const server = http.createServer(async (req, res) => {
try { ofisMetni = arsivMetni(String(body.ad), buf); } catch { /* metin çıkmazsa devam */ }
if (!ikn && body.otoIkn && ofisMetni) ikn = iknCikar(ofisMetni);
}
const dosyaAdi = `${Date.now()}-${crypto.randomUUID()}`;
fs.writeFileSync(path.join(store.BELGE_DIR, dosyaAdi), buf);
const id = store.addDocument(user.email, {
const id = store.saveDocumentFile(user.email, {
ad: String(body.ad).slice(0, 200),
kategori: metadata.kategori || null,
boyut: buf.length, // GERÇEK bayt — rastgele değil
mime: body.mime || null,
dosya: dosyaAdi,
sonKullanma: metadata.sonKullanma || null,
ikn, // ihaleye bağlı belge
});
}, buf);
// Yükleme anında otomatik kalem çıkarımı — AI kullanmaz, kullanıcıdan
// tıklama beklemez. PDF'ler tarayıcıda çözüldüğü için istemci
// metni /api/kalem/cikar'a gönderir.
+17 -1
View File
@@ -249,6 +249,21 @@ export function addDocument(email, { ad, kategori, boyut, mime, dosya, sonKullan
return id;
}
/** A rejected metadata insert must not leave private uploaded bytes on disk. */
export function saveDocumentFile(email, metadata, bytes) {
fs.mkdirSync(BELGE_DIR, { recursive:true });
const dosya = crypto.randomUUID();
const destination = path.join(BELGE_DIR, dosya);
fs.writeFileSync(destination, bytes, { flag:'wx', mode:0o600 });
try {
return addDocument(email, { ...metadata, dosya, boyut:bytes.length });
} catch (error) {
try { fs.unlinkSync(destination); }
catch (cleanupError) { throw new AggregateError([error,cleanupError], 'Belge kaydedilemedi ve geçici dosya temizlenemedi.'); }
throw error;
}
}
export function listDocuments(email, { ikn } = {}) {
const alanlar = 'id, ad, kategori, boyut, mime, son_kullanma, ikn, olusturma, dosya';
return withDb((db) => (ikn
@@ -280,7 +295,8 @@ export function listUsers() {
export function deleteDocument(email, id) {
const rec = getDocument(email, id);
if (!rec) return false;
try { fs.unlinkSync(path.join(BELGE_DIR, rec.dosya)); } catch { /* dosya zaten yok */ }
try { fs.unlinkSync(path.join(BELGE_DIR, rec.dosya)); }
catch (error) { if (error.code !== 'ENOENT') throw error; }
return withDb((db) => db.prepare('DELETE FROM belgeler WHERE id=? AND email=?').run(id, email).changes > 0, false);
}