Split submissions into rotation vs leg paths — decided by the chain
Two leg-build members submitted the /start form thinking it was required, polluting rotation bookkeeping. Rather than two forms, the server now classifies every submission by on-chain truth: referrer == active rotation sponsor -> "rotation" (Telegram says +1 direct, add to queue); anyone else -> "leg" (correct sponsor credited, "no rotation action needed"). The member dashboard gains its own "Just joined under this position?" form so leg builders have a proper landing spot; /start feedback explains each path to the submitter; admin submissions table shows a rotation/leg chip. Verified against live data: ID 65 claiming sponsor 36 correctly classified leg under #62. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -135,17 +135,29 @@ async function handleSubmitId(req, res) {
|
||||
new Promise((_, rej) => setTimeout(() => rej(new Error('timeout')), 6000))
|
||||
]);
|
||||
} catch (e) { onchain = null; }
|
||||
subs.push({ newId, memberName, sponsorId, source: source||'(direct)', clickid, ts: new Date().toISOString(),
|
||||
// the chain decides the path: rotation join (referrer = active rotation sponsor)
|
||||
// vs leg join (someone's personal team build) — regardless of which page they used
|
||||
const active = activeSponsor(getSponsors());
|
||||
let joinPath = 'unknown';
|
||||
if (onchain && onchain.registered) joinPath = (active && String(onchain.referrerId) === String(active.id)) ? 'rotation' : 'leg';
|
||||
else if (onchain && !onchain.registered) joinPath = 'notfound';
|
||||
subs.push({ newId, memberName, sponsorId, source: source||'(direct)', clickid, ts: new Date().toISOString(), path: joinPath,
|
||||
onchain: onchain ? { registered: onchain.registered, tier: onchain.tierName, level: onchain.levelName, referrerId: onchain.referrerId, uplineId: onchain.uplineId } : undefined });
|
||||
writeJson(SUBMISSIONS_FILE, subs.slice(-1000));
|
||||
recordEvent('purchase', source);
|
||||
firePostback(clickid, `purchase-${clickid}`, source);
|
||||
const chainLine = onchain === null ? '⏳ On-chain check unavailable — verify manually in admin.'
|
||||
: onchain.registered
|
||||
? `✅ VERIFIED ON-CHAIN: ${onchain.tierName} tier, level ${onchain.levelName}, referred by ID ${onchain.referrerId}${String(onchain.referrerId)!==sponsorId?` ⚠ (submitted sponsor was ${sponsorId})`:''}`
|
||||
: `❌ NOT FOUND ON-CHAIN — ID ${newId} has no registration on the contract yet.`;
|
||||
sendTelegram(`🔔 RM Circle: NEW MEMBER CONFIRMED\nName: ${memberName}\nNew ID: ${newId}\nJoined under sponsor: ${sponsorId}\nSource: ${source||'(direct)'}\n${chainLine}\n→ Add ${memberName} (ID ${newId}) to the rotation queue.`);
|
||||
return json(res, 200, { ok: true, onchain: onchain ? { registered: onchain.registered, tier: onchain.tierName, level: onchain.levelName, referrerId: onchain.referrerId } : null });
|
||||
let msg;
|
||||
if (joinPath === 'rotation') {
|
||||
msg = `🔔 RM Circle: ROTATION JOIN CONFIRMED ✅\nName: ${memberName}\nNew ID: ${newId} (${onchain.tierName}, verified on-chain)\nJoined under rotation sponsor: #${onchain.referrerId}\nSource: ${source||'(direct)'}\n→ +1 direct for ID ${active.id}; add ${memberName} (ID ${newId}) to the rotation queue.`;
|
||||
} else if (joinPath === 'leg') {
|
||||
msg = `🌱 RM Circle: TEAM-BUILD JOIN (not rotation)\nName: ${memberName}\nNew ID: ${newId} (${onchain.tierName}, verified on-chain)\nActual sponsor on-chain: #${onchain.referrerId}${sponsorId!=='?'&&String(onchain.referrerId)!==sponsorId?` (form said ${sponsorId})`:''}\nSource: ${source||'(direct)'}\n→ Leg growth under #${onchain.referrerId} — no rotation action needed. Add them to the rotation queue only if they want the team effort.`;
|
||||
} else if (joinPath === 'notfound') {
|
||||
msg = `🔔 RM Circle: ID SUBMITTED — ❌ NOT FOUND ON-CHAIN\nName: ${memberName}\nNew ID: ${newId}\nClaimed sponsor: ${sponsorId}\nSource: ${source||'(direct)'}\n→ ID has no registration on the contract — double-check with them before any queue action.`;
|
||||
} else {
|
||||
msg = `🔔 RM Circle: NEW MEMBER SUBMITTED\nName: ${memberName}\nNew ID: ${newId}\nClaimed sponsor: ${sponsorId}\nSource: ${source||'(direct)'}\n⏳ On-chain check unavailable — verify manually in admin (member lookup).`;
|
||||
}
|
||||
sendTelegram(msg);
|
||||
return json(res, 200, { ok: true, path: joinPath, onchain: onchain ? { registered: onchain.registered, tier: onchain.tierName, level: onchain.levelName, referrerId: onchain.referrerId } : null });
|
||||
}
|
||||
async function handleChat(req, res) {
|
||||
const ip = String(req.headers['x-forwarded-for']||req.socket.remoteAddress||'').split(',')[0].trim();
|
||||
|
||||
Reference in New Issue
Block a user