// Local fixture validator. Does not reproduce GA4 reporting or deduplication. export function audit(orders,events){ const paid=orders.filter(o=>o.status==='paid'),issues=[],counts=new Map(); for(const e of events){ const id=e.transaction_id,order=orders.find(o=>o.id===id); if(!id)issues.push({event:e.event_id,code:'empty_id',text:'Пустой transaction_id'}); else {counts.set(id,(counts.get(id)||0)+1);if(counts.get(id)>1)issues.push({event:e.event_id,code:'duplicate',text:'Повторная отправка '+id});} if(id&&!order)issues.push({event:e.event_id,code:'unknown',text:'Заказ отсутствует в реестре'}); if(order&&order.status!=='paid')issues.push({event:e.event_id,code:'unpaid',text:'Заказ ещё не оплачен'}); // context_order_id comes from the test harness, NOT a fallback identity in analytics. const reference=order||orders.find(o=>o.id===e.context_order_id); if(reference&&e.value!==reference.value)issues.push({event:e.event_id,code:'value',text:'Сумма не совпадает с реестром'}); if(reference&&e.currency!==reference.currency)issues.push({event:e.event_id,code:'currency',text:'Валюта не совпадает с реестром'}); } for(const o of paid)if(!events.some(e=>e.transaction_id===o.id))issues.push({event:o.id,code:'missing',text:'Для оплаченного заказа нет события'}); const matched=paid.filter(o=>events.filter(e=>e.transaction_id===o.id).length===1&&events.some(e=>e.transaction_id===o.id&&e.value===o.value&&e.currency===o.currency)); return {issues,paid:paid.length,events:events.length,matched:matched.length,revenue:paid.reduce((s,o)=>s+o.value,0)}; }