backend/src/controllers/ScanStationController.ts

116 lines
5.3 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 { ScanStationHasScansError, ScanStationIdsNotMatchingError, ScanStationNotFoundError } from '../errors/ScanStationErrors';
import { TrackNotFoundError } from '../errors/TrackErrors';
import { CreateScanStation } from '../models/actions/create/CreateScanStation';
import { UpdateScanStation } from '../models/actions/update/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(@QueryParam("page", { required: false }) page: number, @QueryParam("page_size", { required: false }) page_size: number = 100) {
let responseStations: ResponseScanStation[] = new Array<ResponseScanStation>();
let stations: Array<ScanStation>;
if (page != undefined) {
stations = await this.stationRepository.find({ relations: ['track'], skip: page * page_size, take: page_size });
} else {
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.update(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) {
await scanController.remove(scan.id, force);
}
const responseStation = await this.stationRepository.findOne({ id: station.id }, { relations: ["track"] });
await this.stationRepository.delete(station);
return responseStation.toResponse();
}
}