Verify stored PDF retry in browser and clarify upload errors

This commit is contained in:
2026-09-06 09:41:17 +03:00
parent 277c9407a2
commit 01d4acf246
7 changed files with 358 additions and 2 deletions
@@ -0,0 +1,49 @@
[level=4]:
- text: İhale Dokümanları
- paragraph:
- text: İhale dokümanları EKAP üzerinde tutulur. Aşağıdaki bağlantı sizi doğrudan bu ihalenin EKAP doküman sayfasına götürür; EKAP önce kısa bir
- strong: güvenlik doğrulaması
- text: (resim seçme) ister, ardından şartname ve ekleri listelenir. İlan metnini ise analiz için buradan çekebilirsiniz.
- button "EKAP Dokümanlarını Aç":
- text: EKAP Dokümanlarını Aç
- button "İlan Metnini AI ile Analiz Et":
- text: İlan Metnini AI ile Analiz Et
- paragraph:
- strong: document-broken.pdf
- text: yüklendi ve bu ihaleye bağlandı.
- alert: "Kalem aktarımı tamamlanamadı: Invalid PDF structure.. Dosya kaydı korunmuştur."
- text: Bu dosyadan teklif cetveli kalemi çıkarılamadı.
- paragraph:
- text: EKAP dokümanı kendi oturumunuz üzerinden
- strong: bilgisayarınıza iner
- text: — biz sunucudan alamıyoruz. İnen dosyayı buraya yükleyin; bu ihaleye bağlanır ve AI ile analiz edebilirsiniz.
- button "İndirdiğim dosyayı yükle":
- text: İndirdiğim dosyayı yükle
- generic: PDF, DOCX, XLSX, ZIP · en fazla 10 MB
- paragraph:
- text: Bu ihaleye yüklenen belgeler (2)
- generic: document-broken.pdf
- generic: Dosya metni okunamadı. Dosya biçimini ve bütünlüğünü kontrol edip yeniden deneyin.
- generic: 0 KB
- button "AI analiz"
- button "Derin"
- button "document-broken.pdf için kalem çıkarımını yeniden dene": Kalemleri yeniden çıkar
- button "Sil":
- generic: document-readable.pdf
- generic: Kalem çıkarılamadı — resmi cetveli kontrol edin
- generic: 3 KB
- button "AI analiz"
- button "Derin"
- button "document-readable.pdf için kalem çıkarımını yeniden dene": Kalemleri yeniden çıkar
- button "Sil":
- heading "Derin Analiz & Yol Haritası" [level=5]
- paragraph:
- text: EKAP ilan metni ve bu ihaleye yüklediğiniz tüm evrak
- strong: birlikte
- text: okunur; elenme sebepleri, gözden kaçan ince detaylar, belge kontrol listesi, kritik tarihler ve teklife kadar adım adım yol haritası çıkarılır.
- button "Tüm Evrakı Derin Analiz Et":
- text: Tüm Evrakı Derin Analiz Et
- paragraph: İlan metni + 2 yüklü belge okunacak
- heading "Kritik Yeterlik Şartları" [level=4]
- list
- button "Kullanım kılavuzu (? tuşu)":
@@ -0,0 +1,48 @@
- button "Yeniden dene"
- heading "Belge Kasası" [level=2]
- paragraph: İhale dosyalarınıza her cihazdan erişin — belgeler sunucuda saklanır, tarayıcınızda değil.
- text: Kullanım
- generic: 2 / 5 belge · 3.4 KB / 25.0 MB
- heading "Belge Yükleyin" [level=3]
- paragraph: İmza sirküleri, sertifikalar, vergi levhası… (en fazla 10 MB)
- combobox:
- option "Yasal Belgeler" [selected]
- option "Kalite Belgeleri"
- option "Mali Belgeler"
- option "Resmi Kayıtlar"
- option "Teknik Belgeler"
- option "Diğer"
- text: Dosya Seç
- heading "İhale Dokümanlarını Toplu Yükle" [level=3]
- paragraph:
- text: EKAP'tan indirdiğiniz şartname/doküman dosyalarını (PDF, DOCX, XLSX, ZIP) hepsini birden seçin. Her dosyanın
- strong: İKN'si metninden bulunur
- text: ", ihaleye bağlanır ve teklif cetveli kalemleri otomatik çıkarılır — o ihale herkesin kartında kalemleriyle görünür."
- text: Dosyaları Seç (çoklu)
- paragraph: PDF dosyası bozuk veya geçerli PDF biçiminde değil.
- paragraph: document-broken.pdf
- paragraph:
- text: İhale dokümanı · İhale Dokümanı ·
- strong: 43 B
- paragraph:
- text: 06.09.2026 09:40:14
- generic: Dosya metni okunamadı. Dosya biçimini ve bütünlüğünü kontrol edip yeniden deneyin.
- generic: Son kullanma
- textbox "Son kullanma"
- button "document-broken.pdf için kalem çıkarımını yeniden dene": Kalemleri yeniden çıkar
- button "İndir":
- button "Sil":
- paragraph: document-readable.pdf
- paragraph:
- text: İhale dokümanı · İhale Dokümanı ·
- strong: 3.4 KB
- paragraph:
- text: 06.09.2026 09:40:06
- generic: Kalem çıkarılamadı — resmi cetveli kontrol edin
- generic: Son kullanma
- textbox "Son kullanma"
- button "document-readable.pdf için kalem çıkarımını yeniden dene": Kalemleri yeniden çıkar
- button "İndir":
- button "Sil":
- button "Kullanım kılavuzu (? tuşu)":
+8
View File
@@ -319,3 +319,11 @@ Doküman Deposu'nda İKN bağlantılı, okunabilir ihale belgelerine yeniden kal
Doküman Deposu hesap kimliğine göre yeniden oluşturuluyor; eski bileşenden veya değişmiş token'dan gelen sonuçlar durum güncellemesine uygulanmıyor. Toplu yüklemenin sonraki dosyası ve kalem aktarımı öncesinde oturum kontrolü var. Ortak yükleme servisi FileReader tamamlandığında token değişmişse istek göndermiyor; ortak indirme servisi blob tamamlandığında token değişmişse tarayıcı indirmesi başlatmıyor. Bu kontroller sunucunun sahiplik kontrollerine ek olarak istemcide eski oturum işinin devamını sınırlıyor. Doküman Deposu hesap kimliğine göre yeniden oluşturuluyor; eski bileşenden veya değişmiş token'dan gelen sonuçlar durum güncellemesine uygulanmıyor. Toplu yüklemenin sonraki dosyası ve kalem aktarımı öncesinde oturum kontrolü var. Ortak yükleme servisi FileReader tamamlandığında token değişmişse istek göndermiyor; ortak indirme servisi blob tamamlandığında token değişmişse tarayıcı indirmesi başlatmıyor. Bu kontroller sunucunun sahiplik kontrollerine ek olarak istemcide eski oturum işinin devamını sınırlıyor.
72 test ve üretim derlemesi geçti. Yeni test, FileReader sırasında hesap değiştiğinde sıfır yükleme isteği gönderildiğini ve blob okuma sırasında hesap değiştiğinde indirmenin reddedildiğini doğruluyor. Gerçek tarayıcıda çok dosyalı yükleme/hesap değişimi kabulü, aynı hesapta eşzamanlı metadata yanıt sıralaması ve diğer modüllerin oturum denetimi halen açık. 72 test ve üretim derlemesi geçti. Yeni test, FileReader sırasında hesap değiştiğinde sıfır yükleme isteği gönderildiğini ve blob okuma sırasında hesap değiştiğinde indirmenin reddedildiğini doğruluyor. Gerçek tarayıcıda çok dosyalı yükleme/hesap değişimi kabulü, aynı hesapta eşzamanlı metadata yanıt sıralaması ve diğer modüllerin oturum denetimi halen açık.
### Gerçek tarayıcıda PDF yükleme/yeniden işleme kabulü
Güncel backend için ayrı localhost:5174 QA örneği açıldı (önceki 5173 örneğine dokunulmadı). In-app tarayıcıda sentetik Giresun kaydına iki dosya yüklendi: okunabilir, cetvel içermeyen PDF ve kasıtlı bozuk PDF. Okunabilir PDF kalemsiz sonuç verdi; aynı dosyada yeniden çıkarım 0 kalem sonucunu gösterdi. Bozuk PDF kaydı korundu, okuma hatası kalıcı göründü. Genel depoya geçiş ve sayfa yenilemesi sonrasında iki dosya ve ayrı durumları korundu; depodaki yeniden çıkarım bozuk dosya hatasını gösterdi, belge sayısı 2 kaldı.
Tarayıcı testinde bulunan İngilizce PDF istisnası kullanıcıya yönelik Türkçe mesaja dönüştürüldü; depodaki eski 8 MB metni sunucunun 10 MB sınırıyla eşitlendi. Türkçe hata tarayıcıda tekrar doğrulandı. 72 test ve üretim derlemesi geçti.
Kanıt: evidence/qa-document-upload.txt (ilk hata metni dahil), evidence/qa-document-vault-retry.txt (düzeltme sonrası). Test dosyaları tests/fixtures/document-readable.pdf ve document-broken.pdf; resmi ihale belgesi değildir. Bu kabul OCR, 40 sayfayı aşan doküman, gerçek cetvel kalem doğruluğu veya beş resmi dosyanın tamamlanması anlamına gelmez. Bunlar halen açık.
+1 -1
View File
@@ -191,7 +191,7 @@ const DocumentVaultSession = ({signedIn}) => {
</div> </div>
<div> <div>
<h3 className="font-bold text-sm text-slate-800">Belge Yükleyin</h3> <h3 className="font-bold text-sm text-slate-800">Belge Yükleyin</h3>
<p className="text-xs text-slate-500">İmza sirküleri, sertifikalar, vergi levhası… (en fazla 8 MB)</p> <p className="text-xs text-slate-500">İmza sirküleri, sertifikalar, vergi levhası… (en fazla 10 MB)</p>
</div> </div>
<div className="flex justify-center gap-2 flex-wrap"> <div className="flex justify-center gap-2 flex-wrap">
<select value={kategori} onChange={(e) => setKategori(e.target.value)} <select value={kategori} onChange={(e) => setKategori(e.target.value)}
+7 -1
View File
@@ -10,7 +10,13 @@ export async function extractPdfText(file, { maxPages = 40 } = {}) {
pdfjs.GlobalWorkerOptions.workerSrc = workerUrl; pdfjs.GlobalWorkerOptions.workerSrc = workerUrl;
const buf = await file.arrayBuffer(); const buf = await file.arrayBuffer();
const doc = await pdfjs.getDocument({ data: buf }).promise; let doc;
try { doc = await pdfjs.getDocument({ data: buf }).promise; }
catch (error) {
if (error.name === 'InvalidPDFException') throw new Error('PDF dosyası bozuk veya geçerli PDF biçiminde değil.');
if (error.name === 'PasswordException') throw new Error('PDF parola korumalı; okunabilir bir kopyasını yükleyin.');
throw new Error('PDF okunamadı. Dosyayı kontrol edip yeniden deneyin.');
}
const pages = Math.min(doc.numPages, maxPages); const pages = Math.min(doc.numPages, maxPages);
const parts = []; const parts = [];
for (let i = 1; i <= pages; i++) { for (let i = 1; i <= pages; i++) {
+1
View File
@@ -0,0 +1 @@
Synthetic invalid PDF for isolated QA only.
+244
View File
@@ -0,0 +1,244 @@
%PDF-1.3
%ºß¬à
3 0 obj
<</Type /Page
/Parent 1 0 R
/Resources 2 0 R
/MediaBox [0 0 595.2799999999999727 841.8899999999999864]
/Contents 4 0 R
>>
endobj
4 0 obj
<<
/Length 399
>>
stream
0.5670000000000001 w
0 G
BT
/F1 16 Tf
18.3999999999999986 TL
0 g
42.5196850393700814 785.1970866141732586 Td
(SYNTHETIC QA DOCUMENT - NOT AN OFFICIAL TENDER) Tj
T* (Reference: 2026/1582991) Tj
T* (This PDF tests stored document reading and retry behavior.) Tj
T* (There is no bid schedule or product table in this fixture.) Tj
T* (No price or readiness decision may be derived from this file.) Tj
ET
endstream
endobj
1 0 obj
<</Type /Pages
/Kids [3 0 R ]
/Count 1
>>
endobj
5 0 obj
<<
/Type /Font
/BaseFont /Helvetica
/Subtype /Type1
/Encoding /WinAnsiEncoding
/FirstChar 32
/LastChar 255
>>
endobj
6 0 obj
<<
/Type /Font
/BaseFont /Helvetica-Bold
/Subtype /Type1
/Encoding /WinAnsiEncoding
/FirstChar 32
/LastChar 255
>>
endobj
7 0 obj
<<
/Type /Font
/BaseFont /Helvetica-Oblique
/Subtype /Type1
/Encoding /WinAnsiEncoding
/FirstChar 32
/LastChar 255
>>
endobj
8 0 obj
<<
/Type /Font
/BaseFont /Helvetica-BoldOblique
/Subtype /Type1
/Encoding /WinAnsiEncoding
/FirstChar 32
/LastChar 255
>>
endobj
9 0 obj
<<
/Type /Font
/BaseFont /Courier
/Subtype /Type1
/Encoding /WinAnsiEncoding
/FirstChar 32
/LastChar 255
>>
endobj
10 0 obj
<<
/Type /Font
/BaseFont /Courier-Bold
/Subtype /Type1
/Encoding /WinAnsiEncoding
/FirstChar 32
/LastChar 255
>>
endobj
11 0 obj
<<
/Type /Font
/BaseFont /Courier-Oblique
/Subtype /Type1
/Encoding /WinAnsiEncoding
/FirstChar 32
/LastChar 255
>>
endobj
12 0 obj
<<
/Type /Font
/BaseFont /Courier-BoldOblique
/Subtype /Type1
/Encoding /WinAnsiEncoding
/FirstChar 32
/LastChar 255
>>
endobj
13 0 obj
<<
/Type /Font
/BaseFont /Times-Roman
/Subtype /Type1
/Encoding /WinAnsiEncoding
/FirstChar 32
/LastChar 255
>>
endobj
14 0 obj
<<
/Type /Font
/BaseFont /Times-Bold
/Subtype /Type1
/Encoding /WinAnsiEncoding
/FirstChar 32
/LastChar 255
>>
endobj
15 0 obj
<<
/Type /Font
/BaseFont /Times-Italic
/Subtype /Type1
/Encoding /WinAnsiEncoding
/FirstChar 32
/LastChar 255
>>
endobj
16 0 obj
<<
/Type /Font
/BaseFont /Times-BoldItalic
/Subtype /Type1
/Encoding /WinAnsiEncoding
/FirstChar 32
/LastChar 255
>>
endobj
17 0 obj
<<
/Type /Font
/BaseFont /ZapfDingbats
/Subtype /Type1
/FirstChar 32
/LastChar 255
>>
endobj
18 0 obj
<<
/Type /Font
/BaseFont /Symbol
/Subtype /Type1
/FirstChar 32
/LastChar 255
>>
endobj
2 0 obj
<<
/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
/Font <<
/F1 5 0 R
/F2 6 0 R
/F3 7 0 R
/F4 8 0 R
/F5 9 0 R
/F6 10 0 R
/F7 11 0 R
/F8 12 0 R
/F9 13 0 R
/F10 14 0 R
/F11 15 0 R
/F12 16 0 R
/F13 17 0 R
/F14 18 0 R
>>
/XObject <<
>>
>>
endobj
19 0 obj
<<
/Producer (jsPDF 4.2.1)
/CreationDate (D:20260906093957+03'00')
>>
endobj
20 0 obj
<<
/Type /Catalog
/Pages 1 0 R
/OpenAction [3 0 R /FitH null]
/PageLayout /OneColumn
>>
endobj
xref
0 21
0000000000 65535 f
0000000602 00000 n
0000002419 00000 n
0000000015 00000 n
0000000152 00000 n
0000000659 00000 n
0000000784 00000 n
0000000914 00000 n
0000001047 00000 n
0000001184 00000 n
0000001307 00000 n
0000001436 00000 n
0000001568 00000 n
0000001704 00000 n
0000001832 00000 n
0000001959 00000 n
0000002088 00000 n
0000002221 00000 n
0000002323 00000 n
0000002667 00000 n
0000002753 00000 n
trailer
<<
/Size 21
/Root 20 0 R
/Info 19 0 R
/ID [ <FBBCA9D41DC98BC98838F862671E2D64> <FBBCA9D41DC98BC98838F862671E2D64> ]
>>
startxref
2857
%%EOF