diff --git a/src/datasources/db/cargobikeAPI.ts b/src/datasources/db/cargobikeAPI.ts index 4af0edf..47dd961 100644 --- a/src/datasources/db/cargobikeAPI.ts +++ b/src/datasources/db/cargobikeAPI.ts @@ -1,15 +1,17 @@ import { DataSource } from 'apollo-datasource'; -import { getConnection, Connection, ObjectType, EntityManager } from 'typeorm'; -import { CargoBike, Lockable } from '../../model/CargoBike'; +import { Connection, EntityManager, getConnection } from 'typeorm'; +import { CargoBike } from '../../model/CargoBike'; import { GraphQLError } from 'graphql'; import { BikeEvent } from '../../model/BikeEvent'; import { Equipment } from '../../model/Equipment'; import { Engagement } from '../../model/Engagement'; import { Provider } from '../../model/Provider'; import { TimeFrame } from '../../model/TimeFrame'; -import { ActionLogger, LockUtils } from './utils'; +import { ActionLogger, deleteEntity, LockUtils } from './utils'; import { EquipmentType } from '../../model/EquipmentType'; import { BikeEventType } from '../../model/BikeEventType'; +import { UserInputError } from 'apollo-server-express'; +import { Actions } from '../../model/ActionLog'; /** * extended datasource to feed resolvers with data about cargoBikes @@ -33,13 +35,13 @@ export class CargoBikeAPI extends DataSource { /** * Finds cargo bike by id, returns null if id was not found - * @param param0 id of bike + * @param id */ async findCargoBikeById (id: number) { return await this.connection.getRepository(CargoBike) - .createQueryBuilder('cargobike') + .createQueryBuilder('cb') .select() - .where('cargobike.id = :id', { id }) + .where('id = :id', { id }) .getOne(); } @@ -67,9 +69,18 @@ export class CargoBikeAPI extends DataSource { .loadOne(); } + async lockCargoBike (id: number, userId: number) { + return await LockUtils.lockEntity(this.connection, CargoBike, 'cb', id, userId); + } + + async unlockCargoBike (id: number, userId: number) { + return await LockUtils.unlockEntity(this.connection, CargoBike, 'cb', id, userId); + } + /** * Updates CargoBike and return updated cargoBike - * @param param0 cargoBike to be updated + * @param cargoBike + * @param userId */ async updateCargoBike (cargoBike: any, userId:number) { const keepLock = cargoBike?.keepLock; @@ -86,13 +97,13 @@ export class CargoBikeAPI extends DataSource { } await ActionLogger.log(entityManager, CargoBike, 'cb', cargoBike, userId); await entityManager.getRepository(CargoBike) - .createQueryBuilder('cargobike') + .createQueryBuilder('cb') .update() .set({ ...cargoBike }) .where('id = :id', { id: cargoBike.id }) .execute(); equipmentTypeIds && await entityManager.getRepository(CargoBike) - .createQueryBuilder('cargobike') + .createQueryBuilder('cb') .relation(CargoBike, 'equipmentTypeIds') .of(cargoBike.id) .addAndRemove(equipmentTypeIds, await this.equipmentTypeByCargoBikeId(cargoBike.id)); // TODO remove all existing relations @@ -101,29 +112,42 @@ export class CargoBikeAPI extends DataSource { return await this.findCargoBikeById(cargoBike.id); } + async deleteCargoBike (id: number, userId: number) { + return await this.connection.transaction(async (entityManager: EntityManager) => { + if (await LockUtils.isLocked(entityManager, CargoBike, 'cb', id, userId)) { + throw new UserInputError('Attempting to soft delete locked resource'); + } + await ActionLogger.log(entityManager, CargoBike, 'bg', { id: id }, userId, Actions.SOFT_DELETE); + return await entityManager.getRepository(CargoBike) + .createQueryBuilder('cb') + .delete() + .where('id = :id', { id: id }) + .execute(); + }).then(value => value.affected === 1); + } + /** * createCargoBike * created CargoBike and returns created bike with new ID * @param param0 cargoBike to be created */ async createCargoBike ({ cargoBike }: { cargoBike: any }) { - let inserts: any; + let inserts: any = {}; await this.connection.transaction(async (entityManager:any) => { inserts = await entityManager.getRepository(CargoBike) - .createQueryBuilder('cargobike') + .createQueryBuilder('cb') .insert() .values([cargoBike]) .returning('*') .execute(); cargoBike?.equipmentTypeIds && await entityManager.getRepository(CargoBike) - .createQueryBuilder('cargobike') + .createQueryBuilder('cb') .relation(CargoBike, 'equipmentTypeIds') .of(inserts.identifiers[0].id) .add(cargoBike.equipmentTypeIds); }); - const newbike = inserts.generatedMaps[0]; - newbike.id = inserts.identifiers[0].id; - return newbike; + inserts.generatedMaps[0] = inserts?.identifiers[0].id; + return inserts?.generatedMaps[0]; } async createBikeEvent ({ bikeEvent }: { bikeEvent: any }) { @@ -154,6 +178,14 @@ export class CargoBikeAPI extends DataSource { return await this.bikeEventById(bikeEvent.id); } + async deleteBikeEventType (id: number, userId: number) { + return await deleteEntity(this.connection, BikeEventType, 'bet', id, userId); + } + + async deleteBikeEvent (id: number, userId: number) { + return await deleteEntity(this.connection, BikeEvent, 'be', id, userId); + } + async cargoBikeByEventId (id: number) { return await this.connection.getRepository(BikeEvent) .createQueryBuilder('be') @@ -286,17 +318,6 @@ export class CargoBikeAPI extends DataSource { .getOne(); } - async checkId (target: ObjectType, alias: string, id: number) { - const result = await this.connection.getRepository(target) - .createQueryBuilder(alias) - .select([ - alias + '.id' - ]) - .where('id = :id', { id: id }) - .getCount(); - return result === 1; - } - /** * Returns equipment of one cargoBike * @param offset @@ -312,14 +333,16 @@ export class CargoBikeAPI extends DataSource { } async createEquipment ({ equipment }: { equipment: any }) { - const inserts = await this.connection.getRepository(Equipment) + return await this.connection.getRepository(Equipment) .createQueryBuilder('equipment') .insert() .into(Equipment) .values([equipment]) .returning('*') - .execute(); - return this.equipmentById(inserts.identifiers[0].id); + .execute() + .then(async inserts => { + return await this.equipmentById(inserts.identifiers[0].id); + }); } async cargoBikeByEquipmentId (id: number) { @@ -341,13 +364,12 @@ export class CargoBikeAPI extends DataSource { /** * Will update Equipment, crashes when id not in db or cargoBikeId not db. * Will return updated Equipment joined with CargoBike only if cargoBike is was set in param0 - * @param param0 struct with equipment properites + * @param equipment + * @param userId */ async updateEquipment (equipment: any, userId: number) { const keepLock = equipment.keepLock; delete equipment.keepLock; - // const cargoBikeId = equipment.cargoBikeId; - // delete equipment.cargoBikeId; await this.connection.transaction(async (entityManager: EntityManager) => { if (await LockUtils.isLocked(entityManager, Equipment, 'equipment', equipment.id, userId)) { return new GraphQLError('Equipment is locked by other user'); @@ -359,21 +381,15 @@ export class CargoBikeAPI extends DataSource { .set({ ...equipment }) .where('id = :id', { id: equipment.id }) .execute(); - /* if (cargoBikeId || cargoBikeId === null) { - await this.connection.getRepository(Equipment) - .createQueryBuilder() - .relation(Equipment, 'cargoBike') - .of(equipment.id) - .set(cargoBikeId); - } - - */ - } - ); + }); !keepLock && await LockUtils.unlockEntity(this.connection, Equipment, 'e', equipment.id, userId); return this.equipmentById(equipment.id); } + async deleteEquipment (id: number, userId: number) { + return await deleteEntity(this.connection, Equipment, 'e', id, userId); + } + async getEquipment (offset: number, limit: number) { return await this.connection.getRepository(Equipment) .createQueryBuilder('equipment') @@ -385,14 +401,16 @@ export class CargoBikeAPI extends DataSource { } async createEquipmentType (equipmentType: any) { - const inserts = await this.connection.getRepository(EquipmentType) + return await this.connection.getRepository(EquipmentType) .createQueryBuilder('equipment') .insert() .values([equipmentType]) .returning('*') - .execute(); - inserts.generatedMaps[0].id = inserts.identifiers[0].id; - return inserts.generatedMaps[0]; + .execute() + .then(inserts => { + inserts.generatedMaps[0].id = inserts.identifiers[0].id; + return inserts.generatedMaps[0]; + }); } async lockEquipmentType (id: number, userId : number) { @@ -422,6 +440,10 @@ export class CargoBikeAPI extends DataSource { return await this.equipmentTypeById(equipmentType.id); } + async deleteEquipmentType (id:number, userId: number) { + return await deleteEntity(this.connection, EquipmentType, 'et', id, userId); + } + async equipmentTypeById (id: number) { return await this.connection.getRepository(EquipmentType) .createQueryBuilder('equipmentType') @@ -441,7 +463,7 @@ export class CargoBikeAPI extends DataSource { async equipmentTypeByCargoBikeId (id: number) { return await this.connection.getRepository(CargoBike) - .createQueryBuilder('cargobike') + .createQueryBuilder('cb') .relation(CargoBike, 'equipmentTypeIds') .of(id) .loadMany(); diff --git a/src/datasources/db/contactinformationAPI.ts b/src/datasources/db/contactinformationAPI.ts index 4b596bb..fe493d5 100644 --- a/src/datasources/db/contactinformationAPI.ts +++ b/src/datasources/db/contactinformationAPI.ts @@ -2,7 +2,7 @@ import { DataSource } from 'apollo-datasource'; import { Connection, EntityManager, getConnection } from 'typeorm'; import { ContactInformation } from '../../model/ContactInformation'; import { Person } from '../../model/Person'; -import { ActionLogger, LockUtils } from './utils'; +import { ActionLogger, deleteEntity, LockUtils } from './utils'; import { GraphQLError } from 'graphql'; import { LendingStation } from '../../model/LendingStation'; @@ -23,7 +23,7 @@ export class ContactInformationAPI extends DataSource { async contactInformation (offset: number, limit: number) { return await this.connection.getRepository(ContactInformation) - .createQueryBuilder('contactinformation') + .createQueryBuilder('ci') .select() .offset(offset) .limit(limit) @@ -76,6 +76,10 @@ export class ContactInformationAPI extends DataSource { return this.personById(person.id); } + async deletePerson (id: number, userId: number) { + return await deleteEntity(this.connection, Person, 'p', id, userId); + } + async persons (offset: number, limit: number) { return await this.connection.getRepository(Person) .createQueryBuilder('person') @@ -155,12 +159,15 @@ export class ContactInformationAPI extends DataSource { return await this.contactInformationById(contactInformation.id); } + async deleteContactInformation (id: number, userId: number) { + return await deleteEntity(this.connection, ContactInformation, 'ci', id, userId); + } + async contactInformationByPersonId (id: number) { - const res = await this.connection.getRepository(ContactInformation) + return await this.connection.getRepository(ContactInformation) .createQueryBuilder('ci') .select() .where('ci."personId" = :id', { id: id }) .getMany(); - return res; } } diff --git a/src/datasources/db/lendingstationAPI.ts b/src/datasources/db/lendingstationAPI.ts index 38cd82f..0a2cc23 100644 --- a/src/datasources/db/lendingstationAPI.ts +++ b/src/datasources/db/lendingstationAPI.ts @@ -1,11 +1,11 @@ import { DataSource } from 'apollo-datasource'; -import { ApolloError, UserInputError } from 'apollo-server-express'; +import { UserInputError } from 'apollo-server-express'; import { GraphQLError } from 'graphql'; -import { Connection, EntityManager, getConnection, QueryFailedError } from 'typeorm'; +import { Connection, EntityManager, getConnection } from 'typeorm'; import { CargoBike } from '../../model/CargoBike'; import { LendingStation } from '../../model/LendingStation'; import { TimeFrame } from '../../model/TimeFrame'; -import { ActionLogger, genDateRange, LockUtils } from './utils'; +import { ActionLogger, deleteEntity, genDateRange, LockUtils } from './utils'; export class LendingStationAPI extends DataSource { connection : Connection @@ -71,7 +71,7 @@ export class LendingStationAPI extends DataSource { async timeFramesByCargoBikeId (id: number) { return await this.connection.getRepository(CargoBike) - .createQueryBuilder('cargobike') + .createQueryBuilder('cb') .relation(CargoBike, 'timeFrames') .of(id) .loadMany(); @@ -126,36 +126,37 @@ export class LendingStationAPI extends DataSource { .where('timeframes."lendingStationId" = :id', { id: id }) .andWhere('timeframes."dateRange" && daterange(CURRENT_DATE,CURRENT_DATE,\'[]\')') .printSql() - .getMany(); // .catch(() => { return []; }); + .getMany(); } /** * creates new lendingStation and returns new lendingStation with its new id - * @param param0 new lendingStation + * @param lendingStation */ async createLendingStation (lendingStation: any) { let inserts: any; await this.connection.transaction(async entityManager => { - inserts = await entityManager.createQueryBuilder(LendingStation, 'lendingstation') + inserts = await entityManager.createQueryBuilder(LendingStation, 'ls') .insert() .values([lendingStation]) .returning('*') .execute(); }); // when using the return values, the simple array has a different format and must treated in another way, so this is the more expansive solution - return await this.lendingStationById(inserts.generatedMaps[0].id); + return await this.lendingStationById(inserts?.generatedMaps[0].id); } /** * updates lendingStation and return updated lendingStation - * @param param0 lendingStation to be updated + * @param lendingStation + * @param userId */ async updateLendingStation (lendingStation: any, userId: number) { const keepLock = lendingStation.keepLock; delete lendingStation.keepLock; await this.connection.transaction(async (entityManager: EntityManager) => { if (await LockUtils.isLocked(entityManager, LendingStation, 'ls', lendingStation.id, userId)) { - throw new GraphQLError('LendingStation is locked by another user'); + throw new UserInputError('Attempting to update locked resource'); } await ActionLogger.log(entityManager, LendingStation, 'ls', lendingStation, userId); await entityManager.getRepository(LendingStation) @@ -169,43 +170,39 @@ export class LendingStationAPI extends DataSource { return await this.lendingStationById(lendingStation.id); } + async deleteLendingStationById (id: number, userId: number) { + return await deleteEntity(this.connection, LendingStation, 'ls', id, userId); + } + async createTimeFrame (timeFrame: any) { - let inserts: any; - try { - await this.connection.transaction(async (entityManager: EntityManager) => { - if (timeFrame.to === undefined) { - timeFrame.to = ''; - } - timeFrame.dateRange = '[' + timeFrame.from + ',' + timeFrame.to + ')'; - // checking for overlapping time frames - const overlapping = await entityManager.getRepository(TimeFrame) - .createQueryBuilder('timeframe') - .select([ - 'timeframe.id' - ]) - .where('timeframe."cargoBikeId" = :id', { id: timeFrame.cargoBikeId }) - .andWhere('timeframe."dateRange" && :tr', { tr: timeFrame.dateRange }) - .getMany(); - if (overlapping.length !== 0) { - throw new UserInputError('TimeFrames with ids: ' + overlapping.map((e) => { return e.id + ', '; }) + 'are overlapping'); - } - inserts = await entityManager.getRepository(TimeFrame) - .createQueryBuilder('timeframe') - .insert() - .returning('*') - .values([timeFrame]) - .execute(); - }); - } catch (e) { - if (e instanceof UserInputError) { - return e; - } else if (e instanceof QueryFailedError) { - return e; + return await this.connection.transaction(async (entityManager: EntityManager) => { + if (timeFrame.to === undefined) { + timeFrame.to = ''; } - return new ApolloError('Transaction could not be completed'); - } - inserts.generatedMaps[0].id = inserts.identifiers[0].id; - return inserts.generatedMaps[0]; + timeFrame.dateRange = '[' + timeFrame.from + ',' + timeFrame.to + ')'; + // checking for overlapping time frames + const overlapping = await entityManager.getRepository(TimeFrame) + .createQueryBuilder('timeframe') + .select([ + 'timeframe.id' + ]) + .where('timeframe."cargoBikeId" = :id', { id: timeFrame.cargoBikeId }) + .andWhere('timeframe."dateRange" && :tr', { tr: timeFrame.dateRange }) + .getMany(); + if (overlapping.length !== 0) { + throw new UserInputError('TimeFrames with ids: ' + overlapping.map((e) => { return e.id + ', '; }) + 'are overlapping'); + } + return await entityManager.getRepository(TimeFrame) + .createQueryBuilder('timeframe') + .insert() + .returning('*') + .values([timeFrame]) + .execute() + .then(inserts => { + inserts.generatedMaps[0].id = inserts?.identifiers[0].id; + return inserts.generatedMaps[0]; + }); + }); } async lockTimeFrame (id: number, userId: number) { @@ -245,9 +242,13 @@ export class LendingStationAPI extends DataSource { .set({ ...timeFrame }) .where('id = :id', { id: timeFrame.id }) .execute() - .then(value => { if (value.affected !== 1) { throw new GraphQLError('ID not found'); } }); + .then(value => { if (value.affected !== 1) { throw new UserInputError('ID not found'); } }); }); !keepLock && await this.unlockTimeFrame(timeFrame.id, userId); return this.timeFrameById(timeFrame.id); } + + async deleteTimeFrame (id: number, userId: number) { + return await deleteEntity(this.connection, TimeFrame, 'tf', id, userId); + } } diff --git a/src/datasources/db/participantAPI.ts b/src/datasources/db/participantAPI.ts index ec15cab..b982325 100644 --- a/src/datasources/db/participantAPI.ts +++ b/src/datasources/db/participantAPI.ts @@ -4,7 +4,7 @@ import { ContactInformation } from '../../model/ContactInformation'; import { Engagement } from '../../model/Engagement'; import { Participant } from '../../model/Participant'; import { EngagementType } from '../../model/EngagementType'; -import { ActionLogger, genDateRange, LockUtils } from './utils'; +import { ActionLogger, deleteEntity, genDateRange, LockUtils } from './utils'; import { UserInputError } from 'apollo-server-express'; import { GraphQLError } from 'graphql'; @@ -177,6 +177,10 @@ export class ParticipantAPI extends DataSource { return await this.participantById(participant.id); } + async deleteParticipant (id: number, userId: number) { + return await deleteEntity(this.connection, Participant, 'p', id, userId); + } + async createEngagement (engagement: any) { let inserts: any; genDateRange(engagement); @@ -242,6 +246,10 @@ export class ParticipantAPI extends DataSource { return await this.engagementById(engagement.id); } + async deleteEngagement (id: number, userId: number) { + return await deleteEntity(this.connection, Engagement, 'e', id, userId); + } + async createEngagementType (engagementType: any) { const inserts = await this.connection.getRepository(EngagementType) .createQueryBuilder('et') @@ -279,4 +287,8 @@ export class ParticipantAPI extends DataSource { !keepLock && await LockUtils.unlockEntity(this.connection, EngagementType, 'et', engagementType.id, userId); return await this.engagementTypeById(engagementType.id); } + + async deleteEngagementType (id: number, userId: number) { + return await deleteEntity(this.connection, EngagementType, 'et', id, userId); + } } diff --git a/src/datasources/db/providerAPI.ts b/src/datasources/db/providerAPI.ts index 2f5f48e..9a83665 100644 --- a/src/datasources/db/providerAPI.ts +++ b/src/datasources/db/providerAPI.ts @@ -5,7 +5,7 @@ import { Organisation } from '../../model/Organisation'; import { UserInputError } from 'apollo-server-express'; import { CargoBike } from '../../model/CargoBike'; import { LendingStation } from '../../model/LendingStation'; -import { ActionLogger, LockUtils } from './utils'; +import { ActionLogger, deleteEntity, LockUtils } from './utils'; import { GraphQLError } from 'graphql'; export class ProviderAPI extends DataSource { @@ -160,6 +160,10 @@ export class ProviderAPI extends DataSource { return await this.providerById(provider.id); } + async deleteProvider (id: number, userId: number) { + return await deleteEntity(this.connection, Provider, 'p', id, userId); + } + async createOrganisation (organisation: any) { let inserts: any = null; await this.connection.transaction(async (entityManager: EntityManager) => { @@ -198,4 +202,8 @@ export class ProviderAPI extends DataSource { !keepLock && await LockUtils.unlockEntity(this.connection, Organisation, 'o', organisation.id, userId); return this.organisationById(organisation.id); } + + async deleteOrganisation (id: number, userId: number) { + return await deleteEntity(this.connection, Organisation, 'o', id, userId); + } } diff --git a/src/datasources/db/utils.ts b/src/datasources/db/utils.ts index c8da655..6c720a3 100644 --- a/src/datasources/db/utils.ts +++ b/src/datasources/db/utils.ts @@ -2,6 +2,7 @@ import { Connection, EntityManager, ObjectType } from 'typeorm'; import { Lockable } from '../../model/CargoBike'; import { GraphQLError } from 'graphql'; import { ActionLog, Actions } from '../../model/ActionLog'; +import { UserInputError } from 'apollo-server-express'; export function genDateRange (struct: any) { if (struct.to === undefined) { @@ -29,12 +30,26 @@ export function isLocked (parent: any, { dataSources, req }: { dataSources: any; }); } +export async function deleteEntity (connection: Connection, target: ObjectType, alias: string, id: number, userId: number): Promise { + return await connection.transaction(async (entityManger: EntityManager) => { + if (await LockUtils.isLocked(entityManger, target, alias, id, userId)) { + throw new UserInputError('Attempting to delete locked resource'); + } + await ActionLogger.log(entityManger, target, alias, { id: id }, userId, Actions.DELETE); + return await entityManger.getRepository(target) + .createQueryBuilder(alias) + .delete() + .where('id = :id', { id: id }) + .execute().then(value => value.affected === 1); + }); +} + export class LockUtils { static getToken (req: any) : string { return req.headers.authorization?.replace('Bearer ', ''); } - static async findById (connection: Connection, target: ObjectType, alias: string, id: number, userId: number): Promise { + static async findById (connection: Connection, target: ObjectType, alias: string, id: number): Promise { return await connection.getRepository(target) .createQueryBuilder(alias) .select() @@ -66,7 +81,7 @@ export class LockUtils { }) .where('id = :id', { id: id }) .execute(); - return await this.findById(connection, target, alias, id, userId); + return await this.findById(connection, target, alias, id); } else { // lock was set throw new GraphQLError('Entry locked by other user'); @@ -113,8 +128,7 @@ export class LockUtils { * @param target * @param alias * @param id - * @param req - * @param dataSources + * @param userId */ static async isLocked (connection: EntityManager, target: ObjectType, alias: string, id: number, userId: number) { const lock = await connection.getRepository(target) @@ -134,29 +148,14 @@ export class LockUtils { // eslint-disable-next-line eqeqeq } else return lock?.lockedBy != userId; } - - /** - * Returns true if id is found in database - * @param connection - * @param target - * @param alias - * @param id - */ - static async checkId (connection: Connection, target: ObjectType, alias: string, id: number) { - const result = await connection.getRepository(target) - .createQueryBuilder(alias) - .select([ - alias + '.id' - ]) - .where('id = :id', { id: id }) - .getCount(); - return result === 1; - } } export class ActionLogger { private static buildSelect (updates: any, alias: string) : string[] { // this hacky shit makes it possible to select subfields like the address or insurance data. Only one layer at the moment + if (updates === null) { + return ['*']; + } const ret :string[] = []; Object.keys(updates).forEach(value => { if (typeof updates[value] === 'object' && !Array.isArray(updates[value])) { @@ -176,7 +175,7 @@ export class ActionLogger { .where('id = :id', { id: updates.id }) .getRawOne().then(value => { if (value === undefined) { - throw new GraphQLError('Id not found'); + throw new UserInputError('Id not found'); } return value; }); // use getRawOne to also get ids of related entities diff --git a/src/datasources/db/workshopAPI.ts b/src/datasources/db/workshopAPI.ts index 05a016c..f86ae87 100644 --- a/src/datasources/db/workshopAPI.ts +++ b/src/datasources/db/workshopAPI.ts @@ -2,7 +2,7 @@ import { DataSource } from 'apollo-datasource'; import { Connection, EntityManager, getConnection } from 'typeorm'; import { WorkshopType } from '../../model/WorkshopType'; import { Workshop } from '../../model/Workshop'; -import { ActionLogger, LockUtils } from './utils'; +import { ActionLogger, deleteEntity, LockUtils } from './utils'; import { UserInputError } from 'apollo-server-express'; import { GraphQLError } from 'graphql'; @@ -52,6 +52,10 @@ export class WorkshopAPI extends DataSource { return await this.workshopById(workshop.id); } + async deleteWorkshop (id: number, userId: number) { + return await deleteEntity(this.connection, Workshop, 'w', id, userId); + } + async createWorkshopType (workshopType: any) { const inserts = await this.connection.getRepository(WorkshopType) .createQueryBuilder('wt') @@ -90,6 +94,10 @@ export class WorkshopAPI extends DataSource { return await this.workshopTypeById(workshopType.id); } + async deleteWorkshopType (id: number, userId: number) { + return await deleteEntity(this.connection, WorkshopType, 'wt', id, userId); + } + async workshopTypeById (id: number) { return await this.connection.getRepository(WorkshopType) .createQueryBuilder('wt') diff --git a/src/datasources/userserver/permission.ts b/src/datasources/userserver/permission.ts index e25a030..4fb305d 100644 --- a/src/datasources/userserver/permission.ts +++ b/src/datasources/userserver/permission.ts @@ -27,7 +27,22 @@ export enum Permission { WriteEquipmentType = 'EQUIPMENT_TYPE_WRITE', WriteEngagementType = 'ENGAGEMENT_TYPE_WRITE', ReadActionLog = 'ACTION_LOG_READ', - ReadActionLogAll = 'ACTION_LOG_ALL_READ' + ReadActionLogAll = 'ACTION_LOG_ALL_READ', + DeleteBike = 'BIKE_DELETE', + DeleteTimeFrame = 'TIME_FRAME_DELETE', + DeletePerson = 'PERSON_DELETE', + DeleteParticipant = ' PARTICIPANT_DELETE', + DeleteProvider = 'PROVIDER_DELETE', + DeleteLendingStation = 'LENDING_STATION_DELETE', + DeleteOrganisation = 'ORGANISATION_DELETE', + DeleteWorkshop = 'WORKSHOP_DELETE', + DeleteBikeEvent = 'BIKE_EVENT_DELETE', + DeleteEngagement = 'ENGAGEMENT_DELETE', + DeleteEquipment = 'EQUIPMENT_DELETE', + DeleteWorkshopType = 'WORKSHOP_TYPE_DELETE', + DeleteEventType = 'EVENT_TYPE_DELETE', + DeleteEquipmentType = 'EQUIPMENT_TYPE_DELETE', + DeleteEngagementType = 'ENGAGEMENT_TYPE_DELETE' } // Permissions where the creation will be requested on startup @@ -143,5 +158,65 @@ export const requiredPermissions = [ { name: Permission.ReadActionLogAll, description: 'Allows to read action log of other users' + }, + { + name: Permission.DeleteBike, + description: 'Allows to delete bikes' + }, + { + name: Permission.DeleteTimeFrame, + description: 'Allows to delete time frames' + }, + { + name: Permission.DeletePerson, + description: 'Allows to delete persons and personal data' + }, + { + name: Permission.DeleteParticipant, + description: 'Allows to delete participants' + }, + { + name: Permission.DeleteProvider, + description: 'Allows to delete provider' + }, + { + name: Permission.DeleteLendingStation, + description: 'Allows to delete lending stations' + }, + { + name: Permission.DeleteOrganisation, + description: 'Allows to delete organisations' + }, + { + name: Permission.DeleteWorkshop, + description: 'Allows to delete workshops' + }, + { + name: Permission.DeleteBikeEvent, + description: 'Allows to delete bike events' + }, + { + name: Permission.DeleteEngagement, + description: 'Allows to delete engagements' + }, + { + name: Permission.DeleteEquipment, + description: 'Allows to delete equipment' + }, + { + name: Permission.DeleteWorkshopType, + description: 'Allows to delete workshop types' + }, + { + name: Permission.DeleteEventType, + description: 'Allows to delete event types' + }, + { + name: Permission.DeleteEquipmentType, + description: 'Allows to delete equipment types' + }, + { + name: Permission.DeleteEngagementType, + description: 'Allows to delete engagement types' } ]; diff --git a/src/model/CargoBike.ts b/src/model/CargoBike.ts index 7b6dd82..67a3661 100644 --- a/src/model/CargoBike.ts +++ b/src/model/CargoBike.ts @@ -1,5 +1,15 @@ /* eslint no-unused-vars: "off" */ -import { Entity, Column, PrimaryGeneratedColumn, OneToMany, ManyToOne, JoinColumn, ManyToMany, JoinTable } from 'typeorm'; +import { + Entity, + Column, + PrimaryGeneratedColumn, + OneToMany, + ManyToOne, + JoinColumn, + ManyToMany, + JoinTable, + DeleteDateColumn +} from 'typeorm'; import { Provider } from './Provider'; import { Participant } from './Participant'; import { InsuranceData } from './InsuranceData'; @@ -145,6 +155,9 @@ export class CargoBike implements Lockable { @PrimaryGeneratedColumn() id: number; + @DeleteDateColumn() + deleteDate: Date; + @Column({ type: 'enum', enum: Group diff --git a/src/resolvers/cargobikeResolver.ts b/src/resolvers/cargobikeResolver.ts index 4e558d0..6ca00ae 100644 --- a/src/resolvers/cargobikeResolver.ts +++ b/src/resolvers/cargobikeResolver.ts @@ -187,14 +187,14 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, - lockCargoBikeById: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + lockCargoBike: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteBike)) { return dataSources.cargoBikeAPI.lockCargoBike(id, req.userId); } else { return new GraphQLError('Insufficient Permissions'); } }, - unlockCargoBikeById: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + unlockCargoBike: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteBike)) { return dataSources.cargoBikeAPI.unlockCargoBike(id, req.userId); } else { @@ -208,6 +208,13 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, + deleteCargoBike: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteBike)) { + return dataSources.cargoBikeAPI.deleteCargoBike(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } + }, createBikeEvent: (_: any, { bikeEvent }: { bikeEvent: any }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteBikeEvent)) { return dataSources.cargoBikeAPI.createBikeEvent({ bikeEvent }); @@ -215,14 +222,14 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, - lockBikeEventById: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + lockBikeEvent: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteBikeEvent)) { return dataSources.cargoBikeAPI.lockBikeEvent(id, req.userId); } else { return new GraphQLError('Insufficient Permissions'); } }, - unlockBikeEventById: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + unlockBikeEvent: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteBikeEvent)) { return dataSources.cargoBikeAPI.unlockBikeEvent(id, req.userId); } else { @@ -236,6 +243,13 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, + deleteBikeEvent: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteBikeEvent)) { + return dataSources.cargoBikeAPI.deleteBikeEvent(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } + }, createEquipment: (_: any, { equipment }: { equipment: any }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteEquipment)) { return dataSources.cargoBikeAPI.createEquipment({ equipment }); @@ -243,14 +257,14 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, - lockEquipmentById: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + lockEquipment: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteEquipment)) { return dataSources.cargoBikeAPI.lockEquipment(id, req.userId); } else { return new GraphQLError('Insufficient Permissions'); } }, - unlockEquipmentById: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + unlockEquipment: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteEquipment)) { return dataSources.cargoBikeAPI.unlockEquipment(id, req.userId); } else { @@ -264,6 +278,13 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, + deleteEquipment: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteEquipment)) { + return dataSources.cargoBikeAPI.deleteEquipment(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } + }, createEquipmentType: (_: any, { equipmentType }: { equipmentType: any }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteEquipmentType)) { return dataSources.cargoBikeAPI.createEquipmentType(equipmentType); @@ -292,6 +313,13 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, + deleteEquipmentType: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteEquipmentType)) { + return dataSources.cargoBikeAPI.deleteEquipmentType(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } + }, createBikeEventType: (_: any, { name }: { name: any }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteEventType)) { return dataSources.cargoBikeAPI.createBikeEventType(name); @@ -319,6 +347,13 @@ export default { } else { return new GraphQLError('Insufficient Permissions'); } + }, + deleteBikeEventType: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteEventType)) { + return dataSources.cargoBikeAPI.deleteBikeEventType(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } } } }; diff --git a/src/resolvers/contactinformationResolvers.ts b/src/resolvers/contactinformationResolvers.ts index 2e09595..1e4fce5 100644 --- a/src/resolvers/contactinformationResolvers.ts +++ b/src/resolvers/contactinformationResolvers.ts @@ -55,13 +55,6 @@ export default { isLocked: (parent: any, __: any, { dataSources, req }: { dataSources: any; req: any }) => isLocked(parent, { dataSources, req }) }, Mutation: { - createContactInformation: (_: any, { contactInformation }: { contactInformation: any }, { dataSources, req }: { dataSources: any, req: any }) => { - if (req.permissions.includes(Permission.WritePerson)) { - return dataSources.contactInformationAPI.createContactInformation(contactInformation); - } else { - return new GraphQLError('Insufficient Permissions'); - } - }, createPerson: (_: any, { person }: { person: any }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WritePerson)) { return dataSources.contactInformationAPI.createPerson(person); @@ -90,6 +83,20 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, + deletePerson: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeletePerson)) { + return dataSources.contactInformationAPI.deletePerson(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } + }, + createContactInformation: (_: any, { contactInformation }: { contactInformation: any }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.WritePerson)) { + return dataSources.contactInformationAPI.createContactInformation(contactInformation); + } else { + return new GraphQLError('Insufficient Permissions'); + } + }, lockContactInformation: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WritePerson)) { return dataSources.contactInformationAPI.lockContactInformation(id, req.userId); @@ -110,6 +117,13 @@ export default { } else { return new GraphQLError('Insufficient Permissions'); } + }, + deleteContactInformation: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeletePerson)) { + return dataSources.contactInformationAPI.deleteContactInformation(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } } } }; diff --git a/src/resolvers/lendingstationResolvers.ts b/src/resolvers/lendingstationResolvers.ts index a1df1da..118914b 100644 --- a/src/resolvers/lendingstationResolvers.ts +++ b/src/resolvers/lendingstationResolvers.ts @@ -80,15 +80,15 @@ export default { isLocked: (parent: any, __: any, { dataSources, req }: { dataSources: any; req: any }) => isLocked(parent, { dataSources, req }) }, LoanPeriod: { - loanTimes (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) { + loanTimes (parent: any) { return parent.loanTimes ? parent.loanTimes : []; } }, TimeFrame: { - from (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) { + from (parent: any) { return (parent.dateRange as string).split(',')[0].replace('[', ''); }, - to (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) { + to (parent: any) { const str = (parent.dateRange as string).split(',')[1].replace(')', ''); return (str.length > 0) ? str : null; }, @@ -116,14 +116,14 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, - lockLendingStationById: (_: any, { id }:{ id: number }, { dataSources, req }:{dataSources: any, req: any }) => { + lockLendingStation: (_: any, { id }:{ id: number }, { dataSources, req }:{dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteLendingStation)) { return dataSources.lendingStationAPI.lockLendingStationById(id, req.userId); } else { return new GraphQLError('Insufficient Permissions'); } }, - unlockLendingStationById: (_: any, { id }:{ id: number }, { dataSources, req }:{dataSources: any, req: any }) => { + unlockLendingStation: (_: any, { id }:{ id: number }, { dataSources, req }:{dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteLendingStation)) { return dataSources.lendingStationAPI.unlockLendingStationById(id, req.userId); } else { @@ -137,6 +137,13 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, + deleteLendingStation: (_: any, { id }:{ id: number }, { dataSources, req }:{dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteLendingStation)) { + return dataSources.lendingStationAPI.deleteLendingStationById(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } + }, createTimeFrame: (_: any, { timeFrame }:{ timeFrame: LendingStation }, { dataSources, req }:{dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteTimeFrame)) { return dataSources.lendingStationAPI.createTimeFrame(timeFrame); @@ -164,6 +171,13 @@ export default { } else { return new GraphQLError('Insufficient Permissions'); } + }, + deleteTimeFrame: (_: any, { id }:{ id: number }, { dataSources, req }:{dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteTimeFrame)) { + return dataSources.lendingStationAPI.deleteTimeFrame(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } } } }; diff --git a/src/resolvers/participantResolvers.ts b/src/resolvers/participantResolvers.ts index d6c5033..7a837be 100644 --- a/src/resolvers/participantResolvers.ts +++ b/src/resolvers/participantResolvers.ts @@ -86,10 +86,10 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, - from (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) { + from (parent: any) { return (parent.dateRange as string).split(',')[0].replace('[', ''); }, - to (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) { + to (parent: any) { const str = (parent.dateRange as string).split(',')[1].replace(')', ''); return (str.length > 0) ? str : null; }, @@ -105,7 +105,7 @@ export default { }, lockParticipant: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteParticipant)) { - return dataSources.participantAPI.lockeParticipant(id, req.userId); + return dataSources.participantAPI.lockParticipant(id, req.userId); } else { return new GraphQLError('Insufficient Permissions'); } @@ -124,6 +124,13 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, + deleteParticipant: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteParticipant)) { + return dataSources.participantAPI.deleteParticipant(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } + }, createEngagement: (_: any, { engagement }: { engagement: any }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteEngagement)) { return dataSources.participantAPI.createEngagement(engagement); @@ -140,7 +147,7 @@ export default { }, unlockEngagement: (_: any, { id }: {id: number }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteEngagement)) { - return dataSources.participantAPI.unlockngagement(id, req.userId); + return dataSources.participantAPI.unlockEngagement(id, req.userId); } else { return new GraphQLError('Insufficient Permissions'); } @@ -152,6 +159,20 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, + deleteEngagement: (_: any, { id }: {id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteEngagement)) { + return dataSources.participantAPI.deleteEngagement(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } + }, + createEngagementType: (_: any, { engagementType }: { engagementType: any }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.WriteEngagementType)) { + return dataSources.participantAPI.createEngagementType(engagementType); + } else { + return new GraphQLError('Insufficient Permissions'); + } + }, lockEngagementType: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteEngagementType)) { return dataSources.participantAPI.lockEngagementType(id, req.userId); @@ -161,7 +182,7 @@ export default { }, unlockEngagementType: (_: any, { id }: {id: number }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteEngagementType)) { - return dataSources.participantAPI.unlockngagementType(id, req.userId); + return dataSources.participantAPI.unlockEngagementType(id, req.userId); } else { return new GraphQLError('Insufficient Permissions'); } @@ -173,9 +194,9 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, - createEngagementType: (_: any, { engagementType }: { engagementType: any }, { dataSources, req }: { dataSources: any, req: any }) => { - if (req.permissions.includes(Permission.WriteEngagementType)) { - return dataSources.participantAPI.createEngagementType(engagementType); + deleteEngagementType: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteEngagementType)) { + return dataSources.participantAPI.deleteEngagementType(id, req.userId); } else { return new GraphQLError('Insufficient Permissions'); } diff --git a/src/resolvers/providerResolvers.ts b/src/resolvers/providerResolvers.ts index 862e08e..e1b7f0b 100644 --- a/src/resolvers/providerResolvers.ts +++ b/src/resolvers/providerResolvers.ts @@ -110,6 +110,13 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, + deleteProvider: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteProvider)) { + return dataSources.providerAPI.deleteProvider(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } + }, createOrganisation: (_: any, { organisation }: { organisation: any }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteOrganisation)) { return dataSources.providerAPI.createOrganisation(organisation); @@ -137,6 +144,13 @@ export default { } else { return new GraphQLError('Insufficient Permissions'); } + }, + deleteOrganisation: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteOrganisation)) { + return dataSources.providerAPI.deleteOrganisation(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } } } }; diff --git a/src/resolvers/workshopResolvers.ts b/src/resolvers/workshopResolvers.ts index ac322e2..7955a43 100644 --- a/src/resolvers/workshopResolvers.ts +++ b/src/resolvers/workshopResolvers.ts @@ -82,6 +82,13 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, + deleteWorkshop: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteWorkshop)) { + return dataSources.workshopAPI.deleteWorkshop(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } + }, createWorkshopType: (_: any, { workshopType }: { workshopType: any }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteWorkshopType)) { return dataSources.workshopAPI.createWorkshopType(workshopType); @@ -109,6 +116,13 @@ export default { } else { return new GraphQLError('Insufficient Permissions'); } + }, + deleteWorkshopType: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { + if (req.permissions.includes(Permission.DeleteWorkshopType)) { + return dataSources.workshopAPI.deleteWorkshopType(id, req.userId); + } else { + return new GraphQLError('Insufficient Permissions'); + } } } }; diff --git a/src/schema/type-defs.ts b/src/schema/type-defs.ts index 63f30ef..97e4ffd 100644 --- a/src/schema/type-defs.ts +++ b/src/schema/type-defs.ts @@ -926,44 +926,50 @@ type Query { type Mutation { """ - CargoBikes + CARGO BIKE creates new cargoBike and returns cargobike with new ID """ createCargoBike(cargoBike: CargoBikeCreateInput!): CargoBike! "lock cargoBike returns bike if bike is not locked and locks bike or Error if bike cannot be locked" - lockCargoBikeById(id: ID!): CargoBike! + lockCargoBike(id: ID!): CargoBike! "unlock cargoBike, returns true if Bike does not exist" - unlockCargoBikeById(id: ID!): Boolean! + unlockCargoBike(id: ID!): Boolean! "updates cargoBike of given ID with supplied fields and returns updated cargoBike" updateCargoBike(cargoBike: CargoBikeUpdateInput!): CargoBike! + "true on success" + deleteCargoBike(id: ID!): Boolean! """ EQUIPMENT creates new peace of unique Equipment """ createEquipment(equipment: EquipmentCreateInput!): Equipment! "lock equipment returns true if bike is not locked or if it doesnt exist" - lockEquipmentById(id: ID!): Equipment! + lockEquipment(id: ID!): Equipment! "unlock Equipment, returns true if Bike does not exist" - unlockEquipmentById(id: ID!): Boolean! + unlockEquipment(id: ID!): Boolean! "update Equipment, returns updated equipment. CargoBike will be null, if cargoBikeId is not set. Pass null for cargoBikeIs to delete the relation" updateEquipment(equipment: EquipmentUpdateInput!): Equipment! + deleteEquipment(id: ID!): Boolean! createEquipmentType(equipmentType: EquipmentTypeCreateInput!): EquipmentType! lockEquipmentType(id: ID!): EquipmentType! unlockEquipmentType(id: ID!): Boolean! updateEquipmentType(equipmentType: EquipmentTypeUpdateInput!): EquipmentType! + deleteEquipmentType(id: ID!): Boolean! """ LENDINGSTATION creates new lendingStation and returns lendingStation with new ID """ createLendingStation(lendingStation: LendingStationCreateInput): LendingStation! - lockLendingStationById(id: ID!): LendingStation - unlockLendingStationById(id: ID!): Boolean! + lockLendingStation(id: ID!): LendingStation + unlockLendingStation(id: ID!): Boolean! "updates lendingStation of given ID with supplied fields and returns updated lendingStation" updateLendingStation(lendingStation: LendingStationUpdateInput!): LendingStation! + deleteLendingStation(id: ID!): Boolean! createTimeFrame(timeFrame: TimeFrameCreateInput!): TimeFrame! lockTimeFrame(id: ID!): TimeFrame! unlockTimeFrame(id: ID!): Boolean! updateTimeFrame(timeFrame: TimeFrameUpdateInput!): TimeFrame! + deleteTimeFrame(id: ID!): Boolean! """ BIKEEVENT """ @@ -971,11 +977,13 @@ type Mutation { lockBikeEventType(id: ID!): BikeEventType! unlockBikeEventType(id:ID!): Boolean! updateBikeEventType(bikeEventType: BikeEventTypeUpdateInput!): BikeEventType! + deleteBikeEventType(id: ID!): Boolean! "creates new BikeEvent" createBikeEvent(bikeEvent: BikeEventCreateInput!): BikeEvent! - lockBikeEventById(id: ID!): BikeEvent - unlockBikeEventById(id: ID!): Boolean! + lockBikeEvent(id: ID!): BikeEvent + unlockBikeEvent(id: ID!): Boolean! updateBikeEvent(bikeEvent: BikeEventUpdateInput!): BikeEvent + deleteBikeEvent(id: ID!): Boolean! """ PARTICIPANTS """ @@ -983,40 +991,49 @@ type Mutation { lockParticipant(id: ID!): Participant! unlockParticipant(id: ID!): Boolean updateParticipant(participant: ParticipantUpdateInput!): Participant! + deleteParticipant(id: ID!): Boolean! createWorkshopType(workshopType: WorkshopTypeCreateInput!): WorkshopType! lockWorkshopType(id: ID!): WorkshopType! unlockWorkshopType(id: ID!): Boolean! updateWorkshopType(workshopType: WorkshopTypeUpdateInput!): WorkshopType! + deleteWorkshopType(id: ID!): Boolean! createWorkshop(workshop: WorkshopCreateInput!): Workshop! lockWorkshop(id: ID!): Workshop! unlockWorkshop(id: ID!): Boolean! updateWorkshop(workshop: WorkshopUpdateInput!): Workshop! + deleteWorkshop(id: ID!): Boolean! "create new contactInfo" createContactInformation(contactInformation: ContactInformationCreateInput!): ContactInformation! lockContactInformation(id: ID!): ContactInformation! unlockContactInformation(id: ID!): Boolean! updateContactInformation(contactInformation: ContactInformationUpdateInput!): ContactInformation! + deleteContactInformation(id: ID!): Boolean! createPerson(person: PersonCreateInput!): Person! lockPerson(id: ID!): Person! unlockPerson(id: ID!): Person! updatePerson(person: PersonUpdateInput!): Person! + deletePerson(id: ID!): Boolean! + "create Engagement" + createEngagement(engagement: EngagementCreateInput): Engagement! lockEngagement(id: ID!): Engagement! unlockEngagement(id: ID!): Boolean! updateEngagement(engagement: EngagementUpdateInput!): Engagement! + deleteEngagement(id: ID!): Boolean! createEngagementType(engagementType: EngagementTypeCreateInput!): EngagementType! lockEngagementType(id: ID!): EngagementType! unlockEngagementType(id: ID!): Boolean! updateEngagementType(engagementType: EngagementTypeUpdateInput!): EngagementType! - "create Engagement" - createEngagement(engagement: EngagementCreateInput): Engagement! + deleteEngagementType(id: ID!): Boolean! createProvider(provider: ProviderCreateInput!): Provider! lockProvider(id: ID!): Provider! unlockProvider(id: ID!): Boolean! updateProvider(provider: ProviderUpdateInput!): Provider! + deleteProvider(id: ID!): Boolean! createOrganisation(organisation: OrganisationCreateInput!): Organisation! lockOrganisation(id: ID!): Organisation! unlockOrganisation(id: ID!): Boolean! updateOrganisation(organisation: OrganisationUpdateInput!): Organisation! + deleteOrganisation(id: ID!): Boolean! } `;