Files
HexaHost-GameCloud/apps/api/src/integrations/whmcs/whmcs-dashboard.service.ts
smueller 4b20efe4bc
Some checks failed
CI / Node — lint, typecheck, test, build (push) Failing after 10s
CI / Go — node-agent tests (push) Failing after 8s
CI / Go — edge-gateway build (push) Successful in 17s
Implement WHMCS Addon Dashboard with API for stats and integrate billing provider logic
2026-06-26 15:11:29 +02:00

85 lines
2.7 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import type { WhmcsDashboardStatsResponse } from '@hexahost/contracts';
import { getBillingProvider } from '../../billing/billing-provider';
import { PrismaService } from '../../prisma/prisma.service';
type InstallationRef = {
id: string;
integrationId: string;
};
@Injectable()
export class WhmcsDashboardService {
constructor(private readonly prisma: PrismaService) {}
async getStats(installation: InstallationRef): Promise<WhmcsDashboardStatsResponse> {
const [
linkedClients,
linkedServices,
pendingEvents,
deadLetterEvents,
openIssues,
exportedUsagePeriods,
syncCursor,
lastReconciledLink,
] = await Promise.all([
this.prisma.whmcsClientLink.count({
where: { installationId: installation.id },
}),
this.prisma.whmcsServiceLink.count({
where: { installationId: installation.id },
}),
this.prisma.integrationEvent.count({
where: { installationId: installation.id, status: 'PENDING' },
}),
this.prisma.integrationEvent.count({
where: { installationId: installation.id, status: 'DEAD_LETTER' },
}),
this.prisma.reconciliationIssue.count({
where: { installationId: installation.id, resolvedAt: null },
}),
this.prisma.whmcsUsageExport.count({
where: { installationId: installation.id, status: { in: ['EXPORTED', 'ADJUSTED'] } },
}),
this.prisma.integrationSyncCursor.findUnique({
where: { installationId: installation.id },
}),
this.prisma.whmcsServiceLink.findFirst({
where: {
installationId: installation.id,
lastReconciledAt: { not: null },
},
orderBy: { lastReconciledAt: 'desc' },
select: { lastReconciledAt: true },
}),
]);
const suspendedServices = await this.prisma.whmcsServiceLink.count({
where: { installationId: installation.id, status: 'SUSPENDED' },
});
const terminatedServices = await this.prisma.whmcsServiceLink.count({
where: { installationId: installation.id, status: 'TERMINATED' },
});
return {
integrationId: installation.integrationId,
billingProvider: getBillingProvider(),
moduleVersion: '1.0.0',
linkedClients,
linkedServices,
suspendedServices,
terminatedServices,
pendingEvents,
deadLetterEvents,
openReconciliationIssues: openIssues,
exportedUsagePeriods,
eventsCursor: syncCursor?.eventsCursor ?? null,
lastEventSyncAt: syncCursor?.updatedAt.toISOString() ?? null,
lastReconciliationAt: lastReconciledLink?.lastReconciledAt?.toISOString() ?? null,
};
}
}