feat: add profile editing (bio, display name, stat visibility)

This commit is contained in:
2026-03-06 13:56:12 -08:00
committed by Naomi Carrigan
parent 32c13f73c4
commit 7e04daa073
11 changed files with 525 additions and 30 deletions
+2
View File
@@ -14,6 +14,8 @@ model Player {
discriminator String
avatar String?
characterName String @default("")
bio String @default("")
profileSettings Json?
createdAt Float
lastSavedAt Float
totalGoldEarned Float @default(0)
+56 -1
View File
@@ -1,9 +1,32 @@
import type { GameState } from "@elysium/types";
import type {
GameState,
ProfileSettings,
UpdateProfileRequest,
} from "@elysium/types";
import { Hono } from "hono";
import { prisma } from "../db/client.js";
import { DEFAULT_PROFILE_SETTINGS } from "@elysium/types";
import { authMiddleware } from "../middleware/auth.js";
export const profileRouter = new Hono();
const parseProfileSettings = (raw: unknown): ProfileSettings => {
if (
raw !== null &&
typeof raw === "object" &&
!Array.isArray(raw)
) {
const obj = raw as Record<string, unknown>;
return {
showTotalGold: obj.showTotalGold !== false,
showTotalClicks: obj.showTotalClicks !== false,
showPrestige: obj.showPrestige !== false,
showGuildFounded: obj.showGuildFounded !== false,
};
}
return { ...DEFAULT_PROFILE_SETTINGS };
};
profileRouter.get("/:discordId", async (context) => {
const { discordId } = context.req.param();
@@ -18,14 +41,46 @@ profileRouter.get("/:discordId", async (context) => {
const state = gameStateRecord?.state as unknown as GameState | undefined;
const prestigeCount = state?.prestige.count ?? 0;
const profileSettings = parseProfileSettings(player.profileSettings);
return context.json({
characterName: player.characterName,
username: player.username,
avatar: player.avatar ?? null,
bio: player.bio ?? "",
profileSettings,
prestigeCount,
totalGoldEarned: player.totalGoldEarned,
totalClicks: player.totalClicks,
createdAt: player.createdAt,
});
});
profileRouter.put("/", authMiddleware, async (context) => {
const discordId = context.get("discordId") as string;
const body = await context.req.json<UpdateProfileRequest>();
const characterName = (body.characterName ?? "").trim().slice(0, 32);
const bio = (body.bio ?? "").trim().slice(0, 200);
const profileSettings: ProfileSettings = {
showTotalGold: body.profileSettings?.showTotalGold !== false,
showTotalClicks: body.profileSettings?.showTotalClicks !== false,
showPrestige: body.profileSettings?.showPrestige !== false,
showGuildFounded: body.profileSettings?.showGuildFounded !== false,
};
if (!characterName) {
return context.json({ error: "Character name cannot be empty" }, 400);
}
const updated = await prisma.player.update({
where: { discordId },
data: { characterName, bio, profileSettings },
});
return context.json({
characterName: updated.characterName,
bio: updated.bio,
profileSettings,
});
});