2021-08-09 21:11:35 +02:00
|
|
|
import { DataGatheringService } from '@ghostfolio/api/services/data-gathering.service';
|
2021-04-21 20:27:39 +02:00
|
|
|
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.service';
|
|
|
|
import { PrismaService } from '@ghostfolio/api/services/prisma.service';
|
2021-05-16 22:11:14 +02:00
|
|
|
import { AdminData } from '@ghostfolio/common/interfaces';
|
2021-04-13 21:53:58 +02:00
|
|
|
import { Injectable } from '@nestjs/common';
|
|
|
|
import { Currency } from '@prisma/client';
|
2021-08-14 11:12:08 +02:00
|
|
|
import { differenceInDays } from 'date-fns';
|
2021-04-13 21:53:58 +02:00
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
export class AdminService {
|
|
|
|
public constructor(
|
2021-08-09 21:11:35 +02:00
|
|
|
private readonly dataGatheringService: DataGatheringService,
|
2021-08-07 22:38:07 +02:00
|
|
|
private readonly exchangeRateDataService: ExchangeRateDataService,
|
|
|
|
private readonly prismaService: PrismaService
|
2021-04-13 21:53:58 +02:00
|
|
|
) {}
|
|
|
|
|
|
|
|
public async get(): Promise<AdminData> {
|
|
|
|
return {
|
|
|
|
exchangeRates: [
|
|
|
|
{
|
|
|
|
label1: Currency.EUR,
|
|
|
|
label2: Currency.CHF,
|
|
|
|
value: await this.exchangeRateDataService.toCurrency(
|
|
|
|
1,
|
|
|
|
Currency.EUR,
|
|
|
|
Currency.CHF
|
|
|
|
)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label1: Currency.GBP,
|
|
|
|
label2: Currency.CHF,
|
|
|
|
value: await this.exchangeRateDataService.toCurrency(
|
|
|
|
1,
|
|
|
|
Currency.GBP,
|
|
|
|
Currency.CHF
|
|
|
|
)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label1: Currency.USD,
|
|
|
|
label2: Currency.CHF,
|
|
|
|
value: await this.exchangeRateDataService.toCurrency(
|
|
|
|
1,
|
|
|
|
Currency.USD,
|
|
|
|
Currency.CHF
|
|
|
|
)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label1: Currency.USD,
|
|
|
|
label2: Currency.EUR,
|
|
|
|
value: await this.exchangeRateDataService.toCurrency(
|
|
|
|
1,
|
|
|
|
Currency.USD,
|
|
|
|
Currency.EUR
|
|
|
|
)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label1: Currency.USD,
|
|
|
|
label2: Currency.GBP,
|
|
|
|
value: await this.exchangeRateDataService.toCurrency(
|
|
|
|
1,
|
|
|
|
Currency.USD,
|
|
|
|
Currency.GBP
|
|
|
|
)
|
|
|
|
}
|
|
|
|
],
|
|
|
|
lastDataGathering: await this.getLastDataGathering(),
|
2021-08-07 22:38:07 +02:00
|
|
|
transactionCount: await this.prismaService.order.count(),
|
|
|
|
userCount: await this.prismaService.user.count(),
|
2021-04-18 20:12:58 +02:00
|
|
|
users: await this.getUsersWithAnalytics()
|
2021-04-13 21:53:58 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
private async getLastDataGathering() {
|
2021-08-09 21:11:35 +02:00
|
|
|
const lastDataGathering =
|
|
|
|
await this.dataGatheringService.getLastDataGathering();
|
2021-04-13 21:53:58 +02:00
|
|
|
|
2021-08-09 21:11:35 +02:00
|
|
|
if (lastDataGathering) {
|
|
|
|
return lastDataGathering;
|
2021-04-13 21:53:58 +02:00
|
|
|
}
|
|
|
|
|
2021-08-07 22:38:07 +02:00
|
|
|
const dataGatheringInProgress =
|
2021-08-09 21:11:35 +02:00
|
|
|
await this.dataGatheringService.getIsInProgress();
|
2021-04-13 21:53:58 +02:00
|
|
|
|
|
|
|
if (dataGatheringInProgress) {
|
|
|
|
return 'IN_PROGRESS';
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-08-14 11:12:08 +02:00
|
|
|
private async getUsersWithAnalytics(): Promise<AdminData['users']> {
|
|
|
|
const usersWithAnalytics = await this.prismaService.user.findMany({
|
2021-04-18 20:12:58 +02:00
|
|
|
orderBy: {
|
|
|
|
Analytics: {
|
|
|
|
updatedAt: 'desc'
|
|
|
|
}
|
|
|
|
},
|
2021-04-13 21:53:58 +02:00
|
|
|
select: {
|
2021-04-18 20:12:58 +02:00
|
|
|
_count: {
|
2021-04-25 21:25:23 +02:00
|
|
|
select: { Account: true, Order: true }
|
2021-04-18 20:12:58 +02:00
|
|
|
},
|
|
|
|
alias: true,
|
|
|
|
Analytics: {
|
2021-04-13 21:53:58 +02:00
|
|
|
select: {
|
2021-04-18 20:12:58 +02:00
|
|
|
activityCount: true,
|
|
|
|
updatedAt: true
|
2021-04-13 21:53:58 +02:00
|
|
|
}
|
2021-04-18 20:12:58 +02:00
|
|
|
},
|
|
|
|
createdAt: true,
|
|
|
|
id: true
|
2021-04-13 21:53:58 +02:00
|
|
|
},
|
2021-05-22 10:17:12 +02:00
|
|
|
take: 30,
|
2021-04-22 20:55:05 +02:00
|
|
|
where: {
|
|
|
|
NOT: {
|
|
|
|
Analytics: null
|
|
|
|
}
|
|
|
|
}
|
2021-04-13 21:53:58 +02:00
|
|
|
});
|
2021-08-14 11:12:08 +02:00
|
|
|
|
|
|
|
return usersWithAnalytics.map(
|
|
|
|
({ _count, alias, Analytics, createdAt, id }) => {
|
|
|
|
const daysSinceRegistration =
|
|
|
|
differenceInDays(new Date(), createdAt) + 1;
|
|
|
|
const engagement = Analytics.activityCount / daysSinceRegistration;
|
|
|
|
|
|
|
|
return {
|
|
|
|
alias,
|
|
|
|
createdAt,
|
|
|
|
engagement,
|
|
|
|
id,
|
|
|
|
accountCount: _count.Account || 0,
|
|
|
|
lastActivity: Analytics.updatedAt,
|
|
|
|
transactionCount: _count.Order || 0
|
|
|
|
};
|
|
|
|
}
|
|
|
|
);
|
2021-04-13 21:53:58 +02:00
|
|
|
}
|
|
|
|
}
|