import { IsInt, IsNotEmpty, IsOptional, IsPositive, IsString } from "class-validator"; import { BeforeInsert, BeforeUpdate, Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; import { ResponseTrack } from '../responses/ResponseTrack'; import { ScanStation } from "./ScanStation"; import { TrackScan } from "./TrackScan"; /** * Defines the Track entity. */ @Entity() export class Track { /** * Autogenerated unique id (primary key). */ @PrimaryGeneratedColumn() @IsInt() id: number; /** * The track's name. * Mainly here for UX. */ @Column() @IsString() @IsNotEmpty() name: string; /** * The track's length/distance in meters. * Will be used to calculate runner's ran distances. */ @Column() @IsInt() @IsPositive() distance: number; /** * The minimum time a runner should take to run a lap on this track (in seconds). * Will be used for fraud detection. */ @Column({ nullable: true }) @IsInt() @IsOptional() minimumLapTime?: number; /** * Used to link scan stations to a certain track. * This makes the configuration of the scan stations easier. */ @OneToMany(() => ScanStation, station => station.track, { nullable: true }) stations: ScanStation[]; /** * Used to link track scans to a track. * The scan will derive it's distance from the track's distance. */ @OneToMany(() => TrackScan, scan => scan.track, { nullable: true }) scans: TrackScan[]; @Column({ type: 'bigint', nullable: true, readonly: true }) @IsInt() @IsPositive() created_at: number; @Column({ type: 'bigint', nullable: true }) @IsInt() @IsPositive() updated_at: number; @BeforeInsert() public setCreatedAt() { this.created_at = Math.floor(Date.now() / 1000); this.updated_at = Math.floor(Date.now() / 1000); } @BeforeUpdate() public setUpdatedAt() { this.updated_at = Math.floor(Date.now() / 1000); } /** * Turns this entity into it's response class. */ public toResponse(): ResponseTrack { return new ResponseTrack(this); } }