import fs from 'node:fs'; import path from 'node:path'; import {createHash} from 'node:crypto'; import {openDb,BELGE_DIR} from './user-store.mjs'; const hash=value=>createHash('sha256').update(value).digest('hex'); const fail=(status,message)=>Object.assign(new Error(message),{status}); function source(db,email,id) { const record=db.prepare('SELECT * FROM belgeler WHERE id=? AND email=?').get(id,email); if(!record || record.tur !== 'ihale') throw fail(404,'İhale dokümanı bulunamadı.'); let bytes; try {bytes=fs.readFileSync(path.join(BELGE_DIR,record.dosya));} catch {throw fail(409,'Kaynak dosya okunamıyor; inceleme kaydedilemez.');} return hash(bytes); } function latest(db,email,id) { return db.prepare('SELECT revision,file_hash,text_hash,corrected_text,review_note,reviewed_at FROM document_text_reviews WHERE document_id=? AND email=? ORDER BY revision DESC LIMIT 1').get(id,email) || null; } export function documentReview(email,id) { const db=openDb(); try { const fileHash=source(db,email,id), review=latest(db,email,id); return {documentId:id,fileHash,review,stale:Boolean(review && review.file_hash!==fileHash)}; } finally {db.close();} } export function saveDocumentReview(email,id,input) { if(typeof input.correctedText !== 'string' || input.correctedText.trim().length<40 || Buffer.byteLength(input.correctedText)>1024*1024) throw fail(400,'Kontrol edilen metin 40 karakter ile 1 MB arasında olmalı.'); if(typeof input.note !== 'string' || input.note.trim().length<20 || input.note.length>2000) throw fail(400,'Karşılaştırılan sayfaları ve yapılan düzeltmeleri en az 20 karakterle açıklayın.'); if(input.allPagesCompared !== true) throw fail(400,'Tüm kaynak sayfalarıyla karşılaştırma gerekli.'); if(!Number.isInteger(input.expectedRevision) || input.expectedRevision<0) throw fail(400,'Geçerli inceleme sürümü gerekli.'); const db=openDb(); try { db.exec('BEGIN IMMEDIATE'); const fileHash=source(db,email,id), previous=latest(db,email,id); if(input.fileHash!==fileHash || input.expectedRevision!==(previous?.revision || 0)) throw fail(409,'Dosya veya inceleme sürümü değişti. Güncel kaydı yeniden açın.'); const text=input.correctedText.trim(); db.prepare('INSERT INTO document_text_reviews VALUES (?,?,?,?,?,?,?,?)').run(id,email,input.expectedRevision+1,fileHash,hash(text),text,input.note.trim(),new Date().toISOString()); const review=latest(db,email,id); db.exec('COMMIT');return {documentId:id,fileHash,review,stale:false}; } catch(error) {try {db.exec('ROLLBACK');} catch {} throw error;} finally {db.close();} }