Pipeline advice follows the main wallet's buyer count (what the contract pays on); card states the linked-positions rule; chatbot knows it
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
+7
-5
@@ -10,8 +10,9 @@ const path = require('path');
|
||||
const db = require('./db');
|
||||
|
||||
let DATA_DIR = null, accounts = null, coach = null, chain = null;
|
||||
// linked positions (Qualified Start) belong to the member: their buyers count toward the account, the same way
|
||||
// My line chips and the badges count them (Jim's card showed 1 buyer while his badge said Circuit, 2026-09-15)
|
||||
// linked positions (Qualified Start) belong to the member and their buyers count toward badges, but the contract
|
||||
// pays level 2 and 3 to the MAIN wallet only when that wallet's own buyerCount reaches 2 and 5. The card shows both
|
||||
// numbers; the stage and the advice follow the main wallet, because that is what gets paid (Marty's audit, 2026-09-15)
|
||||
const posCache = new Map();
|
||||
async function positionBuyers(email) {
|
||||
let ids = []; try { ids = (await accounts.positions(email)).map(p => p.memberId).filter(Boolean); } catch (e) {}
|
||||
@@ -23,7 +24,6 @@ async function positionBuyers(email) {
|
||||
}
|
||||
return { count: n, positions: ids.length };
|
||||
}
|
||||
function rungForTotal(rung, total) { if (rung < 3) return rung; return total === 0 ? 3 : total === 1 ? 4 : total < 5 ? 5 : 6; }
|
||||
const DAY = 86400000;
|
||||
|
||||
// columns, in order. Prospects live in the first and last; directs land by coaching rung.
|
||||
@@ -95,14 +95,16 @@ async function board(email) {
|
||||
const n = notes[m.email] || {};
|
||||
const pb = c && c.rung >= 3 ? await positionBuyers(m.email) : { count: 0, positions: 0 };
|
||||
const buyersMain = c ? c.buyerCount || 0 : 0, buyersAll = buyersMain + pb.count;
|
||||
const rung = c ? rungForTotal(c.rung, buyersAll) : 0;
|
||||
const rung = c ? c.rung : 0;
|
||||
const RR = coach.RUNGS[rung];
|
||||
// when positions carry buyers the main wallet does not, say exactly what the contract needs
|
||||
const gap = pb.count && rung >= 3 && rung < 6 ? ' The contract pays level ' + (buyersMain < 2 ? '2' : '3') + ' to their main wallet only when that wallet has ' + (buyersMain < 2 ? 2 : 5) + ' qualifying buyers of its own: ' + buyersMain + ' now, plus ' + pb.count + ' on linked positions that count for badges only.' : '';
|
||||
const stage = PARKED.has(n.tag) && rung < 3 ? 'later' : RUNG_STAGE[rung] || 'joined';
|
||||
cards.push({ key: m.email, kind: 'member', email: m.email, name: m.username ? '@' + m.username : (m.memberId ? 'member #' + m.memberId : 'member'),
|
||||
memberId: m.memberId || 0, stage, rung, rungLabel: RR.label, since: m.created || now,
|
||||
lastSeen: m.lastSeen || 0, quietDays: c ? c.quietDays : 0, stalled: !!(c && c.stalled && rung < 6),
|
||||
buyers: buyersAll, buyersMain, buyersPositions: pb.count, positions: pb.positions, bought: !!(c && c.counted),
|
||||
next: RR.next, say: RR.say.replace('{{name}}', m.username || 'there'),
|
||||
next: RR.next + gap, say: RR.say.replace('{{name}}', m.username || 'there'),
|
||||
note: n.note || '', followUp: n.followUp || null, tag: n.tag || '' });
|
||||
}
|
||||
const due = cards.filter(c => c.followUp && c.followUp <= eod.getTime()).sort((a, b) => a.followUp - b.followUp);
|
||||
|
||||
Reference in New Issue
Block a user