Finished implementing match endpoints

This commit is contained in:
jd
2026-02-22 12:02:05 +00:00
parent 0fa00e6759
commit 872a79663b
7 changed files with 94 additions and 31 deletions

View File

@@ -4,6 +4,7 @@ import { first, orderBy } from 'lodash';
import { BadRequestError, NotFoundError, UnauthorizedError } from '../utilities/errors';
import { GameId, MatchId, PlayerId, UserId } from '../utilities/secureIds';
import { calculateElos } from '../utilities/elo';
import { orm } from './orm';
export class MatchParticipant {
matchId?: MatchId;
@@ -125,13 +126,14 @@ export class MatchOrm {
throw new UnauthorizedError();
}
if (!dbResult) {
throw new NotFoundError('No matching user exists');
const matchData = dbResult?.find((x: any) => x.match_id);
if (!matchData?.match_id) {
throw new NotFoundError('No matching match exists');
}
return new Match(
MatchId.fromID(dbResult?.[0]?.match_id),
GameId.fromID(dbResult?.[0]?.game_id),
MatchId.fromID(matchData?.match_id),
GameId.fromID(matchData?.game_id),
orderBy(
dbResult
.filter((x: any) => x.player_id)
@@ -152,28 +154,52 @@ export class MatchOrm {
);
}
async drop(id: UserId, claims?: Claims): Promise<void> {
// if (
// !(
// Claims.test(Claims.ADMIN, claims) ||
// Claims.test(Claims.USERS.OTHER.DELETE, claims) ||
// (Claims.test(Claims.USERS.SELF.DELETE, claims) && id === claims?.userId)
// )
// ) {
// throw new UnauthorizedError();
// }
//
// // Ensure user exists before attempting to delete
// await this.get(id);
// await sql.transaction(async (tx) => {
// await tx`DELETE
// FROM user_claims
// WHERE user_id = ${id.raw}`;
// await tx`DELETE
// FROM users
// WHERE id = ${id.raw}`;
// });
async drop(id: MatchId, claims?: Claims): Promise<void> {
const match = await this.get(id);
if (
!(
Claims.test(Claims.ADMIN, claims) ||
(Claims.test(Claims.MATCHES.OWNED.DELETE, claims) && match.owner === claims?.userId)
)
) {
throw new UnauthorizedError();
}
await sql.transaction(async (tx) => {
await tx`DELETE
FROM match_players
WHERE match_id = ${id.raw}`;
await tx`DELETE
FROM matches
WHERE id = ${id.raw}`;
});
return;
}
async removePlayer(matchId: MatchId, participantId: UserId): Promise<void>;
async removePlayer(matchId: MatchId, participantId: PlayerId): Promise<void> {
let playerId: PlayerId = participantId;
if (participantId instanceof UserId) {
playerId = (await orm.users.get(participantId))?.playerId;
if (!playerId) {
throw new BadRequestError('User is not a participant');
}
}
const player = await orm.players.get(playerId);
sql.transaction(async (tx) => {
const eloRefund = parseInt(
(
await tx`SELECT elo_change FROM public.match_players WHERE match_id=${matchId.raw} AND player_id = ${playerId.raw}`
)?.[0]?.elo_change ?? 0,
);
await tx`DELETE FROM match_players WHERE match_id=${matchId.raw} AND player_id=${playerId.raw}`;
if (!player.isRatingLocked) {
await tx`UPDATE players SET elo=${player.elo - eloRefund} WHERE id=${playerId.raw}`;
}
});
return;
}
}