diff --git a/server.js b/server.js index 6f009d4..7a0f0fe 100644 --- a/server.js +++ b/server.js @@ -1573,7 +1573,17 @@ chain.startIndexer(evt=>{ const c=getConfig(); // teamRootId accepts a comma list ("21,136") — alerts fire for ANY listed org const roots=String(c.teamRootId||'').split(',').map(n=>Number(n.trim())).filter(n=>n>0); - const ids=evt.type==='payout'?[evt.toId,evt.fromId]:[evt.id]; + // A brand-new member has no uplineId yet at the moment the 'registered' + // event fires: the indexer wires the matrix in a SEPARATE pass after the + // log loop. So isInTeam(newId) walks nothing, returns false, and the + // announcement is silently dropped — while the payout it triggered goes + // out, because that references existing members whose uplines are known. + // That was the "payout with no joiner beside it" Marty kept seeing. + // The referrer is always already wired, and if they are in the org so is + // anyone joining under them, so test them too. + const ids=evt.type==='payout'?[evt.toId,evt.fromId] + :evt.type==='registered'?[evt.id,evt.referrerId] + :[evt.id]; if(roots.length&&ids.some(i=>roots.some(r=>chain.isInTeam(i,r)))){ const contact=id=>{const s=getSponsors().find(x=>String(x.id)===String(id));return s&&s.email?`\nContact: ${s.name?s.name+' — ':''}${s.email}`:''}; let text;