From b150095361622ee3b65e8fdacdbe95f4f2133b90 Mon Sep 17 00:00:00 2001 From: user Date: Mon, 20 Oct 2025 22:41:15 +0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=84=20cleanup:=20useless=20domain=20lo?= =?UTF-8?q?gic=20on=20admin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/lib/domains/ticket/controller.ts | 54 ----- .../ticket/data/entities/create.entities.ts | 1 - .../lib/domains/ticket/data/entities/enums.ts | 1 - .../lib/domains/ticket/data/entities/index.ts | 1 - .../src/lib/domains/ticket/data/repository.ts | 193 ---------------- .../domains/ticket/data/scrape.data.source.ts | 50 ----- .../src/lib/domains/ticket/data/store.ts | 22 -- .../domains/ticket/view/ticket.vm.svelte.ts | 207 ------------------ .../ticket/view/ticket/baggage-info.svelte | 50 ----- .../view/ticket/ticket-details-modal.svelte | 25 --- .../ticket/view/ticket/ticket-details.svelte | 22 -- .../view/ticket/ticket-itinerary.svelte | 91 -------- .../view/ticket/ticket-legs-overview.svelte | 88 -------- 13 files changed, 805 deletions(-) delete mode 100644 apps/admin/src/lib/domains/ticket/controller.ts delete mode 100644 apps/admin/src/lib/domains/ticket/data/entities/create.entities.ts delete mode 100644 apps/admin/src/lib/domains/ticket/data/entities/enums.ts delete mode 100644 apps/admin/src/lib/domains/ticket/data/entities/index.ts delete mode 100644 apps/admin/src/lib/domains/ticket/data/repository.ts delete mode 100644 apps/admin/src/lib/domains/ticket/data/scrape.data.source.ts delete mode 100644 apps/admin/src/lib/domains/ticket/data/store.ts delete mode 100644 apps/admin/src/lib/domains/ticket/view/ticket.vm.svelte.ts delete mode 100644 apps/admin/src/lib/domains/ticket/view/ticket/baggage-info.svelte delete mode 100644 apps/admin/src/lib/domains/ticket/view/ticket/ticket-details-modal.svelte delete mode 100644 apps/admin/src/lib/domains/ticket/view/ticket/ticket-details.svelte delete mode 100644 apps/admin/src/lib/domains/ticket/view/ticket/ticket-itinerary.svelte delete mode 100644 apps/admin/src/lib/domains/ticket/view/ticket/ticket-legs-overview.svelte diff --git a/apps/admin/src/lib/domains/ticket/controller.ts b/apps/admin/src/lib/domains/ticket/controller.ts deleted file mode 100644 index dbc1e5e..0000000 --- a/apps/admin/src/lib/domains/ticket/controller.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { TicketRepository } from "$lib/domains/ticket/data/repository"; -import { db } from "@pkg/db"; -import { Logger } from "@pkg/logger"; -import type { FlightTicket } from "./data/entities"; -import { ScrapedTicketsDataSource } from "./data/scrape.data.source"; - -// if the discount is lower than 1 or more than 100, then we don't apply the discount -function applyDiscount(price: number, discountPercent: number) { - if (discountPercent < 1 || discountPercent > 100) { - return price; - } - const discount = price * (discountPercent / 100); - // Logger.info(`Discounted: ${price} -> ${discount}`); - return price - discount; -} - -export class TicketController { - private repo: TicketRepository; - - constructor(repo: TicketRepository) { - this.repo = repo; - } - - async createTicket(payload: FlightTicket) { - const checkRes = await this.repo.getTicketIdByInfo({ - ticketId: "", - departureDate: payload.departureDate, - returnDate: payload.returnDate, - cabinClass: payload.cabinClass, - departure: payload.departure, - arrival: payload.arrival, - }); - if (checkRes.error) { - return { error: checkRes.error }; - } - if (!checkRes.data) { - Logger.info("Ticket not already found, so making a new one"); - return this.repo.createTicket(payload); - } - Logger.info( - "Ticket already exists with similar features, so just returning that", - ); - return { data: checkRes.data }; - } - - async getTicketById(id: number) { - return this.repo.getTicketById(id); - } -} - -export function getTC() { - const ds = new ScrapedTicketsDataSource("", ""); - return new TicketController(new TicketRepository(db, ds)); -} diff --git a/apps/admin/src/lib/domains/ticket/data/entities/create.entities.ts b/apps/admin/src/lib/domains/ticket/data/entities/create.entities.ts deleted file mode 100644 index c9225f8..0000000 --- a/apps/admin/src/lib/domains/ticket/data/entities/create.entities.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "@pkg/logic/domains/passengerinfo/data/entities"; diff --git a/apps/admin/src/lib/domains/ticket/data/entities/enums.ts b/apps/admin/src/lib/domains/ticket/data/entities/enums.ts deleted file mode 100644 index 39067c5..0000000 --- a/apps/admin/src/lib/domains/ticket/data/entities/enums.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "@pkg/logic/domains/ticket/data/entities/enums"; diff --git a/apps/admin/src/lib/domains/ticket/data/entities/index.ts b/apps/admin/src/lib/domains/ticket/data/entities/index.ts deleted file mode 100644 index 9c9f302..0000000 --- a/apps/admin/src/lib/domains/ticket/data/entities/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "@pkg/logic/domains/ticket/data/entities/index"; diff --git a/apps/admin/src/lib/domains/ticket/data/repository.ts b/apps/admin/src/lib/domains/ticket/data/repository.ts deleted file mode 100644 index 9305456..0000000 --- a/apps/admin/src/lib/domains/ticket/data/repository.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { and, eq, or, type Database } from "@pkg/db"; -import { - flightTicketModel, - TicketType, - type FlightTicket, - type TicketSearchDTO, -} from "./entities"; -import { type Result, ERROR_CODES } from "@pkg/result"; -import { getError, Logger } from "@pkg/logger"; -import type { ScrapedTicketsDataSource } from "./scrape.data.source"; -import { flightTicketInfo } from "@pkg/db/schema"; - -export class TicketRepository { - private db: Database; - private scraper: ScrapedTicketsDataSource; - - constructor(db: Database, scraper: ScrapedTicketsDataSource) { - this.db = db; - this.scraper = scraper; - } - - async searchForTickets( - payload: TicketSearchDTO, - ): Promise> { - try { - return this.scraper.searchForTickets(payload); - } catch (err) { - return { - error: getError( - { - code: ERROR_CODES.NETWORK_ERROR, - message: "Failed to search for tickets", - detail: "Could not fetch tickets for the given payload", - userHint: "Please try again later", - error: err, - actionable: false, - }, - err, - ), - }; - } - } - - async getTicketById(id: number): Promise> { - const out = await this.db.query.flightTicketInfo.findFirst({ - where: eq(flightTicketInfo.id, id), - }); - if (!out) { - return { - error: getError({ - code: ERROR_CODES.NOT_FOUND_ERROR, - message: "Ticket not found", - userHint: - "Please check if the selected ticket is correct, or try again", - detail: "The ticket is not found by the id provided", - }), - }; - } - const parsed = flightTicketModel.safeParse(out); - if (!parsed.success) { - return { - error: getError( - { - code: ERROR_CODES.INTERNAL_SERVER_ERROR, - message: "Failed to parse ticket", - userHint: "Please try again", - detail: "Failed to parse ticket", - }, - JSON.stringify(parsed.error.errors), - ), - }; - } - return { data: parsed.data }; - } - - async getTicketIdByInfo(info: { - ticketId: string; - arrival: string; - departure: string; - cabinClass: string; - departureDate: string; - returnDate: string; - }): Promise> { - try { - const out = await this.db.query.flightTicketInfo.findFirst({ - where: or( - eq(flightTicketInfo.ticketId, info.ticketId), - and( - eq(flightTicketInfo.arrival, info.arrival), - eq(flightTicketInfo.departure, info.departure), - eq(flightTicketInfo.cabinClass, info.cabinClass), - eq( - flightTicketInfo.departureDate, - new Date(info.departureDate), - ), - ), - ), - columns: { id: true }, - }); - if (out && out.id) { - return { data: out?.id }; - } - - return {}; - } catch (e) { - Logger.debug(info); - return { - error: getError( - { - code: ERROR_CODES.DATABASE_ERROR, - message: "Failed to lookup ticket", - detail: "A database error occured while getting ticket by id", - userHint: "Contact us to resolve this issue", - actionable: false, - }, - e, - ), - }; - } - } - - async createTicket(payload: FlightTicket): Promise> { - try { - let rd = new Date(); - if ( - payload.returnDate && - payload.returnDate.length > 0 && - payload.flightType !== TicketType.OneWay - ) { - rd = new Date(payload.returnDate); - } - const out = await this.db - .insert(flightTicketInfo) - .values({ - ticketId: payload.ticketId, - flightType: payload.flightType, - - arrival: payload.arrival, - departure: payload.departure, - cabinClass: payload.cabinClass, - departureDate: new Date(payload.departureDate), - returnDate: rd, - - priceDetails: payload.priceDetails, - passengerCounts: payload.passengerCounts, - bagsInfo: payload.bagsInfo, - - lastAvailable: payload.lastAvailable, - - flightIteneraries: payload.flightIteneraries, - checkoutUrl: payload.checkoutUrl ?? "", - - dates: payload.dates, - - refundable: payload.refundable ?? false, - isCache: payload.isCache ?? false, - - shareId: payload.shareId, - }) - .returning({ id: flightTicketInfo.id }) - .execute(); - - if (!out || out.length === 0) { - Logger.error("Failed to create ticket"); - Logger.debug(out); - Logger.debug(payload); - return { - error: getError({ - code: ERROR_CODES.INTERNAL_SERVER_ERROR, - message: "Failed to create ticket", - userHint: "Please try again", - detail: "Failed to create ticket", - }), - }; - } - - return { data: out[0].id }; - } catch (e) { - return { - error: getError( - { - code: ERROR_CODES.INTERNAL_SERVER_ERROR, - message: "An error occured while creating ticket", - userHint: "Please try again later", - actionable: false, - detail: "An error occured while creating ticket", - }, - e, - ), - }; - } - } -} diff --git a/apps/admin/src/lib/domains/ticket/data/scrape.data.source.ts b/apps/admin/src/lib/domains/ticket/data/scrape.data.source.ts deleted file mode 100644 index 6d1af60..0000000 --- a/apps/admin/src/lib/domains/ticket/data/scrape.data.source.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { ERROR_CODES, type Result } from "@pkg/result"; -import type { FlightTicket, TicketSearchDTO } from "./entities"; -import { betterFetch } from "@better-fetch/fetch"; -import { getError, Logger } from "@pkg/logger"; - -export class ScrapedTicketsDataSource { - scraperUrl: string; - apiKey: string; - - constructor(scraperUrl: string, apiKey: string) { - this.scraperUrl = scraperUrl; - this.apiKey = apiKey; - } - - async searchForTickets( - payload: TicketSearchDTO, - ): Promise> { - const { data, error } = await betterFetch>( - `${this.scraperUrl}/api/v1/tickets/search`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${this.apiKey}`, - }, - body: JSON.stringify(payload), - }, - ); - - if (error) { - return { - error: getError( - { - code: ERROR_CODES.NETWORK_ERROR, - message: "Failed to search for tickets", - detail: "Could not fetch tickets for the given payload", - userHint: "Please try again later", - error: error, - actionable: false, - }, - JSON.stringify(error, null, 4), - ), - }; - } - - Logger.info(`Returning ${data.data?.length} tickets`); - - return { data: data.data ?? [] }; - } -} diff --git a/apps/admin/src/lib/domains/ticket/data/store.ts b/apps/admin/src/lib/domains/ticket/data/store.ts deleted file mode 100644 index 1d392cd..0000000 --- a/apps/admin/src/lib/domains/ticket/data/store.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { writable } from "svelte/store"; -import { - CabinClass, - TicketType, - type FlightTicket, - type TicketSearchPayload, -} from "./entities"; -import { nanoid } from "nanoid"; - -export const flightTicketStore = writable(); - -export const ticketSearchStore = writable({ - sessionId: nanoid(), - ticketType: TicketType.Return, - cabinClass: CabinClass.Economy, - passengerCounts: { adults: 1, children: 0 }, - departure: "", - arrival: "", - departureDate: "", - returnDate: "", - loadMore: false, -}); diff --git a/apps/admin/src/lib/domains/ticket/view/ticket.vm.svelte.ts b/apps/admin/src/lib/domains/ticket/view/ticket.vm.svelte.ts deleted file mode 100644 index fee05e6..0000000 --- a/apps/admin/src/lib/domains/ticket/view/ticket.vm.svelte.ts +++ /dev/null @@ -1,207 +0,0 @@ -import { - type FlightTicket, - ticketSearchPayloadModel, -} from "$lib/domains/ticket/data/entities/index"; -import { trpcApiStore } from "$lib/stores/api"; -import { toast } from "svelte-sonner"; -import { get } from "svelte/store"; -import { - MaxStops, - SortOption, - ticketFiltersStore, -} from "./ticket-filters.vm.svelte"; -import { ticketSearchStore } from "../data/store"; - -export class FlightTicketViewModel { - searching = $state(false); - tickets = $state([]); - renderedTickets = $state([]); - - async searchForTickets(loadMore = false) { - const api = get(trpcApiStore); - if (!api) { - return toast.error("Please try again by reloading the page", { - description: "Page state not properly initialized", - }); - } - let payload = get(ticketSearchStore); - if (!payload) { - return toast.error( - "Could not search for tickets due to invalid payload", - ); - } - - const parsed = ticketSearchPayloadModel.safeParse(payload); - if (!parsed.success) { - console.log("Enter some parameters to search for tickets"); - this.searching = false; - return; - } - payload = parsed.data; - - if (loadMore) { - payload.loadMore = true; - } - - this.searching = true; - const out = await api.ticket.searchTickets.query(payload); - this.searching = false; - - console.log(out); - - if (out.error) { - return toast.error(out.error.message, { - description: out.error.userHint, - }); - } - if (!out.data) { - this.tickets = []; - return toast.error("No search results", { - description: "Please try again with different parameters", - }); - } - - this.tickets = out.data; - this.applyFilters(); - } - - applyFilters() { - this.searching = true; - const filters = get(ticketFiltersStore); - const filteredTickets = this.tickets.filter((ticket) => { - // Price filter - if (filters.priceRange.max > 0) { - if ( - ticket.priceDetails.displayPrice < filters.priceRange.min || - ticket.priceDetails.displayPrice > filters.priceRange.max - ) { - return false; - } - } - - if (filters.maxStops !== MaxStops.Any) { - // Calculate stops for outbound flight - const outboundStops = - ticket.flightIteneraries.outbound.length - 1; - // Calculate stops for inbound flight - const inboundStops = ticket.flightIteneraries.inbound.length - 1; - - // Get the maximum number of stops between outbound and inbound - const maxStopsInJourney = Math.max(outboundStops, inboundStops); - - switch (filters.maxStops) { - case MaxStops.Direct: - if (maxStopsInJourney > 0) return false; - break; - case MaxStops.One: - if (maxStopsInJourney > 1) return false; - break; - case MaxStops.Two: - if (maxStopsInJourney > 2) return false; - break; - } - } - - // Time range filters - if (filters.time.departure.max > 0 || filters.time.arrival.max > 0) { - const allItineraries = [ - ...ticket.flightIteneraries.outbound, - ...ticket.flightIteneraries.inbound, - ]; - for (const itinerary of allItineraries) { - const departureHour = new Date( - itinerary.departure.utcTime, - ).getHours(); - const arrivalHour = new Date( - itinerary.destination.utcTime, - ).getHours(); - - if (filters.time.departure.max > 0) { - if ( - departureHour < filters.time.departure.min || - departureHour > filters.time.departure.max - ) { - return false; - } - } - - if (filters.time.arrival.max > 0) { - if ( - arrivalHour < filters.time.arrival.min || - arrivalHour > filters.time.arrival.max - ) { - return false; - } - } - } - } - - // Duration filter - if (filters.duration.max > 0) { - const allItineraries = [ - ...ticket.flightIteneraries.outbound, - ...ticket.flightIteneraries.inbound, - ]; - const totalDuration = allItineraries.reduce( - (sum, itinerary) => sum + itinerary.durationSeconds, - 0, - ); - const durationHours = totalDuration / 3600; - - if ( - durationHours < filters.duration.min || - durationHours > filters.duration.max - ) { - return false; - } - } - - // Overnight filter - if (!filters.allowOvernight) { - const allItineraries = [ - ...ticket.flightIteneraries.outbound, - ...ticket.flightIteneraries.inbound, - ]; - const hasOvernightFlight = allItineraries.some((itinerary) => { - const departureHour = new Date( - itinerary.departure.utcTime, - ).getHours(); - const arrivalHour = new Date( - itinerary.destination.utcTime, - ).getHours(); - - // Consider a flight overnight if it departs between 8 PM (20) and 6 AM (6) - return ( - departureHour >= 20 || - departureHour <= 6 || - arrivalHour >= 20 || - arrivalHour <= 6 - ); - }); - if (hasOvernightFlight) return false; - } - - return true; - }); - - filteredTickets.sort((a, b) => { - switch (filters.sortBy) { - case SortOption.PriceLowToHigh: - return ( - a.priceDetails.displayPrice - b.priceDetails.displayPrice - ); - case SortOption.PriceHighToLow: - return ( - b.priceDetails.displayPrice - a.priceDetails.displayPrice - ); - default: - return 0; - } - }); - - this.renderedTickets = filteredTickets; - this.searching = false; - } -} - -export const flightTicketVM = new FlightTicketViewModel(); diff --git a/apps/admin/src/lib/domains/ticket/view/ticket/baggage-info.svelte b/apps/admin/src/lib/domains/ticket/view/ticket/baggage-info.svelte deleted file mode 100644 index b9a21fc..0000000 --- a/apps/admin/src/lib/domains/ticket/view/ticket/baggage-info.svelte +++ /dev/null @@ -1,50 +0,0 @@ - - -{#if data} - Baggage Info -
- -
-
- - Personal Item -
- {data.bagsInfo.includedPersonalBags} included -
- - -
-
- - Cabin Baggage -
- {#if data.bagsInfo.hasHandBagsSupport} - {data.bagsInfo.includedHandBags} included - {:else} - Not available - {/if} -
- - -
-
- - Checked Baggage -
- {#if data.bagsInfo.hasCheckedBagsSupport} - {data.bagsInfo.includedCheckedBags} included - {:else} - Not available - {/if} -
-
-{/if} diff --git a/apps/admin/src/lib/domains/ticket/view/ticket/ticket-details-modal.svelte b/apps/admin/src/lib/domains/ticket/view/ticket/ticket-details-modal.svelte deleted file mode 100644 index 484ff17..0000000 --- a/apps/admin/src/lib/domains/ticket/view/ticket/ticket-details-modal.svelte +++ /dev/null @@ -1,25 +0,0 @@ - - - - {@render children()} - - -
- -
-
-
diff --git a/apps/admin/src/lib/domains/ticket/view/ticket/ticket-details.svelte b/apps/admin/src/lib/domains/ticket/view/ticket/ticket-details.svelte deleted file mode 100644 index 3b17794..0000000 --- a/apps/admin/src/lib/domains/ticket/view/ticket/ticket-details.svelte +++ /dev/null @@ -1,22 +0,0 @@ - - - - -
- - ${data.priceDetails.displayPrice} - - -
diff --git a/apps/admin/src/lib/domains/ticket/view/ticket/ticket-itinerary.svelte b/apps/admin/src/lib/domains/ticket/view/ticket/ticket-itinerary.svelte deleted file mode 100644 index 7ce6dc7..0000000 --- a/apps/admin/src/lib/domains/ticket/view/ticket/ticket-itinerary.svelte +++ /dev/null @@ -1,91 +0,0 @@ - - -
- -
- {departure} - - {departureTime} - - - {departureDate} - -
- - -
-
-
-
-
- -
-
-
- - - {durationFormatted} - - -
- {#if stops !== undefined} - 0 ? "secondary" : "outline"} - class="font-medium" - > - {#if stops > 0} - {stops} {stops === 1 ? "Stop" : "Stops"} - {:else} - Direct Flight - {/if} - - {/if} - {#if airlineName} - {airlineName} - {/if} -
-
- - -
- {destination} - - {arrivalTime} - - {arrivalDate} -
-
diff --git a/apps/admin/src/lib/domains/ticket/view/ticket/ticket-legs-overview.svelte b/apps/admin/src/lib/domains/ticket/view/ticket/ticket-legs-overview.svelte deleted file mode 100644 index e3f88e9..0000000 --- a/apps/admin/src/lib/domains/ticket/view/ticket/ticket-legs-overview.svelte +++ /dev/null @@ -1,88 +0,0 @@ - - -{#if isReturnTicket} - - Outbound - -{/if} - - -{#if isReturnTicket} -
- - {#if isReturnTicket} - - Inbound - - {/if} - - -{:else} -
-{/if}