The board says the one condition out loud

The card read "when someone new opens PolHunter" and listed everyone a hunter
had brought as hunting or earning, including members who joined InstantAdPay
before the mission existed and can never pay a bounty. So the board promised an
earning the payout code would refuse.

It now says what actually qualifies: someone who has never had an InstantAdPay
account. People who were already members are listed as exactly that, the match
window is not claimed for them, and the counts show how many of the brought are
genuinely new.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-23 11:41:54 -05:00
parent d04474fd7b
commit 2503b1e1a2
4 changed files with 254 additions and 240 deletions
+11 -2
View File
@@ -162,17 +162,25 @@ function state(member) {
const me = hunter(id) || { memberId: id };
const rows = refRows().filter(p => Number(p.memberId) === id);
const today = ctDay();
// the same floor onFind pays by, so the card can never promise an earning it will not make
const floor = Date.parse(String(c.refNewAfter || ''));
const gateOk = Number.isFinite(floor) && floor > 0;
const mine = broughtBy(id).map(x => {
const theirFinds = store.read('payouts', []).filter(p => Number(p.memberId) === Number(x.memberId) && !p.ref && !p.prize && p.status !== 'failed');
const paid = bountyPaidFor(x.memberId);
const isNew = !!(gateOk && x.joinedAt && Number(x.joinedAt) >= floor);
return {
name: x.username || ('#' + x.memberId),
// when they actually joined InstantAdPay, not when this directory first noticed them:
// the backfill stamped firstSeen at seeding time and made everyone look brought-in today
joinedAt: x.joinedAt || x.firstSeen || null,
finds: theirFinds.length,
state: paid ? 'earning' : theirFinds.length ? 'hunting' : 'signed up, no find yet',
stillNew: x.joinedAt ? (Date.now() - Number(x.joinedAt)) / 86400000 <= Number(c.refMatchDays) : false,
// an account that predates the mission was already a member: say so plainly rather than
// show them as 'hunting' next to a bounty that will never arrive
isNew,
state: !isNew ? 'already a member before the mission, earns nothing'
: paid ? 'earning' : theirFinds.length ? 'hunting' : 'signed up, no find yet',
stillNew: isNew && (Date.now() - Number(x.joinedAt)) / 86400000 <= Number(c.refMatchDays),
};
});
return {
@@ -182,6 +190,7 @@ function state(member) {
matchPct: Number(c.refMatchPct),
matchDays: Number(c.refMatchDays),
brought: mine.length,
broughtNew: mine.filter(x => x.isNew).length, // the only ones that can ever pay
broughtToday: mine.filter(x => x.joinedAt && ctDay(x.joinedAt) === today).length,
earnedPol: round4(rows.reduce((n, p) => n + p.pol, 0)),
earnedTodayPol: round4(rows.filter(p => p.day === today).reduce((n, p) => n + p.pol, 0)),