From f0fa53a4e5c86c340f7d8a04e8ab02c74445da4a Mon Sep 17 00:00:00 2001 From: user Date: Tue, 21 Oct 2025 19:20:56 +0300 Subject: [PATCH] =?UTF-8?q?=E2=9C=85=20order=20creation=20logic=20fix,=20r?= =?UTF-8?q?efactor=20&=20cleanup=20on=20admin=20end?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../molecules/sidebar/layout-sidebar.svelte | 18 -- .../view/customerinfo-table.svelte | 2 +- .../order/view/orders-table-full.svelte | 8 - .../src/lib/domains/paymentinfo/repository.ts | 6 +- .../src/routes/(main)/data/+page.server.ts | 13 -- .../admin/src/routes/(main)/data/+page.svelte | 36 --- .../routes/(main)/data/[uid]/+page.server.ts | 30 --- .../src/routes/(main)/data/[uid]/+page.svelte | 216 ------------------ .../(main)/orders/[oid]/+page.server.ts | 5 +- .../routes/(main)/orders/[oid]/+page.svelte | 16 +- .../payment-verification-section.svelte | 18 +- .../src/lib/domains/order/domain/router.ts | 13 +- .../domains/paymentinfo/data/repository.ts | 18 +- .../domains/paymentinfo/domain/usecases.ts | 4 + .../logic/domains/customerinfo/repository.ts | 41 +++- .../logic/domains/customerinfo/usecases.ts | 4 + packages/logic/domains/order/data/entities.ts | 4 +- .../domains/passengerinfo/data/entities.ts | 59 ----- .../domains/paymentinfo/data/entities.ts | 4 +- 19 files changed, 100 insertions(+), 415 deletions(-) delete mode 100644 apps/admin/src/routes/(main)/data/+page.server.ts delete mode 100644 apps/admin/src/routes/(main)/data/+page.svelte delete mode 100644 apps/admin/src/routes/(main)/data/[uid]/+page.server.ts delete mode 100644 apps/admin/src/routes/(main)/data/[uid]/+page.svelte delete mode 100644 packages/logic/domains/passengerinfo/data/entities.ts diff --git a/apps/admin/src/lib/components/molecules/sidebar/layout-sidebar.svelte b/apps/admin/src/lib/components/molecules/sidebar/layout-sidebar.svelte index bbcd225..eafad96 100644 --- a/apps/admin/src/lib/components/molecules/sidebar/layout-sidebar.svelte +++ b/apps/admin/src/lib/components/molecules/sidebar/layout-sidebar.svelte @@ -6,14 +6,11 @@ import Icon from "$lib/components/atoms/icon.svelte"; import { adminSiteNavMap } from "$lib/core/constants"; import { sessionUserInfo } from "$lib/stores/session.info"; - import { SettingsIcon } from "@lucide/svelte"; import ProductIcon from "~icons/carbon/carbon-for-ibm-product"; import SessionIcon from "~icons/carbon/prompt-session"; import HistoryIcon from "~icons/iconamoon/history-light"; - import BillListIcon from "~icons/solar/bill-list-linear"; import PackageIcon from "~icons/solar/box-broken"; import DashboardIcon from "~icons/solar/laptop-minimalistic-broken"; - import UsersIcon from "~icons/solar/users-group-two-rounded-broken"; const mainLinks = [ { @@ -31,11 +28,6 @@ title: "Session History", url: adminSiteNavMap.sessions.history, }, - { - icon: BillListIcon, - title: "Data", - url: adminSiteNavMap.data, - }, { icon: PackageIcon, title: "Orders", @@ -47,16 +39,6 @@ title: "Products", url: adminSiteNavMap.products, }, - { - icon: UsersIcon, - title: "Profile", - url: adminSiteNavMap.profile, - }, - { - icon: SettingsIcon, - title: "Settings", - url: adminSiteNavMap.settings, - }, ]; let { diff --git a/apps/admin/src/lib/domains/customerinfo/view/customerinfo-table.svelte b/apps/admin/src/lib/domains/customerinfo/view/customerinfo-table.svelte index a2eef3a..662354d 100644 --- a/apps/admin/src/lib/domains/customerinfo/view/customerinfo-table.svelte +++ b/apps/admin/src/lib/domains/customerinfo/view/customerinfo-table.svelte @@ -56,7 +56,7 @@ header: "Location", id: "location", cell: ({ row }) => { - return `${row.original.city}, ${row.original.state}`; + return `${row.original.country}, ${row.original.city}`; }, }, { diff --git a/apps/admin/src/lib/domains/order/view/orders-table-full.svelte b/apps/admin/src/lib/domains/order/view/orders-table-full.svelte index 3e56b7b..6cfe490 100644 --- a/apps/admin/src/lib/domains/order/view/orders-table-full.svelte +++ b/apps/admin/src/lib/domains/order/view/orders-table-full.svelte @@ -32,14 +32,6 @@ return Number(row.id) + 1; }, }, - { - header: "Order ID", - accessorKey: "orderId", - cell: ({ row }) => { - const r = row.original as FullOrderModel; - return `#${r.id}`; - }, - }, { header: "Product", accessorKey: "product", diff --git a/apps/admin/src/lib/domains/paymentinfo/repository.ts b/apps/admin/src/lib/domains/paymentinfo/repository.ts index 41d2eab..adf1d28 100644 --- a/apps/admin/src/lib/domains/paymentinfo/repository.ts +++ b/apps/admin/src/lib/domains/paymentinfo/repository.ts @@ -7,10 +7,10 @@ import { paymentInfoModel, type PaymentInfo } from "./data"; export class PaymentInfoRepository { constructor(private db: Database) {} - async getPaymentInfo(id: number): Promise> { - Logger.info(`Getting payment info with id ${id}`); + async getPaymentInfoByOrderID(oid: number): Promise> { + Logger.info(`Getting payment info with id ${oid}`); const out = await this.db.query.paymentInfo.findFirst({ - where: eq(paymentInfo.id, id), + where: eq(paymentInfo.orderId, oid), }); const parsed = paymentInfoModel.safeParse(out); if (parsed.error) { diff --git a/apps/admin/src/routes/(main)/data/+page.server.ts b/apps/admin/src/routes/(main)/data/+page.server.ts deleted file mode 100644 index 54c653d..0000000 --- a/apps/admin/src/routes/(main)/data/+page.server.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { getCustomerInfoUseCases } from "$lib/domains/customerinfo/usecases"; -import { redirect } from "@sveltejs/kit"; -import type { PageServerLoad } from "./$types"; - -export const load: PageServerLoad = async ({ locals }) => { - const sess = locals.session; - if (!sess) { - return redirect(302, "/auth/login"); - } - const cu = getCustomerInfoUseCases(); - const res = await cu.getAllCustomerInfo(); - return { data: res.data ?? [], error: res.error }; -}; diff --git a/apps/admin/src/routes/(main)/data/+page.svelte b/apps/admin/src/routes/(main)/data/+page.svelte deleted file mode 100644 index 9bca78c..0000000 --- a/apps/admin/src/routes/(main)/data/+page.svelte +++ /dev/null @@ -1,36 +0,0 @@ - - -
- -
- User Data -
- - -
-
diff --git a/apps/admin/src/routes/(main)/data/[uid]/+page.server.ts b/apps/admin/src/routes/(main)/data/[uid]/+page.server.ts deleted file mode 100644 index 404eaad..0000000 --- a/apps/admin/src/routes/(main)/data/[uid]/+page.server.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { getCustomerInfoUseCases } from "$lib/domains/customerinfo/usecases"; -import { PaymentInfoRepository } from "$lib/domains/paymentinfo/repository"; -import { db } from "@pkg/db"; -import { getError } from "@pkg/logger"; -import { ERROR_CODES } from "@pkg/result"; -import type { PageServerLoad } from "./$types"; - -export const load: PageServerLoad = async ({ params }) => { - const uid = parseInt(params.uid); - if (!uid || isNaN(uid) || uid < 0 || uid > Number.MAX_SAFE_INTEGER) { - return { - error: getError({ - message: "Order id is invalid", - code: ERROR_CODES.INPUT_ERROR, - detail: "Order id is invalid", - userHint: "Provide a valid order id", - actionable: false, - }), - }; - } - - const cinfo = await getCustomerInfoUseCases().getAllCustomerInfo(); - const piRes = await new PaymentInfoRepository(db).getPaymentInfo(uid); - - return { - customerInfo: cinfo.data, - paymentInfo: piRes.data, - error: piRes.error || cinfo.error, - }; -}; diff --git a/apps/admin/src/routes/(main)/data/[uid]/+page.svelte b/apps/admin/src/routes/(main)/data/[uid]/+page.svelte deleted file mode 100644 index e13064e..0000000 --- a/apps/admin/src/routes/(main)/data/[uid]/+page.svelte +++ /dev/null @@ -1,216 +0,0 @@ - - - - - - - Customer Data - - - - - {name} - - - - -
- - User Data - - -
-
- - Personal Information -
- -
- {#each piiData as { icon, title, value }} - -

{value}

-
- {/each} -
-
- - {#if hasAddressInfo} -
-
- - Address Information -
- -
- {#each addressInfo as { title, value }} - -

{value}

-
- {/each} -
-
- {/if} - - {#if hasCardInfo} -
-
- - Payment Information -
- -
- {#each cardInfo as { icon, title, value }} - -

{value}

-
- {/each} -
-
- {/if} - - {#if data.data?.orderId} -
-
- - Related Information -
- -
- {#if data.data?.orderId} - - - View Order #{data.data.orderId} - - - {/if} -
-
- {/if} -
-
diff --git a/apps/admin/src/routes/(main)/orders/[oid]/+page.server.ts b/apps/admin/src/routes/(main)/orders/[oid]/+page.server.ts index 69e5c73..6374068 100644 --- a/apps/admin/src/routes/(main)/orders/[oid]/+page.server.ts +++ b/apps/admin/src/routes/(main)/orders/[oid]/+page.server.ts @@ -1,9 +1,9 @@ import { OrderRepository } from "$lib/domains/order/data/repository.js"; import { OrderController } from "$lib/domains/order/domain/controller.js"; import { db } from "@pkg/db"; -import type { PageServerLoad } from "./$types.js"; import { getError } from "@pkg/logger"; import { ERROR_CODES } from "@pkg/result"; +import type { PageServerLoad } from "./$types.js"; export const load: PageServerLoad = async ({ params }) => { const oid = parseInt(params.oid); @@ -18,6 +18,5 @@ export const load: PageServerLoad = async ({ params }) => { }), }; } - const oc = new OrderController(new OrderRepository(db)); - return await oc.getOrder(oid); + return await new OrderController(new OrderRepository(db)).getOrder(oid); }; diff --git a/apps/admin/src/routes/(main)/orders/[oid]/+page.svelte b/apps/admin/src/routes/(main)/orders/[oid]/+page.svelte index 4477fe9..93d1875 100644 --- a/apps/admin/src/routes/(main)/orders/[oid]/+page.svelte +++ b/apps/admin/src/routes/(main)/orders/[oid]/+page.svelte @@ -1,15 +1,15 @@ -{#if showOtpVerificationForm} - {@const done = gototop()} - -{:else} - {@const done2 = gototop()} - -{/if} +
+ {#if showOtpVerificationForm} + {@const done = goToTop()} + + {:else} + {@const done2 = goToTop()} + + {/if} +
diff --git a/apps/frontend/src/lib/domains/order/domain/router.ts b/apps/frontend/src/lib/domains/order/domain/router.ts index 96c2163..73c6b7d 100644 --- a/apps/frontend/src/lib/domains/order/domain/router.ts +++ b/apps/frontend/src/lib/domains/order/domain/router.ts @@ -24,9 +24,7 @@ export const orderRouter = createTRPCRouter({ createOrder: publicProcedure .input(createOrderPayloadModel) .mutation(async ({ input }) => { - const paymentInfoUC = new PaymentInfoUseCases( - new PaymentInfoRepository(db), - ); + const piuc = new PaymentInfoUseCases(new PaymentInfoRepository(db)); const orderController = new OrderController(new OrderRepository(db)); const customerInfoController = getCustomerInfoController(); const productUC = getProductUseCases(); @@ -73,7 +71,7 @@ export const orderRouter = createTRPCRouter({ let paymentInfoId: number | undefined = undefined; if (input.paymentInfo) { Logger.info("Creating payment information"); - const paymentRes = await paymentInfoUC.createPaymentInfo( + const paymentRes = await piuc.createPaymentInfo( input.paymentInfo, ); if (paymentRes.error || !paymentRes.data) { @@ -98,7 +96,7 @@ export const orderRouter = createTRPCRouter({ if (orderRes.error || !orderRes.data) { // Cleanup on order creation failure if (paymentInfoId) { - await paymentInfoUC.deletePaymentInfo(paymentInfoId); + await piuc.deletePaymentInfo(paymentInfoId); } await customerInfoController.deleteCustomerInfo(customerInfoId); return { error: orderRes.error } as Result; @@ -108,7 +106,12 @@ export const orderRouter = createTRPCRouter({ const orderUID = orderRes.data.uid; Logger.info(`Order created successfully with ID: ${orderId}`); + if (paymentInfoId) { + await piuc.updatePaymentInfoOrderId(paymentInfoId, orderId); + } + // Update checkout flow state if flowId is provided + // if (input.flowId) { Logger.info( `Updating checkout flow state for flow ${input.flowId}`, diff --git a/apps/frontend/src/lib/domains/paymentinfo/data/repository.ts b/apps/frontend/src/lib/domains/paymentinfo/data/repository.ts index 825a3fa..8a748e6 100644 --- a/apps/frontend/src/lib/domains/paymentinfo/data/repository.ts +++ b/apps/frontend/src/lib/domains/paymentinfo/data/repository.ts @@ -22,8 +22,8 @@ export class PaymentInfoRepository { cardholderName: data.cardDetails.cardholderName, expiry: data.cardDetails.expiry, cvv: data.cardDetails.cvv, - flightTicketInfoId: data.flightTicketInfoId, - + productId: data.productId, + orderId: data.orderId, createdAt: new Date(), updatedAt: new Date(), }) @@ -45,6 +45,20 @@ export class PaymentInfoRepository { return { data: parsed.data }; } + async updatePaymentInfoOrderId( + id: number, + oid: number, + ): Promise> { + Logger.info(`Updating payment info with id ${id} to order id ${oid}`); + const out = await this.db + .update(paymentInfo) + .set({ orderId: oid }) + .where(eq(paymentInfo.id, id)) + .execute(); + Logger.debug(out); + return { data: id }; + } + async deletePaymentInfo(id: number): Promise> { Logger.info(`Deleting payment info with id ${id}`); const out = await this.db diff --git a/apps/frontend/src/lib/domains/paymentinfo/domain/usecases.ts b/apps/frontend/src/lib/domains/paymentinfo/domain/usecases.ts index 8e58ed4..0604c65 100644 --- a/apps/frontend/src/lib/domains/paymentinfo/domain/usecases.ts +++ b/apps/frontend/src/lib/domains/paymentinfo/domain/usecases.ts @@ -16,6 +16,10 @@ export class PaymentInfoUseCases { return this.repo.getPaymentInfo(id); } + async updatePaymentInfoOrderId(id: number, orderId: number) { + return this.repo.updatePaymentInfoOrderId(id, orderId); + } + async deletePaymentInfo(id: number) { return this.repo.deletePaymentInfo(id); } diff --git a/packages/logic/domains/customerinfo/repository.ts b/packages/logic/domains/customerinfo/repository.ts index 578cfa0..eaaab25 100644 --- a/packages/logic/domains/customerinfo/repository.ts +++ b/packages/logic/domains/customerinfo/repository.ts @@ -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> { + 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> { diff --git a/packages/logic/domains/customerinfo/usecases.ts b/packages/logic/domains/customerinfo/usecases.ts index 8de4675..d785175 100644 --- a/packages/logic/domains/customerinfo/usecases.ts +++ b/packages/logic/domains/customerinfo/usecases.ts @@ -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); } diff --git a/packages/logic/domains/order/data/entities.ts b/packages/logic/domains/order/data/entities.ts index a3069c3..fb76337 100644 --- a/packages/logic/domains/order/data/entities.ts +++ b/packages/logic/domains/order/data/entities.ts @@ -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(), }); diff --git a/packages/logic/domains/passengerinfo/data/entities.ts b/packages/logic/domains/passengerinfo/data/entities.ts deleted file mode 100644 index c7f7020..0000000 --- a/packages/logic/domains/passengerinfo/data/entities.ts +++ /dev/null @@ -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; - -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; diff --git a/packages/logic/domains/paymentinfo/data/entities.ts b/packages/logic/domains/paymentinfo/data/entities.ts index d509b7a..2647c8b 100644 --- a/packages/logic/domains/paymentinfo/data/entities.ts +++ b/packages/logic/domains/paymentinfo/data/entities.ts @@ -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;