validate notification history arrays
This commit is contained in:
+14
-5
@@ -19,6 +19,15 @@ try {
|
|||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const DATA_DIR = process.env.IHALEIST_USER_DATA_DIR || path.join(__dirname, 'data');
|
const DATA_DIR = process.env.IHALEIST_USER_DATA_DIR || path.join(__dirname, 'data');
|
||||||
const DB_PATH = path.join(DATA_DIR, 'notify.sqlite');
|
const DB_PATH = path.join(DATA_DIR, 'notify.sqlite');
|
||||||
|
function parseArrayJson(raw, label) {
|
||||||
|
try {
|
||||||
|
const value = JSON.parse(raw || '[]');
|
||||||
|
if (!Array.isArray(value)) throw new Error('dizi değil');
|
||||||
|
return value;
|
||||||
|
} catch {
|
||||||
|
throw new Error(`${label} verisi bozuk; bildirim işlemi durduruldu.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const SCHEMA = `
|
const SCHEMA = `
|
||||||
CREATE TABLE IF NOT EXISTS abonelikler (
|
CREATE TABLE IF NOT EXISTS abonelikler (
|
||||||
@@ -182,7 +191,7 @@ function recordSeen(id,ihaleIdleri,sent) {
|
|||||||
db.exec('BEGIN IMMEDIATE');
|
db.exec('BEGIN IMMEDIATE');
|
||||||
const row=db.prepare('SELECT sonGorulenler FROM abonelikler WHERE id=?').get(id);
|
const row=db.prepare('SELECT sonGorulenler FROM abonelikler WHERE id=?').get(id);
|
||||||
if(!row)throw new Error('Abonelik artık yok.');
|
if(!row)throw new Error('Abonelik artık yok.');
|
||||||
const seen=[...new Set([...JSON.parse(row.sonGorulenler || '[]'),...ihaleIdleri])];
|
const seen=[...new Set([...parseArrayJson(row.sonGorulenler, 'Görülen ihale'),...ihaleIdleri])];
|
||||||
db.prepare('UPDATE abonelikler SET sonGorulenler=?,sonGonderim=CASE WHEN ? THEN ? ELSE sonGonderim END WHERE id=?')
|
db.prepare('UPDATE abonelikler SET sonGorulenler=?,sonGonderim=CASE WHEN ? THEN ? ELSE sonGonderim END WHERE id=?')
|
||||||
.run(JSON.stringify(seen),sent?1:0,new Date().toISOString(),id);
|
.run(JSON.stringify(seen),sent?1:0,new Date().toISOString(),id);
|
||||||
db.exec('COMMIT');
|
db.exec('COMMIT');
|
||||||
@@ -200,7 +209,7 @@ export function reserveDelivery(subscriptionId,payload,tenderIds,{clock=Date.now
|
|||||||
if(!subscription){db.exec('COMMIT');return null;}
|
if(!subscription){db.exec('COMMIT');return null;}
|
||||||
let row=db.prepare("SELECT * FROM notification_outbox WHERE subscription_id=? AND state IN ('pending','sending','uncertain')").get(subscriptionId);
|
let row=db.prepare("SELECT * FROM notification_outbox WHERE subscription_id=? AND state IN ('pending','sending','uncertain')").get(subscriptionId);
|
||||||
if(!row){
|
if(!row){
|
||||||
const seen=new Set(JSON.parse(subscription.sonGorulenler || '[]'));
|
const seen=new Set(parseArrayJson(subscription.sonGorulenler, 'Görülen ihale'));
|
||||||
if(!payload||!tenderIds.length||(!force&&tenderIds.some(id=>seen.has(id)))){db.exec('COMMIT');return null;}
|
if(!payload||!tenderIds.length||(!force&&tenderIds.some(id=>seen.has(id)))){db.exec('COMMIT');return null;}
|
||||||
const id=randomUUID();
|
const id=randomUUID();
|
||||||
db.prepare("INSERT INTO notification_outbox(id,subscription_id,payload,tender_ids,state) VALUES (?,?,?,?,'pending')").run(id,subscriptionId,JSON.stringify(payload),JSON.stringify(tenderIds));
|
db.prepare("INSERT INTO notification_outbox(id,subscription_id,payload,tender_ids,state) VALUES (?,?,?,?,'pending')").run(id,subscriptionId,JSON.stringify(payload),JSON.stringify(tenderIds));
|
||||||
@@ -215,7 +224,7 @@ export function reserveDelivery(subscriptionId,payload,tenderIds,{clock=Date.now
|
|||||||
const lease=randomUUID();
|
const lease=randomUUID();
|
||||||
db.prepare("UPDATE notification_outbox SET state='sending',first_attempt=COALESCE(first_attempt,?),lease=?,lease_until=? WHERE id=?").run(clock,lease,clock+120000,row.id);
|
db.prepare("UPDATE notification_outbox SET state='sending',first_attempt=COALESCE(first_attempt,?),lease=?,lease_until=? WHERE id=?").run(clock,lease,clock+120000,row.id);
|
||||||
db.exec('COMMIT');return {id:row.id,lease,payload:JSON.parse(row.payload),tenderIds:JSON.parse(row.tender_ids)};
|
db.exec('COMMIT');return {id:row.id,lease,payload:JSON.parse(row.payload),tenderIds:JSON.parse(row.tender_ids)};
|
||||||
}catch(error){try{db.exec('ROLLBACK');}catch{}throw error;}finally{db.close();}
|
}catch(error){try{db.exec('ROLLBACK');}catch{}throw error;}finally{db.close();}
|
||||||
}
|
}
|
||||||
export function acceptDelivery(delivery,providerId) {
|
export function acceptDelivery(delivery,providerId) {
|
||||||
if(typeof providerId!=='string'||!providerId)throw new Error('Sağlayıcı gönderim kimliği gerekli.');
|
if(typeof providerId!=='string'||!providerId)throw new Error('Sağlayıcı gönderim kimliği gerekli.');
|
||||||
@@ -226,7 +235,7 @@ export function acceptDelivery(delivery,providerId) {
|
|||||||
if(!row)throw new Error('Gönderim kaydı artık etkin değil.');
|
if(!row)throw new Error('Gönderim kaydı artık etkin değil.');
|
||||||
const subscription=db.prepare('SELECT sonGorulenler FROM abonelikler WHERE id=?').get(row.subscription_id);
|
const subscription=db.prepare('SELECT sonGorulenler FROM abonelikler WHERE id=?').get(row.subscription_id);
|
||||||
if(!subscription)throw new Error('Abonelik artık yok.');
|
if(!subscription)throw new Error('Abonelik artık yok.');
|
||||||
const seen=[...new Set([...JSON.parse(subscription.sonGorulenler||'[]'),...JSON.parse(row.tender_ids)])];
|
const seen=[...new Set([...parseArrayJson(subscription.sonGorulenler, 'Görülen ihale'),...parseArrayJson(row.tender_ids, 'İhale')])];
|
||||||
db.prepare('UPDATE abonelikler SET sonGorulenler=?,sonGonderim=? WHERE id=?').run(JSON.stringify(seen),new Date().toISOString(),row.subscription_id);
|
db.prepare('UPDATE abonelikler SET sonGorulenler=?,sonGonderim=? WHERE id=?').run(JSON.stringify(seen),new Date().toISOString(),row.subscription_id);
|
||||||
db.prepare("UPDATE notification_outbox SET state='sent',provider_id=?,error=NULL WHERE id=?").run(providerId,row.id);
|
db.prepare("UPDATE notification_outbox SET state='sent',provider_id=?,error=NULL WHERE id=?").run(providerId,row.id);
|
||||||
db.exec('COMMIT');
|
db.exec('COMMIT');
|
||||||
@@ -264,7 +273,7 @@ export function resolveDelivery(id,actor,input) {
|
|||||||
if(!row)throw Object.assign(new Error('Kayıt artık inceleme beklemiyor. Listeyi yenileyin.'),{status:409});
|
if(!row)throw Object.assign(new Error('Kayıt artık inceleme beklemiyor. Listeyi yenileyin.'),{status:409});
|
||||||
const subscription=db.prepare('SELECT sonGorulenler FROM abonelikler WHERE id=?').get(row.subscription_id);
|
const subscription=db.prepare('SELECT sonGorulenler FROM abonelikler WHERE id=?').get(row.subscription_id);
|
||||||
if(!subscription)throw new Error('Abonelik artık yok.');
|
if(!subscription)throw new Error('Abonelik artık yok.');
|
||||||
const seen=[...new Set([...JSON.parse(subscription.sonGorulenler||'[]'),...JSON.parse(row.tender_ids)])];
|
const seen=[...new Set([...parseArrayJson(subscription.sonGorulenler, 'Görülen ihale'),...parseArrayJson(row.tender_ids, 'İhale')])];
|
||||||
const now=new Date().toISOString(),sent=input.action==='confirmed_sent';
|
const now=new Date().toISOString(),sent=input.action==='confirmed_sent';
|
||||||
db.prepare('UPDATE abonelikler SET sonGorulenler=?,sonGonderim=CASE WHEN ? THEN ? ELSE sonGonderim END WHERE id=?').run(JSON.stringify(seen),sent?1:0,now,row.subscription_id);
|
db.prepare('UPDATE abonelikler SET sonGorulenler=?,sonGonderim=CASE WHEN ? THEN ? ELSE sonGonderim END WHERE id=?').run(JSON.stringify(seen),sent?1:0,now,row.subscription_id);
|
||||||
db.prepare('INSERT INTO notification_outbox_reviews VALUES (?,?,?,?,?,?)').run(id,actor,input.action,input.note.trim(),sent?input.providerId.trim():null,now);
|
db.prepare('INSERT INTO notification_outbox_reviews VALUES (?,?,?,?,?,?)').run(id,actor,input.action,input.note.trim(),sent?input.providerId.trim():null,now);
|
||||||
|
|||||||
Reference in New Issue
Block a user