62 lines
1.5 KiB
TypeScript
62 lines
1.5 KiB
TypeScript
import { usePrisma } from "../utils/prisma";
|
|
|
|
export type ScoreEventType =
|
|
| "post_created"
|
|
| "upvote_received"
|
|
| "custom_domain_submitted"
|
|
| "daily_checkin"
|
|
| "chat_message"
|
|
| "streak_milestone"
|
|
| "helped_user";
|
|
|
|
const POINTS: Record<ScoreEventType, number> = {
|
|
post_created: 50,
|
|
upvote_received: 10,
|
|
custom_domain_submitted: 30,
|
|
daily_checkin: 5,
|
|
chat_message: 2,
|
|
streak_milestone: 100,
|
|
helped_user: 20,
|
|
};
|
|
|
|
export async function awardPoints(
|
|
userId: string,
|
|
type: ScoreEventType,
|
|
meta?: Record<string, unknown>,
|
|
) {
|
|
const db = usePrisma();
|
|
const points = POINTS[type] ?? 0;
|
|
if (points === 0) return;
|
|
|
|
await db.scoreEvent.create({
|
|
data: { userId, eventType: type, points, meta: meta ?? null },
|
|
});
|
|
}
|
|
|
|
export async function getUserScore(userId: string) {
|
|
const db = usePrisma();
|
|
return db.userScore.findUnique({
|
|
where: { userId },
|
|
select: { totalPoints: true, tier: true, updatedAt: true },
|
|
});
|
|
}
|
|
|
|
export async function getRecentScoreEvents(userId: string, limit = 20) {
|
|
const db = usePrisma();
|
|
return db.scoreEvent.findMany({
|
|
where: { userId },
|
|
orderBy: { createdAt: "desc" },
|
|
take: limit,
|
|
select: { eventType: true, points: true, createdAt: true, meta: true },
|
|
});
|
|
}
|
|
|
|
export async function getLeaderboard(limit = 50) {
|
|
const db = usePrisma();
|
|
return db.userScore.findMany({
|
|
orderBy: { totalPoints: "desc" },
|
|
take: limit,
|
|
select: { userId: true, totalPoints: true, tier: true },
|
|
});
|
|
}
|