Classify rotation joins by worked-sponsor status, not just active
A rotation joiner submits their ID after the rotation may have advanced (esp. with auto-advance: the direct who completes a sponsor's 2/2 joined under it, but the queue has already moved on). Keying "rotation" off the currently-active sponsor mislabeled them "leg" (hit live: Harvey #92 under #36 after #36 qualified). Now: rotation if the on-chain referrer is a queue sponsor that is active OR qualified (was/is worked); a still-waiting or non-queue referrer stays a leg join, preserving the original #49/#56-under-#46 fix. Auto-enqueue now parents the new position to the actual on-chain referrer, not the current active. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -156,12 +156,20 @@ async function handleSubmitId(req, res) {
|
||||
new Promise((_, rej) => setTimeout(() => rej(new Error('timeout')), 6000))
|
||||
]);
|
||||
} catch (e) { onchain = null; }
|
||||
// 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());
|
||||
// the chain decides the path: a rotation join is one whose on-chain referrer is
|
||||
// a rotation-queue sponsor that IS or HAS BEEN worked (status active or
|
||||
// qualified) — not just the currently-active one. With auto-advance, the direct
|
||||
// who completes a sponsor's 2/2 (and thus joined under it) submits their ID
|
||||
// AFTER the rotation has already moved on, so keying off "active only" wrongly
|
||||
// labeled them a leg join. A referrer that's a still-waiting queue position, or
|
||||
// not in the queue at all, is a personal leg join.
|
||||
const sponsorsNow = getSponsors();
|
||||
const active = activeSponsor(sponsorsNow);
|
||||
let joinPath = 'unknown';
|
||||
if (onchain && onchain.registered) joinPath = (active && String(onchain.referrerId) === String(active.id)) ? 'rotation' : 'leg';
|
||||
else if (onchain && !onchain.registered) joinPath = 'notfound';
|
||||
if (onchain && onchain.registered) {
|
||||
const refSp = sponsorsNow.find(s => String(s.id) === String(onchain.referrerId));
|
||||
joinPath = (refSp && (refSp.status === 'active' || refSp.status === 'qualified')) ? '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));
|
||||
@@ -177,14 +185,14 @@ async function handleSubmitId(req, res) {
|
||||
queueNote = 'Already in the rotation queue.';
|
||||
} else {
|
||||
const maxOrder = sponsors.reduce((m, s) => Math.max(m, s.sortOrder || 0), 0);
|
||||
sponsors.push({ id: String(newId), name: memberName, parentId: String(active.id), directs: 0, level: onchain.levelName || 'Scintilla', status: sponsors.some(s => s.status === 'active') ? 'waiting' : 'active', sortOrder: maxOrder + 10, clicks: 0, notes: `auto-added: rotation join ${new Date().toISOString().slice(0, 10)}` });
|
||||
sponsors.push({ id: String(newId), name: memberName, parentId: String(onchain.referrerId), directs: 0, level: onchain.levelName || 'Scintilla', status: sponsors.some(s => s.status === 'active') ? 'waiting' : 'active', sortOrder: maxOrder + 10, clicks: 0, notes: `auto-added: rotation join under #${onchain.referrerId} ${new Date().toISOString().slice(0, 10)}` });
|
||||
sponsors = normalizeStatuses(sponsors);
|
||||
saveSponsors(sponsors);
|
||||
const waitingAhead = sponsors.filter(s => s.status === 'waiting' && (s.sortOrder || 0) < maxOrder + 10).length;
|
||||
queueNote = `Auto-added to the rotation queue (${waitingAhead} waiting ahead of them).`;
|
||||
}
|
||||
} catch (e) { queueNote = `⚠ Auto-add to queue failed (${e.message}) — add manually.`; console.error('queue auto-add', e.message); }
|
||||
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✅ ${queueNote}\n(+1 direct for ID ${active.id} syncs from the chain automatically.)`;
|
||||
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✅ ${queueNote}\n(Sponsor #${onchain.referrerId}'s direct count syncs from the chain automatically.)`;
|
||||
} 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') {
|
||||
|
||||
Reference in New Issue
Block a user