diff --git a/docs/quality/uygulama-durumu.md b/docs/quality/uygulama-durumu.md index 4ea351e..c3ff294 100644 --- a/docs/quality/uygulama-durumu.md +++ b/docs/quality/uygulama-durumu.md @@ -2260,3 +2260,9 @@ Doğrulama: browserTimezone `America/New_York`, mobil viewport 390 px ve yatay t Canlı drift probe’u artık API yanıt gövdesini de doğruluyor: `/api/health` için `ok:true`, `/api/ready` için `success:true` ve JSON içerik türü aranıyor. Böylece HTTP 200 dönen SPA/ara hata sayfaları sağlıklı servis kabul edilmiyor. Güncel canlı sonuçta health `ok:true` olsa da readiness `404` ve güvenlik başlıkları eksik olduğu için probe başarısız kaldı; kanıt `qa-live-runtime.json` içinde. + +### 2026-09-06 · D04 sonuç durumu normalizasyonu + +Kaynaklar `Sonuçlandı` durumunu boşluk veya büyük/küçük harf farkıyla döndürdüğünde tekilleştirme artık aynı award anahtarını kullanıyor. Lot numarası hâlâ kimliğin parçası; farklı kısımlar birbirine karışmıyor ve aynı lotun farklı kaynak kayıtları birleşiyor. + +Doğrulama: yeni regresyonla otomatik test sayısı 295/295’e yükseldi; üretim derlemesi başarılı. diff --git a/server/tender-quality.mjs b/server/tender-quality.mjs index 5bf27ef..4efb851 100644 --- a/server/tender-quality.mjs +++ b/server/tender-quality.mjs @@ -2,7 +2,7 @@ const norm = v => String(v || '').trim().replace(/\s+/g,' ').toLocaleLowerCase(' export function tenderIdentity(t) { const ikn = String(t.ikn || '').replace(/\s/g,''); // Awards from different lots must never be collapsed into one contract. - if (t.durum === 'Sonuçlandı') return `award:${ikn}:${t.kisim ?? t.id}:${norm(t.kazananFirma)}`; + if (norm(t.durum) === 'sonuçlandı') return `award:${ikn}:${t.kisim ?? t.id}:${norm(t.kazananFirma)}`; if (/^\d{2}DT\d+$/i.test(ikn)) return `dt:${ikn.toUpperCase()}:${norm(t.kurum)}`; // Corrections/cancellations remain separate events until their source linkage is verified. if (/düzeltme|zeyilname|iptal/i.test(t.baslik || '')) return `event:${t.id}`; diff --git a/tests/tender-quality.test.mjs b/tests/tender-quality.test.mjs index 5066ee6..d76f4bb 100644 --- a/tests/tender-quality.test.mjs +++ b/tests/tender-quality.test.mjs @@ -11,6 +11,13 @@ test('distinct contract lots and corrections remain separate',()=>{ assert.equal(uniqueTenders([t,t,{...t,id:'b',kisim:'2'}]).length,2); assert.equal(uniqueTenders([{ikn:'2026/123',id:'1'},{ikn:'2026/123',id:'2',baslik:'Düzeltme ilanı'}]).length,2); }); +test('result status whitespace is normalized without collapsing distinct lots',()=>{ + const first={ikn:'2026/456',durum:' Sonuçlandı ',kisim:'1',id:'a',kazananFirma:'Firma'}; + const same={...first,id:'b'}; + const other={...first,id:'c',kisim:'2'}; + const out=uniqueTenders([first,same,other]); + assert.equal(out.length,2);assert.deepEqual(out[0].sourceIds,['a','b']); +}); test('malformed source rows do not crash pool deduplication',()=>{ const out=uniqueTenders([null,42,{},[],{ikn:'2026/123',baslik:'Eksik kimlik'}]); assert.deepEqual(out,[]);