import { IsInt, IsPositive } from 'class-validator'; import { getConnection } from 'typeorm'; import { RunnerCardNotFoundError } from '../../../errors/RunnerCardErrors'; import { RunnerNotFoundError } from '../../../errors/RunnerErrors'; import { ScanStationNotFoundError } from '../../../errors/ScanStationErrors'; import { RunnerCard } from '../../entities/RunnerCard'; import { ScanStation } from '../../entities/ScanStation'; import { TrackScan } from '../../entities/TrackScan'; /** * This classed is used to create a new Scan entity from a json body (post request). */ export class CreateTrackScan { /** * The id of the runnerCard associated with the scan. * This get's saved for documentation and management purposes. */ @IsInt() @IsPositive() card: number; /** * The scanning station's id that created the scan. * Mainly used for logging and traceing back scans (or errors). */ @IsInt() @IsPositive() station: number; /** * Creates a new Track entity from this. */ public async toEntity(): Promise { let newScan: TrackScan = new TrackScan(); newScan.station = await this.getStation(); newScan.card = await this.getCard(); newScan.track = newScan.station.track; newScan.runner = newScan.card.runner; if (!newScan.runner) { throw new RunnerNotFoundError(); } newScan.timestamp = Math.round(new Date().getTime() / 1000); newScan.valid = await this.validateScan(newScan); return newScan; } public async getCard(): Promise { const track = await getConnection().getRepository(RunnerCard).findOne({ id: this.card }, { relations: ["runner"] }); if (!track) { throw new RunnerCardNotFoundError(); } return track; } public async getStation(): Promise { const station = await getConnection().getRepository(ScanStation).findOne({ id: this.station }, { relations: ["track"] }); if (!station) { throw new ScanStationNotFoundError(); } return station; } public async validateScan(scan: TrackScan): Promise { const scans = await getConnection().getRepository(TrackScan).find({ where: { runner: scan.runner, valid: true }, relations: ["track"] }); if (scans.length == 0) { return true; } const newestScan = scans[scans.length - 1]; if ((scan.timestamp - newestScan.timestamp) > scan.track.minimumLapTime) { return true; } return false; } }