diff --git a/server-new/app/Controllers/Http/SummonersController.ts b/server-new/app/Controllers/Http/SummonersController.ts index 12b8694..5e16950 100644 --- a/server-new/app/Controllers/Http/SummonersController.ts +++ b/server-new/app/Controllers/Http/SummonersController.ts @@ -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) + } } diff --git a/server-new/app/Repositories/MatchRepository.ts b/server-new/app/Repositories/MatchRepository.ts index 33d539d..41bece3 100644 --- a/server-new/app/Repositories/MatchRepository.ts +++ b/server-new/app/Repositories/MatchRepository.ts @@ -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 diff --git a/server-new/app/Validators/SummonerRecordValidator.ts b/server-new/app/Validators/SummonerRecordValidator.ts new file mode 100644 index 0000000..5485409 --- /dev/null +++ b/server-new/app/Validators/SummonerRecordValidator.ts @@ -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 = {} +}