src/*: hard delete implemented and code clean up

pull/14/head
leonnicolas 4 years ago
parent 660e775de2
commit f037d563b9
No known key found for this signature in database
GPG Key ID: 088D0743E2B65C07

@ -1,15 +1,17 @@
import { DataSource } from 'apollo-datasource'; import { DataSource } from 'apollo-datasource';
import { getConnection, Connection, ObjectType, EntityManager } from 'typeorm'; import { Connection, EntityManager, getConnection } from 'typeorm';
import { CargoBike, Lockable } from '../../model/CargoBike'; import { CargoBike } from '../../model/CargoBike';
import { GraphQLError } from 'graphql'; import { GraphQLError } from 'graphql';
import { BikeEvent } from '../../model/BikeEvent'; import { BikeEvent } from '../../model/BikeEvent';
import { Equipment } from '../../model/Equipment'; import { Equipment } from '../../model/Equipment';
import { Engagement } from '../../model/Engagement'; import { Engagement } from '../../model/Engagement';
import { Provider } from '../../model/Provider'; import { Provider } from '../../model/Provider';
import { TimeFrame } from '../../model/TimeFrame'; import { TimeFrame } from '../../model/TimeFrame';
import { ActionLogger, LockUtils } from './utils'; import { ActionLogger, deleteEntity, LockUtils } from './utils';
import { EquipmentType } from '../../model/EquipmentType'; import { EquipmentType } from '../../model/EquipmentType';
import { BikeEventType } from '../../model/BikeEventType'; 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 * 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 * Finds cargo bike by id, returns null if id was not found
* @param param0 id of bike * @param id
*/ */
async findCargoBikeById (id: number) { async findCargoBikeById (id: number) {
return await this.connection.getRepository(CargoBike) return await this.connection.getRepository(CargoBike)
.createQueryBuilder('cargobike') .createQueryBuilder('cb')
.select() .select()
.where('cargobike.id = :id', { id }) .where('id = :id', { id })
.getOne(); .getOne();
} }
@ -67,9 +69,18 @@ export class CargoBikeAPI extends DataSource {
.loadOne(); .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 * Updates CargoBike and return updated cargoBike
* @param param0 cargoBike to be updated * @param cargoBike
* @param userId
*/ */
async updateCargoBike (cargoBike: any, userId:number) { async updateCargoBike (cargoBike: any, userId:number) {
const keepLock = cargoBike?.keepLock; const keepLock = cargoBike?.keepLock;
@ -86,13 +97,13 @@ export class CargoBikeAPI extends DataSource {
} }
await ActionLogger.log(entityManager, CargoBike, 'cb', cargoBike, userId); await ActionLogger.log(entityManager, CargoBike, 'cb', cargoBike, userId);
await entityManager.getRepository(CargoBike) await entityManager.getRepository(CargoBike)
.createQueryBuilder('cargobike') .createQueryBuilder('cb')
.update() .update()
.set({ ...cargoBike }) .set({ ...cargoBike })
.where('id = :id', { id: cargoBike.id }) .where('id = :id', { id: cargoBike.id })
.execute(); .execute();
equipmentTypeIds && await entityManager.getRepository(CargoBike) equipmentTypeIds && await entityManager.getRepository(CargoBike)
.createQueryBuilder('cargobike') .createQueryBuilder('cb')
.relation(CargoBike, 'equipmentTypeIds') .relation(CargoBike, 'equipmentTypeIds')
.of(cargoBike.id) .of(cargoBike.id)
.addAndRemove(equipmentTypeIds, await this.equipmentTypeByCargoBikeId(cargoBike.id)); // TODO remove all existing relations .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); 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 * createCargoBike
* created CargoBike and returns created bike with new ID * created CargoBike and returns created bike with new ID
* @param param0 cargoBike to be created * @param param0 cargoBike to be created
*/ */
async createCargoBike ({ cargoBike }: { cargoBike: any }) { async createCargoBike ({ cargoBike }: { cargoBike: any }) {
let inserts: any; let inserts: any = {};
await this.connection.transaction(async (entityManager:any) => { await this.connection.transaction(async (entityManager:any) => {
inserts = await entityManager.getRepository(CargoBike) inserts = await entityManager.getRepository(CargoBike)
.createQueryBuilder('cargobike') .createQueryBuilder('cb')
.insert() .insert()
.values([cargoBike]) .values([cargoBike])
.returning('*') .returning('*')
.execute(); .execute();
cargoBike?.equipmentTypeIds && await entityManager.getRepository(CargoBike) cargoBike?.equipmentTypeIds && await entityManager.getRepository(CargoBike)
.createQueryBuilder('cargobike') .createQueryBuilder('cb')
.relation(CargoBike, 'equipmentTypeIds') .relation(CargoBike, 'equipmentTypeIds')
.of(inserts.identifiers[0].id) .of(inserts.identifiers[0].id)
.add(cargoBike.equipmentTypeIds); .add(cargoBike.equipmentTypeIds);
}); });
const newbike = inserts.generatedMaps[0]; inserts.generatedMaps[0] = inserts?.identifiers[0].id;
newbike.id = inserts.identifiers[0].id; return inserts?.generatedMaps[0];
return newbike;
} }
async createBikeEvent ({ bikeEvent }: { bikeEvent: any }) { async createBikeEvent ({ bikeEvent }: { bikeEvent: any }) {
@ -154,6 +178,14 @@ export class CargoBikeAPI extends DataSource {
return await this.bikeEventById(bikeEvent.id); 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) { async cargoBikeByEventId (id: number) {
return await this.connection.getRepository(BikeEvent) return await this.connection.getRepository(BikeEvent)
.createQueryBuilder('be') .createQueryBuilder('be')
@ -286,17 +318,6 @@ export class CargoBikeAPI extends DataSource {
.getOne(); .getOne();
} }
async checkId (target: ObjectType<Lockable>, 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 * Returns equipment of one cargoBike
* @param offset * @param offset
@ -312,14 +333,16 @@ export class CargoBikeAPI extends DataSource {
} }
async createEquipment ({ equipment }: { equipment: any }) { async createEquipment ({ equipment }: { equipment: any }) {
const inserts = await this.connection.getRepository(Equipment) return await this.connection.getRepository(Equipment)
.createQueryBuilder('equipment') .createQueryBuilder('equipment')
.insert() .insert()
.into(Equipment) .into(Equipment)
.values([equipment]) .values([equipment])
.returning('*') .returning('*')
.execute(); .execute()
return this.equipmentById(inserts.identifiers[0].id); .then(async inserts => {
return await this.equipmentById(inserts.identifiers[0].id);
});
} }
async cargoBikeByEquipmentId (id: number) { 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 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 * 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) { async updateEquipment (equipment: any, userId: number) {
const keepLock = equipment.keepLock; const keepLock = equipment.keepLock;
delete equipment.keepLock; delete equipment.keepLock;
// const cargoBikeId = equipment.cargoBikeId;
// delete equipment.cargoBikeId;
await this.connection.transaction(async (entityManager: EntityManager) => { await this.connection.transaction(async (entityManager: EntityManager) => {
if (await LockUtils.isLocked(entityManager, Equipment, 'equipment', equipment.id, userId)) { if (await LockUtils.isLocked(entityManager, Equipment, 'equipment', equipment.id, userId)) {
return new GraphQLError('Equipment is locked by other user'); return new GraphQLError('Equipment is locked by other user');
@ -359,21 +381,15 @@ export class CargoBikeAPI extends DataSource {
.set({ ...equipment }) .set({ ...equipment })
.where('id = :id', { id: equipment.id }) .where('id = :id', { id: equipment.id })
.execute(); .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); !keepLock && await LockUtils.unlockEntity(this.connection, Equipment, 'e', equipment.id, userId);
return this.equipmentById(equipment.id); 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) { async getEquipment (offset: number, limit: number) {
return await this.connection.getRepository(Equipment) return await this.connection.getRepository(Equipment)
.createQueryBuilder('equipment') .createQueryBuilder('equipment')
@ -385,14 +401,16 @@ export class CargoBikeAPI extends DataSource {
} }
async createEquipmentType (equipmentType: any) { async createEquipmentType (equipmentType: any) {
const inserts = await this.connection.getRepository(EquipmentType) return await this.connection.getRepository(EquipmentType)
.createQueryBuilder('equipment') .createQueryBuilder('equipment')
.insert() .insert()
.values([equipmentType]) .values([equipmentType])
.returning('*') .returning('*')
.execute(); .execute()
inserts.generatedMaps[0].id = inserts.identifiers[0].id; .then(inserts => {
return inserts.generatedMaps[0]; inserts.generatedMaps[0].id = inserts.identifiers[0].id;
return inserts.generatedMaps[0];
});
} }
async lockEquipmentType (id: number, userId : number) { async lockEquipmentType (id: number, userId : number) {
@ -422,6 +440,10 @@ export class CargoBikeAPI extends DataSource {
return await this.equipmentTypeById(equipmentType.id); 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) { async equipmentTypeById (id: number) {
return await this.connection.getRepository(EquipmentType) return await this.connection.getRepository(EquipmentType)
.createQueryBuilder('equipmentType') .createQueryBuilder('equipmentType')
@ -441,7 +463,7 @@ export class CargoBikeAPI extends DataSource {
async equipmentTypeByCargoBikeId (id: number) { async equipmentTypeByCargoBikeId (id: number) {
return await this.connection.getRepository(CargoBike) return await this.connection.getRepository(CargoBike)
.createQueryBuilder('cargobike') .createQueryBuilder('cb')
.relation(CargoBike, 'equipmentTypeIds') .relation(CargoBike, 'equipmentTypeIds')
.of(id) .of(id)
.loadMany(); .loadMany();

@ -2,7 +2,7 @@ import { DataSource } from 'apollo-datasource';
import { Connection, EntityManager, getConnection } from 'typeorm'; import { Connection, EntityManager, getConnection } from 'typeorm';
import { ContactInformation } from '../../model/ContactInformation'; import { ContactInformation } from '../../model/ContactInformation';
import { Person } from '../../model/Person'; import { Person } from '../../model/Person';
import { ActionLogger, LockUtils } from './utils'; import { ActionLogger, deleteEntity, LockUtils } from './utils';
import { GraphQLError } from 'graphql'; import { GraphQLError } from 'graphql';
import { LendingStation } from '../../model/LendingStation'; import { LendingStation } from '../../model/LendingStation';
@ -23,7 +23,7 @@ export class ContactInformationAPI extends DataSource {
async contactInformation (offset: number, limit: number) { async contactInformation (offset: number, limit: number) {
return await this.connection.getRepository(ContactInformation) return await this.connection.getRepository(ContactInformation)
.createQueryBuilder('contactinformation') .createQueryBuilder('ci')
.select() .select()
.offset(offset) .offset(offset)
.limit(limit) .limit(limit)
@ -76,6 +76,10 @@ export class ContactInformationAPI extends DataSource {
return this.personById(person.id); 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) { async persons (offset: number, limit: number) {
return await this.connection.getRepository(Person) return await this.connection.getRepository(Person)
.createQueryBuilder('person') .createQueryBuilder('person')
@ -155,12 +159,15 @@ export class ContactInformationAPI extends DataSource {
return await this.contactInformationById(contactInformation.id); 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) { async contactInformationByPersonId (id: number) {
const res = await this.connection.getRepository(ContactInformation) return await this.connection.getRepository(ContactInformation)
.createQueryBuilder('ci') .createQueryBuilder('ci')
.select() .select()
.where('ci."personId" = :id', { id: id }) .where('ci."personId" = :id', { id: id })
.getMany(); .getMany();
return res;
} }
} }

@ -1,11 +1,11 @@
import { DataSource } from 'apollo-datasource'; import { DataSource } from 'apollo-datasource';
import { ApolloError, UserInputError } from 'apollo-server-express'; import { UserInputError } from 'apollo-server-express';
import { GraphQLError } from 'graphql'; import { GraphQLError } from 'graphql';
import { Connection, EntityManager, getConnection, QueryFailedError } from 'typeorm'; import { Connection, EntityManager, getConnection } from 'typeorm';
import { CargoBike } from '../../model/CargoBike'; import { CargoBike } from '../../model/CargoBike';
import { LendingStation } from '../../model/LendingStation'; import { LendingStation } from '../../model/LendingStation';
import { TimeFrame } from '../../model/TimeFrame'; import { TimeFrame } from '../../model/TimeFrame';
import { ActionLogger, genDateRange, LockUtils } from './utils'; import { ActionLogger, deleteEntity, genDateRange, LockUtils } from './utils';
export class LendingStationAPI extends DataSource { export class LendingStationAPI extends DataSource {
connection : Connection connection : Connection
@ -71,7 +71,7 @@ export class LendingStationAPI extends DataSource {
async timeFramesByCargoBikeId (id: number) { async timeFramesByCargoBikeId (id: number) {
return await this.connection.getRepository(CargoBike) return await this.connection.getRepository(CargoBike)
.createQueryBuilder('cargobike') .createQueryBuilder('cb')
.relation(CargoBike, 'timeFrames') .relation(CargoBike, 'timeFrames')
.of(id) .of(id)
.loadMany(); .loadMany();
@ -126,36 +126,37 @@ export class LendingStationAPI extends DataSource {
.where('timeframes."lendingStationId" = :id', { id: id }) .where('timeframes."lendingStationId" = :id', { id: id })
.andWhere('timeframes."dateRange" && daterange(CURRENT_DATE,CURRENT_DATE,\'[]\')') .andWhere('timeframes."dateRange" && daterange(CURRENT_DATE,CURRENT_DATE,\'[]\')')
.printSql() .printSql()
.getMany(); // .catch(() => { return []; }); .getMany();
} }
/** /**
* creates new lendingStation and returns new lendingStation with its new id * creates new lendingStation and returns new lendingStation with its new id
* @param param0 new lendingStation * @param lendingStation
*/ */
async createLendingStation (lendingStation: any) { async createLendingStation (lendingStation: any) {
let inserts: any; let inserts: any;
await this.connection.transaction(async entityManager => { await this.connection.transaction(async entityManager => {
inserts = await entityManager.createQueryBuilder(LendingStation, 'lendingstation') inserts = await entityManager.createQueryBuilder(LendingStation, 'ls')
.insert() .insert()
.values([lendingStation]) .values([lendingStation])
.returning('*') .returning('*')
.execute(); .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 // 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 * updates lendingStation and return updated lendingStation
* @param param0 lendingStation to be updated * @param lendingStation
* @param userId
*/ */
async updateLendingStation (lendingStation: any, userId: number) { async updateLendingStation (lendingStation: any, userId: number) {
const keepLock = lendingStation.keepLock; const keepLock = lendingStation.keepLock;
delete lendingStation.keepLock; delete lendingStation.keepLock;
await this.connection.transaction(async (entityManager: EntityManager) => { await this.connection.transaction(async (entityManager: EntityManager) => {
if (await LockUtils.isLocked(entityManager, LendingStation, 'ls', lendingStation.id, userId)) { 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 ActionLogger.log(entityManager, LendingStation, 'ls', lendingStation, userId);
await entityManager.getRepository(LendingStation) await entityManager.getRepository(LendingStation)
@ -169,43 +170,39 @@ export class LendingStationAPI extends DataSource {
return await this.lendingStationById(lendingStation.id); 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) { async createTimeFrame (timeFrame: any) {
let inserts: any; return await this.connection.transaction(async (entityManager: EntityManager) => {
try { if (timeFrame.to === undefined) {
await this.connection.transaction(async (entityManager: EntityManager) => { timeFrame.to = '';
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 new ApolloError('Transaction could not be completed'); timeFrame.dateRange = '[' + timeFrame.from + ',' + timeFrame.to + ')';
} // checking for overlapping time frames
inserts.generatedMaps[0].id = inserts.identifiers[0].id; const overlapping = await entityManager.getRepository(TimeFrame)
return inserts.generatedMaps[0]; .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) { async lockTimeFrame (id: number, userId: number) {
@ -245,9 +242,13 @@ export class LendingStationAPI extends DataSource {
.set({ ...timeFrame }) .set({ ...timeFrame })
.where('id = :id', { id: timeFrame.id }) .where('id = :id', { id: timeFrame.id })
.execute() .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); !keepLock && await this.unlockTimeFrame(timeFrame.id, userId);
return this.timeFrameById(timeFrame.id); return this.timeFrameById(timeFrame.id);
} }
async deleteTimeFrame (id: number, userId: number) {
return await deleteEntity(this.connection, TimeFrame, 'tf', id, userId);
}
} }

@ -4,7 +4,7 @@ import { ContactInformation } from '../../model/ContactInformation';
import { Engagement } from '../../model/Engagement'; import { Engagement } from '../../model/Engagement';
import { Participant } from '../../model/Participant'; import { Participant } from '../../model/Participant';
import { EngagementType } from '../../model/EngagementType'; 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 { UserInputError } from 'apollo-server-express';
import { GraphQLError } from 'graphql'; import { GraphQLError } from 'graphql';
@ -177,6 +177,10 @@ export class ParticipantAPI extends DataSource {
return await this.participantById(participant.id); 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) { async createEngagement (engagement: any) {
let inserts: any; let inserts: any;
genDateRange(engagement); genDateRange(engagement);
@ -242,6 +246,10 @@ export class ParticipantAPI extends DataSource {
return await this.engagementById(engagement.id); 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) { async createEngagementType (engagementType: any) {
const inserts = await this.connection.getRepository(EngagementType) const inserts = await this.connection.getRepository(EngagementType)
.createQueryBuilder('et') .createQueryBuilder('et')
@ -279,4 +287,8 @@ export class ParticipantAPI extends DataSource {
!keepLock && await LockUtils.unlockEntity(this.connection, EngagementType, 'et', engagementType.id, userId); !keepLock && await LockUtils.unlockEntity(this.connection, EngagementType, 'et', engagementType.id, userId);
return await this.engagementTypeById(engagementType.id); return await this.engagementTypeById(engagementType.id);
} }
async deleteEngagementType (id: number, userId: number) {
return await deleteEntity(this.connection, EngagementType, 'et', id, userId);
}
} }

@ -5,7 +5,7 @@ import { Organisation } from '../../model/Organisation';
import { UserInputError } from 'apollo-server-express'; import { UserInputError } from 'apollo-server-express';
import { CargoBike } from '../../model/CargoBike'; import { CargoBike } from '../../model/CargoBike';
import { LendingStation } from '../../model/LendingStation'; import { LendingStation } from '../../model/LendingStation';
import { ActionLogger, LockUtils } from './utils'; import { ActionLogger, deleteEntity, LockUtils } from './utils';
import { GraphQLError } from 'graphql'; import { GraphQLError } from 'graphql';
export class ProviderAPI extends DataSource { export class ProviderAPI extends DataSource {
@ -160,6 +160,10 @@ export class ProviderAPI extends DataSource {
return await this.providerById(provider.id); 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) { async createOrganisation (organisation: any) {
let inserts: any = null; let inserts: any = null;
await this.connection.transaction(async (entityManager: EntityManager) => { 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); !keepLock && await LockUtils.unlockEntity(this.connection, Organisation, 'o', organisation.id, userId);
return this.organisationById(organisation.id); return this.organisationById(organisation.id);
} }
async deleteOrganisation (id: number, userId: number) {
return await deleteEntity(this.connection, Organisation, 'o', id, userId);
}
} }

@ -2,6 +2,7 @@ import { Connection, EntityManager, ObjectType } from 'typeorm';
import { Lockable } from '../../model/CargoBike'; import { Lockable } from '../../model/CargoBike';
import { GraphQLError } from 'graphql'; import { GraphQLError } from 'graphql';
import { ActionLog, Actions } from '../../model/ActionLog'; import { ActionLog, Actions } from '../../model/ActionLog';
import { UserInputError } from 'apollo-server-express';
export function genDateRange (struct: any) { export function genDateRange (struct: any) {
if (struct.to === undefined) { 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<Lockable>, alias: string, id: number, userId: number): Promise<Boolean> {
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 { export class LockUtils {
static getToken (req: any) : string { static getToken (req: any) : string {
return req.headers.authorization?.replace('Bearer ', ''); return req.headers.authorization?.replace('Bearer ', '');
} }
static async findById (connection: Connection, target: ObjectType<Lockable>, alias: string, id: number, userId: number): Promise<Lockable> { static async findById (connection: Connection, target: ObjectType<Lockable>, alias: string, id: number): Promise<Lockable> {
return await connection.getRepository(target) return await connection.getRepository(target)
.createQueryBuilder(alias) .createQueryBuilder(alias)
.select() .select()
@ -66,7 +81,7 @@ export class LockUtils {
}) })
.where('id = :id', { id: id }) .where('id = :id', { id: id })
.execute(); .execute();
return await this.findById(connection, target, alias, id, userId); return await this.findById(connection, target, alias, id);
} else { } else {
// lock was set // lock was set
throw new GraphQLError('Entry locked by other user'); throw new GraphQLError('Entry locked by other user');
@ -113,8 +128,7 @@ export class LockUtils {
* @param target * @param target
* @param alias * @param alias
* @param id * @param id
* @param req * @param userId
* @param dataSources
*/ */
static async isLocked (connection: EntityManager, target: ObjectType<Lockable>, alias: string, id: number, userId: number) { static async isLocked (connection: EntityManager, target: ObjectType<Lockable>, alias: string, id: number, userId: number) {
const lock = await connection.getRepository(target) const lock = await connection.getRepository(target)
@ -134,29 +148,14 @@ export class LockUtils {
// eslint-disable-next-line eqeqeq // eslint-disable-next-line eqeqeq
} else return lock?.lockedBy != userId; } 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<Lockable>, 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 { export class ActionLogger {
private static buildSelect (updates: any, alias: string) : string[] { 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 // 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[] = []; const ret :string[] = [];
Object.keys(updates).forEach(value => { Object.keys(updates).forEach(value => {
if (typeof updates[value] === 'object' && !Array.isArray(updates[value])) { if (typeof updates[value] === 'object' && !Array.isArray(updates[value])) {
@ -176,7 +175,7 @@ export class ActionLogger {
.where('id = :id', { id: updates.id }) .where('id = :id', { id: updates.id })
.getRawOne().then(value => { .getRawOne().then(value => {
if (value === undefined) { if (value === undefined) {
throw new GraphQLError('Id not found'); throw new UserInputError('Id not found');
} }
return value; return value;
}); // use getRawOne to also get ids of related entities }); // use getRawOne to also get ids of related entities

@ -2,7 +2,7 @@ import { DataSource } from 'apollo-datasource';
import { Connection, EntityManager, getConnection } from 'typeorm'; import { Connection, EntityManager, getConnection } from 'typeorm';
import { WorkshopType } from '../../model/WorkshopType'; import { WorkshopType } from '../../model/WorkshopType';
import { Workshop } from '../../model/Workshop'; import { Workshop } from '../../model/Workshop';
import { ActionLogger, LockUtils } from './utils'; import { ActionLogger, deleteEntity, LockUtils } from './utils';
import { UserInputError } from 'apollo-server-express'; import { UserInputError } from 'apollo-server-express';
import { GraphQLError } from 'graphql'; import { GraphQLError } from 'graphql';
@ -52,6 +52,10 @@ export class WorkshopAPI extends DataSource {
return await this.workshopById(workshop.id); 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) { async createWorkshopType (workshopType: any) {
const inserts = await this.connection.getRepository(WorkshopType) const inserts = await this.connection.getRepository(WorkshopType)
.createQueryBuilder('wt') .createQueryBuilder('wt')
@ -90,6 +94,10 @@ export class WorkshopAPI extends DataSource {
return await this.workshopTypeById(workshopType.id); 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) { async workshopTypeById (id: number) {
return await this.connection.getRepository(WorkshopType) return await this.connection.getRepository(WorkshopType)
.createQueryBuilder('wt') .createQueryBuilder('wt')

@ -27,7 +27,22 @@ export enum Permission {
WriteEquipmentType = 'EQUIPMENT_TYPE_WRITE', WriteEquipmentType = 'EQUIPMENT_TYPE_WRITE',
WriteEngagementType = 'ENGAGEMENT_TYPE_WRITE', WriteEngagementType = 'ENGAGEMENT_TYPE_WRITE',
ReadActionLog = 'ACTION_LOG_READ', 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 // Permissions where the creation will be requested on startup
@ -143,5 +158,65 @@ export const requiredPermissions = [
{ {
name: Permission.ReadActionLogAll, name: Permission.ReadActionLogAll,
description: 'Allows to read action log of other users' 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'
} }
]; ];

@ -1,5 +1,15 @@
/* eslint no-unused-vars: "off" */ /* 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 { Provider } from './Provider';
import { Participant } from './Participant'; import { Participant } from './Participant';
import { InsuranceData } from './InsuranceData'; import { InsuranceData } from './InsuranceData';
@ -145,6 +155,9 @@ export class CargoBike implements Lockable {
@PrimaryGeneratedColumn() @PrimaryGeneratedColumn()
id: number; id: number;
@DeleteDateColumn()
deleteDate: Date;
@Column({ @Column({
type: 'enum', type: 'enum',
enum: Group enum: Group

@ -187,14 +187,14 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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)) { if (req.permissions.includes(Permission.WriteBike)) {
return dataSources.cargoBikeAPI.lockCargoBike(id, req.userId); return dataSources.cargoBikeAPI.lockCargoBike(id, req.userId);
} else { } else {
return new GraphQLError('Insufficient Permissions'); 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)) { if (req.permissions.includes(Permission.WriteBike)) {
return dataSources.cargoBikeAPI.unlockCargoBike(id, req.userId); return dataSources.cargoBikeAPI.unlockCargoBike(id, req.userId);
} else { } else {
@ -208,6 +208,13 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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 }) => { createBikeEvent: (_: any, { bikeEvent }: { bikeEvent: any }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteBikeEvent)) { if (req.permissions.includes(Permission.WriteBikeEvent)) {
return dataSources.cargoBikeAPI.createBikeEvent({ bikeEvent }); return dataSources.cargoBikeAPI.createBikeEvent({ bikeEvent });
@ -215,14 +222,14 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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)) { if (req.permissions.includes(Permission.WriteBikeEvent)) {
return dataSources.cargoBikeAPI.lockBikeEvent(id, req.userId); return dataSources.cargoBikeAPI.lockBikeEvent(id, req.userId);
} else { } else {
return new GraphQLError('Insufficient Permissions'); 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)) { if (req.permissions.includes(Permission.WriteBikeEvent)) {
return dataSources.cargoBikeAPI.unlockBikeEvent(id, req.userId); return dataSources.cargoBikeAPI.unlockBikeEvent(id, req.userId);
} else { } else {
@ -236,6 +243,13 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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 }) => { createEquipment: (_: any, { equipment }: { equipment: any }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteEquipment)) { if (req.permissions.includes(Permission.WriteEquipment)) {
return dataSources.cargoBikeAPI.createEquipment({ equipment }); return dataSources.cargoBikeAPI.createEquipment({ equipment });
@ -243,14 +257,14 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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)) { if (req.permissions.includes(Permission.WriteEquipment)) {
return dataSources.cargoBikeAPI.lockEquipment(id, req.userId); return dataSources.cargoBikeAPI.lockEquipment(id, req.userId);
} else { } else {
return new GraphQLError('Insufficient Permissions'); 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)) { if (req.permissions.includes(Permission.WriteEquipment)) {
return dataSources.cargoBikeAPI.unlockEquipment(id, req.userId); return dataSources.cargoBikeAPI.unlockEquipment(id, req.userId);
} else { } else {
@ -264,6 +278,13 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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 }) => { createEquipmentType: (_: any, { equipmentType }: { equipmentType: any }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteEquipmentType)) { if (req.permissions.includes(Permission.WriteEquipmentType)) {
return dataSources.cargoBikeAPI.createEquipmentType(equipmentType); return dataSources.cargoBikeAPI.createEquipmentType(equipmentType);
@ -292,6 +313,13 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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 }) => { createBikeEventType: (_: any, { name }: { name: any }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteEventType)) { if (req.permissions.includes(Permission.WriteEventType)) {
return dataSources.cargoBikeAPI.createBikeEventType(name); return dataSources.cargoBikeAPI.createBikeEventType(name);
@ -319,6 +347,13 @@ export default {
} else { } else {
return new GraphQLError('Insufficient Permissions'); 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');
}
} }
} }
}; };

@ -55,13 +55,6 @@ export default {
isLocked: (parent: any, __: any, { dataSources, req }: { dataSources: any; req: any }) => isLocked(parent, { dataSources, req }) isLocked: (parent: any, __: any, { dataSources, req }: { dataSources: any; req: any }) => isLocked(parent, { dataSources, req })
}, },
Mutation: { 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 }) => { createPerson: (_: any, { person }: { person: any }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WritePerson)) { if (req.permissions.includes(Permission.WritePerson)) {
return dataSources.contactInformationAPI.createPerson(person); return dataSources.contactInformationAPI.createPerson(person);
@ -90,6 +83,20 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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 }) => { lockContactInformation: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WritePerson)) { if (req.permissions.includes(Permission.WritePerson)) {
return dataSources.contactInformationAPI.lockContactInformation(id, req.userId); return dataSources.contactInformationAPI.lockContactInformation(id, req.userId);
@ -110,6 +117,13 @@ export default {
} else { } else {
return new GraphQLError('Insufficient Permissions'); 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');
}
} }
} }
}; };

@ -80,15 +80,15 @@ export default {
isLocked: (parent: any, __: any, { dataSources, req }: { dataSources: any; req: any }) => isLocked(parent, { dataSources, req }) isLocked: (parent: any, __: any, { dataSources, req }: { dataSources: any; req: any }) => isLocked(parent, { dataSources, req })
}, },
LoanPeriod: { LoanPeriod: {
loanTimes (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) { loanTimes (parent: any) {
return parent.loanTimes ? parent.loanTimes : []; return parent.loanTimes ? parent.loanTimes : [];
} }
}, },
TimeFrame: { TimeFrame: {
from (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) { from (parent: any) {
return (parent.dateRange as string).split(',')[0].replace('[', ''); 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(')', ''); const str = (parent.dateRange as string).split(',')[1].replace(')', '');
return (str.length > 0) ? str : null; return (str.length > 0) ? str : null;
}, },
@ -116,14 +116,14 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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)) { if (req.permissions.includes(Permission.WriteLendingStation)) {
return dataSources.lendingStationAPI.lockLendingStationById(id, req.userId); return dataSources.lendingStationAPI.lockLendingStationById(id, req.userId);
} else { } else {
return new GraphQLError('Insufficient Permissions'); 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)) { if (req.permissions.includes(Permission.WriteLendingStation)) {
return dataSources.lendingStationAPI.unlockLendingStationById(id, req.userId); return dataSources.lendingStationAPI.unlockLendingStationById(id, req.userId);
} else { } else {
@ -137,6 +137,13 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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 }) => { createTimeFrame: (_: any, { timeFrame }:{ timeFrame: LendingStation }, { dataSources, req }:{dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteTimeFrame)) { if (req.permissions.includes(Permission.WriteTimeFrame)) {
return dataSources.lendingStationAPI.createTimeFrame(timeFrame); return dataSources.lendingStationAPI.createTimeFrame(timeFrame);
@ -164,6 +171,13 @@ export default {
} else { } else {
return new GraphQLError('Insufficient Permissions'); 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');
}
} }
} }
}; };

@ -86,10 +86,10 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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('[', ''); 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(')', ''); const str = (parent.dateRange as string).split(',')[1].replace(')', '');
return (str.length > 0) ? str : null; return (str.length > 0) ? str : null;
}, },
@ -105,7 +105,7 @@ export default {
}, },
lockParticipant: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => { lockParticipant: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteParticipant)) { if (req.permissions.includes(Permission.WriteParticipant)) {
return dataSources.participantAPI.lockeParticipant(id, req.userId); return dataSources.participantAPI.lockParticipant(id, req.userId);
} else { } else {
return new GraphQLError('Insufficient Permissions'); return new GraphQLError('Insufficient Permissions');
} }
@ -124,6 +124,13 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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 }) => { createEngagement: (_: any, { engagement }: { engagement: any }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteEngagement)) { if (req.permissions.includes(Permission.WriteEngagement)) {
return dataSources.participantAPI.createEngagement(engagement); return dataSources.participantAPI.createEngagement(engagement);
@ -140,7 +147,7 @@ export default {
}, },
unlockEngagement: (_: any, { id }: {id: number }, { dataSources, req }: { dataSources: any, req: any }) => { unlockEngagement: (_: any, { id }: {id: number }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteEngagement)) { if (req.permissions.includes(Permission.WriteEngagement)) {
return dataSources.participantAPI.unlockngagement(id, req.userId); return dataSources.participantAPI.unlockEngagement(id, req.userId);
} else { } else {
return new GraphQLError('Insufficient Permissions'); return new GraphQLError('Insufficient Permissions');
} }
@ -152,6 +159,20 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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 }) => { lockEngagementType: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteEngagementType)) { if (req.permissions.includes(Permission.WriteEngagementType)) {
return dataSources.participantAPI.lockEngagementType(id, req.userId); return dataSources.participantAPI.lockEngagementType(id, req.userId);
@ -161,7 +182,7 @@ export default {
}, },
unlockEngagementType: (_: any, { id }: {id: number }, { dataSources, req }: { dataSources: any, req: any }) => { unlockEngagementType: (_: any, { id }: {id: number }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteEngagementType)) { if (req.permissions.includes(Permission.WriteEngagementType)) {
return dataSources.participantAPI.unlockngagementType(id, req.userId); return dataSources.participantAPI.unlockEngagementType(id, req.userId);
} else { } else {
return new GraphQLError('Insufficient Permissions'); return new GraphQLError('Insufficient Permissions');
} }
@ -173,9 +194,9 @@ export default {
return new GraphQLError('Insufficient Permissions'); return new GraphQLError('Insufficient Permissions');
} }
}, },
createEngagementType: (_: any, { engagementType }: { engagementType: any }, { dataSources, req }: { dataSources: any, req: any }) => { deleteEngagementType: (_: any, { id }: { id: number }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteEngagementType)) { if (req.permissions.includes(Permission.DeleteEngagementType)) {
return dataSources.participantAPI.createEngagementType(engagementType); return dataSources.participantAPI.deleteEngagementType(id, req.userId);
} else { } else {
return new GraphQLError('Insufficient Permissions'); return new GraphQLError('Insufficient Permissions');
} }

@ -110,6 +110,13 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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 }) => { createOrganisation: (_: any, { organisation }: { organisation: any }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteOrganisation)) { if (req.permissions.includes(Permission.WriteOrganisation)) {
return dataSources.providerAPI.createOrganisation(organisation); return dataSources.providerAPI.createOrganisation(organisation);
@ -137,6 +144,13 @@ export default {
} else { } else {
return new GraphQLError('Insufficient Permissions'); 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');
}
} }
} }
}; };

@ -82,6 +82,13 @@ export default {
return new GraphQLError('Insufficient Permissions'); 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 }) => { createWorkshopType: (_: any, { workshopType }: { workshopType: any }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteWorkshopType)) { if (req.permissions.includes(Permission.WriteWorkshopType)) {
return dataSources.workshopAPI.createWorkshopType(workshopType); return dataSources.workshopAPI.createWorkshopType(workshopType);
@ -109,6 +116,13 @@ export default {
} else { } else {
return new GraphQLError('Insufficient Permissions'); 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');
}
} }
} }
}; };

@ -926,44 +926,50 @@ type Query {
type Mutation { type Mutation {
""" """
CargoBikes CARGO BIKE
creates new cargoBike and returns cargobike with new ID creates new cargoBike and returns cargobike with new ID
""" """
createCargoBike(cargoBike: CargoBikeCreateInput!): CargoBike! createCargoBike(cargoBike: CargoBikeCreateInput!): CargoBike!
"lock cargoBike returns bike if bike is not locked and locks bike or Error if bike cannot be locked" "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" "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" "updates cargoBike of given ID with supplied fields and returns updated cargoBike"
updateCargoBike(cargoBike: CargoBikeUpdateInput!): CargoBike! updateCargoBike(cargoBike: CargoBikeUpdateInput!): CargoBike!
"true on success"
deleteCargoBike(id: ID!): Boolean!
""" """
EQUIPMENT EQUIPMENT
creates new peace of unique Equipment creates new peace of unique Equipment
""" """
createEquipment(equipment: EquipmentCreateInput!): Equipment! createEquipment(equipment: EquipmentCreateInput!): Equipment!
"lock equipment returns true if bike is not locked or if it doesnt exist" "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" "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" "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! updateEquipment(equipment: EquipmentUpdateInput!): Equipment!
deleteEquipment(id: ID!): Boolean!
createEquipmentType(equipmentType: EquipmentTypeCreateInput!): EquipmentType! createEquipmentType(equipmentType: EquipmentTypeCreateInput!): EquipmentType!
lockEquipmentType(id: ID!): EquipmentType! lockEquipmentType(id: ID!): EquipmentType!
unlockEquipmentType(id: ID!): Boolean! unlockEquipmentType(id: ID!): Boolean!
updateEquipmentType(equipmentType: EquipmentTypeUpdateInput!): EquipmentType! updateEquipmentType(equipmentType: EquipmentTypeUpdateInput!): EquipmentType!
deleteEquipmentType(id: ID!): Boolean!
""" """
LENDINGSTATION LENDINGSTATION
creates new lendingStation and returns lendingStation with new ID creates new lendingStation and returns lendingStation with new ID
""" """
createLendingStation(lendingStation: LendingStationCreateInput): LendingStation! createLendingStation(lendingStation: LendingStationCreateInput): LendingStation!
lockLendingStationById(id: ID!): LendingStation lockLendingStation(id: ID!): LendingStation
unlockLendingStationById(id: ID!): Boolean! unlockLendingStation(id: ID!): Boolean!
"updates lendingStation of given ID with supplied fields and returns updated lendingStation" "updates lendingStation of given ID with supplied fields and returns updated lendingStation"
updateLendingStation(lendingStation: LendingStationUpdateInput!): LendingStation! updateLendingStation(lendingStation: LendingStationUpdateInput!): LendingStation!
deleteLendingStation(id: ID!): Boolean!
createTimeFrame(timeFrame: TimeFrameCreateInput!): TimeFrame! createTimeFrame(timeFrame: TimeFrameCreateInput!): TimeFrame!
lockTimeFrame(id: ID!): TimeFrame! lockTimeFrame(id: ID!): TimeFrame!
unlockTimeFrame(id: ID!): Boolean! unlockTimeFrame(id: ID!): Boolean!
updateTimeFrame(timeFrame: TimeFrameUpdateInput!): TimeFrame! updateTimeFrame(timeFrame: TimeFrameUpdateInput!): TimeFrame!
deleteTimeFrame(id: ID!): Boolean!
""" """
BIKEEVENT BIKEEVENT
""" """
@ -971,11 +977,13 @@ type Mutation {
lockBikeEventType(id: ID!): BikeEventType! lockBikeEventType(id: ID!): BikeEventType!
unlockBikeEventType(id:ID!): Boolean! unlockBikeEventType(id:ID!): Boolean!
updateBikeEventType(bikeEventType: BikeEventTypeUpdateInput!): BikeEventType! updateBikeEventType(bikeEventType: BikeEventTypeUpdateInput!): BikeEventType!
deleteBikeEventType(id: ID!): Boolean!
"creates new BikeEvent" "creates new BikeEvent"
createBikeEvent(bikeEvent: BikeEventCreateInput!): BikeEvent! createBikeEvent(bikeEvent: BikeEventCreateInput!): BikeEvent!
lockBikeEventById(id: ID!): BikeEvent lockBikeEvent(id: ID!): BikeEvent
unlockBikeEventById(id: ID!): Boolean! unlockBikeEvent(id: ID!): Boolean!
updateBikeEvent(bikeEvent: BikeEventUpdateInput!): BikeEvent updateBikeEvent(bikeEvent: BikeEventUpdateInput!): BikeEvent
deleteBikeEvent(id: ID!): Boolean!
""" """
PARTICIPANTS PARTICIPANTS
""" """
@ -983,40 +991,49 @@ type Mutation {
lockParticipant(id: ID!): Participant! lockParticipant(id: ID!): Participant!
unlockParticipant(id: ID!): Boolean unlockParticipant(id: ID!): Boolean
updateParticipant(participant: ParticipantUpdateInput!): Participant! updateParticipant(participant: ParticipantUpdateInput!): Participant!
deleteParticipant(id: ID!): Boolean!
createWorkshopType(workshopType: WorkshopTypeCreateInput!): WorkshopType! createWorkshopType(workshopType: WorkshopTypeCreateInput!): WorkshopType!
lockWorkshopType(id: ID!): WorkshopType! lockWorkshopType(id: ID!): WorkshopType!
unlockWorkshopType(id: ID!): Boolean! unlockWorkshopType(id: ID!): Boolean!
updateWorkshopType(workshopType: WorkshopTypeUpdateInput!): WorkshopType! updateWorkshopType(workshopType: WorkshopTypeUpdateInput!): WorkshopType!
deleteWorkshopType(id: ID!): Boolean!
createWorkshop(workshop: WorkshopCreateInput!): Workshop! createWorkshop(workshop: WorkshopCreateInput!): Workshop!
lockWorkshop(id: ID!): Workshop! lockWorkshop(id: ID!): Workshop!
unlockWorkshop(id: ID!): Boolean! unlockWorkshop(id: ID!): Boolean!
updateWorkshop(workshop: WorkshopUpdateInput!): Workshop! updateWorkshop(workshop: WorkshopUpdateInput!): Workshop!
deleteWorkshop(id: ID!): Boolean!
"create new contactInfo" "create new contactInfo"
createContactInformation(contactInformation: ContactInformationCreateInput!): ContactInformation! createContactInformation(contactInformation: ContactInformationCreateInput!): ContactInformation!
lockContactInformation(id: ID!): ContactInformation! lockContactInformation(id: ID!): ContactInformation!
unlockContactInformation(id: ID!): Boolean! unlockContactInformation(id: ID!): Boolean!
updateContactInformation(contactInformation: ContactInformationUpdateInput!): ContactInformation! updateContactInformation(contactInformation: ContactInformationUpdateInput!): ContactInformation!
deleteContactInformation(id: ID!): Boolean!
createPerson(person: PersonCreateInput!): Person! createPerson(person: PersonCreateInput!): Person!
lockPerson(id: ID!): Person! lockPerson(id: ID!): Person!
unlockPerson(id: ID!): Person! unlockPerson(id: ID!): Person!
updatePerson(person: PersonUpdateInput!): Person! updatePerson(person: PersonUpdateInput!): Person!
deletePerson(id: ID!): Boolean!
"create Engagement"
createEngagement(engagement: EngagementCreateInput): Engagement!
lockEngagement(id: ID!): Engagement! lockEngagement(id: ID!): Engagement!
unlockEngagement(id: ID!): Boolean! unlockEngagement(id: ID!): Boolean!
updateEngagement(engagement: EngagementUpdateInput!): Engagement! updateEngagement(engagement: EngagementUpdateInput!): Engagement!
deleteEngagement(id: ID!): Boolean!
createEngagementType(engagementType: EngagementTypeCreateInput!): EngagementType! createEngagementType(engagementType: EngagementTypeCreateInput!): EngagementType!
lockEngagementType(id: ID!): EngagementType! lockEngagementType(id: ID!): EngagementType!
unlockEngagementType(id: ID!): Boolean! unlockEngagementType(id: ID!): Boolean!
updateEngagementType(engagementType: EngagementTypeUpdateInput!): EngagementType! updateEngagementType(engagementType: EngagementTypeUpdateInput!): EngagementType!
"create Engagement" deleteEngagementType(id: ID!): Boolean!
createEngagement(engagement: EngagementCreateInput): Engagement!
createProvider(provider: ProviderCreateInput!): Provider! createProvider(provider: ProviderCreateInput!): Provider!
lockProvider(id: ID!): Provider! lockProvider(id: ID!): Provider!
unlockProvider(id: ID!): Boolean! unlockProvider(id: ID!): Boolean!
updateProvider(provider: ProviderUpdateInput!): Provider! updateProvider(provider: ProviderUpdateInput!): Provider!
deleteProvider(id: ID!): Boolean!
createOrganisation(organisation: OrganisationCreateInput!): Organisation! createOrganisation(organisation: OrganisationCreateInput!): Organisation!
lockOrganisation(id: ID!): Organisation! lockOrganisation(id: ID!): Organisation!
unlockOrganisation(id: ID!): Boolean! unlockOrganisation(id: ID!): Boolean!
updateOrganisation(organisation: OrganisationUpdateInput!): Organisation! updateOrganisation(organisation: OrganisationUpdateInput!): Organisation!
deleteOrganisation(id: ID!): Boolean!
} }
`; `;

Loading…
Cancel
Save