Admin Members: show the sponsor's username, note share-code joins, flag dead sponsor links

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-11 09:06:13 -05:00
parent ab306937e1
commit c9f7a50b30
3 changed files with 11 additions and 2 deletions
+9
View File
@@ -1779,6 +1779,15 @@ const server = http.createServer(async (req, res) => {
if (p === '/api/admin/members' && req.method === 'GET') {
if (!isAdmin(req)) return json(res, 401, { error: 'auth' });
const members = await accounts.listAll(500);
// resolve each sponsor token (username, share code or member #) to the sponsor's name
const byTok = {};
for (const m of members) for (const t of [m.username, m.code, m.memberId ? String(m.memberId) : null]) if (t) byTok[String(t).toLowerCase()] = m;
for (const m of members) {
const t = String(m.sponsorRef || '').toLowerCase();
const sp = t ? byTok[t] : null;
m.sponsorName = sp ? (sp.username ? '@' + sp.username : (sp.memberId ? 'member #' + sp.memberId : sp.email)) : null;
m.sponsorVia = sp ? (t === String(sp.username || '').toLowerCase() ? 'username' : t === String(sp.code || '').toLowerCase() ? 'code' : 'member #') : (t ? 'unresolved' : '');
}
for (const m of members) { try { const ps = await accounts.positions(m.email); m.positions = ps.length; m.positionIds = ps.map(p => p.memberId).filter(Boolean); } catch (e) { m.positions = 0; } }
return json(res, 200, { members });
}