From 924db68d0638172d3dbc280e1ca7dd321d9abed6 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 7 Jul 2022 15:52:55 +0200 Subject: [PATCH 1/5] setup community statistics --- backend/src/auth/RIGHTS.ts | 1 + .../src/graphql/model/CommunityStatistics.ts | 26 +++++++++++++++++++ .../graphql/resolver/StatisticsResolver.ts | 26 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 backend/src/graphql/model/CommunityStatistics.ts create mode 100644 backend/src/graphql/resolver/StatisticsResolver.ts diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index c10fc96de..cbf650ec1 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -44,4 +44,5 @@ export enum RIGHTS { LIST_CONTRIBUTION_LINKS = 'LIST_CONTRIBUTION_LINKS', DELETE_CONTRIBUTION_LINK = 'DELETE_CONTRIBUTION_LINK', UPDATE_CONTRIBUTION_LINK = 'UPDATE_CONTRIBUTION_LINK', + COMMUNITY_STATISTICS = 'COMMUNITY_STATISTICS', } diff --git a/backend/src/graphql/model/CommunityStatistics.ts b/backend/src/graphql/model/CommunityStatistics.ts new file mode 100644 index 000000000..61354115c --- /dev/null +++ b/backend/src/graphql/model/CommunityStatistics.ts @@ -0,0 +1,26 @@ +import { ObjectType, Field } from 'type-graphql' +import Decimal from 'decimal.js-light' + +@ObjectType() +export class CommunityStatistics { + @Field(() => Number) + totalUsers: number + + @Field(() => Number) + activeUsers: number + + @Field(() => Number) + deletedUsers: number + + @Field(() => Decimal) + totalGradidoCreated: Decimal + + @Field(() => Decimal) + totalGradidoDecayed: Decimal + + @Field(() => Decimal) + totalGradidoAvailable: Decimal + + @Field(() => Decimal) + totalGradidoUnbookedDecayed: Decimal +} diff --git a/backend/src/graphql/resolver/StatisticsResolver.ts b/backend/src/graphql/resolver/StatisticsResolver.ts new file mode 100644 index 000000000..a90d42f75 --- /dev/null +++ b/backend/src/graphql/resolver/StatisticsResolver.ts @@ -0,0 +1,26 @@ +import { Resolver, Query, Arg, Args, Authorized, Ctx, Int } from 'type-graphql' +import { RIGHTS } from '@/auth/RIGHTS' +import { CommunityStatistics } from '@model/CommunityStatistics' +import { User as DbUser } from '@entity/User' +import { getConnection } from '@dbTools/typeorm' +import Decimal from 'decimal.js-light' + +@Resolver() +export class StatisticsResolver { + @Authorized([RIGHTS.COMMUNITY_STATISTICS]) + @Query(() => CommunityStatistics) + async communityStatistics(): Promise { + const totalUsers = await DbUser.find({ withDeleted: true }) + console.log(totalUsers.length) + + return { + totalUsers: 12, + activeUsers: 6, + deletedUsers: 1, + totalGradidoCreated: new Decimal(3000), + totalGradidoDecayed: new Decimal(200), + totalGradidoAvailable: new Decimal(2800), + totalGradidoUnbookedDecayed: new Decimal(200), + } + } +} From df227607ad539ad0bc209eebed917d0a7b356bed Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 7 Jul 2022 17:27:50 +0200 Subject: [PATCH 2/5] get basic statistics from database --- .../graphql/resolver/StatisticsResolver.ts | 71 ++++++++++++++++--- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/backend/src/graphql/resolver/StatisticsResolver.ts b/backend/src/graphql/resolver/StatisticsResolver.ts index a90d42f75..4c1500839 100644 --- a/backend/src/graphql/resolver/StatisticsResolver.ts +++ b/backend/src/graphql/resolver/StatisticsResolver.ts @@ -1,26 +1,77 @@ -import { Resolver, Query, Arg, Args, Authorized, Ctx, Int } from 'type-graphql' +import { Resolver, Query, Authorized } from 'type-graphql' import { RIGHTS } from '@/auth/RIGHTS' import { CommunityStatistics } from '@model/CommunityStatistics' import { User as DbUser } from '@entity/User' +import { Transaction as DbTransaction } from '@entity/Transaction' import { getConnection } from '@dbTools/typeorm' import Decimal from 'decimal.js-light' +import { calculateDecay } from '@/util/decay' @Resolver() export class StatisticsResolver { @Authorized([RIGHTS.COMMUNITY_STATISTICS]) @Query(() => CommunityStatistics) async communityStatistics(): Promise { - const totalUsers = await DbUser.find({ withDeleted: true }) - console.log(totalUsers.length) + const allUsers = await DbUser.find({ withDeleted: true }) + + let totalUsers = 0 + let activeUsers = 0 + let deletedUsers = 0 + + let totalGradidoAvailable: Decimal = new Decimal(0) + let totalGradidoUnbookedDecayed: Decimal = new Decimal(0) + + const receivedCallDate = new Date() + + for (let i = 0; i < allUsers.length; i++) { + if (allUsers[i].deletedAt) { + deletedUsers++ + } else { + totalUsers++ + const lastTransaction = await DbTransaction.findOne({ + where: { userId: allUsers[i].id }, + order: { balanceDate: 'DESC' }, + }) + if (lastTransaction) { + activeUsers++ + const decay = calculateDecay( + lastTransaction.balance, + lastTransaction.balanceDate, + receivedCallDate, + ) + if (decay) { + totalGradidoAvailable = totalGradidoAvailable.plus(decay.balance.toString()) + totalGradidoUnbookedDecayed = totalGradidoUnbookedDecayed.plus(decay.decay.toString()) + } + } + } + } + + const queryRunner = getConnection().createQueryRunner() + await queryRunner.connect() + + const { totalGradidoCreated } = await queryRunner.manager + .createQueryBuilder() + .select('SUM(transaction.amount) AS totalGradidoCreated') + .from(DbTransaction, 'transaction') + .where('transaction.typeId = 1') + .getRawOne() + + const { totalGradidoDecayed } = await queryRunner.manager + .createQueryBuilder() + .select('SUM(transaction.decay) AS totalGradidoDecayed') + .from(DbTransaction, 'transaction') + .where('transaction.decay IS NOT NULL') + .getRawOne() return { - totalUsers: 12, - activeUsers: 6, - deletedUsers: 1, - totalGradidoCreated: new Decimal(3000), - totalGradidoDecayed: new Decimal(200), - totalGradidoAvailable: new Decimal(2800), - totalGradidoUnbookedDecayed: new Decimal(200), + totalUsers, + activeUsers, + deletedUsers, + totalGradidoCreated, + totalGradidoDecayed, + totalGradidoAvailable, + totalGradidoUnbookedDecayed, } } } From baa5084f5d6365485f1af3a109e5dcd771155eed Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 7 Jul 2022 17:29:09 +0200 Subject: [PATCH 3/5] add query for communty statistics --- admin/src/graphql/communityStatistics.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 admin/src/graphql/communityStatistics.js diff --git a/admin/src/graphql/communityStatistics.js b/admin/src/graphql/communityStatistics.js new file mode 100644 index 000000000..868bfd02a --- /dev/null +++ b/admin/src/graphql/communityStatistics.js @@ -0,0 +1,15 @@ +import gql from 'graphql-tag' + +export const communityStatistics = gql` + query { + communityStatistics { + totalUsers + activeUsers + deletedUsers + totalGradidoCreated + totalGradidoDecayed + totalGradidoAvailable + totalGradidoUnbookedDecayed + } + } +` From b1a17c52ecdf6be3923f82fd31ba401190605581 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 17 Aug 2022 12:46:29 +0200 Subject: [PATCH 4/5] Add community_statistics to user ROLES. --- backend/src/auth/ROLES.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/auth/ROLES.ts b/backend/src/auth/ROLES.ts index 500c8bec4..25dc3dc92 100644 --- a/backend/src/auth/ROLES.ts +++ b/backend/src/auth/ROLES.ts @@ -29,6 +29,7 @@ export const ROLE_USER = new Role('user', [ RIGHTS.LIST_ALL_CONTRIBUTIONS, RIGHTS.UPDATE_CONTRIBUTION, RIGHTS.LIST_CONTRIBUTION_LINKS, + RIGHTS.COMMUNITY_STATISTICS, ]) export const ROLE_ADMIN = new Role('admin', Object.values(RIGHTS)) // all rights From 194d4a6ad2c9ddb3f3664d047c7c2a638f1d518f Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 17 Aug 2022 15:15:35 +0200 Subject: [PATCH 5/5] move right COMMUNITY_STATISTICS to user rights --- backend/src/auth/RIGHTS.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index a58d0aa2b..6e1c1e63b 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -31,6 +31,7 @@ export enum RIGHTS { LIST_ALL_CONTRIBUTIONS = 'LIST_ALL_CONTRIBUTIONS', UPDATE_CONTRIBUTION = 'UPDATE_CONTRIBUTION', LIST_CONTRIBUTION_LINKS = 'LIST_CONTRIBUTION_LINKS', + COMMUNITY_STATISTICS = 'COMMUNITY_STATISTICS', // Admin SEARCH_USERS = 'SEARCH_USERS', SET_USER_ROLE = 'SET_USER_ROLE', @@ -48,5 +49,4 @@ export enum RIGHTS { CREATE_CONTRIBUTION_LINK = 'CREATE_CONTRIBUTION_LINK', DELETE_CONTRIBUTION_LINK = 'DELETE_CONTRIBUTION_LINK', UPDATE_CONTRIBUTION_LINK = 'UPDATE_CONTRIBUTION_LINK', - COMMUNITY_STATISTICS = 'COMMUNITY_STATISTICS', }