Merge branch 'dev' into feature/79-profile_pics
Some checks failed
continuous-integration/drone/pr Build is failing
Some checks failed
continuous-integration/drone/pr Build is failing
This commit is contained in:
110
src/controllers/ScanController.ts
Normal file
110
src/controllers/ScanController.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam, UseBefore } from 'routing-controllers';
|
||||
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
|
||||
import { getConnectionManager, Repository } from 'typeorm';
|
||||
import { RunnerNotFoundError } from '../errors/RunnerErrors';
|
||||
import { ScanIdsNotMatchingError, ScanNotFoundError } from '../errors/ScanErrors';
|
||||
import ScanAuth from '../middlewares/ScanAuth';
|
||||
import { CreateScan } from '../models/actions/CreateScan';
|
||||
import { CreateTrackScan } from '../models/actions/CreateTrackScan';
|
||||
import { UpdateScan } from '../models/actions/UpdateScan';
|
||||
import { Scan } from '../models/entities/Scan';
|
||||
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
|
||||
import { ResponseScan } from '../models/responses/ResponseScan';
|
||||
import { ResponseTrackScan } from '../models/responses/ResponseTrackScan';
|
||||
|
||||
@JsonController('/scans')
|
||||
@OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
|
||||
export class ScanController {
|
||||
private scanRepository: Repository<Scan>;
|
||||
|
||||
/**
|
||||
* Gets the repository of this controller's model/entity.
|
||||
*/
|
||||
constructor() {
|
||||
this.scanRepository = getConnectionManager().get().getRepository(Scan);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@Authorized("SCAN:GET")
|
||||
@ResponseSchema(ResponseScan, { isArray: true })
|
||||
@ResponseSchema(ResponseTrackScan, { isArray: true })
|
||||
@OpenAPI({ description: 'Lists all scans (normal or track) from all runners. <br> This includes the scan\'s runner\'s distance ran.' })
|
||||
async getAll() {
|
||||
let responseScans: ResponseScan[] = new Array<ResponseScan>();
|
||||
const scans = await this.scanRepository.find({ relations: ['runner', 'runner.scans', 'runner.scans.track'] });
|
||||
scans.forEach(scan => {
|
||||
responseScans.push(scan.toResponse());
|
||||
});
|
||||
return responseScans;
|
||||
}
|
||||
|
||||
@Get('/:id')
|
||||
@Authorized("SCAN:GET")
|
||||
@ResponseSchema(ResponseScan)
|
||||
@ResponseSchema(ResponseTrackScan)
|
||||
@ResponseSchema(ScanNotFoundError, { statusCode: 404 })
|
||||
@OnUndefined(ScanNotFoundError)
|
||||
@OpenAPI({ description: 'Lists all information about the scan whose id got provided. This includes the scan\'s runner\'s distance ran.' })
|
||||
async getOne(@Param('id') id: number) {
|
||||
let scan = await this.scanRepository.findOne({ id: id }, { relations: ['runner', 'runner.scans', 'runner.scans.track'] })
|
||||
if (!scan) { throw new ScanNotFoundError(); }
|
||||
return scan.toResponse();
|
||||
}
|
||||
|
||||
@Post()
|
||||
@UseBefore(ScanAuth)
|
||||
@ResponseSchema(ResponseScan)
|
||||
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
|
||||
@OpenAPI({ description: 'Create a new scan. <br> Please remeber to provide the scan\'s runner\'s id and distance for normal scans.', security: [{ "ScanApiToken": [] }, { "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
|
||||
async post(@Body({ validate: true }) createScan: CreateScan) {
|
||||
let scan = await createScan.toScan();
|
||||
scan = await this.scanRepository.save(scan);
|
||||
return (await this.scanRepository.findOne({ id: scan.id }, { relations: ['runner'] })).toResponse();
|
||||
}
|
||||
|
||||
@Post("/trackscans")
|
||||
@UseBefore(ScanAuth)
|
||||
@ResponseSchema(ResponseScan)
|
||||
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
|
||||
@OpenAPI({ description: 'Create a new track scan. <br> This is just a alias for posting /scans', security: [{ "ScanApiToken": [] }, { "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
|
||||
async postTrackScans(@Body({ validate: true }) createScan: CreateTrackScan) {
|
||||
return this.post(createScan);
|
||||
}
|
||||
|
||||
@Put('/:id')
|
||||
@Authorized("SCAN:UPDATE")
|
||||
@ResponseSchema(ResponseScan)
|
||||
@ResponseSchema(ScanNotFoundError, { statusCode: 404 })
|
||||
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
|
||||
@ResponseSchema(ScanIdsNotMatchingError, { statusCode: 406 })
|
||||
@OpenAPI({ description: "Update the scan whose id you provided. <br> Please remember that ids can't be changed and distances must be positive." })
|
||||
async put(@Param('id') id: number, @Body({ validate: true }) scan: UpdateScan) {
|
||||
let oldScan = await this.scanRepository.findOne({ id: id });
|
||||
|
||||
if (!oldScan) {
|
||||
throw new ScanNotFoundError();
|
||||
}
|
||||
|
||||
if (oldScan.id != scan.id) {
|
||||
throw new ScanIdsNotMatchingError();
|
||||
}
|
||||
|
||||
await this.scanRepository.save(await scan.updateScan(oldScan));
|
||||
return (await this.scanRepository.findOne({ id: id }, { relations: ['runner'] })).toResponse();
|
||||
}
|
||||
|
||||
@Delete('/:id')
|
||||
@Authorized("SCAN:DELETE")
|
||||
@ResponseSchema(ResponseScan)
|
||||
@ResponseSchema(ResponseEmpty, { statusCode: 204 })
|
||||
@OnUndefined(204)
|
||||
@OpenAPI({ description: 'Delete the scan whose id you provided. <br> If no scan with this id exists it will just return 204(no content).' })
|
||||
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
|
||||
let scan = await this.scanRepository.findOne({ id: id });
|
||||
if (!scan) { return null; }
|
||||
const responseScan = await this.scanRepository.findOne({ id: scan.id }, { relations: ["runner"] });
|
||||
|
||||
await this.scanRepository.delete(scan);
|
||||
return responseScan.toResponse();
|
||||
}
|
||||
}
|
||||
108
src/controllers/ScanStationController.ts
Normal file
108
src/controllers/ScanStationController.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam } from 'routing-controllers';
|
||||
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
|
||||
import { getConnectionManager, Repository } from 'typeorm';
|
||||
import { ScanStationHasScansError, ScanStationIdsNotMatchingError, ScanStationNotFoundError } from '../errors/ScanStationErrors';
|
||||
import { TrackNotFoundError } from '../errors/TrackErrors';
|
||||
import { CreateScanStation } from '../models/actions/CreateScanStation';
|
||||
import { UpdateScanStation } from '../models/actions/UpdateScanStation';
|
||||
import { ScanStation } from '../models/entities/ScanStation';
|
||||
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
|
||||
import { ResponseScanStation } from '../models/responses/ResponseScanStation';
|
||||
import { ScanController } from './ScanController';
|
||||
|
||||
@JsonController('/stations')
|
||||
@OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
|
||||
export class ScanStationController {
|
||||
private stationRepository: Repository<ScanStation>;
|
||||
|
||||
/**
|
||||
* Gets the repository of this controller's model/entity.
|
||||
*/
|
||||
constructor() {
|
||||
this.stationRepository = getConnectionManager().get().getRepository(ScanStation);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@Authorized("STATION:GET")
|
||||
@ResponseSchema(ResponseScanStation, { isArray: true })
|
||||
@OpenAPI({ description: 'Lists all stations. <br> This includes their associated tracks.' })
|
||||
async getAll() {
|
||||
let responseStations: ResponseScanStation[] = new Array<ResponseScanStation>();
|
||||
const stations = await this.stationRepository.find({ relations: ['track'] });
|
||||
stations.forEach(station => {
|
||||
responseStations.push(station.toResponse());
|
||||
});
|
||||
return responseStations;
|
||||
}
|
||||
|
||||
@Get('/:id')
|
||||
@Authorized("STATION:GET")
|
||||
@ResponseSchema(ResponseScanStation)
|
||||
@ResponseSchema(ScanStationNotFoundError, { statusCode: 404 })
|
||||
@OnUndefined(ScanStationNotFoundError)
|
||||
@OpenAPI({ description: 'Lists all information about the station whose id got provided. <br> This includes it\'s associated track.' })
|
||||
async getOne(@Param('id') id: number) {
|
||||
let scan = await this.stationRepository.findOne({ id: id }, { relations: ['track'] })
|
||||
if (!scan) { throw new ScanStationNotFoundError(); }
|
||||
return scan.toResponse();
|
||||
}
|
||||
|
||||
@Post()
|
||||
@Authorized("STATION:CREATE")
|
||||
@ResponseSchema(ResponseScanStation)
|
||||
@ResponseSchema(TrackNotFoundError, { statusCode: 404 })
|
||||
@OpenAPI({ description: 'Create a new station. <br> Please remeber to provide the station\'s track\'s id. <br> Please also remember that the station key is only visibe on creation.' })
|
||||
async post(@Body({ validate: true }) createStation: CreateScanStation) {
|
||||
let newStation = await createStation.toEntity();
|
||||
const station = await this.stationRepository.save(newStation);
|
||||
let responseStation = (await this.stationRepository.findOne({ id: station.id }, { relations: ['track'] })).toResponse();
|
||||
responseStation.key = newStation.cleartextkey;
|
||||
return responseStation;
|
||||
}
|
||||
|
||||
@Put('/:id')
|
||||
@Authorized("STATION:UPDATE")
|
||||
@ResponseSchema(ResponseScanStation)
|
||||
@ResponseSchema(ScanStationNotFoundError, { statusCode: 404 })
|
||||
@ResponseSchema(ScanStationIdsNotMatchingError, { statusCode: 406 })
|
||||
@OpenAPI({ description: "Update the station whose id you provided. <br> Please remember that only the description and enabled state can be changed." })
|
||||
async put(@Param('id') id: number, @Body({ validate: true }) station: UpdateScanStation) {
|
||||
let oldStation = await this.stationRepository.findOne({ id: id });
|
||||
|
||||
if (!oldStation) {
|
||||
throw new ScanStationNotFoundError();
|
||||
}
|
||||
|
||||
if (oldStation.id != station.id) {
|
||||
throw new ScanStationIdsNotMatchingError();
|
||||
}
|
||||
|
||||
await this.stationRepository.save(await station.updateStation(oldStation));
|
||||
return (await this.stationRepository.findOne({ id: id }, { relations: ['track'] })).toResponse();
|
||||
}
|
||||
|
||||
@Delete('/:id')
|
||||
@Authorized("STATION:DELETE")
|
||||
@ResponseSchema(ResponseScanStation)
|
||||
@ResponseSchema(ResponseEmpty, { statusCode: 204 })
|
||||
@ResponseSchema(ScanStationHasScansError, { statusCode: 406 })
|
||||
@OnUndefined(204)
|
||||
@OpenAPI({ description: 'Delete the station whose id you provided. <br> If no station with this id exists it will just return 204(no content). <br> If the station still has scans associated you have to provide the force=true query param (warning: this deletes all scans associated with/created by this station - please disable it instead).' })
|
||||
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
|
||||
let station = await this.stationRepository.findOne({ id: id });
|
||||
if (!station) { return null; }
|
||||
|
||||
const stationScans = (await this.stationRepository.findOne({ id: station.id }, { relations: ["scans"] })).scans;
|
||||
if (stationScans.length != 0 && !force) {
|
||||
throw new ScanStationHasScansError();
|
||||
}
|
||||
const scanController = new ScanController;
|
||||
for (let scan of stationScans) {
|
||||
scanController.remove(scan.id, force);
|
||||
}
|
||||
|
||||
const responseStation = await this.stationRepository.findOne({ id: station.id }, { relations: ["track"] });
|
||||
await this.stationRepository.delete(station);
|
||||
return responseStation.toResponse();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put } from 'routing-controllers';
|
||||
import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam } from 'routing-controllers';
|
||||
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
|
||||
import { getConnectionManager, Repository } from 'typeorm';
|
||||
import { TrackIdsNotMatchingError, TrackLapTimeCantBeNegativeError, TrackNotFoundError } from "../errors/TrackErrors";
|
||||
import { TrackHasScanStationsError, TrackIdsNotMatchingError, TrackLapTimeCantBeNegativeError, TrackNotFoundError } from "../errors/TrackErrors";
|
||||
import { CreateTrack } from '../models/actions/CreateTrack';
|
||||
import { UpdateTrack } from '../models/actions/UpdateTrack';
|
||||
import { Track } from '../models/entities/Track';
|
||||
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
|
||||
import { ResponseTrack } from '../models/responses/ResponseTrack';
|
||||
import { ScanStationController } from './ScanStationController';
|
||||
|
||||
@JsonController('/tracks')
|
||||
@OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
|
||||
@@ -85,10 +86,19 @@ export class TrackController {
|
||||
@ResponseSchema(ResponseEmpty, { statusCode: 204 })
|
||||
@OnUndefined(204)
|
||||
@OpenAPI({ description: "Delete the track whose id you provided. <br> If no track with this id exists it will just return 204(no content)." })
|
||||
async remove(@Param("id") id: number) {
|
||||
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
|
||||
let track = await this.trackRepository.findOne({ id: id });
|
||||
if (!track) { return null; }
|
||||
|
||||
const trackStations = (await this.trackRepository.findOne({ id: id }, { relations: ["stations"] })).stations;
|
||||
if (trackStations.length != 0 && !force) {
|
||||
throw new TrackHasScanStationsError();
|
||||
}
|
||||
const scanController = new ScanStationController;
|
||||
for (let station of trackStations) {
|
||||
scanController.remove(station.id, force);
|
||||
}
|
||||
|
||||
await this.trackRepository.delete(track);
|
||||
return new ResponseTrack(track);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user