Add admin "My Positions — Income" panel

Aggregates every on-chain payment received by a set of owned IDs
(defaults to 21,24,25, saved to config.ownerIds and prefilled/auto-loaded
next time). Shows grand total + per-position totals and a merged,
newest-first ledger (to / from / entry-or-upgrade level / amount) via a
focused chain.getIncome read and an admin-gated /api/admin/income
endpoint. Verified: 5,064.43 POL across 21/24/25, 11 payments.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-08-14 14:08:21 -05:00
parent 77310f8974
commit 81d90fbe8e
4 changed files with 56 additions and 2 deletions
+15 -1
View File
@@ -477,4 +477,18 @@ async function memberPublic(id) {
return out;
}
module.exports = { startIndexer, getPayoutsPublic, verifyMember, memberLookup, memberPublic, getMatrixTree, isInTeam, CONTRACT };
// focused income read for one position — for the admin "my positions" income view
async function getIncome(id) {
const m = await fetchMember(id);
if (!m) return { registered: false, id };
await fetchCosts().catch(() => {});
let inc = [];
try { inc = await fetchIncome(id); } catch (e) { inc = []; }
return {
registered: true, id, levelName: levelName(m.level), tierName: tierName(m.tier),
totalEarnedPol: m.totalEarnedPol, directCount: m.directCount,
income: inc.map(p => ({ fromId: p.fromId, pol: p.pol, ts: p.ts, desc: describeIncome(p.fromTier, p.level, p.pol) })).reverse()
};
}
module.exports = { startIndexer, getPayoutsPublic, verifyMember, memberLookup, memberPublic, getIncome, getMatrixTree, isInTeam, CONTRACT };