feat: add summoner/records endpoint

This commit is contained in:
Valentin Kaelin 2020-10-07 17:47:27 +02:00
parent 8184f17fbb
commit 8e272093c9
3 changed files with 166 additions and 0 deletions

View file

@ -6,6 +6,7 @@ import MatchService from 'App/Services/MatchService'
import SummonerService from 'App/Services/SummonerService'
import SummonerBasicValidator from 'App/Validators/SummonerBasicValidator'
import SummonerChampionValidator from 'App/Validators/SummonerChampionValidator'
import SummonerRecordValidator from 'App/Validators/SummonerRecordValidator'
export default class SummonersController {
/**
@ -82,4 +83,16 @@ export default class SummonersController {
console.timeEnd('championsRequest')
return response.json(championStats)
}
/**
* POST: get records view summoner data
* @param ctx
*/
public async records ({ request, response }) {
console.time('recordsRequest')
const { puuid, season } = await request.validate(SummonerRecordValidator)
const records = await MatchRepository.records(puuid, season)
console.timeEnd('recordsRequest')
return response.json(records)
}
}

View file

@ -105,6 +105,106 @@ class MatchRepository {
return this.aggregate(puuid, matchParams, [], '$champion.id', groupParams, finalSteps, season)
}
/**
* Get Summoner's all records
* @param puuid of the summoner
* @param season of the matches to fetch, if null get all seasons
*/
public async records (puuid: string, season?: number) {
const records = await this.collection.aggregate([
{
$match: {
...this.matchParams(puuid, season),
},
},
{
$group: {
_id: null,
maxKills: { $max: '$stats.kills' },
maxDeaths: { $max: '$stats.deaths' },
maxAssists: { $max: '$stats.assists' },
maxGold: { $max: '$stats.gold' },
maxTime: { $max: '$time' },
maxMinions: { $max: '$stats.minions' },
maxKda: { $max: '$stats.realKda' },
maxDmgTaken: { $max: '$stats.dmgTaken' },
maxDmgChamp: { $max: '$stats.dmgChamp' },
maxDmgObj: { $max: '$stats.dmgObj' },
maxKp: { $max: '$stats.kp' },
maxVision: { $max: '$stats.vision' },
maxCriticalStrike: { $max: '$stats.criticalStrike' },
maxLiving: { $max: '$stats.longestLiving' },
maxHeal: { $max: '$stats.heal' },
maxTowers: { $max: '$stats.towers' },
maxKillingSpree: { $max: '$stats.killingSpree' },
maxDouble: { $max: '$stats.doubleKills' },
maxTriple: { $max: '$stats.tripleKills' },
maxQuadra: { $max: '$stats.quadraKills' },
maxPenta: { $max: '$stats.pentaKills' },
docs: {
'$push': {
'champion': '$champion',
'gameId': '$gameId',
'kills': '$stats.kills',
'deaths': '$stats.deaths',
'assists': '$stats.assists',
'gold': '$stats.gold',
'time': '$time',
'minions': '$stats.minions',
'kda': '$stats.realKda',
'dmgTaken': '$stats.dmgTaken',
'dmgChamp': '$stats.dmgChamp',
'dmgObj': '$stats.dmgObj',
'kp': '$stats.kp',
'vision': '$stats.vision',
'criticalStrike': '$stats.criticalStrike',
'longestLiving': '$stats.longestLiving',
'heal': '$stats.heal',
'towers': '$stats.towers',
'killingSpree': '$stats.killingSpree',
'doubleKills': '$stats.doubleKills',
'tripleKills': '$stats.tripleKills',
'quadraKills': '$stats.quadraKills',
'pentaKills': '$stats.pentaKills',
'result': '$result',
'date': '$date',
'gamemode': '$gamemode',
},
},
},
},
{
$project: {
_id: 0,
/* eslint-disable max-len */
maxKills: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.kills', '$maxKills'] } } }, 0] },
maxDeaths: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.deaths', '$maxDeaths'] } } }, 0] },
maxAssists: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.assists', '$maxAssists'] } } }, 0] },
maxGold: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.gold', '$maxGold'] } } }, 0] },
maxTime: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.time', '$maxTime'] } } }, 0] },
maxMinions: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.minions', '$maxMinions'] } } }, 0] },
maxKda: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.kda', '$maxKda'] } } }, 0] },
maxDmgTaken: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.dmgTaken', '$maxDmgTaken'] } } }, 0] },
maxDmgChamp: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.dmgChamp', '$maxDmgChamp'] } } }, 0] },
maxDmgObj: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.dmgObj', '$maxDmgObj'] } } }, 0] },
maxKp: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.kp', '$maxKp'] } } }, 0] },
maxVision: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.vision', '$maxVision'] } } }, 0] },
maxCriticalStrike: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.criticalStrike', '$maxCriticalStrike'] } } }, 0] },
maxLiving: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.longestLiving', '$maxLiving'] } } }, 0] },
maxHeal: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.heal', '$maxHeal'] } } }, 0] },
maxTowers: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.towers', '$maxTowers'] } } }, 0] },
maxKillingSpree: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.killingSpree', '$maxKillingSpree'] } } }, 0] },
maxDouble: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.doubleKills', '$maxDouble'] } } }, 0] },
maxTriple: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.tripleKills', '$maxTriple'] } } }, 0] },
maxQuadra: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.quadraKills', '$maxQuadra'] } } }, 0] },
maxPenta: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.pentaKills', '$maxPenta'] } } }, 0] },
},
},
]).toArray()
return records[0]
}
/**
* Get Summoner's played seasons
* @param puuid of the summoner

View file

@ -0,0 +1,53 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { schema } from '@ioc:Adonis/Core/Validator'
export default class SummonerRecordValidator {
constructor (private ctx: HttpContextContract) {
}
/**
* Defining a schema to validate the "shape", "type", "formatting" and "integrity" of data.
*
* For example:
* 1. The username must be of data type string. But then also, it should
* not contain special characters or numbers.
* ```
* schema.string({}, [ rules.alpha() ])
* ```
*
* 2. The email must be of data type string, formatted as a valid
* email. But also, not used by any other user.
* ```
* schema.string({}, [
* rules.email(),
* rules.unique({ table: 'users', column: 'email' }),
* ])
* ```
*/
public schema = schema.create({
puuid: schema.string(),
season: schema.number.optional(),
})
/**
* The `schema` first gets compiled to a reusable function and then that compiled
* function validates the data at runtime.
*
* Since, compiling the schema is an expensive operation, you must always cache it by
* defining a unique cache key. The simplest way is to use the current request route
* key, which is a combination of the route pattern and HTTP method.
*/
public cacheKey = this.ctx.routeKey
/**
* Custom messages for validation failures. You can make use of dot notation `(.)`
* for targeting nested fields and array expressions `(*)` for targeting all
* children of an array. For example:
*
* {
* 'profile.username.required': 'Username is required',
* 'scores.*.number': 'Define scores as valid numbers'
* }
*/
public messages = {}
}