// Read-only production acceptance probe for the five health/laboratory tenders. // No authentication, writes, payments, messages, or tender submissions. import { writeFile } from 'node:fs/promises'; import { healthAcceptanceCases } from './fixtures/health-acceptance.mjs'; const base = String(process.argv[2] || 'https://ihaleist.com').replace(/\/$/, ''); const evidencePath = process.env.IHALEIST_LIVE_FIVE_EVIDENCE_PATH || 'docs/quality/evidence/qa-live-five-tenders.json'; const timeoutMs = 30_000; async function getJson(path) { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeoutMs); try { const response = await fetch(`${base}${path}`, { signal: controller.signal, headers: { 'User-Agent': 'ihaleist-live-five-probe/1.0' } }); const data = await response.json().catch(() => null); if (!response.ok || !data || data.success !== true) throw new Error(`${path}: HTTP ${response.status}`); return data; } finally { clearTimeout(timer); } } const list = await getJson('/api/tenders?limit=100'); const byIkn = new Map((Array.isArray(list.tenders) ? list.tenders : []).map((tender) => [String(tender.ikn || '').replace(/\s/g, ''), tender])); const tenders = []; for (const fixture of healthAcceptanceCases) { const ikn = `2026/${fixture.ikn}`; const listed = byIkn.get(ikn); if (!listed) throw new Error(`${ikn}: live listede bulunamadı`); const detail = await getJson(`/api/tenders/${encodeURIComponent(listed.id)}/detail`); const document = await getJson(`/api/documents/ilan?ikn=${encodeURIComponent(ikn)}`); const officialDate = document.sourceDateTime || `${document.tarih || detail.tarih || ''} ${document.saat || detail.saat || ''}`.trim(); if (!officialDate || !document.ikn || document.ikn !== ikn) throw new Error(`${ikn}: resmi tarih/İKN doğrulanamadı`); tenders.push({ ikn, scenario: fixture.scenario, id: listed.id, title: listed.baslik, institution: listed.kurum, city: listed.sehir, sector: listed.sektor, procedure: listed.usul, announcementDate: listed.ilanTarihi, tenderDate: document.tarih || detail.tarih || '', tenderTime: document.saat || detail.saat || '', sourceDateTime: officialDate, officialDateSource: 'documents/ilan sourceDateTime', announcementDateConflict: ikn === '2026/1573235' && listed.tarih !== document.tarih ? `ilan listesi ${listed.tarih}; resmi detay ${document.tarih}` : null, detailStatus: detail.success === true, documentProbeStatus: 200, documentCount: Number(document.dokumanSayisi) || 0, announcementCount: Number(document.ilanSayisi) || 0, okasCount: Number(document.okasSayisi) || 0, documentEndpointSuccess: document.success === true, sourceUrl: listed.kaynakUrl, }); } const result = { checkedAt: new Date().toISOString(), base, readOnly: true, listCount: Array.isArray(list.tenders) ? list.tenders.length : 0, tenders, scope: 'Live metadata/detail/document endpoint probes only; no authentication, writes, payments, messages, or submissions.', }; await writeFile(evidencePath, `${JSON.stringify(result, null, 2)}\n`); console.log(JSON.stringify({ base, checkedAt: result.checkedAt, tenders: tenders.map(({ ikn, tenderDate, tenderTime, documentCount }) => ({ ikn, tenderDate, tenderTime, documentCount })) }));