Skip to content

SendouQ match · Repositories

3 modules · 17 exports · 5 repositories · 13 e2e tests · 1 route

Every table a function queries, its own helpers included, read or written. Calls to other repositories are listed apart, their tables are on their own page.

GroupMatchContinueVoteRepository

app/features/sendouq-match/GroupMatchContinueVoteRepository.server.ts
Tables
GroupMatchContinueVote
Calls
no other repositories
Imports
no other modules
Used by
1 action1 script1 other

Functions & values

function

findAllByGroupIds

:8

Every continue vote cast in the given groups.

export async function findAllByGroupIds(
	groupIds: number[],
	trx?: Transaction<DB>,
)
Unit tests (2)
function

castOwnVote

:34

Records the user's continue vote. A no vote also clears the group's yes votes, cast for a size that no longer applies.

export async function castOwnVote(
	{
		groupId,
		isContinuing,
	}: {
		groupId: number;
		isContinuing: boolean;
	},
	trx?: Transaction<DB>,
)
Unit tests not about one export (2)

PlayerStatRepository

app/features/sendouq-match/PlayerStatRepository.server.ts
Tables
CalendarEventGroupMatchGroupMatchMapGroupMemberMapResultPlayerResultSkillTournamentTournamentDivisionTierTournamentMatchTournamentMatchGameResultTournamentMatchGameResultParticipantTournamentResultTournamentStageTournamentTeamUnvalidatedUserSubmittedImageUserUserSubmittedImage
Calls
no other repositories
Imports
no other modules
Used by
3 loaders1 repository1 script

Functions & values

function

upsertMapResults

no JSDoc:24
export function upsertMapResults(
	results: Pick<
		Tables["MapResult"],
		"losses" | "wins" | "userId" | "mode" | "stageId" | "season"
	>[],
	trx?: Transaction<DB>,
)
TablesMapResult
function

findSeasonMapWinrateByUserId

:46

Aggregated map win/loss record for a user in a given season.

export async function findSeasonMapWinrateByUserId({
	userId,
	season,
}: {
	userId: number;
	season: number;
}): Promise<{ wins: number; losses: number }>
TablesMapResult
function

findSeasonSetWinrateByUserId

:68

Aggregated set win/loss record for a user in a given season.

export async function findSeasonSetWinrateByUserId({
	userId,
	season,
}: {
	userId: number;
	season: number;
}): Promise<{ wins: number; losses: number }>
function

findSeasonStagesByUserId

:91

Per-stage per-mode win/loss breakdown for a user in a given season.

export async function findSeasonStagesByUserId({
	userId,
	season,
}: {
	userId: number;
	season: number;
})
TablesMapResult
function

findSeasonMatesEnemiesByUserId

:125

Mates or enemies for a user in a given season, ordered by most sets played together.

export async function findSeasonMatesEnemiesByUserId({
	userId,
	season,
	type,
}: {
	userId: number;
	season: number;
	type: Tables["PlayerResult"]["type"];
})
function

findSeasonSetScoresByUserId

:153

Oldest-first scores of every set the user played in a season, SendouQ and ranked tournaments.

export async function findSeasonSetScoresByUserId(args: {
	userId: number;
	season: number;
}): Promise<Array<{ ownScore: number; opponentScore: number }>>
function

findSeasonSetParticipantsByUserId

:181

One row per other player of each set the user played in a season, SendouQ and ranked tournaments.

export async function findSeasonSetParticipantsByUserId(args: {
	userId: number;
	season: number;
}): Promise<
	Array<{ otherUserId: number; type: "MATE" | "ENEMY"; playedAt: number }>
>
Unit tests (2)
function

findSeasonBestSetsByUserId

:243

The user's won sets of a season, best first by average opponent ordinal at play time. SendouQ and ranked tournaments; tournament sets need at least two opponents with a calculated skill. Only the best set against each opponent roster is included.

export async function findSeasonBestSetsByUserId({
	userId,
	season,
	limit,
}: {
	userId: number;
	season: number;
	limit: number;
})
function

findSeasonTournamentPlacementsByUserId

:410

Placement and field size of each of the user's ranked tournament results in a season.

export async function findSeasonTournamentPlacementsByUserId({
	userId,
	season,
}: {
	userId: number;
	season: number;
})
function

findSeasonTournamentRunsByUserId

:431

The user's ranked tournament results of a season with tier, field size and the average end-of-season ordinal of the top 8, for picking their best run.

export async function findSeasonTournamentRunsByUserId({
	userId,
	season,
}: {
	userId: number;
	season: number;
})
function

upsertPlayerResults

no JSDoc:509
export function upsertPlayerResults(
	results: Tables["PlayerResult"][],
	trx?: Transaction<DB>,
)

ReportedWeaponRepository

app/features/sendouq-match/ReportedWeaponRepository.server.ts
Tables
GroupMatchGroupMatchMapGroupMemberReportedWeaponTournamentTournamentMatchTournamentStage
Calls
no other repositories
Imports
Seasons
Used by
6 loaders2 actions1 route1 repository1 script3 other

Types

interface

WeaponUsageStat

no JSDoc:248
export interface WeaponUsageStat {
	type: "SELF" | "MATE" | "ENEMY";
	weaponSplId: MainWeaponId;
	count: number;
	wins: number;
	losses: number;
}
Only used inside the module

Functions & values

function

upsertOwn

no JSDoc:15
export async function upsertOwn({
	groupMatchId,
	mapIndex,
	weaponSplId,
}: Omit<TablesInsertable["ReportedWeapon"], "userId"> & {
	groupMatchId: number;
	mapIndex: number;
})
function

replaceByMatchId

no JSDoc:37
export async function replaceByMatchId(
	matchId: number,
	weapons: Omit<Tables["ReportedWeapon"], "createdAt">[],
	trx?: Transaction<DB>,
)
function

deleteByMatchId

no JSDoc:52
export async function deleteByMatchId(matchId: number, trx?: Transaction<DB>)
function

deleteOwnByMapIndex

no JSDoc:59
export async function deleteOwnByMapIndex({
	matchId,
	mapIndex,
}: {
	matchId: number;
	mapIndex: number;
})
function

deleteByMapIndex

no JSDoc:74
export async function deleteByMapIndex(
	{
		matchId,
		mapIndex,
	}: {
		matchId: number;
		mapIndex: number;
	},
	trx?: Transaction<DB>,
)
function

findByMatchId

no JSDoc:91
export async function findByMatchId(matchId: number)
function

upsertOwnTournament

no JSDoc:111
export async function upsertOwnTournament({
	tournamentMatchId,
	mapIndex,
	weaponSplId,
	createdAt,
}: Omit<TablesInsertable["ReportedWeapon"], "userId"> & {
	tournamentMatchId: number;
	mapIndex: number;
	createdAt: number;
})
function

deleteOwnByMapIndexTournament

no JSDoc:135
export async function deleteOwnByMapIndexTournament({
	tournamentMatchId,
	mapIndex,
}: {
	tournamentMatchId: number;
	mapIndex: number;
})
function

deleteExtraByTournamentMatchId

:151

Deletes weapons reported "in advance" for map indexes beyond the games played; called when a set ends to trim what score undos intentionally left dangling.

export async function deleteExtraByTournamentMatchId(
	{
		tournamentMatchId,
		gameCount,
	}: {
		tournamentMatchId: number;
		gameCount: number;
	},
	trx?: Transaction<DB>,
)
function

findByTournamentMatchId

no JSDoc:168
export async function findByTournamentMatchId(matchId: number)
function

findSeasonReportedWeaponsByUserId

:189

A user's reported weapons across SendouQ matches and finalized tournaments within the season's date range.

export async function findSeasonReportedWeaponsByUserId({
	userId,
	season,
}: {
	userId: number;
	season: number;
}): Promise<Array<{ weaponSplId: MainWeaponId; count: number }>>
function

findAllWeaponUsageStats

:257

How often a user and their mates/enemies used each weapon on a stage and mode during a season, with win/loss counts.

export async function findAllWeaponUsageStats({
	userId,
	mode,
	stageId,
	season,
}: {
	userId: number;
	mode: ModeShort;
	stageId: StageId;
	season: number;
}): Promise<WeaponUsageStat[]>
Unit tests (2)

SQMatchRepository

app/features/sendouq-match/SQMatchRepository.server.ts
Tables
AllTeamCalendarEventCalendarEventDateGroupGroupMatchGroupMatchCancelReportGroupMatchCancelReportPlayerGroupMatchContinueVoteGroupMatchMapGroupMemberSkillSkillTeamUserTenStarWeaponTournamentResultUnvalidatedUserSubmittedImageUserUserFriendCodeUserSubmittedImageUserWeaponPool
Calls
ChatRepositorySkillRepositoryScannerIngestRepositoryMatchSkillRepositoryPlayerStatRepositoryReportedWeaponRepositorySQGroupRepository
Imports
SeasonsRejoinVoteSendouQMatchSkillDifference
Used by
3 loaders1 action2 routes1 module1 routine1 script6 other

Types

type

SeasonGroupMatch

no JSDoc:487
export type SeasonGroupMatch = Extract<
	Unpacked<Unpacked<ReturnType<typeof findSeasonResultsByUserId>>>,
	{ type: "GROUP_MATCH" }
>["groupMatch"];
type

SeasonTournamentResult

no JSDoc:492
export type SeasonTournamentResult = Extract<
	Unpacked<Unpacked<ReturnType<typeof findSeasonResultsByUserId>>>,
	{ type: "TOURNAMENT_RESULT" }
>["tournamentResult"];
interface

MatchTiers

:1088

Tiers of a starting match's two groups and of the members they are made of.

export interface MatchTiers {
	groups: Array<{
		id: number;
		tier: TieredSkill["tier"];
		members: Array<{
			userId: number;
			/** `"CALCULATING"` when they have too few ranked sets of the season to have a tier. */
			tier: TieredSkill["tier"] | "CALCULATING";
		}>;
	}>;
}
type

CancelMatchResult

no JSDoc:1184
export type CancelMatchResult =
	| { status: "CANCEL_REPORTED"; shouldRefreshCaches: false }
	| { status: "CANCEL_CONFIRMED"; shouldRefreshCaches: true }
	| { status: "CANT_CANCEL"; shouldRefreshCaches: false }
	| { status: "DUPLICATE"; shouldRefreshCaches: false };
Only used inside the module
type

RequestCancelResult

no JSDoc:1283
export type RequestCancelResult =
	| { status: "REQUESTED" }
	| { status: "ALREADY_LOCKED" }
	| { status: "ALREADY_REQUESTED" };
Only used inside the module
type

AcceptCancelResult

no JSDoc:1338
export type AcceptCancelResult =
	| { status: "ACCEPTED" }
	| { status: "ALREADY_LOCKED" }
	| { status: "NO_CANCEL_REQUEST" }
	| { status: "NOT_ALLOWED" };
Only used inside the module
type

RefuseCancelResult

no JSDoc:1417
export type RefuseCancelResult =
	| { status: "REFUSED" }
	| { status: "ALREADY_LOCKED" }
	| { status: "NO_CANCEL_REQUEST" }
	| { status: "NOT_ALLOWED" };
Only used inside the module
type

ReportMapWinnerResult

no JSDoc:1467
export type ReportMapWinnerResult =
	| { status: "MAP_REPORTED" }
	| { status: "MATCH_REPORTED" }
	| { status: "MATCH_FINALIZED" }
	| { status: "ALREADY_LOCKED" }
	| { status: "INVALID_WINNER" }
	| { status: "SCORE_DISAGREEMENT" }
	| { status: "STALE" };
Only used inside the module
type

ResolveUnfinishedMatchResult

no JSDoc:1850
export type ResolveUnfinishedMatchResult =
	| { status: "CANCELED" }
	| { status: "CONFIRMED" }
	| { status: "ALREADY_LOCKED" };
Only used inside the module

Functions & values

function

exists

:67

Whether a GroupMatch with the given id exists.

export async function exists(id: number)
function

findAllByChatRoomIds

:78

Matches owning the given chat rooms, with both groups' members' user ids.

export async function findAllByChatRoomIds(chatRoomIds: number[])
function

findLiveStateById

:112

Just enough of a match to tell still being played apart from over, for the header status.

export async function findLiveStateById(id: number)
function

countSeasonResultPagesByUserId

:352

Page count of a user's season results, counting SendouQ matches, ranked tournaments or both per source.

export async function countSeasonResultPagesByUserId({
	userId,
	season,
	source = "ALL",
}: {
	userId: number;
	season: number;
	source?: SeasonResultSource;
}): Promise<number>
function

findSeasonDaySummariesByUserId

:732

Summary of each of the given days (yyyy-MM-dd, UTC, ascending) a user played season sets on, SendouQ matches, ranked tournaments or both per source. The SP change is null when every change of the day was made while the rating was still being calculated and so never shown.

export async function findSeasonDaySummariesByUserId({
	userId,
	season,
	source = "ALL",
	dates,
}: {
	userId: number;
	season: number;
	source?: SeasonResultSource;
	dates: string[];
})
Unit tests (2)
function

findSeasonCanceledMatchesByUserId

no JSDoc:829
export async function findSeasonCanceledMatchesByUserId({
	userId,
	season,
}: {
	userId: number;
	season: number;
})
Unit tests (1)
function

findCancelReportsByGroupMatchId

:899

Returns both teams' cancel reports of a match with the nominated player ids, requester's report first.

export async function findCancelReportsByGroupMatchId(groupMatchId: number)
function

findCancelNominationCountsByUserIds

:927

Counts per user how many canceled matches they have been nominated in as a cause, both within the given season and within the current calendar year. Only finalized cancellations count; a match where both teams nominated the user counts once.

export async function findCancelNominationCountsByUserIds({
	userIds,
	season,
}: {
	userIds: number[];
	season: number;
})
Unit tests (1)
function

insert

:989

Creates a match between two groups, resolving its ready check in the same transaction; only seeds and tests leave readyCheckId out.

export function insert({
	alphaGroupId,
	bravoGroupId,
	mapList,
	tiers,
	readyCheckId,
}: {
	alphaGroupId: number;
	bravoGroupId: number;
	mapList: TournamentMapListMap[];
	/** Tiers the two groups and their members hold as the match starts, snapshotted on them. */
	tiers: MatchTiers;
	readyCheckId?: number;
})
Unit tests (2)
function

requestCancelMatch

no JSDoc:1288
export async function requestCancelMatch({
	matchId,
	requestedByUserId,
	reason,
	nominatedUserIds,
}: {
	matchId: number;
	requestedByUserId: number;
	reason: string;
	nominatedUserIds: number[];
}): Promise<RequestCancelResult>
Unit tests (2)
function

refuseCancelMatch

no JSDoc:1423
export async function refuseCancelMatch({
	matchId,
	refusedByUserId,
}: {
	matchId: number;
	refusedByUserId: number;
}): Promise<RefuseCancelResult>
Unit tests (1)
function

reportMapWinner

no JSDoc:1476
export async function reportMapWinner({
	matchId,
	winnerId,
	reportedByUserId,
	reportedCount,
	confirmingReportedAt,
	isStaffReport,
}: {
	matchId: number;
	winnerId: number;
	reportedByUserId: number;
	reportedCount: number;
	confirmingReportedAt?: number;
	isStaffReport?: boolean;
}): Promise<ReportMapWinnerResult>
function

findUnfinishedMatchesCreatedBefore

:1817

Matches created before the given cutoff whose score was never confirmed and that no cancellation has locked.

export function findUnfinishedMatchesCreatedBefore(cutoff: Date)
function

undoMatchReport

no JSDoc:1916
export async function undoMatchReport({
	matchId,
	requestedByUserId,
	isStaff,
}: {
	matchId: number;
	requestedByUserId: number;
	isStaff?: boolean;
}): Promise<{ status: "SUCCESS" | "NOT_ALLOWED" | "ALREADY_LOCKED" }>
Unit tests (1)
function

undoMapReport

no JSDoc:1987
export async function undoMapReport({
	matchId,
	mapIndex,
}: {
	matchId: number;
	mapIndex: number;
}): Promise<{ status: "SUCCESS" | "NOT_ALLOWED" | "ALREADY_LOCKED" }>
Unit tests not about one export (8)

Not shown, only used by tests: lockMatchWithoutSkillChange