diff --git a/src/controllers/ScanController.ts b/src/controllers/ScanController.ts
index 6127e8a..fb99d3a 100644
--- a/src/controllers/ScanController.ts
+++ b/src/controllers/ScanController.ts
@@ -1,7 +1,8 @@
-import { Authorized, Get, JsonController, OnUndefined, Param } from 'routing-controllers';
+import { Authorized, Body, Get, JsonController, OnUndefined, Param, Post } from 'routing-controllers';
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnectionManager, Repository } from 'typeorm';
import { ScanNotFoundError } from '../errors/ScanErrors';
+import { CreateScan } from '../models/actions/CreateScan';
import { Scan } from '../models/entities/Scan';
import { ResponseScan } from '../models/responses/ResponseScan';
import { ResponseTrackScan } from '../models/responses/ResponseTrackScan';
@@ -33,7 +34,7 @@ export class ScanController {
}
@Get('/:id')
- @Authorized("DONOR:GET")
+ @Authorized("SCAN:GET")
@ResponseSchema(ResponseScan)
@ResponseSchema(ResponseTrackScan)
@ResponseSchema(ScanNotFoundError, { statusCode: 404 })
@@ -45,21 +46,15 @@ export class ScanController {
return scan;
}
- // @Post()
- // @Authorized("DONOR:CREATE")
- // @ResponseSchema(ResponseDonor)
- // @OpenAPI({ description: 'Create a new runner.
Please remeber to provide the runner\'s group\'s id.' })
- // async post(@Body({ validate: true }) createRunner: CreateDonor) {
- // let donor;
- // try {
- // donor = await createRunner.toDonor();
- // } catch (error) {
- // throw error;
- // }
-
- // donor = await this.donorRepository.save(donor)
- // return new ResponseDonor(await this.donorRepository.findOne(donor));
- // }
+ @Post()
+ @Authorized("SCAN:CREATE")
+ @ResponseSchema(ResponseScan)
+ @OpenAPI({ description: 'Create a new runner.
Please remeber to provide the runner\'s group\'s id.' })
+ async post(@Body({ validate: true }) createScan: CreateScan) {
+ let scan = await createScan.toScan();
+ scan = await this.scanRepository.save(scan)
+ return (await this.scanRepository.findOne(scan)).toResponse();
+ }
// @Put('/:id')
// @Authorized("DONOR:UPDATE")
diff --git a/src/models/actions/CreateScan.ts b/src/models/actions/CreateScan.ts
new file mode 100644
index 0000000..170703b
--- /dev/null
+++ b/src/models/actions/CreateScan.ts
@@ -0,0 +1,11 @@
+import { Scan } from '../entities/Scan';
+
+/**
+ * This classed is used to create a new Scan entity from a json body (post request).
+ */
+export abstract class CreateScan {
+ /**
+ * Creates a new Scan entity from this.
+ */
+ public abstract toScan(): Promise;
+}
\ No newline at end of file
diff --git a/src/models/actions/CreateTrackScan.ts b/src/models/actions/CreateTrackScan.ts
new file mode 100644
index 0000000..2303352
--- /dev/null
+++ b/src/models/actions/CreateTrackScan.ts
@@ -0,0 +1,84 @@
+import { IsNotEmpty } from 'class-validator';
+import { getConnection } from 'typeorm';
+import { RunnerNotFoundError } from '../../errors/RunnerErrors';
+import { RunnerCard } from '../entities/RunnerCard';
+import { ScanStation } from '../entities/ScanStation';
+import { TrackScan } from '../entities/TrackScan';
+import { CreateScan } from './CreateScan';
+
+/**
+ * This classed is used to create a new Scan entity from a json body (post request).
+ */
+export class CreateTrackScan extends CreateScan {
+
+ /**
+ * The scan's associated track.
+ * This is used to determine the scan's distance.
+ */
+ @IsNotEmpty()
+ track: number;
+
+ /**
+ * The runnerCard associated with the scan.
+ * This get's saved for documentation and management purposes.
+ */
+ @IsNotEmpty()
+ card: number;
+
+ /**
+ * The scanning station that created the scan.
+ * Mainly used for logging and traceing back scans (or errors)
+ */
+ @IsNotEmpty()
+ station: number;
+
+ /**
+ * Creates a new Track entity from this.
+ */
+ public async toScan(): 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 = new Date(Date.now()).toString();
+ 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 Error();
+ }
+ return track;
+ }
+
+ public async getStation(): Promise {
+ const track = await getConnection().getRepository(ScanStation).findOne({ id: this.card }, { relations: ["track"] });
+ if (!track) {
+ throw new Error();
+ }
+ return track;
+ }
+
+ public async validateScan(scan: TrackScan): Promise {
+ const scans = await getConnection().getRepository(TrackScan).find({ where: { runner: scan.runner }, relations: ["track"] });
+ if (scans.length == 0) { return true; }
+
+ const newestScan = scans[0];
+ if ((new Date(scan.timestamp).getTime() - new Date(newestScan.timestamp).getTime()) > scan.track.minimumLapTime) {
+ return true;
+ }
+
+ return false;
+ }
+}
\ No newline at end of file