From a21eddda93fd3be7cffd6c85ec882a03a23d6c69 Mon Sep 17 00:00:00 2001 From: Sven Czarnian Date: Sun, 23 Oct 2022 12:53:31 +0200 Subject: [PATCH] define the controller and service for the airport management --- src/airport/airport.controller.spec.ts | 18 ++ src/airport/airport.controller.ts | 237 +++++++++++++++++++++ src/airport/airport.module.ts | 15 ++ src/airport/airport.service.spec.ts | 18 ++ src/airport/airport.service.ts | 64 ++++++ src/airport/dto/airport.dto.ts | 39 ++++ src/airport/dto/arrivalroute.dto.ts | 25 +++ src/airport/dto/assignment.dto.ts | 32 +++ src/airport/dto/constraint.dto.ts | 26 +++ src/airport/dto/constrainttype.dto.ts | 18 ++ src/airport/dto/optimization.dto.ts | 34 +++ src/airport/dto/planning.dto.ts | 18 ++ src/airport/dto/runwayspacing.dto.ts | 18 ++ src/airport/models/airport.model.ts | 42 ++++ src/airport/models/arrivalroute.model.ts | 27 +++ src/airport/models/assignment.model.ts | 32 +++ src/airport/models/constraint.model.ts | 26 +++ src/airport/models/constrainttype.model.ts | 22 ++ src/airport/models/optimization.model.ts | 37 ++++ src/airport/models/planning.model.ts | 23 ++ src/airport/models/runwayspacing.model.ts | 21 ++ src/app.module.ts | 5 +- 22 files changed, 796 insertions(+), 1 deletion(-) create mode 100644 src/airport/airport.controller.spec.ts create mode 100644 src/airport/airport.controller.ts create mode 100644 src/airport/airport.module.ts create mode 100644 src/airport/airport.service.spec.ts create mode 100644 src/airport/airport.service.ts create mode 100644 src/airport/dto/airport.dto.ts create mode 100644 src/airport/dto/arrivalroute.dto.ts create mode 100644 src/airport/dto/assignment.dto.ts create mode 100644 src/airport/dto/constraint.dto.ts create mode 100644 src/airport/dto/constrainttype.dto.ts create mode 100644 src/airport/dto/optimization.dto.ts create mode 100644 src/airport/dto/planning.dto.ts create mode 100644 src/airport/dto/runwayspacing.dto.ts create mode 100644 src/airport/models/airport.model.ts create mode 100644 src/airport/models/arrivalroute.model.ts create mode 100644 src/airport/models/assignment.model.ts create mode 100644 src/airport/models/constraint.model.ts create mode 100644 src/airport/models/constrainttype.model.ts create mode 100644 src/airport/models/optimization.model.ts create mode 100644 src/airport/models/planning.model.ts create mode 100644 src/airport/models/runwayspacing.model.ts diff --git a/src/airport/airport.controller.spec.ts b/src/airport/airport.controller.spec.ts new file mode 100644 index 0000000..e0a29ab --- /dev/null +++ b/src/airport/airport.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AirportController } from './airport.controller'; + +describe('AirportController', () => { + let controller: AirportController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [AirportController], + }).compile(); + + controller = module.get(AirportController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/airport/airport.controller.ts b/src/airport/airport.controller.ts new file mode 100644 index 0000000..7dba59a --- /dev/null +++ b/src/airport/airport.controller.ts @@ -0,0 +1,237 @@ +import { + Body, + Controller, + Get, + Delete, + Post, + Query, + HttpException, + HttpStatus, +} from '@nestjs/common'; +import { ApiBody, ApiQuery, ApiResponse } from '@nestjs/swagger'; +import { AirportService } from './airport.service'; +import { Airport } from './models/airport.model'; +import { AirportDto } from './dto/airport.dto'; +import { ArrivalRouteDto } from './dto/arrivalroute.dto'; +import { AssignmentDto } from './dto/assignment.dto'; +import { ConstraintDto } from './dto/constraint.dto'; +import { PlanningDto } from './dto/planning.dto'; +import { RunwaySpacingDto } from './dto/runwayspacing.dto'; +import { ArrivalRoute } from './models/arrivalroute.model'; +import { Assignment } from './models/assignment.model'; +import { Constraint } from './models/constraint.model'; +import { Planning } from './models/planning.model'; +import { RunwaySpacing } from './models/runwayspacing.model'; + +@Controller('airport') +export class AirportController { + constructor(private readonly airportService: AirportService) {} + + private static convertConstraint( + constraint: Constraint | ConstraintDto, + ): T { + return { + waypoint: constraint.waypoint, + altitude: { + constraint: constraint.altitude.constraint, + mode: constraint.altitude.mode, + }, + speed: { + constraint: constraint.speed.constraint, + mode: constraint.speed.mode, + }, + } as T; + } + + private static convertConstraints( + constraints: Constraint[] | ConstraintDto[], + ): T[] { + const retval: T[] = []; + constraints.forEach((constraint) => + retval.push(AirportController.convertConstraint(constraint)), + ); + return retval; + } + + private static convertArrivalRoutes( + routes: ArrivalRoute[] | ArrivalRouteDto[], + ): T[] { + const retval: T[] = []; + routes.forEach((route) => + retval.push({ + arrival: route.runway, + runway: route.runway, + constraints: AirportController.convertConstraints(route.constraints), + } as T), + ); + return retval; + } + + private static convertRunwaySpacings( + spacings: RunwaySpacing[] | RunwaySpacingDto[], + ): T[] { + const retval: T[] = []; + spacings.forEach((spacing) => + retval.push({ + runway: spacing.runway, + spacing: spacing.spacing, + } as T), + ); + return retval; + } + + private static convertAssignments( + assignments: Assignment[] | AssignmentDto[], + ): T[] { + const retval: T[] = []; + assignments.forEach((assignment) => + retval.push({ + runway: assignment.runway, + type: assignment.type, + aircrafts: assignment.aircrafts, + assignedStands: assignment.assignedStands, + } as T), + ); + return retval; + } + + private static convertPlanning(planning: Planning | PlanningDto): T { + return { + optimization: { + windowSize: planning.optimization.windowSize, + windowOverlap: planning.optimization.windowOverlap, + fixedBeforeInitialApproachFix: + planning.optimization.fixedBeforeInitialApproachFix, + maximumAirportDistance: planning.optimization.maximumAirportDistance, + }, + assignments: AirportController.convertAssignments( + planning.assignments, + ), + } as T; + } + + private static airportToAirportDto(airport: Airport): AirportDto { + if (!airport) return null; + + return { + icao: airport.icao, + upperConstraints: AirportController.convertConstraints( + airport.upperConstraints, + ), + arrivalRoutes: AirportController.convertArrivalRoutes< + ArrivalRouteDto, + ConstraintDto + >(airport.arrivalRoutes), + spacings: AirportController.convertRunwaySpacings( + airport.spacings, + ), + planning: AirportController.convertPlanning( + airport.planning, + ), + }; + } + + private static airportDtoToAirport(airport: AirportDto): Airport { + if (!airport) return null; + + return { + icao: airport.icao, + upperConstraints: AirportController.convertConstraints( + airport.upperConstraints, + ), + arrivalRoutes: AirportController.convertArrivalRoutes< + ArrivalRoute, + Constraint + >(airport.arrivalRoutes), + spacings: AirportController.convertRunwaySpacings( + airport.spacings, + ), + planning: AirportController.convertPlanning( + airport.planning, + ), + }; + } + + @Get('/allCodes') + @ApiResponse({ + status: 200, + description: 'All available airports', + type: [String], + }) + async allCodes(): Promise { + return this.airportService.airportsList(); + } + + @Get('/get') + @ApiQuery({ + name: 'icao', + description: 'The ICAO code of the airport', + type: String, + }) + @ApiResponse({ + status: 200, + description: 'The airport configuration', + type: [AirportDto], + }) + @ApiResponse({ + status: 404, + description: 'No airport found', + }) + async get(@Query('icao') icao: string): Promise { + return this.airportService.airport(icao).then((airport) => { + if (!airport) { + throw new HttpException('Airport not found', HttpStatus.NOT_FOUND); + } + return AirportController.airportToAirportDto(airport); + }); + } + + @Post('/register') + @ApiBody({ + description: 'The airport definition', + type: AirportDto, + }) + @ApiResponse({ + status: 201, + description: 'The airport is registered', + }) + @ApiResponse({ + status: 409, + description: 'The airport is already registered', + }) + async register(@Body('airport') airport: AirportDto): Promise { + await this.airportService + .registerAirport(AirportController.airportDtoToAirport(airport)) + .then((registered) => { + if (!registered) { + throw new HttpException( + 'Airport already available', + HttpStatus.CONFLICT, + ); + } + }); + } + + @Delete('/remove') + @ApiQuery({ + name: 'icao', + description: 'The ICAO code of the airport', + type: String, + }) + @ApiResponse({ + status: 200, + description: 'All log entries are deleted', + }) + @ApiResponse({ + status: 404, + description: 'Could not find the airport', + }) + async remove(@Query('icao') icao: string): Promise { + await this.airportService.airport(icao).then(async (airport) => { + if (!airport) { + throw new HttpException('Airport not found', HttpStatus.NOT_FOUND); + } + await this.airportService.deleteAirport(icao); + }); + } +} diff --git a/src/airport/airport.module.ts b/src/airport/airport.module.ts new file mode 100644 index 0000000..977248c --- /dev/null +++ b/src/airport/airport.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { MongooseModule } from '@nestjs/mongoose'; +import { AirportSchema } from './models/airport.model'; +import { AirportService } from './airport.service'; +import { AirportController } from './airport.controller'; + +@Module({ + imports: [ + MongooseModule.forFeature([{ name: 'airport', schema: AirportSchema }]), + ], + providers: [AirportService], + controllers: [AirportController], + exports: [AirportService], +}) +export class AirportModule {} diff --git a/src/airport/airport.service.spec.ts b/src/airport/airport.service.spec.ts new file mode 100644 index 0000000..09363d4 --- /dev/null +++ b/src/airport/airport.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AirportService } from './airport.service'; + +describe('AirportService', () => { + let service: AirportService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [AirportService], + }).compile(); + + service = module.get(AirportService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/airport/airport.service.ts b/src/airport/airport.service.ts new file mode 100644 index 0000000..87fb88b --- /dev/null +++ b/src/airport/airport.service.ts @@ -0,0 +1,64 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { Model } from 'mongoose'; +import { Airport, AirportDocument } from './models/airport.model'; + +@Injectable() +export class AirportService { + constructor( + @InjectModel('airport') + private readonly airportModel: Model, + ) {} + + private async airportExists(icao: string): Promise { + return this.airportModel + .find({ icao }) + .then((response) => response && response.length !== 0); + } + + async airportsList(): Promise { + return this.airportModel.find({}).then((response) => { + const icaoCodes: string[] = []; + response.forEach((airport) => icaoCodes.push(airport.icao)); + return icaoCodes; + }); + } + + async airport(icao: string): Promise { + return this.airportModel.find({ icao }).then((response) => { + if (!response || response.length !== 1) return null; + return response[0]; + }); + } + + async registerAirport(airport: Airport): Promise { + this.airportExists(airport.icao).then(async (exists) => { + if (!exists) { + await this.airportModel.create(airport); + } + + return !exists; + }); + + return false; + } + + async updateAirport(airport: Airport): Promise { + this.airportExists(airport.icao).then(async (exists) => { + if (exists) { + await this.airportModel.findOneAndUpdate( + { icao: airport.icao }, + airport, + ); + } + + return exists; + }); + + return false; + } + + async deleteAirport(icao: string): Promise { + this.airportModel.deleteOne({ icao }); + } +} diff --git a/src/airport/dto/airport.dto.ts b/src/airport/dto/airport.dto.ts new file mode 100644 index 0000000..9ceac36 --- /dev/null +++ b/src/airport/dto/airport.dto.ts @@ -0,0 +1,39 @@ +import { IsNotEmpty, IsOptional } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; +import { ConstraintDto } from './constraint.dto'; +import { ArrivalRouteDto } from './arrivalroute.dto'; +import { RunwaySpacingDto } from './runwayspacing.dto'; +import { PlanningDto } from './planning.dto'; + +export class AirportDto { + @IsNotEmpty() + @ApiProperty({ + description: 'The unique ICAO code', + example: 'EDDB', + }) + icao: string; + + @IsOptional() + @ApiProperty({ + description: 'The constraints in upper airspaces', + }) + upperConstraints: ConstraintDto[]; + + @IsNotEmpty() + @ApiProperty({ + description: 'The different arrival routes with potential constraints', + }) + arrivalRoutes: ArrivalRouteDto[]; + + @IsNotEmpty() + @ApiProperty({ + description: 'The spacings for the runways', + }) + spacings: RunwaySpacingDto[]; + + @IsNotEmpty() + @ApiProperty({ + description: 'The planning configuration', + }) + planning: PlanningDto; +} diff --git a/src/airport/dto/arrivalroute.dto.ts b/src/airport/dto/arrivalroute.dto.ts new file mode 100644 index 0000000..5a7e659 --- /dev/null +++ b/src/airport/dto/arrivalroute.dto.ts @@ -0,0 +1,25 @@ +import { IsNotEmpty, IsOptional } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; +import { ConstraintDto } from './constraint.dto'; + +export class ArrivalRouteDto { + @IsNotEmpty() + @ApiProperty({ + description: 'The arrival route identifier', + example: 'KLF25L', + }) + arrival: string; + + @IsNotEmpty() + @ApiProperty({ + description: 'The runway of the arrival route', + example: '25L', + }) + runway: string; + + @IsOptional() + @ApiProperty({ + description: 'The constraints on the arrival route', + }) + constraints: ConstraintDto[]; +} diff --git a/src/airport/dto/assignment.dto.ts b/src/airport/dto/assignment.dto.ts new file mode 100644 index 0000000..e9650fa --- /dev/null +++ b/src/airport/dto/assignment.dto.ts @@ -0,0 +1,32 @@ +import { IsNotEmpty, IsOptional } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; + +export class AssignmentDto { + @IsNotEmpty() + @ApiProperty({ + description: 'The runway identifier', + example: '25L', + }) + runway: string; + + @IsNotEmpty() + @ApiProperty({ + description: 'The urgency of the assignment (possible: SHALL, SHOULD, MAY)', + example: 'MAY', + }) + type: string; + + @IsOptional() + @ApiProperty({ + description: 'The aircrafts (ICAO codes) that require this assignment', + example: '[ "A346", "B748" ]', + }) + aircrafts: string[]; + + @IsOptional() + @ApiProperty({ + description: 'The assigned stands that require this assignment', + example: '[ "A01", "A02" ]', + }) + assignedStands: string[]; +} diff --git a/src/airport/dto/constraint.dto.ts b/src/airport/dto/constraint.dto.ts new file mode 100644 index 0000000..1514fc8 --- /dev/null +++ b/src/airport/dto/constraint.dto.ts @@ -0,0 +1,26 @@ +import { IsNotEmpty, IsOptional } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; +import { ConstraintTypeDto } from './constrainttype.dto'; + +export class ConstraintDto { + @IsNotEmpty() + @ApiProperty({ + description: 'The identifier of the waypoint', + example: 'AKUDI', + }) + waypoint: string; + + @IsOptional() + @ApiProperty({ + description: 'The altitude constraint in feet', + example: '{ constraint: 20000, mode: "BELOW" }', + }) + altitude: ConstraintTypeDto; + + @IsOptional() + @ApiProperty({ + description: 'The speed constraint in knots', + example: '{ constraint: 250, mode: "EXACT" }', + }) + speed: ConstraintTypeDto; +} diff --git a/src/airport/dto/constrainttype.dto.ts b/src/airport/dto/constrainttype.dto.ts new file mode 100644 index 0000000..f4d2571 --- /dev/null +++ b/src/airport/dto/constrainttype.dto.ts @@ -0,0 +1,18 @@ +import { IsNotEmpty } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; + +export class ConstraintTypeDto { + @IsNotEmpty() + @ApiProperty({ + description: 'The identifier of the waypoint', + example: 20000, + }) + constraint: number; + + @IsNotEmpty() + @ApiProperty({ + description: 'The constraint mode (possible: BELOW, EXACT, ABOVE)', + example: 'EXACT', + }) + mode: string; +} diff --git a/src/airport/dto/optimization.dto.ts b/src/airport/dto/optimization.dto.ts new file mode 100644 index 0000000..28067ae --- /dev/null +++ b/src/airport/dto/optimization.dto.ts @@ -0,0 +1,34 @@ +import { IsNotEmpty } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; + +export class OptimizationDto { + @IsNotEmpty() + @ApiProperty({ + description: 'The window length in seconds', + example: 120, + }) + windowSize: number; + + @IsNotEmpty() + @ApiProperty({ + description: 'The optimized windows for the sequence', + example: 3, + }) + windowOverlap: number; + + @IsNotEmpty() + @ApiProperty({ + description: + 'The final approach sequence before the IAF is reached in minutes', + example: 10, + }) + fixedBeforeInitialApproachFix: number; + + @IsNotEmpty() + @ApiProperty({ + description: + 'The maximum distance to the airport before the optimization is started', + example: 300, + }) + maximumAirportDistance: number; +} diff --git a/src/airport/dto/planning.dto.ts b/src/airport/dto/planning.dto.ts new file mode 100644 index 0000000..54ebec3 --- /dev/null +++ b/src/airport/dto/planning.dto.ts @@ -0,0 +1,18 @@ +import { IsNotEmpty } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; +import { OptimizationDto } from './optimization.dto'; +import { AssignmentDto } from './assignment.dto'; + +export class PlanningDto { + @IsNotEmpty() + @ApiProperty({ + description: 'The optimization parameters', + }) + optimization: OptimizationDto; + + @IsNotEmpty() + @ApiProperty({ + description: 'The runway assignments', + }) + assignments: AssignmentDto[]; +} diff --git a/src/airport/dto/runwayspacing.dto.ts b/src/airport/dto/runwayspacing.dto.ts new file mode 100644 index 0000000..fe12322 --- /dev/null +++ b/src/airport/dto/runwayspacing.dto.ts @@ -0,0 +1,18 @@ +import { IsNotEmpty, IsOptional } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; + +export class RunwaySpacingDto { + @IsNotEmpty() + @ApiProperty({ + description: 'The runway identifier', + example: '25L', + }) + runway: string; + + @IsOptional() + @ApiProperty({ + description: 'The touch-down sequence in nautical miles', + example: 4, + }) + spacing: number; +} diff --git a/src/airport/models/airport.model.ts b/src/airport/models/airport.model.ts new file mode 100644 index 0000000..0069bf2 --- /dev/null +++ b/src/airport/models/airport.model.ts @@ -0,0 +1,42 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { Document } from 'mongoose'; +import { ArrivalRoute, ArrivalRouteSchema } from './arrivalroute.model'; +import { Constraint, ConstraintSchema } from './constraint.model'; +import { Planning, PlanningSchema } from './planning.model'; +import { RunwaySpacing, RunwaySpacingSchema } from './runwayspacing.model'; + +export type AirportDocument = Airport & Document; + +@Schema() +export class Airport { + @Prop({ + required: true, + type: String, + }) + icao: string; + + @Prop({ + type: [ConstraintSchema], + }) + upperConstraints: Constraint[]; + + @Prop({ + required: true, + type: [ArrivalRouteSchema], + }) + arrivalRoutes: ArrivalRoute[]; + + @Prop({ + required: true, + type: [RunwaySpacingSchema], + }) + spacings: RunwaySpacing[]; + + @Prop({ + required: true, + type: PlanningSchema, + }) + planning: Planning; +} + +export const AirportSchema = SchemaFactory.createForClass(Airport); diff --git a/src/airport/models/arrivalroute.model.ts b/src/airport/models/arrivalroute.model.ts new file mode 100644 index 0000000..02e22d8 --- /dev/null +++ b/src/airport/models/arrivalroute.model.ts @@ -0,0 +1,27 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { Document } from 'mongoose'; +import { Constraint, ConstraintSchema } from './constraint.model'; + +export type ArrivalRouteDocument = ArrivalRoute & Document; + +@Schema() +export class ArrivalRoute { + @Prop({ + required: true, + type: String, + }) + arrival: string; + + @Prop({ + required: true, + type: String, + }) + runway: string; + + @Prop({ + type: [ConstraintSchema], + }) + constraints: Constraint[]; +} + +export const ArrivalRouteSchema = SchemaFactory.createForClass(ArrivalRoute); diff --git a/src/airport/models/assignment.model.ts b/src/airport/models/assignment.model.ts new file mode 100644 index 0000000..46f0190 --- /dev/null +++ b/src/airport/models/assignment.model.ts @@ -0,0 +1,32 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { Document } from 'mongoose'; + +export type AssignmentDocument = Assignment & Document; + +@Schema() +export class Assignment { + @Prop({ + required: true, + type: String, + }) + runway: string; + + @Prop({ + required: true, + type: String, + enum: ['SHALL', 'SHOULD', 'MAY'], + }) + type: string; + + @Prop({ + type: [String], + }) + aircrafts: string[]; + + @Prop({ + type: [String], + }) + assignedStands: string[]; +} + +export const AssignmentSchema = SchemaFactory.createForClass(Assignment); diff --git a/src/airport/models/constraint.model.ts b/src/airport/models/constraint.model.ts new file mode 100644 index 0000000..25b6fa5 --- /dev/null +++ b/src/airport/models/constraint.model.ts @@ -0,0 +1,26 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { Document } from 'mongoose'; +import { ConstraintType, ConstraintTypeSchema } from './constrainttype.model'; + +export type ConstraintDocument = Constraint & Document; + +@Schema() +export class Constraint { + @Prop({ + required: true, + type: String, + }) + waypoint: string; + + @Prop({ + type: ConstraintTypeSchema, + }) + altitude: ConstraintType; + + @Prop({ + type: ConstraintTypeSchema, + }) + speed: ConstraintType; +} + +export const ConstraintSchema = SchemaFactory.createForClass(Constraint); diff --git a/src/airport/models/constrainttype.model.ts b/src/airport/models/constrainttype.model.ts new file mode 100644 index 0000000..5929bec --- /dev/null +++ b/src/airport/models/constrainttype.model.ts @@ -0,0 +1,22 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { Document } from 'mongoose'; + +export type ConstraintTypeDocument = ConstraintType & Document; + +@Schema() +export class ConstraintType { + @Prop({ + type: Number, + }) + constraint: number; + + @Prop({ + type: String, + default: 'EXACT', + enum: ['BELOW', 'EXACT', 'ABOVE'], + }) + mode: string; +} + +export const ConstraintTypeSchema = + SchemaFactory.createForClass(ConstraintType); diff --git a/src/airport/models/optimization.model.ts b/src/airport/models/optimization.model.ts new file mode 100644 index 0000000..6c6e4a5 --- /dev/null +++ b/src/airport/models/optimization.model.ts @@ -0,0 +1,37 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { Document } from 'mongoose'; + +export type OptimizationDocument = Optimization & Document; + +@Schema() +export class Optimization { + @Prop({ + required: true, + type: Number, + default: 120, + }) + windowSize: number; + + @Prop({ + required: true, + type: Number, + default: 3, + }) + windowOverlap: number; + + @Prop({ + required: true, + type: Number, + default: 10, + }) + fixedBeforeInitialApproachFix: number; + + @Prop({ + required: true, + type: Number, + default: 300, + }) + maximumAirportDistance: number; +} + +export const OptimizationSchema = SchemaFactory.createForClass(Optimization); diff --git a/src/airport/models/planning.model.ts b/src/airport/models/planning.model.ts new file mode 100644 index 0000000..d871194 --- /dev/null +++ b/src/airport/models/planning.model.ts @@ -0,0 +1,23 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { Document } from 'mongoose'; +import { Assignment, AssignmentSchema } from './assignment.model'; +import { Optimization, OptimizationSchema } from './optimization.model'; + +export type PlanningDocument = Planning & Document; + +@Schema() +export class Planning { + @Prop({ + required: true, + type: OptimizationSchema, + }) + optimization: Optimization; + + @Prop({ + required: true, + type: [AssignmentSchema], + }) + assignments: Assignment[]; +} + +export const PlanningSchema = SchemaFactory.createForClass(Planning); diff --git a/src/airport/models/runwayspacing.model.ts b/src/airport/models/runwayspacing.model.ts new file mode 100644 index 0000000..1e6a69b --- /dev/null +++ b/src/airport/models/runwayspacing.model.ts @@ -0,0 +1,21 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { Document } from 'mongoose'; + +export type RunwaySpacingDocument = RunwaySpacing & Document; + +@Schema() +export class RunwaySpacing { + @Prop({ + required: true, + type: String, + }) + runway: string; + + @Prop({ + required: true, + type: Number, + }) + spacing: number; +} + +export const RunwaySpacingSchema = SchemaFactory.createForClass(RunwaySpacing); diff --git a/src/app.module.ts b/src/app.module.ts index 933632a..07a81a7 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -4,8 +4,10 @@ import { MongooseModule } from '@nestjs/mongoose'; import Configuration from './config/configuration'; import { VersioningModule } from './versioning/versioning.module'; import { PerformanceModule } from './performance/performance.module'; +import { AirportModule } from './airport/airport.module'; import { LoggingModule } from './logging/logging.module'; import { LoggingController } from './logging/logging.controller'; +import { AirportController } from './airport/airport.controller'; @Module({ imports: [ @@ -26,8 +28,9 @@ import { LoggingController } from './logging/logging.controller'; }), VersioningModule, PerformanceModule, + AirportModule, LoggingModule, ], - controllers: [LoggingController], + controllers: [LoggingController, AirportController], }) export class AppModule {}