Hold stale tender notification retries for review
This commit is contained in:
+23
-3
@@ -9,7 +9,7 @@ import {deadlineInfo} from '../src/services/tenderCalendar.js';
|
||||
* NOTIFY_MAX=25 → e-postada listelenecek en fazla ihale
|
||||
*/
|
||||
|
||||
import { list, markBaseline, reserveDelivery, acceptDelivery, failDelivery, available } from './notify-store.mjs';
|
||||
import { list, markBaseline, reserveDelivery, acceptDelivery, failDelivery, holdDelivery, available } from './notify-store.mjs';
|
||||
import { emailConfigured, emailFrom, sendEmail, tenderDigestHtml, escapeHtml } from './email.mjs';
|
||||
import { telegramConfigured, sendTelegram, tgKacir } from './telegram.mjs';
|
||||
import { getData } from './user-store.mjs';
|
||||
@@ -62,13 +62,30 @@ export function bildirilebilir(t,now=new Date()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// A retry must preserve its original provider request; stale content needs review,
|
||||
// not a rewritten payload under the old idempotency key.
|
||||
export function deliverySourceProblem(delivery,current,clock) {
|
||||
const pinned = delivery.payload.digest;
|
||||
if (!Array.isArray(pinned) || pinned.length !== delivery.tenderIds.length)
|
||||
return 'Gönderim kaynağı doğrulanamadı; otomatik tekrar durduruldu. Yönetici incelemesi gerekli.';
|
||||
const byId = new Map(current.map(t=>[t.id,t]));
|
||||
for (let i=0;i<pinned.length;i++) {
|
||||
const old = pinned[i], fresh = old && byId.get(old.id);
|
||||
if (!old || old.id !== delivery.tenderIds[i] || !fresh || !bildirilebilir(fresh,clock)
|
||||
|| !bildirilebilir(old,clock)
|
||||
|| deadlineInfo(old,clock).deadline?.getTime() !== deadlineInfo(fresh,clock).deadline?.getTime())
|
||||
return 'İhale kaynağı, son teklif zamanı veya başvuru durumu değişti/doğrulanamıyor. Eski e-posta yeniden gönderilmedi; sağlayıcı kaydı ve güncel ilan için yönetici incelemesi gerekli.';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tüm aktif abonelikleri işler.
|
||||
* @param {Function} tenderGetir () => Promise<{tenders: []}>
|
||||
*/
|
||||
let processing=false;
|
||||
export async function bildirimleriIsle(tenderGetir, { zorla = false } = {}, dependencies={}) {
|
||||
const {readSubscriptions=list,saveBaseline=markBaseline,reserve=reserveDelivery,accepted=acceptDelivery,failed=failDelivery,configured=emailConfigured,
|
||||
const {readSubscriptions=list,saveBaseline=markBaseline,reserve=reserveDelivery,accepted=acceptDelivery,failed=failDelivery,hold=holdDelivery,configured=emailConfigured,
|
||||
deliverEmail=sendEmail,telegramReady=telegramConfigured,deliverTelegram=sendTelegram,now=()=>new Date()}=dependencies;
|
||||
if(processing)return {atlandi:'önceki tur sürüyor'};
|
||||
processing=true;
|
||||
@@ -81,7 +98,8 @@ export async function bildirimleriIsle(tenderGetir, { zorla = false } = {}, depe
|
||||
if (!abonelikler.length) return { abonelik: 0 };
|
||||
|
||||
const veri = await tenderGetir();
|
||||
const tumu = notificationSource(veri).filter(t=>bildirilebilir(t,now()));
|
||||
const source = notificationSource(veri);
|
||||
const tumu = source.filter(t=>bildirilebilir(t,now()));
|
||||
const requested=Number(process.env.NOTIFY_MAX || 25);
|
||||
const maxAdet=Number.isInteger(requested)&&requested>0?Math.min(requested,200):25;
|
||||
|
||||
@@ -125,6 +143,8 @@ export async function bildirimleriIsle(tenderGetir, { zorla = false } = {}, depe
|
||||
},gonderilecek.map(t=>t.id),{force:zorla});
|
||||
if(!delivery)continue;
|
||||
if(delivery.blocked){hata++;continue;}
|
||||
const sourceProblem=deliverySourceProblem(delivery,source,now());
|
||||
if(sourceProblem){hold(delivery,sourceProblem);hata++;continue;}
|
||||
try {
|
||||
const result=await deliverEmail({...delivery.payload,idempotencyKey:'notify/'+delivery.id});
|
||||
accepted(delivery,result?.id);
|
||||
|
||||
Reference in New Issue
Block a user