fix package api bug and add some package query

This commit is contained in:
ItsMalma
2025-12-18 07:51:21 +07:00
parent 9ac6e9e3fd
commit d13d9fa158
3 changed files with 75 additions and 21 deletions

View File

@@ -34,6 +34,7 @@ import {
packageDetailParamsSchema,
packageDetailRequestSchema,
packageParamsSchema,
packageQuerySchema,
packageRequestSchema,
} from "@/modules/package/package.schemas";
import type {
@@ -41,7 +42,7 @@ import type {
PackageDetailResponse,
PackageResponse,
} from "@/modules/package/package.types";
import { wrap } from "@mikro-orm/core";
import { wrap, type OrderDefinition } from "@mikro-orm/core";
import { Router, type Request, type Response } from "express";
import slugify from "slugify";
import { ulid } from "ulid";
@@ -143,7 +144,7 @@ export class PackageController extends Controller {
}
async list(req: Request, res: Response) {
const parseQueryResult = paginationQuerySchema.safeParse(req.query);
const parseQueryResult = packageQuerySchema.safeParse(req.query);
if (!parseQueryResult.success) {
return this.handleZodError(parseQueryResult.error, res, "query");
}
@@ -151,16 +152,45 @@ export class PackageController extends Controller {
const count = await orm.em.count(Package);
const packages = await orm.em.find(
Package,
{},
{
limit: query.per_page,
offset: (query.page - 1) * query.per_page,
orderBy: { createdAt: "DESC" },
populate: ["*"],
},
);
const orderBy: OrderDefinition<Package> = {};
switch (query.sort_by) {
case "newest":
orderBy.createdAt = "DESC";
break;
case "oldest":
orderBy.createdAt = "ASC";
break;
}
let packageQueryBuilder = orm.em
.createQueryBuilder(Package, "_package")
.select(["*"], true)
.distinctOn(["class"])
.limit(query.per_page)
.offset((query.page - 1) * query.per_page)
.leftJoinAndSelect("_package.partner", "_partner");
if ("class" in query && query.class) {
packageQueryBuilder = packageQueryBuilder.where({ class: query.class });
}
if ("by_ideal" in query && query.by_ideal) {
packageQueryBuilder = packageQueryBuilder.where({ class: "by_ideal" });
}
switch (query.sort_by) {
case "newest":
packageQueryBuilder = packageQueryBuilder.orderBy({
"_package.created_at": "DESC",
});
break;
case "oldest":
packageQueryBuilder = packageQueryBuilder.orderBy({
"_package.created_at": "ASC",
});
break;
}
const packages = await packageQueryBuilder.getResultList();
return res.status(200).json({
data: packages.map(this.mapper.mapEntityToResponse.bind(this.mapper)),
@@ -376,10 +406,9 @@ export class PackageController extends Controller {
}
let outboundFlightSchedule: FlightSchedule | null = null;
for (const [
index,
outboundFlightId,
] of body.outbound_flight_ids.entries()) {
for (const [index, outboundFlightId] of body.outbound_flight_ids
.toReversed()
.entries()) {
const outboundFlight = await orm.em.findOne(
FlightClass,
{ id: outboundFlightId },
@@ -954,10 +983,9 @@ export class PackageController extends Controller {
orm.em.remove(outboundFlight);
}
let outboundFlightSchedule: FlightSchedule | null = null;
for (const [
index,
outboundFlightId,
] of body.outbound_flight_ids.entries()) {
for (const [index, outboundFlightId] of body.outbound_flight_ids
.toReversed()
.entries()) {
const outboundFlight = await orm.em.findOne(
FlightClass,
{ id: outboundFlightId },

View File

@@ -1,4 +1,4 @@
import { dateSchema } from "@/common/schemas";
import { dateSchema, paginationQuerySchema } from "@/common/schemas";
import { PackageClass } from "@/database/enums/package-class.enum";
import { PackageType } from "@/database/enums/package-type.enum";
import z from "zod";
@@ -205,6 +205,29 @@ 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
.stringbool("Must be string boolean 'true' or 'false'.")
.optional(),
}),
]),
z.object({
sort_by: z
.enum(["newest", "oldest"], "Must be either 'newest' or 'oldest'.")
.default("newest"),
}),
),
);
export const packageParamsSchema = z.object({
id: z
.ulid("Must be ulid string.")

View File

@@ -6,6 +6,7 @@ import type {
packageDetailParamsSchema,
packageDetailRequestSchema,
packageParamsSchema,
packageQuerySchema,
packageRequestSchema,
} from "@/modules/package/package.schemas";
import type { PartnerResponse } from "@/modules/partner/partner.types";
@@ -16,6 +17,8 @@ export type PackageRequest = z.infer<typeof packageRequestSchema>;
export type PackageDetailRequest = z.infer<typeof packageDetailRequestSchema>;
export type PackageQuery = z.infer<typeof packageQuerySchema>;
export type PackageParams = z.infer<typeof packageParamsSchema>;
export type PackageDetailParams = z.infer<typeof packageDetailParamsSchema>;