From 171392585c0691e6ac63623d8e33ed0605df0e6f Mon Sep 17 00:00:00 2001 From: ht Date: Sun, 6 Sep 2026 18:55:43 +0300 Subject: [PATCH] classify document source outages --- docs/quality/uygulama-durumu.md | 4 ++++ server/index.js | 13 ++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/quality/uygulama-durumu.md b/docs/quality/uygulama-durumu.md index dab0f73..3c83ca6 100644 --- a/docs/quality/uygulama-durumu.md +++ b/docs/quality/uygulama-durumu.md @@ -10,6 +10,10 @@ Aynı read-only taramada 6 Eylül 2026 sonrası beş güncel sağlık/tıbbi mal Bu beş adayın canlı `/api/documents/ilan` çağrıları da read-only denendi ve tamamı HTTP 502 döndürdü. Resmi ilan metni alınamadığı için kalem, belge, ÜTS veya teklif türü doğrulaması yapılmadı. Kanıt [`qa-live-health-document-probe.json`](evidence/qa-live-health-document-probe.json). +Belge URL’si, ilan metni ve tarayıcı belge metni endpoint’leri artık 502 durumunda `code: SOURCE_UNAVAILABLE` ve `retryable: true` alanlarını döndürüyor. İstemciler kaynak kesintisini kalıcı biçim hatasından ayırıp yeniden deneme sunabilir. + +Doğrulama: 292/292 otomatik test geçti. + ## Kanıtlanan ilk değişiklikler - Eski belgeler tablosunda ikn indeksi kolon migration'ından önce oluşuyordu. Transaction içinde kolonlar önce ekleniyor; eski belgeyi koruyan, tekrarlanabilir migration testi geçti. diff --git a/server/index.js b/server/index.js index 594e3d1..2347d64 100644 --- a/server/index.js +++ b/server/index.js @@ -657,6 +657,13 @@ function json(res, code, body) { res.end(JSON.stringify(body)); } +const sourceUnavailable = error => ({ + success: false, + error: error?.message || 'Resmi belge kaynağına ulaşılamadı.', + code: 'SOURCE_UNAVAILABLE', + retryable: true, +}); + function readRaw(req, limit = 1024 * 1024) { return new Promise((resolve, reject) => { let buf = ''; @@ -829,7 +836,7 @@ const server = http.createServer(async (req, res) => { const out = await documentUrl(ikn); return json(res, 200, { success: true, ...out }); } catch (e) { - return json(res, 502, { success: false, error: e.message }); + return json(res, 502, sourceUnavailable(e)); } } // İlan metni + kalemler — analiz için (tarayıcı gerektirmez) @@ -840,7 +847,7 @@ const server = http.createServer(async (req, res) => { const out = await ilanMetni(ikn); return json(res, 200, { success: true, ...out, ...announcementFields(out.metin) }); } catch (e) { - return json(res, 502, { success: false, error: e.message }); + return json(res, 502, sourceUnavailable(e)); } } // Doküman metni — sunucu tarafı tarayıcı gerektirir @@ -853,7 +860,7 @@ const server = http.createServer(async (req, res) => { const out = await documentText(ikn); return json(res, 200, { success: true, ...out }); } catch (e) { - return json(res, 502, { success: false, error: e.message }); + return json(res, 502, sourceUnavailable(e)); } } if (url.pathname === '/api/documents/config') {