166 lines
7.2 KiB
TypeScript
166 lines
7.2 KiB
TypeScript
import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam } from 'routing-controllers';
|
|
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
|
|
import { Repository, getConnectionManager } from 'typeorm';
|
|
import { RunnerGroupNeededError, RunnerHasDistanceDonationsError, RunnerIdsNotMatchingError, RunnerNotFoundError } from '../errors/RunnerErrors';
|
|
import { RunnerGroupNotFoundError } from '../errors/RunnerGroupErrors';
|
|
import { CreateRunner } from '../models/actions/create/CreateRunner';
|
|
import { UpdateRunner } from '../models/actions/update/UpdateRunner';
|
|
import { Runner } from '../models/entities/Runner';
|
|
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
|
|
import { ResponseRunner } from '../models/responses/ResponseRunner';
|
|
import { ResponseScan } from '../models/responses/ResponseScan';
|
|
import { ResponseTrackScan } from '../models/responses/ResponseTrackScan';
|
|
import { DonationController } from './DonationController';
|
|
import { RunnerCardController } from './RunnerCardController';
|
|
import { ScanController } from './ScanController';
|
|
|
|
@JsonController('/runners')
|
|
@OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
|
|
export class RunnerController {
|
|
private runnerRepository: Repository<Runner>;
|
|
|
|
/**
|
|
* Gets the repository of this controller's model/entity.
|
|
*/
|
|
constructor() {
|
|
this.runnerRepository = getConnectionManager().get().getRepository(Runner);
|
|
}
|
|
|
|
@Get()
|
|
@Authorized("RUNNER:GET")
|
|
@ResponseSchema(ResponseRunner, { isArray: true })
|
|
@OpenAPI({ description: 'Lists all runners from all teams/orgs. <br> This includes the runner\'s group and distance ran.' })
|
|
async getAll(@QueryParam("page", { required: false }) page: number, @QueryParam("page_size", { required: false }) page_size: number = 100) {
|
|
let responseRunners: ResponseRunner[] = new Array<ResponseRunner>();
|
|
let runners: Array<Runner>;
|
|
|
|
if (page != undefined) {
|
|
runners = await this.runnerRepository.find({ relations: ['scans', 'group', 'group.parentGroup', 'scans.track'], skip: page * page_size, take: page_size });
|
|
} else {
|
|
runners = await this.runnerRepository.find({ relations: ['scans', 'group', 'group.parentGroup', 'scans.track'] });
|
|
}
|
|
|
|
runners.forEach(runner => {
|
|
responseRunners.push(new ResponseRunner(runner));
|
|
});
|
|
return responseRunners;
|
|
}
|
|
|
|
@Get('/:id')
|
|
@Authorized("RUNNER:GET")
|
|
@ResponseSchema(ResponseRunner)
|
|
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
|
|
@OnUndefined(RunnerNotFoundError)
|
|
@OpenAPI({ description: 'Lists all information about the runner whose id got provided.' })
|
|
async getOne(@Param('id') id: number) {
|
|
let runner = await this.runnerRepository.findOne({ id: id }, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards'] })
|
|
if (!runner) { throw new RunnerNotFoundError(); }
|
|
return new ResponseRunner(runner);
|
|
}
|
|
|
|
@Get('/:id/scans')
|
|
@Authorized(["RUNNER:GET", "SCAN:GET"])
|
|
@ResponseSchema(ResponseScan, { isArray: true })
|
|
@ResponseSchema(ResponseTrackScan, { isArray: true })
|
|
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
|
|
@OpenAPI({ description: 'Lists all scans of the runner whose id got provided. <br> If you only want the valid scans just add the ?onlyValid=true query param.' })
|
|
async getScans(@Param('id') id: number, onlyValid?: boolean) {
|
|
let responseScans: ResponseScan[] = new Array<ResponseScan>();
|
|
let runner = await this.runnerRepository.findOne({ id: id }, { relations: ['scans', 'scans.track', 'scans.station', 'scans.runner'] })
|
|
if (!runner) { throw new RunnerNotFoundError(); }
|
|
|
|
if (!onlyValid) {
|
|
for (let scan of runner.scans) {
|
|
responseScans.push(scan.toResponse());
|
|
}
|
|
}
|
|
else {
|
|
for (let scan of runner.validScans) {
|
|
responseScans.push(scan.toResponse());
|
|
}
|
|
}
|
|
|
|
return responseScans;
|
|
}
|
|
|
|
@Post()
|
|
@Authorized("RUNNER:CREATE")
|
|
@ResponseSchema(ResponseRunner)
|
|
@ResponseSchema(RunnerGroupNeededError)
|
|
@ResponseSchema(RunnerGroupNotFoundError)
|
|
@OpenAPI({ description: 'Create a new runner. <br> Please remeber to provide the runner\'s group\'s id.' })
|
|
async post(@Body({ validate: true }) createRunner: CreateRunner) {
|
|
let runner;
|
|
try {
|
|
runner = await createRunner.toEntity();
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
|
|
runner = await this.runnerRepository.save(runner)
|
|
return new ResponseRunner(await this.runnerRepository.findOne(runner, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards'] }));
|
|
}
|
|
|
|
@Put('/:id')
|
|
@Authorized("RUNNER:UPDATE")
|
|
@ResponseSchema(ResponseRunner)
|
|
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
|
|
@ResponseSchema(RunnerIdsNotMatchingError, { statusCode: 406 })
|
|
@OpenAPI({ description: "Update the runner whose id you provided. <br> Please remember that ids can't be changed." })
|
|
async put(@Param('id') id: number, @Body({ validate: true }) runner: UpdateRunner) {
|
|
let oldRunner = await this.runnerRepository.findOne({ id: id }, { relations: ['group'] });
|
|
|
|
if (!oldRunner) {
|
|
throw new RunnerNotFoundError();
|
|
}
|
|
|
|
if (oldRunner.id != runner.id) {
|
|
throw new RunnerIdsNotMatchingError();
|
|
}
|
|
|
|
await this.runnerRepository.save(await runner.update(oldRunner));
|
|
return new ResponseRunner(await this.runnerRepository.findOne({ id: id }, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards'] }));
|
|
}
|
|
|
|
@Delete('/:id')
|
|
@Authorized("RUNNER:DELETE")
|
|
@ResponseSchema(ResponseRunner)
|
|
@ResponseSchema(ResponseEmpty, { statusCode: 204 })
|
|
@ResponseSchema(RunnerHasDistanceDonationsError, { statusCode: 406 })
|
|
@OnUndefined(204)
|
|
@OpenAPI({ description: 'Delete the runner whose id you provided. <br> This will also delete all scans and cards associated with the runner. <br> If no runner with this id exists it will just return 204(no content).' })
|
|
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
|
|
let runner = await this.runnerRepository.findOne({ id: id });
|
|
if (!runner) { return null; }
|
|
const responseRunner = await this.runnerRepository.findOne(runner, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards'] });
|
|
|
|
if (!runner) {
|
|
throw new RunnerNotFoundError();
|
|
}
|
|
|
|
const runnerDonations = (await this.runnerRepository.findOne({ id: runner.id }, { relations: ["distanceDonations"] })).distanceDonations;
|
|
if (runnerDonations.length > 0 && !force) {
|
|
throw new RunnerHasDistanceDonationsError();
|
|
}
|
|
const donationController = new DonationController();
|
|
for (let donation of runnerDonations) {
|
|
await donationController.remove(donation.id, force);
|
|
}
|
|
|
|
const runnerCards = (await this.runnerRepository.findOne({ id: runner.id }, { relations: ["cards"] })).cards;
|
|
const cardController = new RunnerCardController;
|
|
for (let card of runnerCards) {
|
|
await cardController.remove(card.id, force);
|
|
}
|
|
|
|
const runnerScans = (await this.runnerRepository.findOne({ id: runner.id }, { relations: ["scans"] })).scans;
|
|
const scanController = new ScanController;
|
|
for (let scan of runnerScans) {
|
|
await scanController.remove(scan.id, force);
|
|
}
|
|
|
|
await this.runnerRepository.delete(runner);
|
|
return new ResponseRunner(responseRunner);
|
|
}
|
|
}
|