Badges: the proxy asks which IMVU accounts show the T5 badge
CI / test (push) Successful in 49s

POST /api/v1/badges {imvuIds} (at most 200) answers the linked accounts whose
badge is on, of people who aren't banned, in one query. It uses the existing
per-account showBadge (off by default, set from the account page).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
dhkatzandClaude Opus 5.5 committed 2026-10-30 02:38:01 -07:00
1 parent 6668b55117
commit 0c67232425
4 files changed
+149 -2

No files matched your search

+24
View File
@@ -957,6 +957,30 @@ export function createApp({ db, auth, imvu, realtime: rt, age: ageService, rooms
},
)
// T5DE's proxy: which of the IMVU accounts it's showing get the T5 badge (linked, the badge turned on, the
// person not banned). Nothing else about them.
.post(
"/badges",
async ({ me, body }) => {
if (!limiter.allow(`badges:${me.id}`, 120, 60 * 1000))
throw new Problem(429, "rate_limited", "Too many lookups. Try again in a while.");
const ids = [...new Set(body.imvuIds)];
if (ids.length === 0) return { badges: [] };
const rows = await db
.select({ imvuId: imvuLink.imvuId })
.from(imvuLink)
.innerJoin(user, eq(user.id, imvuLink.userId))
.where(and(inArray(imvuLink.imvuId, ids), eq(imvuLink.showBadge, true), sql`coalesce(${user.banned}, false) = false`));
return { badges: rows.map((r) => r.imvuId) };
},
{
signedIn: true,
body: t.Object({
imvuIds: t.Array(t.Integer({ minimum: 1, maximum: Number.MAX_SAFE_INTEGER }), { maxItems: 200 }),
}),
},
)
// T5DE's proxy: the live connection.
.ws("/realtime", {
async beforeHandle({ person, set }) {