mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
commit
a48b124da2
@ -15,13 +15,6 @@ export class Decay {
|
||||
}
|
||||
}
|
||||
|
||||
static async getDecayStartBlock(): Promise<Transaction | undefined> {
|
||||
if (!this.decayStartBlockTransaction) {
|
||||
this.decayStartBlockTransaction = await Transaction.getDecayStartBlock()
|
||||
}
|
||||
return this.decayStartBlockTransaction
|
||||
}
|
||||
|
||||
@Field(() => Number)
|
||||
balance: number
|
||||
|
||||
@ -38,6 +31,4 @@ export class Decay {
|
||||
|
||||
@Field(() => Int, { nullable: true })
|
||||
decayStartBlock?: string
|
||||
|
||||
static decayStartBlockTransaction: Transaction | undefined
|
||||
}
|
||||
|
||||
@ -2,9 +2,10 @@
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
|
||||
import { Resolver, Query, Ctx, Authorized } from 'type-graphql'
|
||||
import { getCustomRepository } from 'typeorm'
|
||||
import { Balance } from '../models/Balance'
|
||||
import { User as dbUser } from '../../typeorm/entity/User'
|
||||
import { Balance as dbBalance } from '../../typeorm/entity/Balance'
|
||||
import { BalanceRepository } from '../../typeorm/repository/Balance'
|
||||
import { UserRepository } from '../../typeorm/repository/User'
|
||||
import { calculateDecay } from '../../util/decay'
|
||||
import { roundFloorFrom4 } from '../../util/round'
|
||||
|
||||
@ -14,8 +15,11 @@ export class BalanceResolver {
|
||||
@Query(() => Balance)
|
||||
async balance(@Ctx() context: any): Promise<Balance> {
|
||||
// load user and balance
|
||||
const userEntity = await dbUser.findByPubkeyHex(context.pubKey)
|
||||
const balanceEntity = await dbBalance.findByUser(userEntity.id)
|
||||
const balanceRepository = getCustomRepository(BalanceRepository)
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
|
||||
const userEntity = await userRepository.findByPubkeyHex(context.pubKey)
|
||||
const balanceEntity = await balanceRepository.findByUser(userEntity.id)
|
||||
let balance: Balance
|
||||
const now = new Date()
|
||||
if (balanceEntity) {
|
||||
|
||||
@ -2,11 +2,12 @@
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
|
||||
import { Resolver, Query, Args, Ctx, Authorized } from 'type-graphql'
|
||||
import { getCustomRepository } from 'typeorm'
|
||||
import CONFIG from '../../config'
|
||||
import { GdtEntryList } from '../models/GdtEntryList'
|
||||
import { GdtTransactionSessionIdInput } from '../inputs/GdtInputs'
|
||||
import { apiGet } from '../../apis/HttpRequest'
|
||||
import { User as dbUser } from '../../typeorm/entity/User'
|
||||
import { UserRepository } from '../../typeorm/repository/User'
|
||||
|
||||
@Resolver()
|
||||
export class GdtResolver {
|
||||
@ -19,7 +20,8 @@ export class GdtResolver {
|
||||
@Ctx() context: any,
|
||||
): Promise<GdtEntryList> {
|
||||
// load user
|
||||
const userEntity = await dbUser.findByPubkeyHex(context.pubKey)
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
const userEntity = await userRepository.findByPubkeyHex(context.pubKey)
|
||||
|
||||
const resultGDT = await apiGet(
|
||||
`${CONFIG.GDT_API_URL}/GdtEntries/listPerEmailApi/${userEntity.email}/${currentPage}/${pageSize}/${order}`,
|
||||
|
||||
@ -2,12 +2,13 @@
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
|
||||
import { Resolver, Query, Args, Authorized, Ctx, Mutation } from 'type-graphql'
|
||||
import { getCustomRepository } from 'typeorm'
|
||||
import CONFIG from '../../config'
|
||||
import { TransactionList } from '../models/Transaction'
|
||||
import { TransactionListInput, TransactionSendArgs } from '../inputs/TransactionInput'
|
||||
import { apiGet, apiPost } from '../../apis/HttpRequest'
|
||||
import { User as dbUser } from '../../typeorm/entity/User'
|
||||
import { Balance as dbBalance } from '../../typeorm/entity/Balance'
|
||||
import { BalanceRepository } from '../../typeorm/repository/Balance'
|
||||
import { UserRepository } from '../../typeorm/repository/User'
|
||||
import listTransactions from './listTransactions'
|
||||
import { roundFloorFrom4 } from '../../util/round'
|
||||
import { calculateDecay } from '../../util/decay'
|
||||
@ -25,7 +26,8 @@ export class TransactionResolver {
|
||||
if (!result.success) throw new Error(result.data)
|
||||
|
||||
// load user
|
||||
const userEntity = await dbUser.findByPubkeyHex(result.data.user.public_hex)
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
const userEntity = await userRepository.findByPubkeyHex(result.data.user.public_hex)
|
||||
|
||||
const transactions = await listTransactions(firstPage, items, order, userEntity)
|
||||
|
||||
@ -37,7 +39,8 @@ export class TransactionResolver {
|
||||
transactions.gdtSum = resultGDTSum.data.sum
|
||||
|
||||
// get balance
|
||||
const balanceEntity = await dbBalance.findByUser(userEntity.id)
|
||||
const balanceRepository = getCustomRepository(BalanceRepository)
|
||||
const balanceEntity = await balanceRepository.findByUser(userEntity.id)
|
||||
if (balanceEntity) {
|
||||
const now = new Date()
|
||||
transactions.balance = roundFloorFrom4(balanceEntity.amount)
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
import { getCustomRepository } from 'typeorm'
|
||||
import { User as dbUser } from '../../typeorm/entity/User'
|
||||
import { UserRepository } from '../../typeorm/repository/User'
|
||||
import { TransactionList, Transaction } from '../models/Transaction'
|
||||
import { UserTransaction as dbUserTransaction } from '../../typeorm/entity/UserTransaction'
|
||||
import { UserTransactionRepository } from '../../typeorm/repository/UserTransaction'
|
||||
import { Transaction as dbTransaction } from '../../typeorm/entity/Transaction'
|
||||
import { Decay } from '../models/Decay'
|
||||
import { TransactionRepository } from '../../typeorm/repository/Transaction'
|
||||
import { calculateDecayWithInterval } from '../../util/decay'
|
||||
import { roundFloorFrom4 } from '../../util/round'
|
||||
|
||||
@ -20,20 +23,8 @@ async function calculateAndAddDecayTransactions(
|
||||
transactionIds.push(userTransaction.transactionId)
|
||||
})
|
||||
|
||||
const transactions = await dbTransaction
|
||||
.createQueryBuilder('transaction')
|
||||
.where('transaction.id IN (:...transactions)', { transactions: transactionIds })
|
||||
.leftJoinAndSelect(
|
||||
'transaction.transactionSendCoin',
|
||||
'transactionSendCoin',
|
||||
// 'transactionSendCoin.transaction_id = transaction.id',
|
||||
)
|
||||
.leftJoinAndSelect(
|
||||
'transaction.transactionCreation',
|
||||
'transactionCreation',
|
||||
// 'transactionSendCoin.transaction_id = transaction.id',
|
||||
)
|
||||
.getMany()
|
||||
const transactionRepository = getCustomRepository(TransactionRepository)
|
||||
const transactions = await transactionRepository.joinFullTransactionsByIds(transactionIds)
|
||||
|
||||
const transactionIndiced: dbTransaction[] = []
|
||||
transactions.forEach((transaction: dbTransaction) => {
|
||||
@ -46,9 +37,10 @@ async function calculateAndAddDecayTransactions(
|
||||
// remove duplicates
|
||||
// https://stackoverflow.com/questions/1960473/get-all-unique-values-in-a-javascript-array-remove-duplicates
|
||||
const involvedUsersUnique = involvedUserIds.filter((v, i, a) => a.indexOf(v) === i)
|
||||
const userIndiced = await dbUser.getUsersIndiced(involvedUsersUnique)
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
const userIndiced = await userRepository.getUsersIndiced(involvedUsersUnique)
|
||||
|
||||
const decayStartTransaction = await Decay.getDecayStartBlock()
|
||||
const decayStartTransaction = await transactionRepository.findDecayStartBlock()
|
||||
|
||||
for (let i = 0; i < userTransactions.length; i++) {
|
||||
const userTransaction = userTransactions[i]
|
||||
@ -163,7 +155,8 @@ export default async function listTransactions(
|
||||
if (offset && order === 'ASC') {
|
||||
offset--
|
||||
}
|
||||
let [userTransactions, userTransactionsCount] = await dbUserTransaction.findByUserPaged(
|
||||
const userTransactionRepository = getCustomRepository(UserTransactionRepository)
|
||||
let [userTransactions, userTransactionsCount] = await userTransactionRepository.findByUserPaged(
|
||||
user.id,
|
||||
limit,
|
||||
offset,
|
||||
|
||||
@ -16,8 +16,4 @@ export class Balance extends BaseEntity {
|
||||
|
||||
@Column({ type: 'bigint' })
|
||||
amount: number
|
||||
|
||||
static findByUser(userId: number): Promise<Balance | undefined> {
|
||||
return this.createQueryBuilder('balance').where('balance.userId = :userId', { userId }).getOne()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
/* import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
|
||||
import { User } from "./User"
|
||||
|
||||
@Entity()
|
||||
export class Group {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
alias: string;
|
||||
|
||||
@Column()
|
||||
name: string;
|
||||
|
||||
@Column()
|
||||
url: string;
|
||||
|
||||
@Column()
|
||||
description: string;
|
||||
|
||||
@OneToMany(type => User, user => user.group)
|
||||
users: User[];
|
||||
|
||||
} */
|
||||
@ -27,19 +27,4 @@ export class Transaction extends BaseEntity {
|
||||
|
||||
@OneToOne(() => TransactionCreation, (transactionCreation) => transactionCreation.transaction)
|
||||
transactionCreation: TransactionCreation
|
||||
|
||||
static async findByTransactionTypeId(transactionTypeId: number): Promise<Transaction[]> {
|
||||
return this.createQueryBuilder('transaction')
|
||||
.where('transaction.transactionTypeId = :transactionTypeId', {
|
||||
transactionTypeId: transactionTypeId,
|
||||
})
|
||||
.getMany()
|
||||
}
|
||||
|
||||
static async getDecayStartBlock(): Promise<Transaction | undefined> {
|
||||
return this.createQueryBuilder('transaction')
|
||||
.where('transaction.transactionTypeId = :transactionTypeId', { transactionTypeId: 9 })
|
||||
.orderBy('received', 'ASC')
|
||||
.getOne()
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,25 +28,4 @@ export class User extends BaseEntity {
|
||||
|
||||
@Column()
|
||||
disabled: boolean
|
||||
|
||||
// Moriz: I am voting for the data mapper implementation.
|
||||
// see: https://typeorm.io/#/active-record-data-mapper/what-is-the-data-mapper-pattern
|
||||
// We should discuss this ASAP
|
||||
static findByPubkeyHex(pubkeyHex: string): Promise<User> {
|
||||
return this.createQueryBuilder('user')
|
||||
.where('hex(user.pubkey) = :pubkeyHex', { pubkeyHex })
|
||||
.getOneOrFail()
|
||||
}
|
||||
|
||||
static async getUsersIndiced(userIds: number[]): Promise<User[]> {
|
||||
const users = await this.createQueryBuilder('user')
|
||||
.select(['user.id', 'user.firstName', 'user.lastName', 'user.email'])
|
||||
.where('user.id IN (:...users)', { users: userIds })
|
||||
.getMany()
|
||||
const usersIndiced: User[] = []
|
||||
users.forEach((value) => {
|
||||
usersIndiced[value.id] = value
|
||||
})
|
||||
return usersIndiced
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,18 +19,4 @@ export class UserTransaction extends BaseEntity {
|
||||
|
||||
@Column({ name: 'balance_date', type: 'timestamp' })
|
||||
balanceDate: Date
|
||||
|
||||
static findByUserPaged(
|
||||
userId: number,
|
||||
limit: number,
|
||||
offset: number,
|
||||
order: 'ASC' | 'DESC',
|
||||
): Promise<[UserTransaction[], number]> {
|
||||
return this.createQueryBuilder('userTransaction')
|
||||
.where('userTransaction.userId = :userId', { userId })
|
||||
.orderBy('userTransaction.balanceDate', order)
|
||||
.limit(limit)
|
||||
.offset(offset)
|
||||
.getManyAndCount()
|
||||
}
|
||||
}
|
||||
|
||||
11
backend/src/typeorm/repository/Balance.ts
Normal file
11
backend/src/typeorm/repository/Balance.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { EntityRepository, Repository } from 'typeorm'
|
||||
import { Balance } from '../entity/Balance'
|
||||
|
||||
@EntityRepository(Balance)
|
||||
export class BalanceRepository extends Repository<Balance> {
|
||||
findByUser(userId: number): Promise<Balance | undefined> {
|
||||
return this.createQueryBuilder('balance')
|
||||
.where('balance.userId = :userId', { userId })
|
||||
.getOneOrFail()
|
||||
}
|
||||
}
|
||||
28
backend/src/typeorm/repository/Transaction.ts
Normal file
28
backend/src/typeorm/repository/Transaction.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { EntityRepository, Repository } from 'typeorm'
|
||||
import { Transaction } from '../entity/Transaction'
|
||||
|
||||
@EntityRepository(Transaction)
|
||||
export class TransactionRepository extends Repository<Transaction> {
|
||||
async findDecayStartBlock(): Promise<Transaction | undefined> {
|
||||
return this.createQueryBuilder('transaction')
|
||||
.where('transaction.transactionTypeId = :transactionTypeId', { transactionTypeId: 9 })
|
||||
.orderBy('received', 'ASC')
|
||||
.getOne()
|
||||
}
|
||||
|
||||
async joinFullTransactionsByIds(transactionIds: number[]): Promise<Transaction[]> {
|
||||
return this.createQueryBuilder('transaction')
|
||||
.where('transaction.id IN (:...transactions)', { transactions: transactionIds })
|
||||
.leftJoinAndSelect(
|
||||
'transaction.transactionSendCoin',
|
||||
'transactionSendCoin',
|
||||
// 'transactionSendCoin.transaction_id = transaction.id',
|
||||
)
|
||||
.leftJoinAndSelect(
|
||||
'transaction.transactionCreation',
|
||||
'transactionCreation',
|
||||
// 'transactionSendCoin.transaction_id = transaction.id',
|
||||
)
|
||||
.getMany()
|
||||
}
|
||||
}
|
||||
23
backend/src/typeorm/repository/User.ts
Normal file
23
backend/src/typeorm/repository/User.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { EntityRepository, Repository } from 'typeorm'
|
||||
import { User } from '../entity/User'
|
||||
|
||||
@EntityRepository(User)
|
||||
export class UserRepository extends Repository<User> {
|
||||
async findByPubkeyHex(pubkeyHex: string): Promise<User> {
|
||||
return this.createQueryBuilder('user')
|
||||
.where('hex(user.pubkey) = :pubkeyHex', { pubkeyHex })
|
||||
.getOneOrFail()
|
||||
}
|
||||
|
||||
async getUsersIndiced(userIds: number[]): Promise<User[]> {
|
||||
const users = await this.createQueryBuilder('user')
|
||||
.select(['user.id', 'user.firstName', 'user.lastName', 'user.email'])
|
||||
.where('user.id IN (:...users)', { users: userIds })
|
||||
.getMany()
|
||||
const usersIndiced: User[] = []
|
||||
users.forEach((value) => {
|
||||
usersIndiced[value.id] = value
|
||||
})
|
||||
return usersIndiced
|
||||
}
|
||||
}
|
||||
19
backend/src/typeorm/repository/UserTransaction.ts
Normal file
19
backend/src/typeorm/repository/UserTransaction.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { EntityRepository, Repository } from 'typeorm'
|
||||
import { UserTransaction } from '../entity/UserTransaction'
|
||||
|
||||
@EntityRepository(UserTransaction)
|
||||
export class UserTransactionRepository extends Repository<UserTransaction> {
|
||||
findByUserPaged(
|
||||
userId: number,
|
||||
limit: number,
|
||||
offset: number,
|
||||
order: 'ASC' | 'DESC',
|
||||
): Promise<[UserTransaction[], number]> {
|
||||
return this.createQueryBuilder('userTransaction')
|
||||
.where('userTransaction.userId = :userId', { userId })
|
||||
.orderBy('userTransaction.balanceDate', order)
|
||||
.limit(limit)
|
||||
.offset(offset)
|
||||
.getManyAndCount()
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
import { getCustomRepository } from 'typeorm'
|
||||
import { Decay } from '../graphql/models/Decay'
|
||||
import { TransactionRepository } from '../typeorm/repository/Transaction'
|
||||
|
||||
function decayFormula(amount: number, durationInSeconds: number): number {
|
||||
return amount * Math.pow(0.99999997802044727, durationInSeconds)
|
||||
@ -6,7 +8,8 @@ function decayFormula(amount: number, durationInSeconds: number): number {
|
||||
|
||||
async function calculateDecay(amount: number, from: Date, to: Date): Promise<number> {
|
||||
// load decay start block
|
||||
const decayStartBlock = await Decay.getDecayStartBlock()
|
||||
const transactionRepository = getCustomRepository(TransactionRepository)
|
||||
const decayStartBlock = await transactionRepository.findDecayStartBlock()
|
||||
|
||||
// if decay hasn't started yet we return input amount
|
||||
if (!decayStartBlock) return amount
|
||||
@ -20,7 +23,8 @@ async function calculateDecayWithInterval(
|
||||
from: number | Date,
|
||||
to: number | Date,
|
||||
): Promise<Decay> {
|
||||
const decayStartBlock = await Decay.getDecayStartBlock()
|
||||
const transactionRepository = getCustomRepository(TransactionRepository)
|
||||
const decayStartBlock = await transactionRepository.findDecayStartBlock()
|
||||
|
||||
const result = new Decay(undefined)
|
||||
result.balance = amount
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user