diff --git a/src/controllers/RunnerController.ts b/src/controllers/RunnerController.ts index 14658da..6508f67 100644 --- a/src/controllers/RunnerController.ts +++ b/src/controllers/RunnerController.ts @@ -1,7 +1,7 @@ import { 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 { EntityFromBody } from 'typeorm-routing-controllers-extensions'; +import { EntityFromBody, EntityFromParam } from 'typeorm-routing-controllers-extensions'; import { RunnerGroupNeededError, RunnerGroupNotFoundError, RunnerIdsNotMatchingError, RunnerNotFoundError, RunnerOnlyOneGroupAllowedError } from '../errors/RunnerErrors'; import { CreateRunner } from '../models/creation/CreateRunner'; import { Runner } from '../models/entities/Runner'; @@ -55,7 +55,8 @@ export class RunnerController { return error; } - return new ResponseRunner(await this.runnerRepository.save(runner)); + runner = await this.runnerRepository.save(runner) + return new ResponseRunner(await this.runnerRepository.findOne(runner, { relations: ['scans', 'group'] })); } @Put('/:id') @@ -64,7 +65,7 @@ export class RunnerController { @ResponseSchema(RunnerIdsNotMatchingError, { statusCode: 406 }) @OpenAPI({ description: "Update a runner object (id can't be changed)." }) async put(@Param('id') id: number, @EntityFromBody() runner: Runner) { - let oldRunner = await this.runnerRepository.findOne({ id: id }); + let oldRunner = await this.runnerRepository.findOne({ id: id }, { relations: ['scans', 'group'] }); if (!oldRunner) { throw new RunnerNotFoundError(); @@ -82,14 +83,15 @@ export class RunnerController { @ResponseSchema(ResponseRunner) @ResponseSchema(RunnerNotFoundError, { statusCode: 404 }) @OpenAPI({ description: 'Delete a specified runner (if it exists).' }) - async remove(@Param('id') id: number, @QueryParam("force") force: boolean) { - let runner = await this.runnerRepository.findOne({ id: id }); + async remove(@EntityFromParam('id') runner: Runner, @QueryParam("force") force: boolean) { + if (!runner) { throw new RunnerNotFoundError(); } + const responseRunner = await this.runnerRepository.findOne(runner, { relations: ['scans', 'group'] }); if (!runner) { throw new RunnerNotFoundError(); } await this.runnerRepository.delete(runner); - return new ResponseRunner(runner); + return new ResponseRunner(responseRunner); } } diff --git a/src/controllers/RunnerOrganisationController.ts b/src/controllers/RunnerOrganisationController.ts index bed6eec..8cfef6a 100644 --- a/src/controllers/RunnerOrganisationController.ts +++ b/src/controllers/RunnerOrganisationController.ts @@ -1,12 +1,10 @@ import { 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 { EntityFromBody } from 'typeorm-routing-controllers-extensions'; +import { EntityFromBody, EntityFromParam } from 'typeorm-routing-controllers-extensions'; import { RunnerOrganisationHasRunnersError, RunnerOrganisationHasTeamsError, RunnerOrganisationIdsNotMatchingError, RunnerOrganisationNotFoundError } from '../errors/RunnerOrganisationErrors'; import { CreateRunnerOrganisation } from '../models/creation/CreateRunnerOrganisation'; -import { Runner } from '../models/entities/Runner'; import { RunnerOrganisation } from '../models/entities/RunnerOrganisation'; -import { RunnerTeam } from '../models/entities/RunnerTeam'; import { ResponseRunnerOrganisation } from '../models/responses/ResponseRunnerOrganisation'; import { RunnerController } from './RunnerController'; import { RunnerTeamController } from './RunnerTeamController'; @@ -58,9 +56,8 @@ export class RunnerOrganisationController { } runnerOrganisation = await this.runnerOrganisationRepository.save(runnerOrganisation); - runnerOrganisation = await this.runnerOrganisationRepository.findOne(runnerOrganisation, { relations: ['address', 'contact', 'teams'] }); - return new ResponseRunnerOrganisation(runnerOrganisation); + return new ResponseRunnerOrganisation(await this.runnerOrganisationRepository.findOne(runnerOrganisation, { relations: ['address', 'contact', 'teams'] })); } @Put('/:id') @@ -88,39 +85,35 @@ export class RunnerOrganisationController { @Delete('/:id') @ResponseSchema(ResponseRunnerOrganisation) @ResponseSchema(RunnerOrganisationNotFoundError, { statusCode: 404 }) + @ResponseSchema(RunnerOrganisationHasTeamsError, { statusCode: 406 }) @ResponseSchema(RunnerOrganisationHasRunnersError, { statusCode: 406 }) @OpenAPI({ description: 'Delete a specified runnerOrganisation (if it exists).' }) - async remove(@Param('id') id: number, @QueryParam("force") force: boolean) { - let runnerOrganisation = await this.runnerOrganisationRepository.findOne({ id: id }, { relations: ['address', 'contact', 'teams'] }); + async remove(@EntityFromParam('id') organisation: RunnerOrganisation, @QueryParam("force") force: boolean) { + if (!organisation) { throw new RunnerOrganisationNotFoundError() } + let runnerOrganisation = await this.runnerOrganisationRepository.findOne(organisation, { relations: ['address', 'contact', 'runners', 'teams'] }); - if (!runnerOrganisation) { - throw new RunnerOrganisationNotFoundError(); - } - - let runners: Runner[] = await runnerOrganisation.getRunners() if (!force) { - if (runners.length != 0) { - throw new RunnerOrganisationHasRunnersError(); - } - } - const runnerController = new RunnerController() - runners.forEach(runner => { - runnerController.remove(runner.id, true) - }); - - let teams: RunnerTeam[] = await runnerOrganisation.getTeams() - if (!force) { - if (teams.length != 0) { + if (runnerOrganisation.teams.length != 0) { throw new RunnerOrganisationHasTeamsError(); } } const teamController = new RunnerTeamController() - teams.forEach(team => { - teamController.remove(team.id, true) - }); + for (let team of runnerOrganisation.teams) { + await teamController.remove(team, true); + } + + if (!force) { + if (runnerOrganisation.runners.length != 0) { + throw new RunnerOrganisationHasRunnersError(); + } + } + const runnerController = new RunnerController() + for (let runner of runnerOrganisation.runners) { + await runnerController.remove(runner, true); + } const responseOrganisation = new ResponseRunnerOrganisation(runnerOrganisation); - await this.runnerOrganisationRepository.delete({ id: runnerOrganisation.id }); + await this.runnerOrganisationRepository.delete(organisation); return responseOrganisation; } } diff --git a/src/controllers/RunnerTeamController.ts b/src/controllers/RunnerTeamController.ts index 6103083..1b7627d 100644 --- a/src/controllers/RunnerTeamController.ts +++ b/src/controllers/RunnerTeamController.ts @@ -1,10 +1,9 @@ import { 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 { EntityFromBody } from 'typeorm-routing-controllers-extensions'; +import { EntityFromBody, EntityFromParam } from 'typeorm-routing-controllers-extensions'; import { RunnerTeamHasRunnersError, RunnerTeamIdsNotMatchingError, RunnerTeamNotFoundError } from '../errors/RunnerTeamErrors'; import { CreateRunnerTeam } from '../models/creation/CreateRunnerTeam'; -import { Runner } from '../models/entities/Runner'; import { RunnerTeam } from '../models/entities/RunnerTeam'; import { ResponseRunnerTeam } from '../models/responses/ResponseRunnerTeam'; import { RunnerController } from './RunnerController'; @@ -88,26 +87,22 @@ export class RunnerTeamController { @ResponseSchema(RunnerTeamNotFoundError, { statusCode: 404 }) @ResponseSchema(RunnerTeamHasRunnersError, { statusCode: 406 }) @OpenAPI({ description: 'Delete a specified runnerTeam (if it exists).' }) - async remove(@Param('id') id: number, @QueryParam("force") force: boolean) { - let runnerTeam = await this.runnerTeamRepository.findOne({ id: id }, { relations: ['parentGroup', 'contact'] }); + async remove(@EntityFromParam('id') team: RunnerTeam, @QueryParam("force") force: boolean) { + if (!team) { throw new RunnerTeamNotFoundError(); } + let runnerTeam = await this.runnerTeamRepository.findOne(team, { relations: ['parentGroup', 'contact', 'runners'] }); - if (!runnerTeam) { - throw new RunnerTeamNotFoundError(); - } - - let runners: Runner[] = await runnerTeam.getRunners() if (!force) { - if (runners.length != 0) { + if (runnerTeam.runners.length != 0) { throw new RunnerTeamHasRunnersError(); } } const runnerController = new RunnerController() - runners.forEach(runner => { - runnerController.remove(runner.id, true) - }); + for (let runner of runnerTeam.runners) { + await runnerController.remove(runner, true); + } const responseTeam = new ResponseRunnerTeam(runnerTeam); - await this.runnerTeamRepository.delete({ id: runnerTeam.id }); + await this.runnerTeamRepository.delete(team); return responseTeam; } } diff --git a/src/controllers/TrackController.ts b/src/controllers/TrackController.ts index ae451be..02370fc 100644 --- a/src/controllers/TrackController.ts +++ b/src/controllers/TrackController.ts @@ -1,7 +1,7 @@ import { Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; -import { EntityFromBody } from 'typeorm-routing-controllers-extensions'; +import { EntityFromBody, EntityFromParam } from 'typeorm-routing-controllers-extensions'; import { TrackIdsNotMatchingError, TrackNotFoundError } from "../errors/TrackErrors"; import { CreateTrack } from '../models/creation/CreateTrack'; import { Track } from '../models/entities/Track'; @@ -74,14 +74,10 @@ export class TrackController { @ResponseSchema(ResponseTrack) @ResponseSchema(TrackNotFoundError, { statusCode: 404 }) @OpenAPI({ description: "Delete a specified track (if it exists)." }) - async remove(@Param('id') id: number) { - let track = await this.trackRepository.findOne({ id: id }); - - if (!track) { - throw new TrackNotFoundError(); - } + async remove(@EntityFromParam('id') track: Track) { + if (!track) { throw new TrackNotFoundError(); } await this.trackRepository.delete(track); return new ResponseTrack(track); } -} +} \ No newline at end of file diff --git a/src/controllers/UserController.ts b/src/controllers/UserController.ts index dbc4d3a..01e743e 100644 --- a/src/controllers/UserController.ts +++ b/src/controllers/UserController.ts @@ -1,7 +1,7 @@ import { Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; -import { EntityFromBody } from 'typeorm-routing-controllers-extensions'; +import { EntityFromBody, EntityFromParam } from 'typeorm-routing-controllers-extensions'; import { UserGroupNotFoundError, UserIdsNotMatchingError, UserNotFoundError } from '../errors/UserErrors'; import { CreateUser } from '../models/creation/CreateUser'; import { User } from '../models/entities/User'; @@ -73,14 +73,12 @@ export class UserController { @ResponseSchema(User) @ResponseSchema(UserNotFoundError, { statusCode: 404 }) @OpenAPI({ description: 'Delete a specified runner (if it exists).' }) - async remove(@Param('id') id: number) { - let runner = await this.userRepository.findOne({ id: id }); - - if (!runner) { + async remove(@EntityFromParam('id') user: User) { + if (!user) { throw new UserNotFoundError(); } - await this.userRepository.delete(runner); - return runner; + await this.userRepository.delete(user); + return user; } } diff --git a/src/controllers/UserGroupController.ts b/src/controllers/UserGroupController.ts index fb158ed..c937f36 100644 --- a/src/controllers/UserGroupController.ts +++ b/src/controllers/UserGroupController.ts @@ -1,7 +1,7 @@ import { Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; -import { EntityFromBody } from 'typeorm-routing-controllers-extensions'; +import { EntityFromBody, EntityFromParam } from 'typeorm-routing-controllers-extensions'; import { UserGroupIdsNotMatchingError, UserGroupNotFoundError } from '../errors/UserGroupErrors'; import { CreateUserGroup } from '../models/creation/CreateUserGroup'; import { UserGroup } from '../models/entities/UserGroup'; @@ -73,14 +73,12 @@ export class UserGroupController { @ResponseSchema(UserGroup) @ResponseSchema(UserGroupNotFoundError, { statusCode: 404 }) @OpenAPI({ description: 'Delete a specified usergroup (if it exists).' }) - async remove(@Param('id') id: number) { - let userGroup = await this.userGroupsRepository.findOne({ id: id }); - - if (!userGroup) { + async remove(@EntityFromParam('id') group: UserGroup) { + if (!group) { throw new UserGroupNotFoundError(); } - await this.userGroupsRepository.delete(userGroup); - return userGroup; + await this.userGroupsRepository.delete(group); + return group; } } diff --git a/src/errors/AddressErrors.ts b/src/errors/AddressErrors.ts new file mode 100644 index 0000000..c7ae8af --- /dev/null +++ b/src/errors/AddressErrors.ts @@ -0,0 +1,18 @@ +import { IsString } from 'class-validator'; +import { NotAcceptableError, NotFoundError } from 'routing-controllers'; + +export class AddressWrongTypeError extends NotAcceptableError { + @IsString() + name = "AddressWrongTypeError" + + @IsString() + message = "The address must be an existing adress's id. \n You provided a object of another type." +} + +export class AddressNotFoundError extends NotFoundError { + @IsString() + name = "AddressNotFoundError" + + @IsString() + message = "The address you provided couldn't be located in the system. \n Please check your request." +} \ No newline at end of file diff --git a/src/errors/GroupContactErrors.ts b/src/errors/GroupContactErrors.ts new file mode 100644 index 0000000..c5bf9c7 --- /dev/null +++ b/src/errors/GroupContactErrors.ts @@ -0,0 +1,18 @@ +import { IsString } from 'class-validator'; +import { NotAcceptableError, NotFoundError } from 'routing-controllers'; + +export class GroupContactWrongTypeError extends NotAcceptableError { + @IsString() + name = "GroupContactWrongTypeError" + + @IsString() + message = "The groupContact must be an existing groupContact's id. \n You provided a object of another type." +} + +export class GroupContactNotFoundError extends NotFoundError { + @IsString() + name = "GroupContactNotFoundError" + + @IsString() + message = "The groupContact you provided couldn't be located in the system. \n Please check your request." +} \ No newline at end of file diff --git a/src/errors/ParticipantErrors.ts b/src/errors/ParticipantErrors.ts deleted file mode 100644 index de672d8..0000000 --- a/src/errors/ParticipantErrors.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { IsString } from 'class-validator'; -import { NotAcceptableError, NotFoundError } from 'routing-controllers'; - -export class ParticipantOnlyOneAddressAllowedError extends NotAcceptableError { - @IsString() - name = "ParticipantOnlyOneAddressAllowedError" - - @IsString() - message = "Participant's can only have one address! \n You provided an id and address object.." -} - -export class ParticipantAddressNotFoundError extends NotFoundError { - @IsString() - name = "ParticipantAddressNotFoundError" - - @IsString() - message = "The address you provided couldn't be located in the system. \n Please check your request." -} \ No newline at end of file diff --git a/src/errors/RunnerErrors.ts b/src/errors/RunnerErrors.ts index 0be6419..8250d17 100644 --- a/src/errors/RunnerErrors.ts +++ b/src/errors/RunnerErrors.ts @@ -1,5 +1,5 @@ -import { JsonController, Param, Body, Get, Post, Put, Delete, NotFoundError, OnUndefined, NotAcceptableError } from 'routing-controllers'; -import { IsInt, IsNotEmpty, IsPositive, IsString } from 'class-validator'; +import { IsString } from 'class-validator'; +import { NotAcceptableError, NotFoundError } from 'routing-controllers'; /** * Error to throw when a runner couldn't be found. diff --git a/src/errors/RunnerOrganisationErrors.ts b/src/errors/RunnerOrganisationErrors.ts index 1dfb68e..65736b1 100644 --- a/src/errors/RunnerOrganisationErrors.ts +++ b/src/errors/RunnerOrganisationErrors.ts @@ -48,4 +48,12 @@ export class RunnerOrganisationHasTeamsError extends NotAcceptableError { @IsString() message = "This organisation still has teams associated with it. \n If you want to delete this organisation with all it's runners and teams ass `?force` to your query." -} \ No newline at end of file +} + +export class RunnerOrganisationWrongTypeError extends NotAcceptableError { + @IsString() + name = "RunnerOrganisationWrongTypeError" + + @IsString() + message = "The runner organisation must be an existing organisation's id. \n You provided a object of another type." +} diff --git a/src/errors/RunnerTeamErrors.ts b/src/errors/RunnerTeamErrors.ts index a482c26..33fbea5 100644 --- a/src/errors/RunnerTeamErrors.ts +++ b/src/errors/RunnerTeamErrors.ts @@ -36,4 +36,16 @@ export class RunnerTeamHasRunnersError extends NotAcceptableError { @IsString() message = "This team still has runners associated with it. \n If you want to delete this team with all it's runners and teams ass `?force` to your query." +} + +/** + * Error to throw when a team still has runners associated. + * Implemented this waysto work with the json-schema conversion for openapi. + */ +export class RunnerTeamNeedsParentError extends NotAcceptableError { + @IsString() + name = "RunnerTeamNeedsParentError" + + @IsString() + message = "You provided no runner organisation as this team's parent group." } \ No newline at end of file diff --git a/src/models/creation/CreateGroupContact.ts b/src/models/creation/CreateGroupContact.ts new file mode 100644 index 0000000..73f43d0 --- /dev/null +++ b/src/models/creation/CreateGroupContact.ts @@ -0,0 +1,83 @@ +import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; +import { getConnectionManager } from 'typeorm'; +import { AddressNotFoundError, AddressWrongTypeError } from '../../errors/AddressErrors'; +import { Address } from '../entities/Address'; +import { GroupContact } from '../entities/GroupContact'; + +export class CreateGroupContact { + /** + * The contact's first name. + */ + @IsNotEmpty() + @IsString() + firstname: string; + + /** + * The contact's middle name. + * Optional + */ + @IsOptional() + @IsString() + middlename?: string; + + /** + * The contact's last name. + */ + @IsNotEmpty() + @IsString() + lastname: string; + + /** + * The contact's address. + * Optional + */ + @IsInt() + @IsOptional() + address?: number; + + /** + * The contact's phone number. + * Optional + */ + @IsOptional() + @IsPhoneNumber("DE") + phone?: string; + + /** + * The contact's email address. + * Optional + */ + @IsOptional() + @IsEmail() + email?: string; + + /** + * Get's this participant's address from this.address. + */ + public async getAddress(): Promise
{ + if (this.address === undefined) { + return null; + } + if (!isNaN(this.address)) { + let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address }); + if (!address) { throw new AddressNotFoundError; } + return address; + } + + throw new AddressWrongTypeError; + } + + /** + * Creates a Address object based on this. + */ + public async toGroupContact(): Promise