Browse Source

Bugfix/fix pagination issue in market data and user endpoint by adding secondary sort criterion (#5521)

* Add id as secondary sort criterion to ensure consistent ordering

* Refactoring

* Update changelog
pull/5523/head
Thomas Kaul 1 week ago
committed by GitHub
parent
commit
f7f942d08d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 5
      CHANGELOG.md
  2. 34
      apps/api/src/app/admin/admin.service.ts
  3. 12
      apps/api/src/app/order/order.service.ts

5
CHANGELOG.md

@ -18,6 +18,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Refactored the login with access token dialog component to standalone - Refactored the login with access token dialog component to standalone
- Prefixed the `crypto`, `fs` and `path` imports with `node:` - Prefixed the `crypto`, `fs` and `path` imports with `node:`
### Fixed
- Fixed a pagination issue in the market data endpoint by adding `id` as a secondary sort criterion to ensure consistent ordering in the admin control panel
- Fixed a pagination issue in the user endpoint by adding `id` as a secondary sort criterion to ensure consistent ordering in the admin control panel
## 2.198.0 - 2025-09-11 ## 2.198.0 - 2025-09-11
### Changed ### Changed

34
apps/api/src/app/admin/admin.service.ts

@ -192,7 +192,7 @@ export class AdminService {
filters, filters,
presetId, presetId,
sortColumn, sortColumn,
sortDirection, sortDirection = 'asc',
skip, skip,
take = Number.MAX_SAFE_INTEGER take = Number.MAX_SAFE_INTEGER
}: { }: {
@ -262,11 +262,13 @@ export class AdminService {
orderBy = [{ [sortColumn]: sortDirection }]; orderBy = [{ [sortColumn]: sortDirection }];
if (sortColumn === 'activitiesCount') { if (sortColumn === 'activitiesCount') {
orderBy = { orderBy = [
activities: { {
_count: sortDirection activities: {
_count: sortDirection
}
} }
}; ];
} }
} }
@ -275,10 +277,10 @@ export class AdminService {
try { try {
const symbolProfileResult = await Promise.all([ const symbolProfileResult = await Promise.all([
extendedPrismaClient.symbolProfile.findMany({ extendedPrismaClient.symbolProfile.findMany({
orderBy,
skip, skip,
take, take,
where, where,
orderBy: [...orderBy, { id: sortDirection }],
select: { select: {
_count: { _count: {
select: { select: {
@ -817,17 +819,21 @@ export class AdminService {
skip?: number; skip?: number;
take?: number; take?: number;
}): Promise<AdminUsers['users']> { }): Promise<AdminUsers['users']> {
let orderBy: Prisma.UserOrderByWithRelationInput = { let orderBy: Prisma.Enumerable<Prisma.UserOrderByWithRelationInput> = [
createdAt: 'desc' { createdAt: 'desc' }
}; ];
let where: Prisma.UserWhereInput; let where: Prisma.UserWhereInput;
if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) { if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) {
orderBy = { orderBy = [
analytics: { {
lastRequestAt: 'desc' analytics: {
lastRequestAt: 'desc'
}
} }
}; ];
where = { where = {
NOT: { NOT: {
analytics: null analytics: null
@ -836,10 +842,10 @@ export class AdminService {
} }
const usersWithAnalytics = await this.prismaService.user.findMany({ const usersWithAnalytics = await this.prismaService.user.findMany({
orderBy,
skip, skip,
take, take,
where, where,
orderBy: [...orderBy, { id: 'desc' }],
select: { select: {
_count: { _count: {
select: { accounts: true, activities: true } select: { accounts: true, activities: true }

12
apps/api/src/app/order/order.service.ts

@ -325,7 +325,7 @@ export class OrderService {
includeDrafts = false, includeDrafts = false,
skip, skip,
sortColumn, sortColumn,
sortDirection, sortDirection = 'asc',
startDate, startDate,
take = Number.MAX_SAFE_INTEGER, take = Number.MAX_SAFE_INTEGER,
types, types,
@ -347,9 +347,9 @@ export class OrderService {
withExcludedAccountsAndActivities?: boolean; withExcludedAccountsAndActivities?: boolean;
}): Promise<Activities> { }): Promise<Activities> {
let orderBy: Prisma.Enumerable<Prisma.OrderOrderByWithRelationInput> = [ let orderBy: Prisma.Enumerable<Prisma.OrderOrderByWithRelationInput> = [
{ date: 'asc' }, { date: 'asc' }
{ id: 'asc' }
]; ];
const where: Prisma.OrderWhereInput = { userId }; const where: Prisma.OrderWhereInput = { userId };
if (endDate || startDate) { if (endDate || startDate) {
@ -483,7 +483,7 @@ export class OrderService {
} }
if (sortColumn) { if (sortColumn) {
orderBy = [{ [sortColumn]: sortDirection }, { id: sortDirection }]; orderBy = [{ [sortColumn]: sortDirection }];
} }
if (types) { if (types) {
@ -506,7 +506,6 @@ export class OrderService {
const [orders, count] = await Promise.all([ const [orders, count] = await Promise.all([
this.orders({ this.orders({
orderBy,
skip, skip,
take, take,
where, where,
@ -519,7 +518,8 @@ export class OrderService {
// eslint-disable-next-line @typescript-eslint/naming-convention // eslint-disable-next-line @typescript-eslint/naming-convention
SymbolProfile: true, SymbolProfile: true,
tags: true tags: true
} },
orderBy: [...orderBy, { id: sortDirection }]
}), }),
this.prismaService.order.count({ where }) this.prismaService.order.count({ where })
]); ]);

Loading…
Cancel
Save