fix package api bug and add some package query
This commit is contained in:
@@ -34,6 +34,7 @@ import {
|
|||||||
packageDetailParamsSchema,
|
packageDetailParamsSchema,
|
||||||
packageDetailRequestSchema,
|
packageDetailRequestSchema,
|
||||||
packageParamsSchema,
|
packageParamsSchema,
|
||||||
|
packageQuerySchema,
|
||||||
packageRequestSchema,
|
packageRequestSchema,
|
||||||
} from "@/modules/package/package.schemas";
|
} from "@/modules/package/package.schemas";
|
||||||
import type {
|
import type {
|
||||||
@@ -41,7 +42,7 @@ import type {
|
|||||||
PackageDetailResponse,
|
PackageDetailResponse,
|
||||||
PackageResponse,
|
PackageResponse,
|
||||||
} from "@/modules/package/package.types";
|
} 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 { Router, type Request, type Response } from "express";
|
||||||
import slugify from "slugify";
|
import slugify from "slugify";
|
||||||
import { ulid } from "ulid";
|
import { ulid } from "ulid";
|
||||||
@@ -143,7 +144,7 @@ export class PackageController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async list(req: Request, res: Response) {
|
async list(req: Request, res: Response) {
|
||||||
const parseQueryResult = paginationQuerySchema.safeParse(req.query);
|
const parseQueryResult = packageQuerySchema.safeParse(req.query);
|
||||||
if (!parseQueryResult.success) {
|
if (!parseQueryResult.success) {
|
||||||
return this.handleZodError(parseQueryResult.error, res, "query");
|
return this.handleZodError(parseQueryResult.error, res, "query");
|
||||||
}
|
}
|
||||||
@@ -151,16 +152,45 @@ export class PackageController extends Controller {
|
|||||||
|
|
||||||
const count = await orm.em.count(Package);
|
const count = await orm.em.count(Package);
|
||||||
|
|
||||||
const packages = await orm.em.find(
|
const orderBy: OrderDefinition<Package> = {};
|
||||||
Package,
|
switch (query.sort_by) {
|
||||||
{},
|
case "newest":
|
||||||
{
|
orderBy.createdAt = "DESC";
|
||||||
limit: query.per_page,
|
break;
|
||||||
offset: (query.page - 1) * query.per_page,
|
case "oldest":
|
||||||
orderBy: { createdAt: "DESC" },
|
orderBy.createdAt = "ASC";
|
||||||
populate: ["*"],
|
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({
|
return res.status(200).json({
|
||||||
data: packages.map(this.mapper.mapEntityToResponse.bind(this.mapper)),
|
data: packages.map(this.mapper.mapEntityToResponse.bind(this.mapper)),
|
||||||
@@ -376,10 +406,9 @@ export class PackageController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let outboundFlightSchedule: FlightSchedule | null = null;
|
let outboundFlightSchedule: FlightSchedule | null = null;
|
||||||
for (const [
|
for (const [index, outboundFlightId] of body.outbound_flight_ids
|
||||||
index,
|
.toReversed()
|
||||||
outboundFlightId,
|
.entries()) {
|
||||||
] of body.outbound_flight_ids.entries()) {
|
|
||||||
const outboundFlight = await orm.em.findOne(
|
const outboundFlight = await orm.em.findOne(
|
||||||
FlightClass,
|
FlightClass,
|
||||||
{ id: outboundFlightId },
|
{ id: outboundFlightId },
|
||||||
@@ -954,10 +983,9 @@ export class PackageController extends Controller {
|
|||||||
orm.em.remove(outboundFlight);
|
orm.em.remove(outboundFlight);
|
||||||
}
|
}
|
||||||
let outboundFlightSchedule: FlightSchedule | null = null;
|
let outboundFlightSchedule: FlightSchedule | null = null;
|
||||||
for (const [
|
for (const [index, outboundFlightId] of body.outbound_flight_ids
|
||||||
index,
|
.toReversed()
|
||||||
outboundFlightId,
|
.entries()) {
|
||||||
] of body.outbound_flight_ids.entries()) {
|
|
||||||
const outboundFlight = await orm.em.findOne(
|
const outboundFlight = await orm.em.findOne(
|
||||||
FlightClass,
|
FlightClass,
|
||||||
{ id: outboundFlightId },
|
{ id: outboundFlightId },
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { dateSchema } from "@/common/schemas";
|
import { dateSchema, paginationQuerySchema } from "@/common/schemas";
|
||||||
import { PackageClass } from "@/database/enums/package-class.enum";
|
import { PackageClass } from "@/database/enums/package-class.enum";
|
||||||
import { PackageType } from "@/database/enums/package-type.enum";
|
import { PackageType } from "@/database/enums/package-type.enum";
|
||||||
import z from "zod";
|
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({
|
export const packageParamsSchema = z.object({
|
||||||
id: z
|
id: z
|
||||||
.ulid("Must be ulid string.")
|
.ulid("Must be ulid string.")
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import type {
|
|||||||
packageDetailParamsSchema,
|
packageDetailParamsSchema,
|
||||||
packageDetailRequestSchema,
|
packageDetailRequestSchema,
|
||||||
packageParamsSchema,
|
packageParamsSchema,
|
||||||
|
packageQuerySchema,
|
||||||
packageRequestSchema,
|
packageRequestSchema,
|
||||||
} from "@/modules/package/package.schemas";
|
} from "@/modules/package/package.schemas";
|
||||||
import type { PartnerResponse } from "@/modules/partner/partner.types";
|
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 PackageDetailRequest = z.infer<typeof packageDetailRequestSchema>;
|
||||||
|
|
||||||
|
export type PackageQuery = z.infer<typeof packageQuerySchema>;
|
||||||
|
|
||||||
export type PackageParams = z.infer<typeof packageParamsSchema>;
|
export type PackageParams = z.infer<typeof packageParamsSchema>;
|
||||||
|
|
||||||
export type PackageDetailParams = z.infer<typeof packageDetailParamsSchema>;
|
export type PackageDetailParams = z.infer<typeof packageDetailParamsSchema>;
|
||||||
|
|||||||
Reference in New Issue
Block a user