mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-03-21 18:04:39 -05:00
Remove dead code, migrate one Skill function to Kysely (#2785)
This commit is contained in:
parent
49062284f7
commit
f460d52a40
|
|
@ -3,7 +3,7 @@
|
|||
- only rarely use comments, prefer descriptive variable and function names (leave existing comments as is)
|
||||
- if you encounter an existing TODO comment assume it is there for a reason and do not remove it
|
||||
- task is not considered completely until `npm run checks` passes
|
||||
- normal file structure has constants at the top immediately followed by the main function body of the file. Helpers are used to structure the code and they are at the bottom of the file (then hoisted to the top)
|
||||
- normal file structure has constants at the top immediately followed by the main function body of the file. Helpers are used to structure the code and they are at the bottom of the file (main implementation first, at the top of the file)
|
||||
- note: any formatting issue (such as tabs vs. spaces) can be resolved by running the `npm run biome:fix` command
|
||||
|
||||
## Commands
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
## Typescript
|
||||
|
||||
- prefer early return over nesting if statements
|
||||
- prefer early return over nesting if statements (bouncer pattern)
|
||||
- do not use `any` type
|
||||
- for constants use ALL_CAPS
|
||||
- always use named exports
|
||||
|
|
|
|||
40
app/features/mmr/SkillRepository.server.ts
Normal file
40
app/features/mmr/SkillRepository.server.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { sql } from "kysely";
|
||||
import { db } from "~/db/sql";
|
||||
import { MATCHES_COUNT_NEEDED_FOR_LEADERBOARD } from "../leaderboards/leaderboards-constants";
|
||||
|
||||
export async function seasonProgressionByUserId({
|
||||
userId,
|
||||
season,
|
||||
}: {
|
||||
userId: number;
|
||||
season: number;
|
||||
}) {
|
||||
return db
|
||||
.selectFrom("Skill")
|
||||
.leftJoin("GroupMatch", "GroupMatch.id", "Skill.groupMatchId")
|
||||
.leftJoin("Tournament", "Tournament.id", "Skill.tournamentId")
|
||||
.leftJoin("CalendarEvent", "Tournament.id", "CalendarEvent.tournamentId")
|
||||
.leftJoin(
|
||||
"CalendarEventDate",
|
||||
"CalendarEvent.id",
|
||||
"CalendarEventDate.eventId",
|
||||
)
|
||||
.select(({ fn }) => [
|
||||
fn.max("Skill.ordinal").as("ordinal"),
|
||||
sql<string>`date(coalesce("GroupMatch"."createdAt", "CalendarEventDate"."startTime"), 'unixepoch')`.as(
|
||||
"date",
|
||||
),
|
||||
])
|
||||
.where("Skill.userId", "=", userId)
|
||||
.where("Skill.season", "=", season)
|
||||
.where("Skill.matchesCount", ">=", MATCHES_COUNT_NEEDED_FOR_LEADERBOARD)
|
||||
.where(({ or, eb }) =>
|
||||
or([
|
||||
eb("GroupMatch.id", "is not", null),
|
||||
eb("Tournament.id", "is not", null),
|
||||
]),
|
||||
)
|
||||
.groupBy("date")
|
||||
.orderBy("date", "asc")
|
||||
.execute();
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ export function queryCurrentUserRating({
|
|||
userId: number;
|
||||
season: number;
|
||||
}) {
|
||||
const skill = findCurrentSkillByUserId({ userId, season: season ?? null });
|
||||
const skill = findCurrentSkillByUserId({ userId, season });
|
||||
|
||||
if (!skill) {
|
||||
return { rating: rating(), matchesCount: 0 };
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { sql } from "~/db/sql";
|
||||
import type { Tables } from "../../../db/tables";
|
||||
import type { Tables } from "~/db/tables";
|
||||
|
||||
const stm = sql.prepare(/* sql */ `
|
||||
select
|
||||
|
|
|
|||
|
|
@ -21,36 +21,8 @@ const userStm = sql.prepare(/* sql */ `
|
|||
"Skill"."ordinal" desc
|
||||
`);
|
||||
|
||||
const teamStm = sql.prepare(/* sql */ `
|
||||
select
|
||||
"Skill"."ordinal",
|
||||
"Skill"."matchesCount",
|
||||
"Skill"."identifier"
|
||||
from
|
||||
"Skill"
|
||||
inner join (
|
||||
select "identifier", max("id") as "maxId"
|
||||
from "Skill"
|
||||
where "Skill"."season" = @season
|
||||
group by "identifier"
|
||||
) "Latest" on "Skill"."identifier" = "Latest"."identifier" and "Skill"."id" = "Latest"."maxId"
|
||||
where
|
||||
"Skill"."season" = @season
|
||||
and "Skill"."identifier" is not null
|
||||
order by
|
||||
"Skill"."ordinal" desc
|
||||
`);
|
||||
|
||||
export function orderedMMRBySeason({
|
||||
season,
|
||||
type,
|
||||
}: {
|
||||
season: number;
|
||||
type: "team" | "user";
|
||||
}) {
|
||||
const stm = type === "team" ? teamStm : userStm;
|
||||
|
||||
return stm.all({ season }) as Array<
|
||||
Pick<Tables["Skill"], "ordinal" | "matchesCount" | "userId" | "identifier">
|
||||
export function orderedUserMMRBySeason(season: number) {
|
||||
return userStm.all({ season }) as Array<
|
||||
Pick<Tables["Skill"], "ordinal" | "matchesCount" | "userId">
|
||||
>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
import { sql } from "~/db/sql";
|
||||
import { MATCHES_COUNT_NEEDED_FOR_LEADERBOARD } from "~/features/leaderboards/leaderboards-constants";
|
||||
|
||||
const groupedSkillsStm = sql.prepare(/* sql */ `
|
||||
select
|
||||
max("Skill"."ordinal") as "ordinal",
|
||||
date(
|
||||
coalesce("GroupMatch"."createdAt", "CalendarEventDate"."startTime"), 'unixepoch'
|
||||
) as "date"
|
||||
from
|
||||
"Skill"
|
||||
left join "GroupMatch" on "GroupMatch"."id" = "Skill"."groupMatchId"
|
||||
left join "Tournament" on "Tournament"."id" = "Skill"."tournamentId"
|
||||
left join "CalendarEvent" on "Tournament"."id" = "CalendarEvent"."tournamentId"
|
||||
left join "CalendarEventDate" on "CalendarEvent"."id" = "CalendarEventDate"."eventId"
|
||||
where
|
||||
"Skill"."userId" = @userId
|
||||
and "Skill"."season" = @season
|
||||
and "Skill"."matchesCount" >= ${MATCHES_COUNT_NEEDED_FOR_LEADERBOARD}
|
||||
and ("GroupMatch"."id" is not null or "Tournament"."id" is not null)
|
||||
group by "date"
|
||||
order by "date" asc
|
||||
`);
|
||||
|
||||
export function seasonAllMMRByUserId({
|
||||
userId,
|
||||
season,
|
||||
}: {
|
||||
userId: number;
|
||||
season: number;
|
||||
}) {
|
||||
return groupedSkillsStm.all({ userId, season }) as Array<{
|
||||
ordinal: number;
|
||||
date: string;
|
||||
}>;
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import {
|
|||
type TierName,
|
||||
USER_LEADERBOARD_MIN_ENTRIES_FOR_LEVIATHAN,
|
||||
} from "./mmr-constants";
|
||||
import { orderedMMRBySeason } from "./queries/orderedMMRBySeason.server";
|
||||
import { orderedUserMMRBySeason } from "./queries/orderedMMRBySeason.server";
|
||||
|
||||
export interface TieredSkill {
|
||||
ordinal: number;
|
||||
|
|
@ -25,10 +25,7 @@ export function freshUserSkills(season: number): {
|
|||
intervals: SkillTierInterval[];
|
||||
isAccurateTiers: boolean;
|
||||
} {
|
||||
const points = orderedMMRBySeason({
|
||||
season,
|
||||
type: "user",
|
||||
});
|
||||
const points = orderedUserMMRBySeason(season);
|
||||
|
||||
const { intervals, isAccurateTiers } = skillTierIntervals(points, "user");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { getUser } from "~/features/auth/core/user.server";
|
||||
import * as LeaderboardRepository from "~/features/leaderboards/LeaderboardRepository.server";
|
||||
import { seasonAllMMRByUserId } from "~/features/mmr/queries/seasonAllMMRByUserId.server";
|
||||
import * as SkillRepository from "~/features/mmr/SkillRepository.server";
|
||||
import { userSkills as _userSkills } from "~/features/mmr/tiered.server";
|
||||
import { seasonMapWinrateByUserId } from "~/features/sendouq/queries/seasonMapWinrateByUserId.server";
|
||||
import { seasonReportedWeaponsByUserId } from "~/features/sendouq/queries/seasonReportedWeaponsByUserId.server";
|
||||
|
|
@ -58,7 +58,10 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => {
|
|||
maps: seasonMapWinrateByUserId({ season, userId: user.id }),
|
||||
sets: seasonSetWinrateByUserId({ season, userId: user.id }),
|
||||
},
|
||||
skills: seasonAllMMRByUserId({ season, userId: user.id }),
|
||||
skills: await SkillRepository.seasonProgressionByUserId({
|
||||
season,
|
||||
userId: user.id,
|
||||
}),
|
||||
tier,
|
||||
isAccurateTiers,
|
||||
results: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user