Skip to content

Commit

Permalink
getAllRatingResults endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Tschonti committed Jun 10, 2024
1 parent c345752 commit a0bc453
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 19 deletions.
32 changes: 28 additions & 4 deletions packages/common/src/lib/types/ratingResult.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { Category } from './categories'
import { Criterion } from './criteria'
import { DbEvent, DbStage } from './dbEvents'
import { Season } from './seasons'

export interface RatingResult {
id: number
parentId?: number
eventId: number
stageId?: number
criterionId?: number
criterion?: Criterion
categoryId?: number
category?: Category
items: RatingResultItem[]
}

export interface RatingResultWithJoins extends RatingResult {
criterion?: Criterion
category?: Category
}

export interface RatingResultItem {
count: number
average: number
Expand All @@ -22,8 +26,28 @@ export interface RatingResultItem {
}

export interface EventWithResults extends Omit<DbEvent, 'stages'> {
ratingResults: RatingResult
ratingResults: RatingResultWithJoins
stages: (DbStage & {
ratingResults: RatingResult
ratingResults: RatingResultWithJoins
})[]
}

export interface EventResultList {
season: Season
categories: Category[]
criteria: Criterion[]
eventResults: EventResult[]
}

export interface EventResult {
eventId: number
eventName: string
results: RatingResult[]
stages: StageResult[]
}

export interface StageResult {
stageId: number
stageName: string
results: RatingResult[]
}
8 changes: 3 additions & 5 deletions packages/functions/src/functions/events/getOne.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ import Event from '../../typeorm/entities/Event'
import EventRating from '../../typeorm/entities/EventRating'
import { getAppDataSource } from '../../typeorm/getConfig'
import { handleException } from '../../util/handleException'
import { validateId } from '../../util/validation'

/**
* Called when the user visits an event page to get the event data and the user's rating.
*/
export const getOneEvent = async (req: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> => {
try {
const eventId = parseInt(req.params.eventId)
if (isNaN(eventId)) {
throw new PontozoException('Érvénytelen azonosító!', 400)
}
const eventId = validateId(req)

const user = getUserFromHeader(req)
const ads = await getAppDataSource(context)
Expand All @@ -40,6 +38,6 @@ export const getOneEvent = async (req: HttpRequest, context: InvocationContext):

app.http('events-getOne', {
methods: ['GET'],
route: 'events/getOne/{eventId}',
route: 'events/getOne/{id}',
handler: getOneEvent,
})
80 changes: 80 additions & 0 deletions packages/functions/src/functions/results/getEventResults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions'
import { EventResult, EventResultList, EventState, PontozoException } from '@pontozo/common'
import { In } from 'typeorm'
import Category from '../../typeorm/entities/Category'
import Criterion from '../../typeorm/entities/Criterion'
import { RatingResult } from '../../typeorm/entities/RatingResult'
import Season from '../../typeorm/entities/Season'
import { getAppDataSource } from '../../typeorm/getConfig'
import { currentSeasonFilter } from '../../util/currentSeasonFilter'
import { handleException } from '../../util/handleException'

export const getEventResults = async (req: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> => {
try {
const seasonId = req.query.get('seasonId')
const categoryIds =
req.query
.get('categoryIds')
?.split(',')
?.map((s) => parseInt(s))
.filter((n) => !isNaN(n)) ?? []
const criterionIds =
req.query
.get('criterionIds')
?.split(',')
?.map((s) => parseInt(s))
.filter((n) => !isNaN(n)) ?? []

let season: Season
const ads = await getAppDataSource(context)
const seasonRepo = ads.getRepository(Season)
const categorynRepo = ads.getRepository(Category)
const criterionRepo = ads.getRepository(Criterion)
const resultsRepo = ads.getRepository(RatingResult)

if (seasonId) {
season = await seasonRepo.findOne({ where: { id: parseInt(seasonId) }, relations: { events: { stages: true } } })
} else {
season = await seasonRepo.findOne({ where: currentSeasonFilter, relations: { events: { stages: true } } })
}
if (!season) {
throw new PontozoException('Nem található a szezon!', 404)
}

const categoriesQuery = categorynRepo.find({ where: { id: In(categoryIds) } })
const criteriaQuery = criterionRepo.find({ where: { id: In(criterionIds) } })
const [categories, criteria] = await Promise.all([categoriesQuery, criteriaQuery])

const results = await resultsRepo.find({
where: [{ categoryId: In(categories.map((c) => c.id)) }, { criterionId: In(criteria.map((c) => c.id)) }],
})
const closedEvents = season.events.filter((e) => e.state === EventState.RESULTS_READY)
const eventResults: EventResult[] = closedEvents.map((e) => ({
eventId: e.id,
eventName: e.name,
results: results.filter((r) => r.eventId === e.id && !r.stageId).map((r) => ({ ...r, items: JSON.parse(r.items) })),
stages: e.stages.map((s) => ({
stageId: s.id,
stageName: s.name,
results: results.filter((r) => r.eventId === e.id && r.stageId === s.id).map((r) => ({ ...r, items: JSON.parse(r.items) })),
})),
}))
const { events, ...rawSeason } = season
const resultList: EventResultList = {
season: rawSeason,
categories,
criteria: criteria.map((c) => ({ ...c, roles: JSON.parse(c.roles) })),
eventResults,
}

return { jsonBody: resultList }
} catch (error) {
return handleException(req, context, error)
}
}

app.http('results-getEventResults', {
methods: ['GET'],
route: 'results',
handler: getEventResults,
})
8 changes: 3 additions & 5 deletions packages/functions/src/functions/results/getOne.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ import { RatingResult } from '../../typeorm/entities/RatingResult'
import { getAppDataSource } from '../../typeorm/getConfig'
import { handleException } from '../../util/handleException'
import { parseRatingResults } from '../../util/parseRatingResults'
import { validateId } from '../../util/validation'

export const getOneResult = async (req: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> => {
try {
const eventId = parseInt(req.params.eventId)
if (isNaN(eventId)) {
throw new PontozoException('Érvénytelen azonosító!', 400)
}
const eventId = validateId(req)

const redisClient = await getRedisClient(context)
const ratingResult = await redisClient.get(`ratingResult:${eventId}`)
Expand Down Expand Up @@ -46,6 +44,6 @@ export const getOneResult = async (req: HttpRequest, context: InvocationContext)

app.http('results-getOne', {
methods: ['GET'],
route: 'results/{eventId}',
route: 'results/{id}',
handler: getOneResult,
})
4 changes: 2 additions & 2 deletions packages/functions/src/util/parseRatingResults.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Criterion as Criterion_DTO, DbEvent, EventWithResults, RatingResult as RR_DTO } from '@pontozo/common'
import { Criterion as Criterion_DTO, DbEvent, EventWithResults, RatingResultWithJoins } from '@pontozo/common'
import Criterion_DB from '../typeorm/entities/Criterion'
import { RatingResult as RR_DB } from '../typeorm/entities/RatingResult'

export const parseRatingResults = (results: RR_DB[], event: DbEvent): EventWithResults => {
const parsed: RR_DTO[] = results.map((r) => ({
const parsed: RatingResultWithJoins[] = results.map((r) => ({
...r,
items: JSON.parse(r.items),
criterion: parseCriterion(r.criterion),
Expand Down
4 changes: 2 additions & 2 deletions packages/functions/src/util/ratingAverage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ageGroupFilterDict, ALL_AGE_GROUPS, ALL_ROLES, RatingResult as IRatingResult, RatingResultItem } from '@pontozo/common'
import { ageGroupFilterDict, ALL_AGE_GROUPS, ALL_ROLES, RatingResultItem, RatingResultWithJoins } from '@pontozo/common'
import Category from '../typeorm/entities/Category'
import Criterion from '../typeorm/entities/Criterion'
import CriterionRating from '../typeorm/entities/CriterionRating'
Expand Down Expand Up @@ -54,7 +54,7 @@ export const averageByRoleAndGroup = (
}),
]

export const accumulateCategory = (results: Omit<IRatingResult, 'id'>[]): RatingResultItem[] => {
export const accumulateCategory = (results: Omit<RatingResultWithJoins, 'id'>[]): RatingResultItem[] => {
const variatons = ALL_ROLES.length + ALL_AGE_GROUPS.length + 1
const zeroToN = Array.from({ length: variatons }, (_, i) => i)
const sum = Array.from({ length: variatons }, () => 0)
Expand Down
2 changes: 1 addition & 1 deletion packages/functions/src/util/validation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { HttpRequest } from '@azure/functions'
import { PontozoException } from '@pontozo/common'
import { validate } from 'class-validator'
import { PontozoException } from '../../../common/src'

export const validateWithWhitelist = async (object: object): Promise<void> => {
const errors = await validate(object, { whitelist: true })
Expand Down

0 comments on commit a0bc453

Please sign in to comment.