Implement WHMCS Addon Dashboard with API for stats and integrate billing provider logic
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

This commit is contained in:
smueller
2026-06-26 15:11:29 +02:00
parent 15cf302afc
commit 4b20efe4bc
30 changed files with 1414 additions and 16 deletions

View File

@@ -0,0 +1,84 @@
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,
};
}
}