feat: review uncertain weekly brief deliveries with audit history

This commit is contained in:
2026-09-06 14:37:32 +03:00
parent 99a7f2f571
commit 7a01e4bed7
11 changed files with 141 additions and 15 deletions
+37
View File
@@ -97,3 +97,40 @@ test('weekly id uses Monday in Istanbul even while UTC is still Sunday',()=>{
assert.equal(briefWeekKey(new Date('2026-09-06T20:59:59Z')),'2026-08-31');
assert.equal(briefWeekKey(new Date('2026-09-06T21:00:00Z')),'2026-09-07');
});
test('review needs provider evidence, persists actor and closes only the selected message',t=>{
const {outbox,directory}=fixture(t);
const batch=outbox.prepare('2026-09-07','review@example.test',[{channel:'email',to:'review@example.test'},{channel:'telegram',chatId:'test'}]);
const first=outbox.claim(batch.id,0,1000),second=outbox.claim(batch.id,1,1000);
outbox.hold(first,'Unknown response');outbox.hold(second,'Unknown response');
const id=`${batch.id}:0`,input={action:'confirmed_sent',note:'Sağlayıcı kayıtları incelendi ve eşleşti.',providerId:'provider-test-id',confirmed:true};
assert.throws(()=>outbox.resolve(id,'admin@example.test',{...input,confirmed:false}),/onayı/);
assert.throws(()=>outbox.resolve(id,'admin@example.test',{...input,providerId:''}),/kimliği/);
assert.throws(()=>outbox.resolve(id,'admin@example.test',{...input,note:'short'}),/açıklaması/);
assert.equal(outbox.resolve(id,'admin@example.test',input).state,'sent_manual');
assert.throws(()=>outbox.resolve(id,'other-admin@example.test',input),{status:409});
const rows=createBriefOutbox(directory).queue(10000),done=rows.find(row=>row.id===id);
assert.equal(done.review.actor,'admin@example.test');assert.equal(done.review.note,input.note);
assert.equal(done.providerId,'provider-test-id');assert.equal(done.state,'sent_manual');
assert.equal(rows.find(row=>row.id!==id).state,'uncertain');
assert.equal(outbox.claim(batch.id,0).state,'accepted');
});
test('skip never claims delivery and a fully reviewed changed plan cannot start new messages',t=>{
const {outbox}=fixture(t);
const batch=outbox.prepare('2026-09-07','review@example.test',[{channel:'email'}]);
outbox.hold(outbox.claim(batch.id,0),'Uncertain');
outbox.resolve(`${batch.id}:0`,'admin@example.test',{action:'skip',note:'Sonuç doğrulanamadı, tekrar gönderilmeden kapatıldı.'});
assert.equal(outbox.claim(batch.id,0).state,'skipped');
const row=outbox.queue()[0];assert.equal(row.providerId,null);assert.equal(row.state,'skipped');
assert.equal(outbox.prepare('2026-09-07','review@example.test',[{channel:'email',text:'Changed'},{channel:'telegram'}]).closed,true);
});
test('review queue exposes expired interrupted sends but does not allow reviewing a live claim',t=>{
const {outbox}=fixture(t);
const batch=outbox.prepare('2026-09-07','review@example.test',[{channel:'email'}]);
outbox.claim(batch.id,0,1000);
assert.equal(outbox.queue(2000)[0].state,'sending');
assert.throws(()=>outbox.resolve(`${batch.id}:0`,'admin@example.test',{action:'skip',note:'Bu gönderim halen etkin durumdadır.'}),{status:409});
assert.equal(outbox.queue(121001)[0].state,'uncertain');
});