fix: harden real backend workflows and channel connections
This commit is contained in:
@@ -4,7 +4,7 @@ import { PrismaService } from '../prisma/prisma.service';
|
||||
|
||||
export interface CreateTenantDto {
|
||||
name: string;
|
||||
code: string;
|
||||
code?: string;
|
||||
status?: string;
|
||||
creditCode?: string;
|
||||
province?: string;
|
||||
@@ -44,6 +44,31 @@ export class TenantsService {
|
||||
}).then((items) => items.map(withEnterpriseProfile));
|
||||
}
|
||||
|
||||
async listManagementRows() {
|
||||
const sinceToday = startOfToday();
|
||||
const [tenants, accounts, todaySpendGroups] = await Promise.all([
|
||||
this.prisma.tenant.findMany({
|
||||
where: { status: { not: 'deleted' } },
|
||||
include: { enterpriseCertifications: { orderBy: { submittedAt: 'desc' }, take: 1 } },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 100,
|
||||
}),
|
||||
this.prisma.tenantAccount.findMany({ take: 200 }),
|
||||
this.prisma.smsMessageRecord.groupBy({
|
||||
by: ['tenantId'],
|
||||
where: { queuedAt: { gte: sinceToday } },
|
||||
_sum: { amountCents: true },
|
||||
}),
|
||||
]);
|
||||
const accountsByTenant = new Map(accounts.map((account) => [account.tenantId, account]));
|
||||
const todaySpendByTenant = new Map(todaySpendGroups.map((group) => [group.tenantId, group._sum.amountCents ?? 0]));
|
||||
return tenants.map((tenant) => ({
|
||||
...withEnterpriseProfile(tenant),
|
||||
account: accountsByTenant.get(tenant.id) ?? null,
|
||||
todaySpendCents: todaySpendByTenant.get(tenant.id) ?? 0,
|
||||
}));
|
||||
}
|
||||
|
||||
get(id: string) {
|
||||
return this.prisma.tenant.findUnique({
|
||||
where: { id },
|
||||
@@ -57,8 +82,9 @@ export class TenantsService {
|
||||
}
|
||||
|
||||
async create(data: CreateTenantDto) {
|
||||
const code = data.code?.trim() || generateTenantCode(data);
|
||||
const tenant = await this.prisma.tenant.create({
|
||||
data: { name: data.name, code: data.code, status: data.status ?? 'active' },
|
||||
data: { name: data.name, code, status: data.status ?? 'active' },
|
||||
});
|
||||
await this.upsertProfile(tenant.id, data);
|
||||
return this.get(tenant.id);
|
||||
@@ -163,3 +189,16 @@ function withEnterpriseProfile<T extends { enterpriseCertifications?: Array<{ li
|
||||
} : null,
|
||||
};
|
||||
}
|
||||
|
||||
function startOfToday() {
|
||||
const date = new Date();
|
||||
date.setHours(0, 0, 0, 0);
|
||||
return date;
|
||||
}
|
||||
|
||||
function generateTenantCode(data: CreateTenantDto) {
|
||||
const source = data.creditCode?.trim() || data.name.trim();
|
||||
const normalized = source.replace(/[^\da-zA-Z]/g, '').toLowerCase();
|
||||
const suffix = Date.now().toString(36).slice(-6);
|
||||
return `ent-${(normalized || 'tenant').slice(0, 18)}-${suffix}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user