mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-28 06:10:01 -05:00
Exported images w/ SQ season summary downloadable (#3272)
This commit is contained in:
@@ -163,34 +163,42 @@ export async function findSeasonProgressionByUserId({
|
||||
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("Skill"."createdAt", "GroupMatch"."createdAt", "CalendarEventDate"."startsAt"), 'unixepoch')`.as(
|
||||
"date",
|
||||
return seasonSkillsByDayQuery({ userId, season })
|
||||
.select(({ fn }) => fn.max("Skill.ordinal").as("ordinal"))
|
||||
.where("Skill.matchesCount", ">=", MATCHES_COUNT_NEEDED_FOR_LEADERBOARD)
|
||||
.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Days of the season the user played at least one set on, with whether they
|
||||
* played SendouQ, tournaments or both that day. Dates in `yyyy-MM-dd` format.
|
||||
*/
|
||||
export async function findSeasonActiveDaysByUserId({
|
||||
userId,
|
||||
season,
|
||||
}: {
|
||||
userId: number;
|
||||
season: number;
|
||||
}): Promise<Array<{ date: string; activity: "sq" | "tournament" | "both" }>> {
|
||||
const rows = await seasonSkillsByDayQuery({ userId, season })
|
||||
.select([
|
||||
// raw max over a null check: did any of the day's Skill rows come from this source?
|
||||
sql<number>`max("Skill"."groupMatchId" is not null)`.as("playedSq"),
|
||||
sql<number>`max("Skill"."tournamentId" is not null)`.as(
|
||||
"playedTournament",
|
||||
),
|
||||
])
|
||||
.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();
|
||||
|
||||
return rows.map((row) => ({
|
||||
date: row.date,
|
||||
activity:
|
||||
row.playedSq && row.playedTournament
|
||||
? ("both" as const)
|
||||
: row.playedSq
|
||||
? ("sq" as const)
|
||||
: ("tournament" as const),
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,3 +224,42 @@ function latestSkillsOfSeason(
|
||||
])
|
||||
.where("season", "=", season);
|
||||
}
|
||||
|
||||
/**
|
||||
* User's Skill rows of a season that came from a set played, grouped by the day
|
||||
* it was played on (`yyyy-MM-dd`) in ascending order. Callers select what they
|
||||
* want aggregated per day.
|
||||
*/
|
||||
function seasonSkillsByDayQuery({
|
||||
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(
|
||||
sql<string>`date(coalesce("Skill"."createdAt", "GroupMatch"."createdAt", "CalendarEventDate"."startsAt"), 'unixepoch')`.as(
|
||||
"date",
|
||||
),
|
||||
)
|
||||
.where("Skill.userId", "=", userId)
|
||||
.where("Skill.season", "=", season)
|
||||
.where(({ or, eb }) =>
|
||||
or([
|
||||
eb("GroupMatch.id", "is not", null),
|
||||
eb("Tournament.id", "is not", null),
|
||||
]),
|
||||
)
|
||||
.groupBy("date")
|
||||
.orderBy("date", "asc");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user