From 380c92a62bb69d8f0d1ff614755d274e116bf42b Mon Sep 17 00:00:00 2001 From: ItsMalma Date: Thu, 18 Dec 2025 08:33:57 +0700 Subject: [PATCH] fix package list query --- src/modules/package/package.controller.ts | 43 +++++++++++++---------- src/modules/package/package.schemas.ts | 26 +++++--------- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/modules/package/package.controller.ts b/src/modules/package/package.controller.ts index f285c6e..d8f35e5 100644 --- a/src/modules/package/package.controller.ts +++ b/src/modules/package/package.controller.ts @@ -42,7 +42,11 @@ import type { PackageDetailResponse, PackageResponse, } from "@/modules/package/package.types"; -import { wrap } from "@mikro-orm/core"; +import { + wrap, + type QBFilterQuery, + type QBQueryOrderMap, +} from "@mikro-orm/core"; import { Router, type Request, type Response } from "express"; import slugify from "slugify"; import { ulid } from "ulid"; @@ -152,36 +156,39 @@ export class PackageController extends Controller { const count = await orm.em.count(Package); - let packageQueryBuilder = orm.em - .createQueryBuilder(Package, "_package") - .select(["*"]) - .limit(query.per_page) - .offset((query.page - 1) * query.per_page) - .leftJoinAndSelect("_package.partner", "_partner"); + const distinctOn: (keyof Package)[] = ["id"]; + const where: QBFilterQuery = {}; + const orderBy: QBQueryOrderMap = { + id: "desc", + }; if ("class" in query && query.class) { - packageQueryBuilder = packageQueryBuilder.where({ class: query.class }); + where.class = query.class; } if ("by_ideal" in query && query.by_ideal === "1") { - packageQueryBuilder = packageQueryBuilder.distinctOn(["class"]).orderBy({ - class: "ASC", - }); + distinctOn.push("class"); + orderBy.class = "ASC"; } switch (query.sort_by) { case "newest": - packageQueryBuilder = packageQueryBuilder.orderBy({ - createdAt: "DESC", - }); + orderBy.createdAt = "DESC"; break; case "oldest": - packageQueryBuilder = packageQueryBuilder.orderBy({ - createdAt: "ASC", - }); + orderBy.createdAt = "ASC"; break; } - const packages = await packageQueryBuilder.getResultList(); + const packages = await orm.em + .createQueryBuilder(Package, "_package") + .select(["*"]) + .distinctOn(distinctOn) + .limit(query.per_page) + .offset((query.page - 1) * query.per_page) + .leftJoinAndSelect("_package.partner", "_partner") + .where(where) + .orderBy(orderBy) + .getResultList(); return res.status(200).json({ data: packages.map(this.mapper.mapEntityToResponse.bind(this.mapper)), diff --git a/src/modules/package/package.schemas.ts b/src/modules/package/package.schemas.ts index 080c9d4..3b5ed75 100644 --- a/src/modules/package/package.schemas.ts +++ b/src/modules/package/package.schemas.ts @@ -207,23 +207,15 @@ export const packageDetailRequestSchema = z.object({ export const packageQuerySchema = z.intersection( paginationQuerySchema, - z.intersection( - z.union([ - z.object({ - class: z - .enum(PackageClass, "Must be either 'silver', 'gold', or 'platinum'.") - .optional(), - }), - z.object({ - by_ideal: z.enum(["0", "1"], "Must be either '0' or '1'.").optional(), - }), - ]), - z.object({ - sort_by: z - .enum(["newest", "oldest"], "Must be either 'newest' or 'oldest'.") - .default("newest"), - }), - ), + z.object({ + class: z + .enum(PackageClass, "Must be either 'silver', 'gold', or 'platinum'.") + .optional(), + by_ideal: z.enum(["0", "1"], "Must be either '0' or '1'.").optional(), + sort_by: z + .enum(["newest", "oldest"], "Must be either 'newest' or 'oldest'.") + .default("newest"), + }), ); export const packageParamsSchema = z.object({