reconcile official tender dates on detail open
This commit is contained in:
@@ -52,6 +52,38 @@ export async function fetchTenderDetail(tenderId, {signal, timeoutMs = 30000} =
|
||||
}
|
||||
}
|
||||
|
||||
// Live ilan.gov.tr rows can carry an older announcement date than EKAP's
|
||||
// authoritative tender detail. Fetch the official record when a user opens a
|
||||
// tender so the modal/card can reconcile the date without enriching the full
|
||||
// pool (which would be too expensive for thousands of rows).
|
||||
export async function fetchOfficialTenderDetail(ikn, {signal, timeoutMs = 30000} = {}) {
|
||||
const cleanIkn = String(ikn || '').replace(/[\s\u00a0]+/g, '');
|
||||
if (!/^\d{4}\/\d+$/.test(cleanIkn)) throw new Error('Geçersiz İKN');
|
||||
const controller = new AbortController();
|
||||
const cancel = () => controller.abort();
|
||||
if (signal?.aborted) cancel();
|
||||
else signal?.addEventListener('abort', cancel, { once: true });
|
||||
let timedOut = false;
|
||||
const timer = setTimeout(() => { timedOut = true; controller.abort(); }, timeoutMs);
|
||||
try {
|
||||
const res = await fetch(`/api/documents/ilan?ikn=${encodeURIComponent(cleanIkn)}`, { signal: controller.signal });
|
||||
const data = await res.json().catch(() => ({}));
|
||||
if (!res.ok) {
|
||||
if (data.code === 'SOURCE_UNAVAILABLE' && data.retryable) throw new Error('Resmî ihale kaynağı geçici olarak erişilemiyor.');
|
||||
throw new Error(`Resmî detay API hatası: HTTP ${res.status}`);
|
||||
}
|
||||
if (!data.success || data.ikn !== cleanIkn) throw new Error('Resmî detay yanıtı aranan İKN ile uyuşmuyor.');
|
||||
if (!data.tarih || !data.saat) throw new Error('Resmî detayda ihale tarih ve saati bulunamadı.');
|
||||
return data;
|
||||
} catch (error) {
|
||||
if (timedOut) throw new Error('Resmî ihale tarihi yüklenirken zaman aşımı oluştu.');
|
||||
throw error;
|
||||
} finally {
|
||||
clearTimeout(timer);
|
||||
signal?.removeEventListener('abort', cancel);
|
||||
}
|
||||
}
|
||||
|
||||
// Kullanıcının ihale üzerindeki durumunu (kanban, takip vb.) canlı veriyle birleştirir.
|
||||
const USER_FIELDS = ['kanbanStatus', 'takipte', 'incelendi', 'atananPersonel', 'gorev', 'notes', 'checklist', 'bidDraft'];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user