From adab4ea272ce73263ef485b3d9e978420ff30a8f Mon Sep 17 00:00:00 2001 From: leonnicolas Date: Thu, 10 Dec 2020 23:11:31 +0100 Subject: [PATCH 1/9] add city to address --- src/app.ts | 2 ++ src/index.ts | 6 +++++- src/schema/type-defs.ts | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/app.ts b/src/app.ts index 0b5f44c..b921180 100644 --- a/src/app.ts +++ b/src/app.ts @@ -137,6 +137,8 @@ export async function getApp (connOptions: ConnectionOptions) { await cargoBikeAPI.populateCopyConfig(); } catch (err) { console.error(err); + // exit so docker can restart the container and reattempt + process.exit(1); } const server = new ApolloServer({ diff --git a/src/index.ts b/src/index.ts index 7e183f0..2ee549c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,6 +23,10 @@ import { getApp, getConnectionOptions, userAPI } from './app'; app.listen(4000, async () => { await userAPI.createDefinedPermissions().catch( - err => console.log(err)); + err => { + console.log(err); + // exit so docker can restart the container and reattempt + process.exit(1); + }); }); })(); diff --git a/src/schema/type-defs.ts b/src/schema/type-defs.ts index a4e005c..02f6f0d 100644 --- a/src/schema/type-defs.ts +++ b/src/schema/type-defs.ts @@ -983,18 +983,21 @@ export default gql` street: String! number: String! zip: String! + city: String } input AddressCreateInput { street: String! number: String! zip: String! + city: String } input AddressUpdateInput { street: String number: String zip: String + city: String } type ActionLog { From e34e5446290382a2f5cc56030ffb820cec2832f5 Mon Sep 17 00:00:00 2001 From: leonnicolas Date: Fri, 11 Dec 2020 11:00:04 +0100 Subject: [PATCH 2/9] several bug fixes --- src/datasources/db/cargobikeAPI.ts | 7 ++++--- src/datasources/db/workshopAPI.ts | 8 ++++++++ src/resolvers/cargoBikeResolver.ts | 9 ++++++--- src/resolvers/workshopResolvers.ts | 7 +++++++ src/schema/type-defs.ts | 6 +++++- 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/datasources/db/cargobikeAPI.ts b/src/datasources/db/cargobikeAPI.ts index 0a1c804..8f1616f 100644 --- a/src/datasources/db/cargobikeAPI.ts +++ b/src/datasources/db/cargobikeAPI.ts @@ -237,12 +237,13 @@ export class CargoBikeAPI extends DataSource { } async createBikeEvent ({ bikeEvent }: { bikeEvent: any }) { - return (await this.connection.getRepository(BikeEvent) + const inserts = await this.connection.getRepository(BikeEvent) .createQueryBuilder('be') .insert() .values([bikeEvent]) .returning('*') - .execute()).generatedMaps[0]; + .execute(); + return await this.bikeEventById(inserts.identifiers[0].id); } async updateBikeEvent (bikeEvent: any, userId: number) { @@ -310,7 +311,7 @@ export class CargoBikeAPI extends DataSource { return (await this.connection.getRepository(BikeEventType) .createQueryBuilder('bet') .insert() - .values([{ name: bikeEventType }]) + .values([bikeEventType]) .returning('*') .execute())?.generatedMaps[0]; } diff --git a/src/datasources/db/workshopAPI.ts b/src/datasources/db/workshopAPI.ts index 9c0e510..b171010 100644 --- a/src/datasources/db/workshopAPI.ts +++ b/src/datasources/db/workshopAPI.ts @@ -134,6 +134,14 @@ export class WorkshopAPI extends DataSource { .getOne(); } + async workshopTypeByWorkshopId (id: number) { + return await this.connection.getRepository(Workshop) + .createQueryBuilder('w') + .relation(Workshop, 'workshopTypeId') + .of(id) + .loadOne(); + } + async workshopTypes (offset?: number, limit?: number) { return DBUtils.getAllEntity(this.connection, WorkshopType, 'wt', offset, limit); } diff --git a/src/resolvers/cargoBikeResolver.ts b/src/resolvers/cargoBikeResolver.ts index da64451..bbbc1e5 100644 --- a/src/resolvers/cargoBikeResolver.ts +++ b/src/resolvers/cargoBikeResolver.ts @@ -215,11 +215,14 @@ export default { }, related (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) { if (req.permissions.includes(Permission.ReadParticipant)) { - return dataSources.cargoBikeAPI.relatedByBikeEventId(parent.id); + return dataSources.cargoBikeAPI.relatedByBikeEventId(parent.workshopTypeId); } else { throw new PermissionError(); } }, + documents: (parent: any) => { + return (parent.documents) ? parent.documents : []; + }, isLockedByMe: (parent: any, __: any, { req }: { req: any }) => isLockedByMe(parent, { req }), isLocked: (parent: any, __: any, { req }: { req: any }) => isLocked(parent, { req }) }, @@ -368,9 +371,9 @@ export default { throw new PermissionError(); } }, - createBikeEventType: (_: any, { name }: { name: any }, { dataSources, req }: { dataSources: any, req: any }) => { + createBikeEventType: (_: any, { bikeEventType }: { bikeEventType: any }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteEventType)) { - return dataSources.cargoBikeAPI.createBikeEventType(name); + return dataSources.cargoBikeAPI.createBikeEventType(bikeEventType); } else { throw new PermissionError(); } diff --git a/src/resolvers/workshopResolvers.ts b/src/resolvers/workshopResolvers.ts index 82fbd33..c148251 100644 --- a/src/resolvers/workshopResolvers.ts +++ b/src/resolvers/workshopResolvers.ts @@ -75,6 +75,13 @@ export default { throw new PermissionError(); } }, + workshopType (parent: any, _: any, { dataSources, req }: { dataSources: any; req: any }) { + if (req.permissions.includes(Permission.ReadWorkshop)) { + return dataSources.workshopAPI.workshopTypeByWorkshopId(parent.id); + } else { + throw new PermissionError(); + } + }, isLockedByMe: (parent: any, __: any, { req }: { req: any }) => isLockedByMe(parent, { req }), isLocked: (parent: any, __: any, { req }: { req: any }) => isLocked(parent, { req }) }, diff --git a/src/schema/type-defs.ts b/src/schema/type-defs.ts index 02f6f0d..46a4678 100644 --- a/src/schema/type-defs.ts +++ b/src/schema/type-defs.ts @@ -723,6 +723,10 @@ export default gql` keepLock: Boolean } + input BikeEventTypeCreateInput { + name: String! + } + "(dt. Anbieter) bezieht sich auf die Beziehung einer Person oder Organisation zum Lastenrad" type Provider { id: ID! @@ -1126,7 +1130,7 @@ export default gql` """ BIKEEVENT """ - createBikeEventType(name: String!): BikeEventType! + createBikeEventType(bikeEventType: BikeEventTypeCreateInput!): BikeEventType! lockBikeEventType(id: ID!): BikeEventType! unlockBikeEventType(id:ID!): BikeEventType! updateBikeEventType(bikeEventType: BikeEventTypeUpdateInput!): BikeEventType! From dbb30369af5ab4eb0ac39a6069d89252c0b13d83 Mon Sep 17 00:00:00 2001 From: leonnicolas Date: Fri, 11 Dec 2020 11:26:33 +0100 Subject: [PATCH 3/9] lendingStation: add remarks --- src/model/LendingStation.ts | 11 +++++++++++ src/schema/type-defs.ts | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/src/model/LendingStation.ts b/src/model/LendingStation.ts index 9df1441..24e6c9d 100644 --- a/src/model/LendingStation.ts +++ b/src/model/LendingStation.ts @@ -40,6 +40,12 @@ export class LoanPeriod { }) generalRemark: string; + @Column({ + nullable: true, + type: 'text' + }) + holidays: string; + /** * validity for loanPeriods */ @@ -120,6 +126,11 @@ export class LendingStation implements Lockable { }) organisationId: number; + @Column({ + nullable: true + }) + remark: string; + @Column({ nullable: true, type: 'timestamp' diff --git a/src/schema/type-defs.ts b/src/schema/type-defs.ts index 46a4678..8c2a4a8 100644 --- a/src/schema/type-defs.ts +++ b/src/schema/type-defs.ts @@ -876,6 +876,7 @@ export default gql` "Total amount of cargoBikes currently assigned to the lending station" numCargoBikes: Int! organisation: Organisation + remark: String isLocked: Boolean! isLockedByMe: Boolean! "null if not locked by other user" @@ -893,6 +894,7 @@ export default gql` address: AddressCreateInput! loanPeriod: LoanPeriodInput organisationId: ID + remark: String } """ @@ -906,6 +908,7 @@ export default gql` address: AddressUpdateInput loanPeriod: LoanPeriodInput organisationId: ID + remark: String keepLock: Boolean } @@ -914,6 +917,7 @@ export default gql` """ type LoanPeriod { generalRemark: String + holidays: String mo: String tu: String we: String @@ -928,6 +932,7 @@ export default gql` """ input LoanPeriodInput { generalRemark: String + holidays: String mo: String tu: String we: String From 06e225096b6e8c4d9a2fdc31ecd47d6dc5254f96 Mon Sep 17 00:00:00 2001 From: leonnicolas Date: Fri, 11 Dec 2020 14:03:37 +0100 Subject: [PATCH 4/9] bugs and no $ in money --- src/model/Workshop.ts | 2 +- src/resolvers/cargoBikeResolver.ts | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/model/Workshop.ts b/src/model/Workshop.ts index 91e6b11..d44b415 100644 --- a/src/model/Workshop.ts +++ b/src/model/Workshop.ts @@ -60,7 +60,7 @@ export class Workshop implements Lockable { @JoinColumn({ name: 'trainer2Id' }) - trainer2: Participant; + trainer2Id: number; @Column({ nullable: true, diff --git a/src/resolvers/cargoBikeResolver.ts b/src/resolvers/cargoBikeResolver.ts index bbbc1e5..47894db 100644 --- a/src/resolvers/cargoBikeResolver.ts +++ b/src/resolvers/cargoBikeResolver.ts @@ -230,6 +230,11 @@ export default { isLockedByMe: (parent: any, __: any, { req }: { req: any }) => isLockedByMe(parent, { req }), isLocked: (parent: any, __: any, { req }: { req: any }) => isLocked(parent, { req }) }, + InsuranceData: { + projectAllowance: (parent: any): any => { + return (parent as string)?.replace(/€\$/, ''); + } + }, Mutation: { createCargoBike: (_: any, { cargoBike }: { cargoBike: any }, { dataSources, req }: { dataSources: any, req: any }) => { if (req.permissions.includes(Permission.WriteBike)) { From 0d44a98377da008482a86374dee16ceb5f13885e Mon Sep 17 00:00:00 2001 From: leonnicolas Date: Fri, 11 Dec 2020 14:46:40 +0100 Subject: [PATCH 5/9] bug in updateWorkshop --- src/datasources/db/workshopAPI.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/datasources/db/workshopAPI.ts b/src/datasources/db/workshopAPI.ts index b171010..de04f89 100644 --- a/src/datasources/db/workshopAPI.ts +++ b/src/datasources/db/workshopAPI.ts @@ -55,6 +55,8 @@ export class WorkshopAPI extends DataSource { async updateWorkshop (workshop: any, userId: number) { const keepLock = workshop.keepLock; delete workshop.keepLock; + const workshopTypeId = workshop.workshopTypeId; + delete workshop.workshopTypeId; await this.connection.transaction(async (entityManger: EntityManager) => { if (await LockUtils.isLocked(entityManger, Workshop, 'w', workshop.id, userId)) { throw new ResourceLockedError('Workshop', 'Attempting to update locked resource'); @@ -71,6 +73,11 @@ export class WorkshopAPI extends DataSource { throw new NotFoundError('Workshop', 'id', workshop.id); } }); + workshopTypeId && await entityManger.getRepository(Workshop) + .createQueryBuilder('w') + .relation(Workshop, 'workshopTypeId') + .of(workshop.id) + .set(workshopTypeId); }); !keepLock && await this.unlockWorkshop(workshop.id, userId); return await this.workshopById(workshop.id); From 4c0f0fd06dd9800fef58323bb86021eacf955013 Mon Sep 17 00:00:00 2001 From: leonnicolas Date: Fri, 11 Dec 2020 14:56:30 +0100 Subject: [PATCH 6/9] bug with projectAllowance --- src/resolvers/cargoBikeResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resolvers/cargoBikeResolver.ts b/src/resolvers/cargoBikeResolver.ts index 47894db..e6e067e 100644 --- a/src/resolvers/cargoBikeResolver.ts +++ b/src/resolvers/cargoBikeResolver.ts @@ -232,7 +232,7 @@ export default { }, InsuranceData: { projectAllowance: (parent: any): any => { - return (parent as string)?.replace(/€\$/, ''); + return (parent.projectAllowance as string)?.replace(/€\$/, ''); } }, Mutation: { From bf1c057763499c11e45252b89addaddd04f50667 Mon Sep 17 00:00:00 2001 From: leonnicolas Date: Fri, 11 Dec 2020 16:39:21 +0100 Subject: [PATCH 7/9] bug updateParticipant with workshopIds --- src/datasources/db/participantAPI.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/datasources/db/participantAPI.ts b/src/datasources/db/participantAPI.ts index 8efd5b8..ce01f09 100644 --- a/src/datasources/db/participantAPI.ts +++ b/src/datasources/db/participantAPI.ts @@ -230,7 +230,7 @@ export class ParticipantAPI extends DataSource { .createQueryBuilder('w') .relation(Participant, 'workshopIds') .of(participant.id) - .add(workshops); + .addAndRemove(workshops, await this.workshopsByParticipantId(participant.id)); }); !keepLock && await this.unlockParticipant(participant.id, userId); return await this.participantById(participant.id); From e4ab02107486c66145554e8c6bee95e536029100 Mon Sep 17 00:00:00 2001 From: leonnicolas Date: Wed, 16 Dec 2020 21:10:37 +0100 Subject: [PATCH 8/9] bug fix bikeEvent.related resolver fixed --- src/datasources/db/participantAPI.ts | 1 - src/resolvers/cargoBikeResolver.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/datasources/db/participantAPI.ts b/src/datasources/db/participantAPI.ts index ce01f09..bd16bcf 100644 --- a/src/datasources/db/participantAPI.ts +++ b/src/datasources/db/participantAPI.ts @@ -25,7 +25,6 @@ import { Participant } from '../../model/Participant'; import { EngagementType } from '../../model/EngagementType'; import { ActionLogger, DBUtils, genDateRange, LockUtils } from './utils'; import { UserInputError } from 'apollo-server-express'; -import { GraphQLError } from 'graphql'; import { ResourceLockedError } from '../../errors/ResourceLockedError'; export class ParticipantAPI extends DataSource { diff --git a/src/resolvers/cargoBikeResolver.ts b/src/resolvers/cargoBikeResolver.ts index e6e067e..0d56bb9 100644 --- a/src/resolvers/cargoBikeResolver.ts +++ b/src/resolvers/cargoBikeResolver.ts @@ -215,7 +215,7 @@ export default { }, related (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) { if (req.permissions.includes(Permission.ReadParticipant)) { - return dataSources.cargoBikeAPI.relatedByBikeEventId(parent.workshopTypeId); + return dataSources.cargoBikeAPI.relatedByBikeEventId(parent.id); } else { throw new PermissionError(); } From 1cfa73c52ddf69f0c7a580f1ce0e10a62a938225 Mon Sep 17 00:00:00 2001 From: leonnicolas Date: Thu, 17 Dec 2020 14:05:25 +0100 Subject: [PATCH 9/9] fix copy bike return -1 as id, so lending station will always be empty because no bike has id -1. --- README.md | 2 +- src/datasources/db/cargobikeAPI.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cd25810..e5030d5 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ The following environment variables can be used to configure the server: ```bash RPC_HOST=host:port NODE_ENV=develop/production -POSTGRES_CONNECTION_URL=postgres://username:password@host:port/database_name +DATABASE_URL=postgres://username:password@host:port/database_name ``` - __RPC_HOST__ is used for the connection with the [flotte-user-management server](https://github.com/fLotte-meets-HWR-DB/flotte-user-management). - __NODE_ENV__ will not check authentication if set to development diff --git a/src/datasources/db/cargobikeAPI.ts b/src/datasources/db/cargobikeAPI.ts index 8f1616f..41d9867 100644 --- a/src/datasources/db/cargobikeAPI.ts +++ b/src/datasources/db/cargobikeAPI.ts @@ -565,6 +565,7 @@ export class CargoBikeAPI extends DataSource { delete cargoBike[value.key]; } }); + cargoBike.id = -1; return cargoBike; }