fix: handle malformed document lists in preparation overview

This commit is contained in:
2026-09-06 16:23:14 +03:00
parent b5b3d75341
commit b49ae4c59f
4 changed files with 12 additions and 2 deletions
+5
View File
@@ -1276,3 +1276,8 @@ Taslak türü seçicisine erişilebilir ad eklendi. Üretim derlemesi geçti. Ö
- Kayıtlı filtre oluşturma formu artık mevcut anahtar kelime, kurum adı, İKN, şehir, bölge, alım türü, kurum tipi ve ilk sektör ölçütünü başlangıç değeri olarak gösteriyor. Kullanıcı aynı aramayı tekrar elle kurmadan ad verip kaydedebiliyor. - Kayıtlı filtre oluşturma formu artık mevcut anahtar kelime, kurum adı, İKN, şehir, bölge, alım türü, kurum tipi ve ilk sektör ölçütünü başlangıç değeri olarak gösteriyor. Kullanıcı aynı aramayı tekrar elle kurmadan ad verip kaydedebiliyor.
- Alanlar yalnız ilk oluşturulma anında okunuyor; form içindeki taslak değişiklikleri canlı liste durumunun etkisiyle ezilmiyor. Eski kayıt uygulama davranışı değişmedi. - Alanlar yalnız ilk oluşturulma anında okunuyor; form içindeki taslak değişiklikleri canlı liste durumunun etkisiyle ezilmiyor. Eski kayıt uygulama davranışı değişmedi.
- 278 test ve build başarılı. Bu ön doldurma için ayrı tarayıcı kabulü henüz eklenmedi; genel plan açık. - 278 test ve build başarılı. Bu ön doldurma için ayrı tarayıcı kabulü henüz eklenmedi; genel plan açık.
### 2026-09-06 — Belge deposu yanıt şekli dayanıklılığı
- Hazırlık özeti, belge deposu yanıtında `belgeler` alanı eksik veya dizi dışı geldiğinde artık çökmüyor; boş belge listesiyle eksik kontrolü gösteriyor. Bileşen ve özet servisi aynı dizi doğrulamasını kullanıyor.
- Bozuk yanıt için regresyon testi eklendi. 279 test, build ve diff kontrolü başarılı. Gerçek ağ kesintisi kabulü daha önceki hata yolu ile sınırlı; genel plan açık.
+1 -1
View File
@@ -14,7 +14,7 @@ function Overview({tenders,now}) {
useEffect(()=>{ useEffect(()=>{
let cancelled=false; let cancelled=false;
setVault({loading:true,error:null,documents:[]}); setVault({loading:true,error:null,documents:[]});
listDocuments().then(data=>{if(!cancelled)setVault({loading:false,error:null,documents:data.belgeler});}) listDocuments().then(data=>{if(!cancelled)setVault({loading:false,error:null,documents:Array.isArray(data?.belgeler) ? data.belgeler : []});})
.catch(error=>{if(!cancelled)setVault({loading:false,error:error.message,documents:[]});}); .catch(error=>{if(!cancelled)setVault({loading:false,error:error.message,documents:[]});});
return()=>{cancelled=true;}; return()=>{cancelled=true;};
},[refresh]); },[refresh]);
+1 -1
View File
@@ -34,7 +34,7 @@ export function preparationSummary(tender,vault,now=new Date()) {
if(priced.length&&!validateBidRows(priced).length&&bidTotal(priced)===null)add('pricing','Genel toplam geçersiz veya hesaplama sınırını aşıyor.'); if(priced.length&&!validateBidRows(priced).length&&bidTotal(priced)===null)add('pricing','Genel toplam geçersiz veya hesaplama sınırını aşıyor.');
} }
if(bidType==='goturu'&&bidAmount(draft.goturuBedel)===null)add('lumpSum','Toplam teklif bedelini kontrol edin.'); if(bidType==='goturu'&&bidAmount(draft.goturuBedel)===null)add('lumpSum','Toplam teklif bedelini kontrol edin.');
const checkedVault={...vault,deadlineDate:tenderDateKey(tender),tenderIkn:tender.ikn}; const checkedVault={...vault,documents:Array.isArray(vault?.documents) ? vault.documents : [],deadlineDate:tenderDateKey(tender),tenderIkn:tender.ikn};
const documentIssues=preparationBlockers([],documents,draft.checks,checkedVault); const documentIssues=preparationBlockers([],documents,draft.checks,checkedVault);
preparationBlockers(selection.rows,documents,draft.checks,checkedVault).forEach(text=>add('checks',text)); preparationBlockers(selection.rows,documents,draft.checks,checkedVault).forEach(text=>add('checks',text));
return {issues,documentIssues,owner:tender.atananPersonel || 'Atanmadı',next:issues[0] || {target:'source',text:'Dosyayı açıp son kontrolleri yapın.'}}; return {issues,documentIssues,owner:tender.atananPersonel || 'Atanmadı',next:issues[0] || {target:'source',text:'Dosyayı açıp son kontrolleri yapın.'}};
+5
View File
@@ -30,3 +30,8 @@ test('expired source takes priority over completion or manually moved Kanban sta
assert.equal(summary.next.target,'source'); assert.equal(summary.next.target,'source');
assert.equal(summary.owner,'Atanmadı'); assert.equal(summary.owner,'Atanmadı');
}); });
test('malformed document response is treated as empty instead of crashing the summary',()=>{
assert.doesNotThrow(()=>preparationSummary(tender,{loading:false,error:null,documents:null},now));
const summary=preparationSummary(tender,{loading:false,error:null,documents:null},now);
assert.ok(summary.documentIssues.some(text=>text.includes('belge')));
});