From 7ddafdd70d57b0ab7eac485300c5fef26f1e9f16 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 26 Sep 2022 15:24:18 +0200 Subject: [PATCH 01/14] Add updated_at to contributions table. --- .../Contribution.ts | 92 +++++++++++++++++++ database/entity/Contribution.ts | 2 +- .../0051-add_updated_at_to_contributions.ts | 10 ++ 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 database/entity/0051-add_updated_at_to_contributions/Contribution.ts create mode 100644 database/migrations/0051-add_updated_at_to_contributions.ts diff --git a/database/entity/0051-add_updated_at_to_contributions/Contribution.ts b/database/entity/0051-add_updated_at_to_contributions/Contribution.ts new file mode 100644 index 000000000..388216047 --- /dev/null +++ b/database/entity/0051-add_updated_at_to_contributions/Contribution.ts @@ -0,0 +1,92 @@ +import Decimal from 'decimal.js-light' +import { + BaseEntity, + Column, + Entity, + PrimaryGeneratedColumn, + DeleteDateColumn, + JoinColumn, + ManyToOne, + OneToMany, +} from 'typeorm' +import { DecimalTransformer } from '../../src/typeorm/DecimalTransformer' +import { User } from '../User' +import { ContributionMessage } from '../ContributionMessage' + +@Entity('contributions') +export class Contribution extends BaseEntity { + @PrimaryGeneratedColumn('increment', { unsigned: true }) + id: number + + @Column({ unsigned: true, nullable: false, name: 'user_id' }) + userId: number + + @ManyToOne(() => User, (user) => user.contributions) + @JoinColumn({ name: 'user_id' }) + user: User + + @Column({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP', name: 'created_at' }) + createdAt: Date + + @Column({ type: 'datetime', nullable: false, name: 'contribution_date' }) + contributionDate: Date + + @Column({ length: 255, nullable: false, collation: 'utf8mb4_unicode_ci' }) + memo: string + + @Column({ + type: 'decimal', + precision: 40, + scale: 20, + nullable: false, + transformer: DecimalTransformer, + }) + amount: Decimal + + @Column({ unsigned: true, nullable: true, name: 'moderator_id' }) + moderatorId: number + + @Column({ unsigned: true, nullable: true, name: 'contribution_link_id' }) + contributionLinkId: number + + @Column({ unsigned: true, nullable: true, name: 'confirmed_by' }) + confirmedBy: number + + @Column({ nullable: true, name: 'confirmed_at' }) + confirmedAt: Date + + @Column({ unsigned: true, nullable: true, name: 'denied_by' }) + deniedBy: number + + @Column({ nullable: true, name: 'denied_at' }) + deniedAt: Date + + @Column({ + name: 'contribution_type', + length: 12, + nullable: false, + collation: 'utf8mb4_unicode_ci', + }) + contributionType: string + + @Column({ + name: 'contribution_status', + length: 12, + nullable: false, + collation: 'utf8mb4_unicode_ci', + }) + contributionStatus: string + + @Column({ unsigned: true, nullable: true, name: 'transaction_id' }) + transactionId: number + + @DeleteDateColumn({ name: 'deleted_at' }) + deletedAt: Date | null + + @OneToMany(() => ContributionMessage, (message) => message.contribution) + @JoinColumn({ name: 'contribution_id' }) + messages?: ContributionMessage[] + + @Column({ nullable: true, name: 'updated_at' }) + updatedAt: Date +} diff --git a/database/entity/Contribution.ts b/database/entity/Contribution.ts index f6530f00b..451398c01 100644 --- a/database/entity/Contribution.ts +++ b/database/entity/Contribution.ts @@ -1 +1 @@ -export { Contribution } from './0047-messages_tables/Contribution' +export { Contribution } from './0051-add_updated_at_to_contributions/Contribution' diff --git a/database/migrations/0051-add_updated_at_to_contributions.ts b/database/migrations/0051-add_updated_at_to_contributions.ts new file mode 100644 index 000000000..5e991eac9 --- /dev/null +++ b/database/migrations/0051-add_updated_at_to_contributions.ts @@ -0,0 +1,10 @@ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn(`ALTER TABLE \`contributions\` ADD COLUMN \`updated_at\` datetime DEFAULT NULL;`) +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn(`ALTER TABLE \`contributions\` DROP COLUMN \`updated_at\`;`) +} From 3ae79ad935bc348b3142fce429ab0d0286b59af2 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 26 Sep 2022 15:24:36 +0200 Subject: [PATCH 02/14] Change expected database version. --- backend/src/config/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 3e6bafd9f..02ec82e01 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -10,7 +10,7 @@ Decimal.set({ }) const constants = { - DB_VERSION: '0049-add_user_contacts_table', + DB_VERSION: '0051-add_updated_at_to_contributions', DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0 LOG4JS_CONFIG: 'log4js-config.json', // default log level on production should be info From ea234add116a36956a1e9040fc977c84db8c68f6 Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 27 Sep 2022 13:37:45 +0200 Subject: [PATCH 03/14] Add message after updateContribution. --- .../graphql/resolver/ContributionResolver.ts | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index fc93880f1..2caa5a6aa 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -13,6 +13,8 @@ import { Contribution, ContributionListResult } from '@model/Contribution' import { UnconfirmedContribution } from '@model/UnconfirmedContribution' import { validateContribution, getUserCreation, updateCreations } from './util/creations' import { MEMO_MAX_CHARS, MEMO_MIN_CHARS } from './const/const' +import { ContributionMessage } from '@entity/ContributionMessage' +import { ContributionMessageType } from '../enum/MessageType' @Resolver() export class ContributionResolver { @@ -159,7 +161,14 @@ export class ContributionResolver { if (contributionToUpdate.userId !== user.id) { throw new Error('user of the pending contribution and send user does not correspond') } - + if ( + contributionToUpdate.contributionStatus !== ContributionStatus.IN_PROGRESS && + contributionToUpdate.contributionStatus !== ContributionStatus.PENDING + ) { + throw new Error( + `Contribution can not be updated since the state is ${contributionToUpdate.contributionStatus}`, + ) + } const creationDateObj = new Date(creationDate) let creations = await getUserCreation(user.id) if (contributionToUpdate.contributionDate.getMonth() === creationDateObj.getMonth()) { @@ -168,10 +177,20 @@ export class ContributionResolver { // all possible cases not to be true are thrown in this function validateContribution(creations, amount, creationDateObj) + + const contributionMessage = ContributionMessage.create() + contributionMessage.contributionId = contributionId + contributionMessage.createdAt = contributionToUpdate.updatedAt + ? contributionToUpdate.updatedAt + : contributionToUpdate.createdAt + contributionMessage.message = `` + contributionMessage.type = ContributionMessageType.HISTORY + contributionToUpdate.amount = amount contributionToUpdate.memo = memo contributionToUpdate.contributionDate = new Date(creationDate) contributionToUpdate.contributionStatus = ContributionStatus.PENDING + contributionToUpdate.updatedAt = new Date() dbContribution.save(contributionToUpdate) return new UnconfirmedContribution(contributionToUpdate, user, creations) From e29c9a111d36f97f59681a83baac38635f3df4da Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 24 Oct 2022 12:15:54 +0200 Subject: [PATCH 04/14] Add a contribution message when things are changed. --- .../src/graphql/resolver/ContributionResolver.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index b756b33cc..15734d906 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -219,18 +219,20 @@ export class ContributionResolver { contributionMessage.createdAt = contributionToUpdate.updatedAt ? contributionToUpdate.updatedAt : contributionToUpdate.createdAt - const newMessage = '' + let changeMessage = '' if (contributionToUpdate.memo !== memo) { - // - + // TODO: Add message to changeMessage + changeMessage += 'Neuer Memo: ' + memo + '\n' } if (contributionToUpdate.amount !== amount) { - // + // TODO: Add amount to changeMessage + changeMessage += 'Neuer Betrag: ' + amount + '\n' } if (contributionToUpdate.contributionDate !== new Date(creationDate)) { - // + // TODO: Add contributionDate to changeMessage + changeMessage += 'Neuer Beitragsdatum: ' + creationDate + '\n' } - contributionMessage.message = `` + contributionMessage.message = changeMessage contributionMessage.type = ContributionMessageType.HISTORY contributionToUpdate.amount = amount From c17291f74d593bcdb23adb435bb15f8732856651 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 24 Oct 2022 13:19:10 +0200 Subject: [PATCH 05/14] Remove the posibility of null of the contribution entity. --- .../entity/0052-add_updated_at_to_contributions/Contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/entity/0052-add_updated_at_to_contributions/Contribution.ts b/database/entity/0052-add_updated_at_to_contributions/Contribution.ts index 61d0b6cf3..fa61e9274 100644 --- a/database/entity/0052-add_updated_at_to_contributions/Contribution.ts +++ b/database/entity/0052-add_updated_at_to_contributions/Contribution.ts @@ -91,5 +91,5 @@ export class Contribution extends BaseEntity { messages?: ContributionMessage[] @Column({ nullable: true, name: 'updated_at' }) - updatedAt: Date | null + updatedAt: Date } From 94e9039c86b28b9379387db5afc8de723dc80ce0 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 24 Oct 2022 13:23:42 +0200 Subject: [PATCH 06/14] Add changed values to the new contribution message. --- backend/src/graphql/resolver/ContributionResolver.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 15734d906..172c61e65 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -224,16 +224,22 @@ export class ContributionResolver { // TODO: Add message to changeMessage changeMessage += 'Neuer Memo: ' + memo + '\n' } - if (contributionToUpdate.amount !== amount) { + if (contributionToUpdate.amount.toFixed(6) !== amount.toFixed(6)) { // TODO: Add amount to changeMessage changeMessage += 'Neuer Betrag: ' + amount + '\n' } - if (contributionToUpdate.contributionDate !== new Date(creationDate)) { + const isDateDifferent = + contributionToUpdate.contributionDate.getTime() !== new Date(creationDate).getTime() + if (isDateDifferent) { // TODO: Add contributionDate to changeMessage - changeMessage += 'Neuer Beitragsdatum: ' + creationDate + '\n' + changeMessage += 'Neuer Beitragsdatum: ' + creationDate } contributionMessage.message = changeMessage + contributionMessage.createdAt = new Date() + contributionMessage.isModerator = false + contributionMessage.userId = user.id contributionMessage.type = ContributionMessageType.HISTORY + ContributionMessage.save(contributionMessage) contributionToUpdate.amount = amount contributionToUpdate.memo = memo From ce73e2c4474b1ec053007ca1b56f893bf832d916 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 24 Oct 2022 13:40:28 +0200 Subject: [PATCH 07/14] Change value from new to old value. --- backend/src/graphql/resolver/ContributionResolver.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 172c61e65..44c279bf6 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -222,17 +222,17 @@ export class ContributionResolver { let changeMessage = '' if (contributionToUpdate.memo !== memo) { // TODO: Add message to changeMessage - changeMessage += 'Neuer Memo: ' + memo + '\n' + changeMessage += 'Alter Memo: ' + contributionToUpdate.memo + '\n' } if (contributionToUpdate.amount.toFixed(6) !== amount.toFixed(6)) { // TODO: Add amount to changeMessage - changeMessage += 'Neuer Betrag: ' + amount + '\n' + changeMessage += 'Alter Betrag: ' + contributionToUpdate.amount + '\n' } const isDateDifferent = contributionToUpdate.contributionDate.getTime() !== new Date(creationDate).getTime() if (isDateDifferent) { // TODO: Add contributionDate to changeMessage - changeMessage += 'Neuer Beitragsdatum: ' + creationDate + changeMessage += 'Altes Beitragsdatum: ' + contributionToUpdate.contributionDate } contributionMessage.message = changeMessage contributionMessage.createdAt = new Date() From 68aa0a5d072d8c6a0105195205df96350471512c Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 24 Oct 2022 16:00:08 +0200 Subject: [PATCH 08/14] Withdrew createdAt = new Date() and use updatedAt or createdAt from the contribution. --- backend/src/graphql/resolver/ContributionResolver.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 44c279bf6..959dac3f1 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -235,7 +235,6 @@ export class ContributionResolver { changeMessage += 'Altes Beitragsdatum: ' + contributionToUpdate.contributionDate } contributionMessage.message = changeMessage - contributionMessage.createdAt = new Date() contributionMessage.isModerator = false contributionMessage.userId = user.id contributionMessage.type = ContributionMessageType.HISTORY From 53d315749dfcb784051ed1c417269842a662f765 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 24 Oct 2022 16:01:48 +0200 Subject: [PATCH 09/14] Change import from ../enum to @enum --- backend/src/graphql/resolver/ContributionResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 959dac3f1..a652f99a3 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -14,7 +14,7 @@ import { UnconfirmedContribution } from '@model/UnconfirmedContribution' import { validateContribution, getUserCreation, updateCreations } from './util/creations' import { MEMO_MAX_CHARS, MEMO_MIN_CHARS } from './const/const' import { ContributionMessage } from '@entity/ContributionMessage' -import { ContributionMessageType } from '../enum/MessageType' +import { ContributionMessageType } from '@enum/MessageType' import { Event, EventContributionCreate, From 2c3db9da01467267ec2a63267d6eb755de44343a Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 26 Oct 2022 12:04:07 +0200 Subject: [PATCH 10/14] Move updatedAt before deleted variables. --- .../0052-add_updated_at_to_contributions/Contribution.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/database/entity/0052-add_updated_at_to_contributions/Contribution.ts b/database/entity/0052-add_updated_at_to_contributions/Contribution.ts index fa61e9274..2242a753f 100644 --- a/database/entity/0052-add_updated_at_to_contributions/Contribution.ts +++ b/database/entity/0052-add_updated_at_to_contributions/Contribution.ts @@ -80,6 +80,9 @@ export class Contribution extends BaseEntity { @Column({ unsigned: true, nullable: true, name: 'transaction_id' }) transactionId: number + @Column({ nullable: true, name: 'updated_at' }) + updatedAt: Date + @DeleteDateColumn({ name: 'deleted_at' }) deletedAt: Date | null @@ -89,7 +92,4 @@ export class Contribution extends BaseEntity { @OneToMany(() => ContributionMessage, (message) => message.contribution) @JoinColumn({ name: 'contribution_id' }) messages?: ContributionMessage[] - - @Column({ nullable: true, name: 'updated_at' }) - updatedAt: Date } From 0d304f9d71c541a3034c8d33cf61da3204401981 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 26 Oct 2022 12:05:27 +0200 Subject: [PATCH 11/14] Remove TODO comments and change the written message to only the old values no prefix. --- backend/src/graphql/resolver/ContributionResolver.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index a652f99a3..1ca7be253 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -221,18 +221,15 @@ export class ContributionResolver { : contributionToUpdate.createdAt let changeMessage = '' if (contributionToUpdate.memo !== memo) { - // TODO: Add message to changeMessage - changeMessage += 'Alter Memo: ' + contributionToUpdate.memo + '\n' + changeMessage += contributionToUpdate.memo + '\n' } if (contributionToUpdate.amount.toFixed(6) !== amount.toFixed(6)) { - // TODO: Add amount to changeMessage - changeMessage += 'Alter Betrag: ' + contributionToUpdate.amount + '\n' + changeMessage += contributionToUpdate.amount + '\n' } const isDateDifferent = contributionToUpdate.contributionDate.getTime() !== new Date(creationDate).getTime() if (isDateDifferent) { - // TODO: Add contributionDate to changeMessage - changeMessage += 'Altes Beitragsdatum: ' + contributionToUpdate.contributionDate + changeMessage += contributionToUpdate.contributionDate } contributionMessage.message = changeMessage contributionMessage.isModerator = false From 12f64a3cbd8938f74feccd1d1e5ca10e049391f1 Mon Sep 17 00:00:00 2001 From: elweyn Date: Fri, 28 Oct 2022 11:28:19 +0200 Subject: [PATCH 12/14] Add after statement to alter table. --- database/migrations/0052-add_updated_at_to_contributions.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/database/migrations/0052-add_updated_at_to_contributions.ts b/database/migrations/0052-add_updated_at_to_contributions.ts index 5e991eac9..e7cc5b7b4 100644 --- a/database/migrations/0052-add_updated_at_to_contributions.ts +++ b/database/migrations/0052-add_updated_at_to_contributions.ts @@ -2,7 +2,9 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { - await queryFn(`ALTER TABLE \`contributions\` ADD COLUMN \`updated_at\` datetime DEFAULT NULL;`) + await queryFn( + `ALTER TABLE \`contributions\` ADD COLUMN \`updated_at\` datetime DEFAULT NULL AFTER \`transaction_id\`;`, + ) } export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { From b3fd53ab7a4ecff2207d19be4e07b3d283ad05e8 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 3 Nov 2022 08:35:26 +0100 Subject: [PATCH 13/14] Change the display of the history message. --- backend/src/graphql/resolver/ContributionResolver.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 1ca7be253..246be6254 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -220,16 +220,14 @@ export class ContributionResolver { ? contributionToUpdate.updatedAt : contributionToUpdate.createdAt let changeMessage = '' + if (contributionToUpdate.contributionDate.getTime() !== new Date(creationDate).getTime()) { + changeMessage += contributionToUpdate.contributionDate + '\n' + } if (contributionToUpdate.memo !== memo) { - changeMessage += contributionToUpdate.memo + '\n' + changeMessage += '---\n' + contributionToUpdate.memo + '\n' } if (contributionToUpdate.amount.toFixed(6) !== amount.toFixed(6)) { - changeMessage += contributionToUpdate.amount + '\n' - } - const isDateDifferent = - contributionToUpdate.contributionDate.getTime() !== new Date(creationDate).getTime() - if (isDateDifferent) { - changeMessage += contributionToUpdate.contributionDate + changeMessage += '---\n' + contributionToUpdate.amount } contributionMessage.message = changeMessage contributionMessage.isModerator = false From c79d186a45d8c4c269b83cac282c4dee2f249f88 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 7 Nov 2022 10:32:26 +0100 Subject: [PATCH 14/14] Log error when contribution is in the wrong state. Write full content in changeMessage. --- .../graphql/resolver/ContributionResolver.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 246be6254..ede61b413 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -198,6 +198,9 @@ export class ContributionResolver { contributionToUpdate.contributionStatus !== ContributionStatus.IN_PROGRESS && contributionToUpdate.contributionStatus !== ContributionStatus.PENDING ) { + logger.error( + `Contribution can not be updated since the state is ${contributionToUpdate.contributionStatus}`, + ) throw new Error( `Contribution can not be updated since the state is ${contributionToUpdate.contributionStatus}`, ) @@ -219,16 +222,11 @@ export class ContributionResolver { contributionMessage.createdAt = contributionToUpdate.updatedAt ? contributionToUpdate.updatedAt : contributionToUpdate.createdAt - let changeMessage = '' - if (contributionToUpdate.contributionDate.getTime() !== new Date(creationDate).getTime()) { - changeMessage += contributionToUpdate.contributionDate + '\n' - } - if (contributionToUpdate.memo !== memo) { - changeMessage += '---\n' + contributionToUpdate.memo + '\n' - } - if (contributionToUpdate.amount.toFixed(6) !== amount.toFixed(6)) { - changeMessage += '---\n' + contributionToUpdate.amount - } + const changeMessage = `${contributionToUpdate.contributionDate} + --- + ${contributionToUpdate.memo} + --- + ${contributionToUpdate.amount}` contributionMessage.message = changeMessage contributionMessage.isModerator = false contributionMessage.userId = user.id