mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-11-13 12:46:11 +01:00
feat: voting averages
This commit is contained in:
1 parent
c3c16bf607
commit
2d2d31adf7
24 files changed
+643
-254
No files matched your search
@@ -0,0 +1,81 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { isValidBlitzId } from '../../../../../core/blitz/isValidBlitzId';
|
||||
import { tankDefinitions } from '../../../../../core/blitzkit/tankDefinitions';
|
||||
import { usersDatabase } from '../../../../../databases/users';
|
||||
import { BlitzkitResponse } from '../../../../../hooks/useTankVotes';
|
||||
import { TankVoteCategory } from '../cast/route';
|
||||
|
||||
export interface TankVotes {
|
||||
categories: Record<TankVoteCategory, number | null>;
|
||||
votes: number;
|
||||
last_updated?: number;
|
||||
}
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{ params }: { params: { id: string } },
|
||||
) {
|
||||
const id = Number(params.id);
|
||||
const awaitedTankDefinitions = await tankDefinitions;
|
||||
|
||||
if (isNaN(id) || !awaitedTankDefinitions[id]) {
|
||||
return NextResponse.json({
|
||||
status: 'error',
|
||||
error: 'INVALID_TANK_ID',
|
||||
} satisfies BlitzkitResponse<TankVotes>);
|
||||
}
|
||||
|
||||
const blitzIdString = request.nextUrl.searchParams.get('player');
|
||||
const blitzId = Number(blitzIdString);
|
||||
const blitzToken = request.nextUrl.searchParams.get('token');
|
||||
|
||||
if ((blitzIdString === null) !== (blitzToken === null)) {
|
||||
return NextResponse.json({
|
||||
status: 'error',
|
||||
error: 'UNDEFINED_TOKEN_OR_PLAYER_ID',
|
||||
} satisfies BlitzkitResponse<TankVotes>);
|
||||
}
|
||||
|
||||
if (
|
||||
blitzIdString !== null &&
|
||||
(!(await isValidBlitzId(blitzId, blitzToken ?? undefined)) ||
|
||||
isNaN(blitzId))
|
||||
) {
|
||||
return NextResponse.json({
|
||||
status: 'error',
|
||||
error: 'INVALID_TOKEN_OR_PLAYER_ID',
|
||||
} satisfies BlitzkitResponse);
|
||||
}
|
||||
|
||||
try {
|
||||
const aggregation = await usersDatabase.tankVote.aggregate({
|
||||
where: { id },
|
||||
_count: { id: true },
|
||||
_avg: {
|
||||
easiness: true,
|
||||
firepower: true,
|
||||
maneuverability: true,
|
||||
survivability: true,
|
||||
},
|
||||
});
|
||||
const userVote = await usersDatabase.tankVote.findUnique({
|
||||
where: { id, user_blitz_id: blitzId },
|
||||
select: { last_updated: true },
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
status: 'ok',
|
||||
data: {
|
||||
categories: aggregation._avg,
|
||||
votes: aggregation._count.id,
|
||||
last_updated: userVote?.last_updated.getTime(),
|
||||
},
|
||||
} satisfies BlitzkitResponse<TankVotes>);
|
||||
} catch (message) {
|
||||
return NextResponse.json({
|
||||
status: 'error',
|
||||
error: 'DATABASE_ERROR',
|
||||
message,
|
||||
} satisfies BlitzkitResponse<TankVotes>);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { isValidBlitzId } from '../../../../../core/blitz/isValidBlitzId';
|
||||
import { tankDefinitions } from '../../../../../core/blitzkit/tankDefinitions';
|
||||
import { usersDatabase } from '../../../../../databases/users';
|
||||
import { BlitzkitResponse } from '../../../../../hooks/useTankVotes';
|
||||
import { StarsInt } from '../../../../tools/tankopedia/[id]/components/Model/MetaSection/components/Stars';
|
||||
|
||||
export const TANK_VOTE_CATEGORIES = [
|
||||
'easiness',
|
||||
'firepower',
|
||||
'maneuverability',
|
||||
'survivability',
|
||||
];
|
||||
|
||||
export type TankVoteCategory = (typeof TANK_VOTE_CATEGORIES)[number];
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{ params }: { params: { id: string } },
|
||||
) {
|
||||
const tankId = Number(params.id);
|
||||
const awaitedTankDefinitions = await tankDefinitions;
|
||||
|
||||
if (isNaN(tankId) || !awaitedTankDefinitions[tankId]) {
|
||||
return NextResponse.json({
|
||||
status: 'error',
|
||||
error: 'INVALID_TANK_ID',
|
||||
} satisfies BlitzkitResponse);
|
||||
}
|
||||
|
||||
const blitzId = Number(request.nextUrl.searchParams.get('player'));
|
||||
|
||||
if (isNaN(blitzId) || !(await isValidBlitzId(blitzId))) {
|
||||
return NextResponse.json({
|
||||
status: 'error',
|
||||
error: 'INVALID_PLAYER_ID',
|
||||
} satisfies BlitzkitResponse);
|
||||
}
|
||||
|
||||
const votes: Partial<Record<TankVoteCategory, StarsInt>> = {};
|
||||
let recognizedVoteCategories = 0;
|
||||
|
||||
for (const category of TANK_VOTE_CATEGORIES) {
|
||||
const voteRaw = request.nextUrl.searchParams.get(category);
|
||||
|
||||
if (voteRaw === null) continue;
|
||||
|
||||
const vote = Number(voteRaw);
|
||||
|
||||
if (isNaN(vote) || !Number.isInteger(vote) || vote < 1 || vote > 5) {
|
||||
return NextResponse.json({
|
||||
status: 'error',
|
||||
error: 'INVALID_VOTE',
|
||||
} satisfies BlitzkitResponse);
|
||||
}
|
||||
|
||||
votes[category] = vote as StarsInt;
|
||||
recognizedVoteCategories++;
|
||||
}
|
||||
|
||||
if (recognizedVoteCategories === 0) {
|
||||
return NextResponse.json({
|
||||
status: 'error',
|
||||
error: 'NO_VOTES',
|
||||
} satisfies BlitzkitResponse);
|
||||
}
|
||||
|
||||
try {
|
||||
await usersDatabase.user.upsert({
|
||||
where: { blitz_id: blitzId },
|
||||
update: {
|
||||
last_used: new Date(),
|
||||
tank_votes: {
|
||||
upsert: {
|
||||
where: { id: tankId },
|
||||
update: { ...votes, last_updated: new Date() },
|
||||
create: { ...votes, id: tankId, last_updated: new Date() },
|
||||
},
|
||||
},
|
||||
},
|
||||
create: {
|
||||
blitz_id: blitzId,
|
||||
last_used: new Date(),
|
||||
tank_votes: {
|
||||
create: { ...votes, id: tankId, last_updated: new Date() },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
status: 'ok',
|
||||
data: undefined,
|
||||
} satisfies BlitzkitResponse<undefined>);
|
||||
} catch (message) {
|
||||
return NextResponse.json({
|
||||
status: 'error',
|
||||
error: 'DATABASE_ERROR',
|
||||
message,
|
||||
} satisfies BlitzkitResponse);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user