Merge branch 'master' into improve-apollo-logging

This commit is contained in:
Moriz Wahl 2022-05-16 15:31:46 +02:00
commit 44c5cb8dc1
33 changed files with 461 additions and 72 deletions

7
.gitignore vendored
View File

@ -13,4 +13,9 @@ package-lock.json
/deployment/bare_metal/nginx/update-page/updating.html
/deployment/bare_metal/log
/deployment/bare_metal/backup
/.nvmrc
# Node Version Manager configuration file
.nvmrc
# Apple macOS folder attribute file
.DS_Store

View File

@ -4,8 +4,30 @@ All notable changes to this project will be documented in this file. Dates are d
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
#### [1.8.3](https://github.com/gradido/gradido/compare/1.8.2...1.8.3)
- Checkbox [`#1894`](https://github.com/gradido/gradido/pull/1894)
- fix: Count Deprecated Links as Well [`#1892`](https://github.com/gradido/gradido/pull/1892)
#### [1.8.2](https://github.com/gradido/gradido/compare/1.8.1...1.8.2)
> 12 May 2022
- Release 1.8.2 [`#1890`](https://github.com/gradido/gradido/pull/1890)
- Update README.md [`#1878`](https://github.com/gradido/gradido/pull/1878)
- fix: Unique Previous Column in Transactions Table [`#1879`](https://github.com/gradido/gradido/pull/1879)
- fix: Up and Down Migrations for Older SQL Versions [`#1861`](https://github.com/gradido/gradido/pull/1861)
- 🍰 Refactor THX Page 1. Step [`#1856`](https://github.com/gradido/gradido/pull/1856)
- Create LICENSE [`#1803`](https://github.com/gradido/gradido/pull/1803)
- docu: Update Deployment Documentation [`#1864`](https://github.com/gradido/gradido/pull/1864)
- fix: Loading Transaction Links after Reopening Link List [`#1863`](https://github.com/gradido/gradido/pull/1863)
- 🍰 Add NVM Config Files To '.gitignore' [`#1846`](https://github.com/gradido/gradido/pull/1846)
#### [1.8.1](https://github.com/gradido/gradido/compare/1.8.0...1.8.1)
> 28 April 2022
- v1.8.1 [`#1855`](https://github.com/gradido/gradido/pull/1855)
- 1851 integrate and test the behaviour of clipboard polyfill [`#1853`](https://github.com/gradido/gradido/pull/1853)
- fix: Deprecated Warning from Faker on Seeding [`#1854`](https://github.com/gradido/gradido/pull/1854)
- feat: Test Admin Resolver [`#1848`](https://github.com/gradido/gradido/pull/1848)

View File

@ -93,3 +93,15 @@ Note: The Changelog will be regenerated with all tags on release on the external
## Useful Links
- [Gradido.net](https://gradido.net/)
## Attributions
![browserstack_logo-freelogovectors net_](https://user-images.githubusercontent.com/1324583/167782608-0e4db0d4-3d34-45fb-ab06-344aa5e5ef4b.png)
Browser compatibility testing with [BrowserStack](https://www.browserstack.com/).
## License
See the [LICENSE](LICENSE.md) file for license rights and limitations (Apache-2.0 license).

1
admin/.gitignore vendored
View File

@ -10,4 +10,3 @@ coverage/
# emacs
*~
/.nvmrc

View File

@ -3,7 +3,7 @@
"description": "Administraion Interface for Gradido",
"main": "index.js",
"author": "Moriz Wahl",
"version": "1.8.1",
"version": "1.8.3",
"license": "MIT",
"private": false,
"scripts": {

1
backend/.gitignore vendored
View File

@ -6,4 +6,3 @@ package-json.lock
coverage
# emacs
*~
/.nvmrc

View File

@ -1,6 +1,6 @@
{
"name": "gradido-backend",
"version": "1.8.1",
"version": "1.8.3",
"description": "Gradido unified backend providing an API-Service for Gradido Transactions",
"main": "src/index.ts",
"repository": "https://github.com/gradido/gradido/backend",

View File

@ -10,7 +10,7 @@ Decimal.set({
})
const constants = {
DB_VERSION: '0035-admin_pending_creations_decimal',
DB_VERSION: '0036-unique_previous_in_transactions',
DECAY_START_TIME: new Date('2021-05-13 17:46:31'), // GMT+0
LOG4JS_CONFIG: 'log4js-config.json',
// default log level on production should be info

View File

@ -1077,6 +1077,53 @@ describe('AdminResolver', () => {
expect(transaction[0].typeId).toEqual(1)
})
})
describe('confirm two creations one after the other quickly', () => {
let c1: AdminPendingCreation | void
let c2: AdminPendingCreation | void
beforeAll(async () => {
const now = new Date()
c1 = await creationFactory(testEnv, {
email: 'bibi@bloxberg.de',
amount: 50,
memo: 'Herzlich Willkommen bei Gradido liebe Bibi!',
creationDate: new Date(now.getFullYear(), now.getMonth() - 2, 1).toISOString(),
})
c2 = await creationFactory(testEnv, {
email: 'bibi@bloxberg.de',
amount: 50,
memo: 'Herzlich Willkommen bei Gradido liebe Bibi!',
creationDate: new Date(now.getFullYear(), now.getMonth() - 2, 1).toISOString(),
})
})
// In the futrue this should not throw anymore
it('throws an error for the second confirmation', async () => {
const r1 = mutate({
mutation: confirmPendingCreation,
variables: {
id: c1 ? c1.id : -1,
},
})
const r2 = mutate({
mutation: confirmPendingCreation,
variables: {
id: c2 ? c2.id : -1,
},
})
await expect(r1).resolves.toEqual(
expect.objectContaining({
data: { confirmPendingCreation: true },
}),
)
await expect(r2).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('Unable to confirm creation.')],
}),
)
})
})
})
})
})

View File

@ -361,7 +361,9 @@ export class AdminResolver {
transaction.balanceDate = receivedCallDate
transaction.decay = decay ? decay.decay : new Decimal(0)
transaction.decayStart = decay ? decay.start : null
await transaction.save()
await transaction.save().catch(() => {
throw new Error('Unable to confirm creation.')
})
await AdminPendingCreation.delete(pendingCreation)

View File

@ -9,7 +9,7 @@ import { Transaction as dbTransaction } from '@entity/Transaction'
import Decimal from 'decimal.js-light'
import { GdtResolver } from './GdtResolver'
import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink'
import { MoreThan, getCustomRepository } from '@dbTools/typeorm'
import { getCustomRepository } from '@dbTools/typeorm'
import { TransactionLinkRepository } from '@repository/TransactionLink'
const logger = getLogger('backend')
@ -52,16 +52,13 @@ export class BalanceResolver {
: await dbTransaction.count({ where: { userId: user.id } })
logger.debug(`transactionCount=${count}`)
const linkCount =
context.linkCount || context.linkCount === 0
? context.linkCount
: await dbTransactionLink.count({
where: {
userId: user.id,
redeemedAt: null,
validUntil: MoreThan(new Date()),
},
})
const linkCount = await dbTransactionLink.count({
where: {
userId: user.id,
redeemedAt: null,
// validUntil: MoreThan(new Date()),
},
})
logger.debug(`linkCount=${linkCount}`)
// The decay is always calculated on the last booked transaction

View File

@ -1,6 +1,131 @@
import { CreationInterface } from './CreationInterface'
import { nMonthsBefore } from '../factory/creation'
const bobsSendings = [
{
amount: 10,
memo: 'Herzlich Willkommen bei Gradido!',
},
{
amount: 10,
memo: 'für deine Hilfe, Betty',
},
{
amount: 23.37,
memo: 'für deine Hilfe, David',
},
{
amount: 47,
memo: 'für deine Hilfe, Frau Holle',
},
{
amount: 1.02,
memo: 'für deine Hilfe, Herr Müller',
},
{
amount: 5.67,
memo: 'für deine Hilfe, Maier',
},
{
amount: 72.93,
memo: 'für deine Hilfe, Elsbeth',
},
{
amount: 5.6,
memo: 'für deine Hilfe, Daniel',
},
{
amount: 8.87,
memo: 'für deine Hilfe, Yoda',
},
{
amount: 7.56,
memo: 'für deine Hilfe, Sabine',
},
{
amount: 7.89,
memo: 'für deine Hilfe, Karl',
},
{
amount: 8.9,
memo: 'für deine Hilfe, Darth Vader',
},
{
amount: 56.79,
memo: 'für deine Hilfe, Luci',
},
{
amount: 3.45,
memo: 'für deine Hilfe, Hanne',
},
{
amount: 8.74,
memo: 'für deine Hilfe, Luise',
},
{
amount: 7.85,
memo: 'für deine Hilfe, Annegred',
},
{
amount: 32.7,
memo: 'für deine Hilfe, Prinz von Zamunda',
},
{
amount: 44.2,
memo: 'für deine Hilfe, Charly Brown',
},
{
amount: 38.17,
memo: 'für deine Hilfe, Michael',
},
{
amount: 5.72,
memo: 'für deine Hilfe, Kaja',
},
{
amount: 3.99,
memo: 'für deine Hilfe, Maja',
},
{
amount: 4.5,
memo: 'für deine Hilfe, Martha',
},
{
amount: 8.3,
memo: 'für deine Hilfe, Ursula',
},
{
amount: 2.9,
memo: 'für deine Hilfe, Urs',
},
{
amount: 4.6,
memo: 'für deine Hilfe, Mecedes',
},
{
amount: 74.1,
memo: 'für deine Hilfe, Heidi',
},
{
amount: 4.5,
memo: 'für deine Hilfe, Peter',
},
{
amount: 5.8,
memo: 'für deine Hilfe, Fräulein Rottenmeier',
},
]
const bobsTransactions: CreationInterface[] = []
bobsSendings.forEach((sending) => {
bobsTransactions.push({
email: 'bob@baumeister.de',
amount: sending.amount,
memo: sending.memo,
creationDate: nMonthsBefore(new Date()),
confirmed: true,
})
})
export const creations: CreationInterface[] = [
{
email: 'bibi@bloxberg.de',
@ -10,14 +135,7 @@ export const creations: CreationInterface[] = [
confirmed: true,
moveCreationDate: 12,
},
{
email: 'bob@baumeister.de',
amount: 1000,
memo: 'Herzlich Willkommen bei Gradido!',
creationDate: nMonthsBefore(new Date()),
confirmed: true,
moveCreationDate: 8,
},
...bobsTransactions,
{
email: 'raeuber@hotzenplotz.de',
amount: 1000,

View File

@ -66,7 +66,10 @@ const run = async () => {
// create GDD
for (let i = 0; i < creations.length; i++) {
const now = new Date().getTime() // we have to wait a little! quick fix for account sum problem of bob@baumeister.de, (see https://github.com/gradido/gradido/issues/1886)
await creationFactory(seedClient, creations[i])
// eslint-disable-next-line no-empty
while (new Date().getTime() < now + 1000) {} // we have to wait a little! quick fix for account sum problem of bob@baumeister.de, (see https://github.com/gradido/gradido/issues/1886)
}
// create Transaction Links

1
database/.gitignore vendored
View File

@ -25,4 +25,3 @@ package-lock.json
coverage/
*~
/.nvmrc

View File

@ -0,0 +1,94 @@
import Decimal from 'decimal.js-light'
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm'
import { DecimalTransformer } from '../../src/typeorm/DecimalTransformer'
@Entity('transactions')
export class Transaction extends BaseEntity {
@PrimaryGeneratedColumn('increment', { unsigned: true })
id: number
@Column({ name: 'user_id', unsigned: true, nullable: false })
userId: number
@Column({ type: 'int', unsigned: true, unique: true, nullable: true, default: null })
previous: number | null
@Column({ name: 'type_id', unsigned: true, nullable: false })
typeId: number
@Column({
type: 'decimal',
precision: 40,
scale: 20,
nullable: false,
transformer: DecimalTransformer,
})
amount: Decimal
@Column({
type: 'decimal',
precision: 40,
scale: 20,
nullable: false,
transformer: DecimalTransformer,
})
balance: Decimal
@Column({
name: 'balance_date',
type: 'datetime',
default: () => 'CURRENT_TIMESTAMP',
nullable: false,
})
balanceDate: Date
@Column({
type: 'decimal',
precision: 40,
scale: 20,
nullable: false,
transformer: DecimalTransformer,
})
decay: Decimal
@Column({
name: 'decay_start',
type: 'datetime',
nullable: true,
default: null,
})
decayStart: Date | null
@Column({ length: 255, nullable: false, collation: 'utf8mb4_unicode_ci' })
memo: string
@Column({ name: 'creation_date', type: 'datetime', nullable: true, default: null })
creationDate: Date | null
@Column({
name: 'linked_user_id',
type: 'int',
unsigned: true,
nullable: true,
default: null,
})
linkedUserId?: number | null
@Column({
name: 'linked_transaction_id',
type: 'int',
unsigned: true,
nullable: true,
default: null,
})
linkedTransactionId?: number | null
@Column({
name: 'transaction_link_id',
type: 'int',
unsigned: true,
nullable: true,
default: null,
})
transactionLinkId?: number | null
}

View File

@ -1 +1 @@
export { Transaction } from './0032-add-transaction-link-to-transaction/Transaction'
export { Transaction } from './0036-unique_previous_in_transactions/Transaction'

View File

@ -0,0 +1,13 @@
/* MIGRATION TO SET previous COLUMN UNIQUE in TRANSACTION table
*/
/* 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<Array<any>>) {
await queryFn('ALTER TABLE `transactions` ADD UNIQUE(`previous`);')
}
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn('ALTER TABLE `transactions` DROP INDEX `previous`;')
}

View File

@ -1,6 +1,6 @@
{
"name": "gradido-database",
"version": "1.8.1",
"version": "1.8.3",
"description": "Gradido Database Tool to execute database migrations",
"main": "src/index.ts",
"repository": "https://github.com/gradido/gradido/database",

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 20 20" style="enable-background:new 0 0 20 20;" xml:space="preserve">
<style type="text/css">
.st0{fill:#047006;}
.st1{fill:none;stroke:#F5F5F5;stroke-width:2;stroke-linecap:round;}
.st2{display:none;}
.st3{display:inline;}
.st4{fill:#FFFFFF;}
.st5{fill:none;stroke:#707070;}
.st6{fill:none;stroke:#F5F5F5;stroke-width:2;stroke-linecap:round;stroke-opacity:0;}
</style>
<g id="Ebene_1">
<g id="Gruppe_4989" transform="translate(-772 -261.959)">
<circle id="Ellipse_17" class="st0" cx="782.16" cy="271.95" r="9.5"/>
<line id="Linie_20" class="st1" x1="777.46" y1="271.95" x2="780.54" y2="275.47"/>
<line id="Linie_21" class="st1" x1="780.54" y1="275.47" x2="787.53" y2="268.44"/>
</g>
</g>
<g id="Ebene_2" class="st2">
<g id="Gruppe_4989_00000034808020233716670080000006186173982805041337_" transform="translate(-772 -261.959)" class="st3">
<g id="Ellipse_17_00000100354317347125335040000001067099806688704903_" transform="translate(772 261.959)">
<circle class="st4" cx="10.16" cy="9.99" r="9.5"/>
<circle class="st5" cx="10.16" cy="9.99" r="9"/>
</g>
<line id="Linie_20_00000062902523139473969010000009779348807157657532_" class="st6" x1="777.46" y1="271.95" x2="780.54" y2="275.47"/>
<line id="Linie_21_00000005969448249974932320000012316677830959789444_" class="st6" x1="780.54" y1="275.47" x2="787.53" y2="268.44"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 20 20" style="enable-background:new 0 0 20 20;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
.st1{display:inline;}
.st2{fill:#047006;}
.st3{fill:none;stroke:#F5F5F5;stroke-width:2;stroke-linecap:round;}
.st4{fill:#FFFFFF;}
.st5{fill:none;stroke:#707070;}
.st6{fill:none;stroke:#F5F5F5;stroke-width:2;stroke-linecap:round;stroke-opacity:0;}
</style>
<g id="Ebene_1" class="st0">
<g id="Gruppe_4989" transform="translate(-772 -261.959)" class="st1">
<circle id="Ellipse_17" class="st2" cx="782.16" cy="271.95" r="9.5"/>
<line id="Linie_20" class="st3" x1="777.46" y1="271.95" x2="780.54" y2="275.47"/>
<line id="Linie_21" class="st3" x1="780.54" y1="275.47" x2="787.53" y2="268.44"/>
</g>
</g>
<g id="Ebene_2">
<g id="Gruppe_4989_00000034808020233716670080000006186173982805041337_" transform="translate(-772 -261.959)">
<g id="Ellipse_17_00000100354317347125335040000001067099806688704903_" transform="translate(772 261.959)">
<circle class="st4" cx="10.16" cy="9.99" r="9.5"/>
<circle class="st5" cx="10.16" cy="9.99" r="9"/>
</g>
<line id="Linie_20_00000062902523139473969010000009779348807157657532_" class="st6" x1="777.46" y1="271.95" x2="780.54" y2="275.47"/>
<line id="Linie_21_00000005969448249974932320000012316677830959789444_" class="st6" x1="780.54" y1="275.47" x2="787.53" y2="268.44"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

1
frontend/.gitignore vendored
View File

@ -24,4 +24,3 @@ package-lock.json
coverage/
*~
/.nvmrc

View File

@ -1,6 +1,6 @@
{
"name": "bootstrap-vue-gradido-wallet",
"version": "1.8.1",
"version": "1.8.3",
"private": true,
"scripts": {
"start": "node run/server.js",

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 KiB

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-type" viewBox="0 0 16 16">
<path d="m2.244 13.081.943-2.803H6.66l.944 2.803H8.86L5.54 3.75H4.322L1 13.081h1.244zm2.7-7.923L6.34 9.314H3.51l1.4-4.156h.034zm9.146 7.027h.035v.896h1.128V8.125c0-1.51-1.114-2.345-2.646-2.345-1.736 0-2.59.916-2.666 2.174h1.108c.068-.718.595-1.19 1.517-1.19.971 0 1.518.52 1.518 1.464v.731H12.19c-1.647.007-2.522.8-2.522 2.058 0 1.319.957 2.18 2.345 2.18 1.06 0 1.716-.43 2.078-1.011zm-1.763.035c-.752 0-1.456-.397-1.456-1.244 0-.65.424-1.115 1.408-1.115h1.805v.834c0 .896-.752 1.525-1.757 1.525z"/>
</svg>

After

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -407,29 +407,34 @@ describe('GddTransactionList', () => {
})
describe('pagination buttons', () => {
const createTransaction = (idx) => {
return {
amount: '3.14',
balanceDate: '2021-04-29T17:26:40+00:00',
decay: {
decay: '-477.01',
start: '2021-05-13T17:46:31.000Z',
end: '2022-04-20T06:51:25.000Z',
duration: 29509494,
},
memo: 'Kreiszahl PI',
linkedUser: {
firstName: 'Bibi',
lastName: 'Bloxberg',
},
id: idx + 1,
typeId: 'RECEIVE',
balance: '33.33',
}
}
beforeEach(async () => {
const transactionCount = 42
await wrapper.setProps({
transactions: Array.from({ length: 42 }, (_, idx) => {
return {
amount: '3.14',
balanceDate: '2021-04-29T17:26:40+00:00',
decay: {
decay: '-477.01',
start: '2021-05-13T17:46:31.000Z',
end: '2022-04-20T06:51:25.000Z',
duration: 29509494,
},
memo: 'Kreiszahl PI',
linkedUser: {
firstName: 'Bibi',
lastName: 'Bloxberg',
},
id: idx + 1,
typeId: 'RECEIVE',
balance: '33.33',
}
transactions: Array.from({ length: transactionCount }, (_, idx) => {
return createTransaction(idx)
}),
transactionCount: 42,
transactionCount,
decayStartBlock,
pageSize: 25,
showPagination: true,
@ -449,22 +454,22 @@ describe('GddTransactionList', () => {
)
})
})
})
describe('show no pagination', () => {
beforeEach(async () => {
await wrapper.setProps({
transactions: [],
transactionCount: 2,
decayStartBlock,
pageSize: 25,
showPagination: false,
describe('show no pagination', () => {
it('shows no pagination buttons', async () => {
const transactionCount = 2
await wrapper.setProps({
transactions: Array.from({ length: transactionCount }, (_, idx) => {
return createTransaction(idx)
}),
transactionCount,
decayStartBlock,
pageSize: 25,
showPagination: false,
})
expect(wrapper.find('ul.pagination').exists()).toBe(false)
})
})
it('shows no pagination buttons', () => {
expect(wrapper.find('ul.pagination').exists()).toBe(false)
})
})
})
})

View File

@ -61,7 +61,7 @@
</div>
</div>
<b-pagination
v-if="showPagination"
v-if="isPaginationVisible"
class="mt-3"
pills
size="lg"
@ -96,11 +96,6 @@ export default {
TransactionCreation,
TransactionLinkSummary,
},
data() {
return {
currentPage: 1,
}
},
props: {
transactions: { default: () => [] },
pageSize: { type: Number, default: 25 },
@ -110,6 +105,11 @@ export default {
showPagination: { type: Boolean, default: false },
pending: { type: Boolean },
},
data() {
return {
currentPage: 1,
}
},
methods: {
updateTransactions() {
this.$emit('update-transactions', {
@ -123,6 +123,11 @@ export default {
return '0'
},
},
computed: {
isPaginationVisible() {
return this.showPagination && this.pageSize < this.transactionCount
},
},
watch: {
currentPage() {
this.updateTransactions()
@ -134,6 +139,7 @@ export default {
},
}
</script>
<style>
collaps-icon {
width: 95%;

View File

@ -9,7 +9,7 @@
:transactionCount="transactionCount"
:transactionLinkCount="transactionLinkCount"
:transactions="transactions"
:show-pagination="true"
:showPagination="true"
@update-transactions="updateTransactions"
v-on="$listeners"
/>

View File

@ -1,6 +1,6 @@
{
"name": "gradido",
"version": "1.8.1",
"version": "1.8.3",
"description": "Gradido",
"main": "index.js",
"repository": "git@github.com:gradido/gradido.git",