feat(customers): opt-in debug block on the omde lists, printed in the panel console

Sending X-Debug: 1 makes the five wholesale list endpoints return a counts-only
`debug` block next to the rows: the WHERE that actually ran, how many customers
the scope matches before the grid's own filters, how many customers exist per
kind/active/archived/step and how many are an expert's trading account. The
panel sends the header and console-logs the block when localStorage.debug === '1'.

Off by default; DIAG_LOG=false disables it server-side. No names or mobiles.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
mahmood
2026-10-26 08:59:33 +03:30
co-authored by Claude Sonnet 5.5
parent ab39f6abed
commit 0156a976e7
4 changed files with 113 additions and 16 deletions
@@ -296,7 +296,39 @@ export class AdminCustomersService {
}
}
async list(query: TableQueryDto, scope: OmdeScope = 'all') {
/**
* Opt-in (X-Debug header) troubleshooting block for an empty list: counts only,
* no names/mobiles. Shows the exact WHERE the request ran, how many customers
* the scope matches before the grid's own filters, and how many customers
* exist per kind / are an expert's trading account. Off with DIAG_LOG=false.
*/
private async listDebug(
scope: OmdeScope,
scoped: Prisma.CustomerWhereInput,
total: number,
returned: number,
) {
const [byKind, inScope, expertTradingAccounts] = await Promise.all([
this.prisma.customer.groupBy({
by: ['kind', 'isActive', 'isArchived', 'verificationStep'],
_count: { _all: true },
}),
this.prisma.customer.count({ where: this.scopeWhere(scope) }),
this.prisma.customer.count({ where: { salesExpertTradingFor: { isNot: null } } }),
]);
return {
scope,
where: scoped,
matched_with_grid_filters: total,
returned_rows: returned,
matched_by_scope_only: inScope,
customers_total: byKind.reduce((n, g) => n + g._count._all, 0),
expert_trading_accounts: expertTradingAccounts,
by_kind: byKind.map(({ _count, ...g }) => ({ ...g, n: _count._all })),
};
}
async list(query: TableQueryDto, scope: OmdeScope = 'all', debug = false) {
this.table.assertNotExport(query);
const aliased = this.applyAliases(query);
@@ -325,13 +357,15 @@ export class AdminCustomersService {
]);
const linked = await this.accountingLinked(rows.map((r) => r.id));
return this.table.respond(
const result = this.table.respond(
rows.map((r) => ({ ...this.toRow(r), ...AdminCustomersService.accountingCells(r, linked) })),
total,
query,
page,
limit,
);
if (!debug || process.env.DIAG_LOG === 'false') return result;
return { ...result, debug: await this.listDebug(scope, scoped, total, rows.length) };
}
/**