order creation logic fix, refactor & cleanup on admin end

This commit is contained in:
user
2025-10-21 19:20:56 +03:00
parent b6bdb6d7e8
commit f0fa53a4e5
19 changed files with 100 additions and 415 deletions

View File

@@ -1,5 +1,5 @@
import { desc, eq, type Database } from "@pkg/db";
import { customerInfo } from "@pkg/db/schema";
import { customerInfo, order } from "@pkg/db/schema";
import { getError, Logger } from "@pkg/logger";
import { ERROR_CODES, type Result } from "@pkg/result";
import {
@@ -97,6 +97,45 @@ export class CustomerInfoRepository {
}
}
async getCustomerInfoByOrderId(
oid: number,
): Promise<Result<CustomerInfoModel>> {
try {
const result = await this.db.query.order.findFirst({
where: eq(order.id, oid),
columns: { id: true },
with: { customerInfo: true },
});
const parsed = customerInfoModel.safeParse(result?.customerInfo);
if (!parsed.success) {
Logger.error("Failed to parse customer info", result);
return {
error: getError({
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
message: "Failed to parse customer information",
userHint: "Please try again",
detail: "Failed to parse customer information",
}),
};
}
return { data: parsed.data };
} catch (e) {
return {
error: getError(
{
code: ERROR_CODES.DATABASE_ERROR,
message: "Failed to fetch customer information",
detail:
"An error occurred while retrieving the customer information from the database",
userHint: "Please try refreshing the page",
actionable: false,
},
e,
),
};
}
}
async createCustomerInfo(
payload: CreateCustomerInfoPayload,
): Promise<Result<number>> {

View File

@@ -20,6 +20,10 @@ export class CustomerInfoUseCases {
return this.repo.getCustomerInfoById(id);
}
async getCustomerInfoByOrderId(oid: number) {
return this.repo.getCustomerInfoByOrderId(oid);
}
async createCustomerInfo(payload: CreateCustomerInfoPayload) {
return this.repo.createCustomerInfo(payload);
}

View File

@@ -19,7 +19,7 @@ export enum OrderStatus {
}
export const orderPriceDetailsModel = z.object({
currency: z.string(),
currency: z.string().optional(),
discountAmount: z.coerce.number().min(0),
basePrice: z.coerce.number().min(0),
displayPrice: z.coerce.number().min(0),
@@ -114,7 +114,7 @@ export const newOrderModel = orderModel
paymentInfoId: true,
})
.extend({
currency: z.string().default("USD"),
currency: z.string().optional().default("USD"),
customerInfoId: z.number().optional(),
paymentInfoId: z.number().optional(),
});

View File

@@ -1,59 +0,0 @@
import { z } from "zod";
import { paymentInfoModel } from "../../paymentinfo/data/entities";
export enum Gender {
Male = "male",
Female = "female",
Other = "other",
}
export enum PassengerType {
Adult = "adult",
Child = "child",
}
export const customerInfoModel = z.object({
firstName: z.string().min(1).max(255),
middleName: z.string().min(0).max(255),
lastName: z.string().min(1).max(255),
email: z.string().email(),
phoneCountryCode: z.string().min(2).max(6).regex(/^\+/),
phoneNumber: z.string().min(2).max(20),
nationality: z.string().min(1).max(128),
gender: z.enum([Gender.Male, Gender.Female, Gender.Other]),
dob: z.string().date(),
passportNo: z.string().min(1).max(64),
// add a custom validator to ensure this is not expired (present or older)
passportExpiry: z
.string()
.date()
.refine(
(v) => new Date(v).getTime() > new Date().getTime(),
"Passport expiry must be in the future",
),
country: z.string().min(1).max(128),
state: z.string().min(1).max(128),
city: z.string().min(1).max(128),
zipCode: z.string().min(4).max(21),
address: z.string().min(1).max(128),
address2: z.string().min(0).max(128),
});
export type CustomerInfo = z.infer<typeof customerInfoModel>;
export const passengerInfoModel = z.object({
id: z.number(),
passengerType: z.enum([PassengerType.Adult, PassengerType.Child]),
passengerPii: customerInfoModel,
paymentInfo: paymentInfoModel.optional(),
passengerPiiId: z.number().optional(),
paymentInfoId: z.number().optional(),
seatSelection: z.any(),
bagSelection: z.any(),
agentsInfo: z.boolean().default(false).optional(),
agentId: z.coerce.string().optional(),
flightTicketInfoId: z.number().optional(),
orderId: z.number().optional(),
});
export type PassengerInfo = z.infer<typeof passengerInfoModel>;

View File

@@ -87,8 +87,8 @@ export const paymentInfoModel = cardInfoModel.merge(
id: z.number().int(),
productId: z.number().int(),
orderId: z.number().int(),
createdAt: z.string().datetime(),
updatedAt: z.string().datetime(),
createdAt: z.coerce.string().datetime(),
updatedAt: z.coerce.string().datetime(),
}),
);
export type PaymentInfo = z.infer<typeof paymentInfoModel>;