fix: align server deadlines and follow consumers with preparation state
This commit is contained in:
+21
-15
@@ -6,6 +6,8 @@
|
||||
// Claude Desktop (mcp-remote) araçları: search_tenders, get_tender,
|
||||
// search_results, search_items, upcoming_deadlines. Bağımlılık yok.
|
||||
import * as store from './user-store.mjs';
|
||||
import { deadlineInfo, tenderDateKey } from '../src/services/tenderCalendar.js';
|
||||
import { applyTenderStates, tenderStateKey } from '../src/services/tenderState.js';
|
||||
import { readHistory, resultsByIkn } from './history-store.mjs';
|
||||
import * as kalemStore from './kalem-store.mjs';
|
||||
|
||||
@@ -25,17 +27,17 @@ export function rssUret({ title, link, description, items }) {
|
||||
|
||||
/** dd.mm.yyyy → Date (ihaleist tarih biçimi). */
|
||||
export function trTarih(s) {
|
||||
const m = /(\d{1,2})[./](\d{1,2})[./](\d{4})/.exec(String(s ?? ''));
|
||||
return m ? new Date(Number(m[3]), Number(m[2]) - 1, Number(m[1])) : null;
|
||||
const m = /^(\d{1,2})[./](\d{1,2})[./](\d{4})$/.exec(String(s ?? '').trim());
|
||||
const key = m && tenderDateKey({ tarih: `${m[1].padStart(2, '0')}.${m[2].padStart(2, '0')}.${m[3]}` });
|
||||
return key ? new Date(key + 'T00:00:00+03:00') : null;
|
||||
}
|
||||
|
||||
/** Liste filtresi — RSS ve MCP ortak. */
|
||||
export function ihaleFiltrele(tenders, { q, il, sektor, sadeceAcik = true, limit = 50 } = {}) {
|
||||
export function ihaleFiltrele(tenders, { q, il, sektor, sadeceAcik = true, limit = 50 } = {}, now = new Date()) {
|
||||
const qq = norm(q); const ill = norm(il); const sek = norm(sektor);
|
||||
const bugun = new Date(); bugun.setHours(0, 0, 0, 0);
|
||||
return tenders
|
||||
.filter((t) => !sadeceAcik || !t.kazananFirma)
|
||||
.filter((t) => !sadeceAcik || !trTarih(t.tarih) || trTarih(t.tarih) >= bugun)
|
||||
.filter((t) => !sadeceAcik || deadlineInfo(t, now).expired !== true)
|
||||
.filter((t) => !ill || norm(t.sehir).includes(ill))
|
||||
.filter((t) => !sek || norm(t.sektor).includes(sek))
|
||||
.filter((t) => !qq || norm(t.baslik).includes(qq) || norm(t.kurum).includes(qq) || String(t.ikn ?? '').includes(qq) ||
|
||||
@@ -99,16 +101,20 @@ export const TOOLS = [
|
||||
const hata = (id, code, message) => ({ jsonrpc: '2.0', id: id ?? null, error: { code, message } });
|
||||
const sonuc = (id, result) => ({ jsonrpc: '2.0', id: id ?? null, result });
|
||||
|
||||
export function yaklasanIhaleler(email, tenders, gun = 14) {
|
||||
const takip = new Set((store.getData(email, 'takip') || []).map(String));
|
||||
const bugun = new Date(); bugun.setHours(0, 0, 0, 0);
|
||||
const sinir = new Date(bugun.getTime() + gun * 86400000);
|
||||
return tenders
|
||||
.filter((t) => t.ikn && takip.has(String(t.ikn)))
|
||||
.map((t) => ({ t, d: trTarih(t.tarih) }))
|
||||
.filter(({ d }) => d && d >= bugun && d <= sinir)
|
||||
.sort((a, b) => a.d - b.d)
|
||||
.map(({ t, d }) => ({ ikn: t.ikn, baslik: t.baslik, kurum: t.kurum, sehir: t.sehir, tarih: t.tarih, saat: t.saat, kalan_gun: Math.round((d - bugun) / 86400000), kaynakUrl: t.kaynakUrl }));
|
||||
export function yaklasanIhaleler(email, tenders, gun = 14, now = new Date()) {
|
||||
const states = store.getTenderStates(email);
|
||||
const takip = new Set(store.getTrackedTenderKeys(email, states));
|
||||
const days = Math.min(90, Math.max(1, Math.floor(Number(gun) || 14)));
|
||||
return applyTenderStates(tenders, states)
|
||||
.filter(t => !t.kazananFirma && takip.has(tenderStateKey(t)))
|
||||
.map(t => ({ t, info: deadlineInfo(t, now) }))
|
||||
.filter(({ info }) => info.days !== null && info.days >= 0 && info.days <= days && info.expired !== true)
|
||||
.sort((a, b) => a.info.days - b.info.days ||
|
||||
(a.info.deadline?.getTime() ?? Infinity) - (b.info.deadline?.getTime() ?? Infinity))
|
||||
.map(({ t, info }) => ({ ikn: t.ikn, baslik: t.baslik, kurum: t.kurum, sehir: t.sehir,
|
||||
tarih: t.tarih, saat: t.saat, kalan_gun: info.days,
|
||||
son_teklif_zamani: info.deadline?.toISOString() ?? null,
|
||||
saat_dogrulanmali: !info.deadline, kaynakUrl: t.kaynakUrl }));
|
||||
}
|
||||
|
||||
export async function aracCalistir(name, args, user, ctx) {
|
||||
|
||||
Reference in New Issue
Block a user