add reproducible live five tender probe
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
// 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 })) }));
|
||||
Reference in New Issue
Block a user