Skip to content

Commit

Permalink
feat: adjusted efficiency ratings
Browse files Browse the repository at this point in the history
  • Loading branch information
BlueSCar committed Jan 30, 2025
1 parent c4a1f0b commit f4b2019
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 3 deletions.
20 changes: 18 additions & 2 deletions src/app/ratings/controller.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Route, Tags, Controller, Get, Query, Middlewares } from 'tsoa';

import middlewares from '../../config/middleware';
import { SrsInfo } from './types';
import { getSrs } from './service';
import { AdjustedEfficiencyInfo, SrsInfo } from './types';
import { getAdjustedEfficiency, getSrs } from './service';

@Route('ratings')
@Middlewares(middlewares.standard)
Expand All @@ -23,4 +23,20 @@ export class RatingsController extends Controller {
): Promise<SrsInfo[]> {
return await getSrs(season, team, conference);
}

/**
* Retrieves adjusted efficiency ratings for the provided season, team, or conference.
* @param season Optional season filter
* @param team Optional team filter
* @param conference Optional conference abbreviation filter
* @isInt season
*/
@Get('adjusted')
public async getAdjustedEfficiency(
@Query() season?: number,
@Query() team?: string,
@Query() conference?: string,
): Promise<AdjustedEfficiencyInfo[]> {
return await getAdjustedEfficiency(season, team, conference);
}
}
70 changes: 69 additions & 1 deletion src/app/ratings/service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { db } from '../../config/database';

import { SrsInfo } from './types';
import { AdjustedEfficiencyInfo, SrsInfo } from './types';

export const getSrs = async (
year?: number,
Expand Down Expand Up @@ -61,3 +61,71 @@ export const getSrs = async (
rating: Number(r.rating),
}));
};

export const getAdjustedEfficiency = async (
year?: number,
team?: string,
conference?: string,
): Promise<AdjustedEfficiencyInfo[]> => {
let query = db
.selectFrom('adjustedEfficiency')
.innerJoin('team', 'team.id', 'adjustedEfficiency.teamId')
.innerJoin('conferenceTeam', (join) =>
join
.onRef('conferenceTeam.teamId', '=', 'team.id')
.onRef('conferenceTeam.startYear', '<=', 'adjustedEfficiency.season')
.on((eb) =>
eb.or([
eb(
'conferenceTeam.endYear',
'>=',
eb.ref('adjustedEfficiency.season'),
),
eb('conferenceTeam.endYear', 'is', null),
]),
),
)
.innerJoin('conference', 'conference.id', 'conferenceTeam.conferenceId')
.select([
'adjustedEfficiency.season',
'adjustedEfficiency.teamId',
'team.school as team',
'conference.abbreviation as conference',
'adjustedEfficiency.offense as offensiveRating',
'adjustedEfficiency.defense as defensiveRating',
'adjustedEfficiency.net as netRating',
])
.orderBy('adjustedEfficiency.season', 'desc')
.orderBy('adjustedEfficiency.net', 'desc');

if (year) {
query = query.where('adjustedEfficiency.season', '=', year);
}

if (team) {
query = query.where(
(eb) => eb.fn('lower', [eb.ref('team.school')]),
'=',
team.toLowerCase(),
);
}

if (conference) {
query = query.where(
(eb) => eb.fn('lower', [eb.ref('conference.abbreviation')]),
'=',
conference.toLowerCase(),
);
}

const ratings = await query.execute();
return ratings.map((r) => ({
season: r.season,
teamId: r.teamId,
team: r.team,
conference: r.conference,
offensiveRating: Number(r.offensiveRating),
defensiveRating: Number(r.defensiveRating),
netRating: Number(r.netRating),
}));
};
16 changes: 16 additions & 0 deletions src/app/ratings/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,19 @@ export interface SrsInfo {
conference: string;
rating: number;
}

export interface AdjustedEfficiencyInfo {
/**
* @isInt
*/
season: number;
/**
* @isInt
*/
teamId: number;
team: string;
conference: string;
offensiveRating: number;
defensiveRating: number;
netRating: number;
}
10 changes: 10 additions & 0 deletions src/config/types/db.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ export type SeasonType = 'postseason' | 'preseason' | 'regular';

export type Timestamp = ColumnType<Date, Date | string, Date | string>;

export interface AdjustedEfficiency {
defense: Numeric;
id: Generated<number>;
net: Numeric;
offense: Numeric;
season: number;
teamId: number;
}

export interface Athlete {
dob: Timestamp | null;
firstName: string | null;
Expand Down Expand Up @@ -317,6 +326,7 @@ export interface Venue {
}

export interface DB {
adjustedEfficiency: AdjustedEfficiency;
athlete: Athlete;
athleteTeam: AthleteTeam;
conference: Conference;
Expand Down

0 comments on commit f4b2019

Please sign in to comment.