refactor: more legacy code replaced more on the model and a bit on the admin side
This commit is contained in:
@@ -17,13 +17,6 @@ export const customerInfoRouter = createTRPCRouter({
|
||||
return controller.getCustomerInfoById(input.id);
|
||||
}),
|
||||
|
||||
getCustomerInfoByOrderId: protectedProcedure
|
||||
.input(z.object({ orderId: z.number() }))
|
||||
.query(async ({ input }) => {
|
||||
const controller = getCustomerInfoUseCases();
|
||||
return controller.getCustomerInfoByOrderId(input.orderId);
|
||||
}),
|
||||
|
||||
createCustomerInfo: protectedProcedure
|
||||
.input(createCustomerInfoPayload)
|
||||
.mutation(async ({ input }) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ERROR_CODES, type Result } from "$lib/core/data.types";
|
||||
import { count, eq, type Database } from "@pkg/db";
|
||||
import { customerInfo, order } from "@pkg/db/schema";
|
||||
import { order } from "@pkg/db/schema";
|
||||
import { getError, Logger } from "@pkg/logger";
|
||||
import { fullOrderModel, type FullOrderModel } from "./entities";
|
||||
|
||||
@@ -23,16 +23,12 @@ export class OrderRepository {
|
||||
async listAllOrders(): Promise<Result<FullOrderModel[]>> {
|
||||
try {
|
||||
const res = await this.db.query.order.findMany({
|
||||
with: {
|
||||
flightTicketInfo: true,
|
||||
emailAccount: true,
|
||||
},
|
||||
with: { customerInfo: true, product: true },
|
||||
});
|
||||
const out = [] as FullOrderModel[];
|
||||
for (const each of res) {
|
||||
const parsed = fullOrderModel.safeParse({
|
||||
...each,
|
||||
customerInfos: [],
|
||||
});
|
||||
if (!parsed.success) {
|
||||
Logger.error(JSON.stringify(parsed.error.errors, null, 2));
|
||||
@@ -40,7 +36,6 @@ export class OrderRepository {
|
||||
}
|
||||
out.push(parsed.data);
|
||||
}
|
||||
|
||||
return { data: out };
|
||||
} catch (e) {
|
||||
return {
|
||||
@@ -61,18 +56,11 @@ export class OrderRepository {
|
||||
async getOrder(oid: number): Promise<Result<FullOrderModel>> {
|
||||
const out = await this.db.query.order.findFirst({
|
||||
where: eq(order.id, oid),
|
||||
with: {
|
||||
emailAccount: true,
|
||||
flightTicketInfo: true,
|
||||
},
|
||||
with: { customerInfo: true, product: true },
|
||||
});
|
||||
if (!out) return {};
|
||||
const relatedCustomerInfos = await this.db.query.customerInfo.findMany({
|
||||
where: eq(customerInfo.orderId, oid),
|
||||
});
|
||||
const parsed = fullOrderModel.safeParse({
|
||||
...out,
|
||||
customerInfo: relatedCustomerInfos,
|
||||
});
|
||||
if (!parsed.success) {
|
||||
return {
|
||||
|
||||
@@ -1,292 +0,0 @@
|
||||
CREATE TABLE IF NOT EXISTS "account" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"account_id" text NOT NULL,
|
||||
"provider_id" text NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"access_token" text,
|
||||
"refresh_token" text,
|
||||
"id_token" text,
|
||||
"access_token_expires_at" timestamp,
|
||||
"refresh_token_expires_at" timestamp,
|
||||
"scope" text,
|
||||
"password" text,
|
||||
"created_at" timestamp NOT NULL,
|
||||
"updated_at" timestamp NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "user" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"email" text NOT NULL,
|
||||
"email_verified" boolean NOT NULL,
|
||||
"image" text,
|
||||
"created_at" timestamp NOT NULL,
|
||||
"updated_at" timestamp NOT NULL,
|
||||
"username" text,
|
||||
"display_username" text,
|
||||
"role" text,
|
||||
"banned" boolean,
|
||||
"ban_reason" text,
|
||||
"ban_expires" timestamp,
|
||||
"parent_id" text,
|
||||
"discount_percent" integer,
|
||||
CONSTRAINT "user_email_unique" UNIQUE("email"),
|
||||
CONSTRAINT "user_username_unique" UNIQUE("username")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "verification" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"identifier" text NOT NULL,
|
||||
"value" text NOT NULL,
|
||||
"expires_at" timestamp NOT NULL,
|
||||
"created_at" timestamp,
|
||||
"updated_at" timestamp
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "coupon" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"code" varchar(32) NOT NULL,
|
||||
"description" text,
|
||||
"discount_type" varchar(16) NOT NULL,
|
||||
"discount_value" numeric(12, 2) NOT NULL,
|
||||
"max_usage_count" integer,
|
||||
"current_usage_count" integer DEFAULT 0 NOT NULL,
|
||||
"min_order_value" numeric(12, 2),
|
||||
"max_discount_amount" numeric(12, 2),
|
||||
"start_date" timestamp NOT NULL,
|
||||
"end_date" timestamp,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now(),
|
||||
"created_by" text,
|
||||
CONSTRAINT "coupon_code_unique" UNIQUE("code")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "coupon_usage" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"coupon_id" integer NOT NULL,
|
||||
"user_id" text,
|
||||
"order_id" integer,
|
||||
"discount_amount" numeric(12, 2) NOT NULL,
|
||||
"used_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "email_account" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"email" varchar(128) NOT NULL,
|
||||
"password" varchar(128) NOT NULL,
|
||||
"used" boolean DEFAULT false NOT NULL,
|
||||
"agent_id" text,
|
||||
"last_active_check_at" timestamp DEFAULT now(),
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now(),
|
||||
CONSTRAINT "email_account_email_unique" UNIQUE("email")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "flight_ticket_info" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"ticket_id" text DEFAULT '' NOT NULL,
|
||||
"flight_type" varchar(24) NOT NULL,
|
||||
"departure" text NOT NULL,
|
||||
"arrival" text NOT NULL,
|
||||
"departure_date" timestamp NOT NULL,
|
||||
"return_date" timestamp NOT NULL,
|
||||
"dates" json DEFAULT '[]'::json NOT NULL,
|
||||
"flight_iteneraries" json DEFAULT '[]'::json NOT NULL,
|
||||
"price_details" json NOT NULL,
|
||||
"bags_info" json NOT NULL,
|
||||
"last_available" json NOT NULL,
|
||||
"refundable" boolean DEFAULT false NOT NULL,
|
||||
"passenger_counts" json DEFAULT '{"adult":1,"children":0}'::json NOT NULL,
|
||||
"cabin_class" varchar(24) NOT NULL,
|
||||
"share_id" text DEFAULT '' NOT NULL,
|
||||
"checkout_url" text DEFAULT '' NOT NULL,
|
||||
"is_cache" boolean DEFAULT false NOT NULL,
|
||||
"ref_oids" json DEFAULT '[]'::json NOT NULL,
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "inbox" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"email_id" text DEFAULT '' NOT NULL,
|
||||
"from" text,
|
||||
"to" text,
|
||||
"cc" text,
|
||||
"subject" text,
|
||||
"body" text,
|
||||
"attachments" json,
|
||||
"date" timestamp DEFAULT now(),
|
||||
"email_account_id" integer NOT NULL,
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "order" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"order_price" numeric(12, 2),
|
||||
"discount_amount" numeric(12, 2),
|
||||
"display_price" numeric(12, 2),
|
||||
"base_price" numeric(12, 2),
|
||||
"fullfilled_price" numeric(12, 2) DEFAULT '0',
|
||||
"price_per_passenger" numeric(12, 2) DEFAULT '0',
|
||||
"status" varchar(24),
|
||||
"pnr" varchar(12) DEFAULT '' NOT NULL,
|
||||
"flight_ticket_info_id" integer NOT NULL,
|
||||
"payment_details_id" integer,
|
||||
"email_account_id" integer,
|
||||
"agent_id" text,
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "passenger_info" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"passenger_pii_id" integer,
|
||||
"payment_details_id" integer,
|
||||
"passenger_type" varchar(24) NOT NULL,
|
||||
"seat_selection" json,
|
||||
"bag_selection" json,
|
||||
"order_id" integer,
|
||||
"flight_ticket_info_id" integer,
|
||||
"agents_info" boolean DEFAULT false NOT NULL,
|
||||
"agent_id" text,
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "passenger_pii" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"first_name" varchar(64) NOT NULL,
|
||||
"middle_name" varchar(64) NOT NULL,
|
||||
"last_name" varchar(64) NOT NULL,
|
||||
"email" varchar(128) NOT NULL,
|
||||
"phone_country_code" varchar(6) NOT NULL,
|
||||
"phone_number" varchar(20) NOT NULL,
|
||||
"nationality" varchar(32) NOT NULL,
|
||||
"gender" varchar(32) NOT NULL,
|
||||
"dob" date NOT NULL,
|
||||
"passport_no" varchar(64) NOT NULL,
|
||||
"passport_expiry" varchar(12) NOT NULL,
|
||||
"country" varchar(128) NOT NULL,
|
||||
"state" varchar(128) NOT NULL,
|
||||
"city" varchar(128) NOT NULL,
|
||||
"zip_code" varchar(21) NOT NULL,
|
||||
"address" text NOT NULL,
|
||||
"address2" text,
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "payment_details" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"cardholder_name" varchar(128) NOT NULL,
|
||||
"card_number" varchar(20) NOT NULL,
|
||||
"expiry" varchar(5) NOT NULL,
|
||||
"cvv" varchar(6) NOT NULL,
|
||||
"flight_ticket_info_id" integer,
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "account" ADD CONSTRAINT "account_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "coupon" ADD CONSTRAINT "coupon_created_by_user_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "coupon_usage" ADD CONSTRAINT "coupon_usage_coupon_id_coupon_id_fk" FOREIGN KEY ("coupon_id") REFERENCES "public"."coupon"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "coupon_usage" ADD CONSTRAINT "coupon_usage_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "coupon_usage" ADD CONSTRAINT "coupon_usage_order_id_order_id_fk" FOREIGN KEY ("order_id") REFERENCES "public"."order"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "email_account" ADD CONSTRAINT "email_account_agent_id_user_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "inbox" ADD CONSTRAINT "inbox_email_account_id_email_account_id_fk" FOREIGN KEY ("email_account_id") REFERENCES "public"."email_account"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "order" ADD CONSTRAINT "order_flight_ticket_info_id_flight_ticket_info_id_fk" FOREIGN KEY ("flight_ticket_info_id") REFERENCES "public"."flight_ticket_info"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "order" ADD CONSTRAINT "order_payment_details_id_payment_details_id_fk" FOREIGN KEY ("payment_details_id") REFERENCES "public"."payment_details"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "order" ADD CONSTRAINT "order_email_account_id_email_account_id_fk" FOREIGN KEY ("email_account_id") REFERENCES "public"."email_account"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "order" ADD CONSTRAINT "order_agent_id_user_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "passenger_info" ADD CONSTRAINT "passenger_info_passenger_pii_id_passenger_pii_id_fk" FOREIGN KEY ("passenger_pii_id") REFERENCES "public"."passenger_pii"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "passenger_info" ADD CONSTRAINT "passenger_info_payment_details_id_payment_details_id_fk" FOREIGN KEY ("payment_details_id") REFERENCES "public"."payment_details"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "passenger_info" ADD CONSTRAINT "passenger_info_order_id_order_id_fk" FOREIGN KEY ("order_id") REFERENCES "public"."order"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "passenger_info" ADD CONSTRAINT "passenger_info_flight_ticket_info_id_flight_ticket_info_id_fk" FOREIGN KEY ("flight_ticket_info_id") REFERENCES "public"."flight_ticket_info"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "passenger_info" ADD CONSTRAINT "passenger_info_agent_id_user_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "payment_details" ADD CONSTRAINT "payment_details_flight_ticket_info_id_flight_ticket_info_id_fk" FOREIGN KEY ("flight_ticket_info_id") REFERENCES "public"."flight_ticket_info"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
192
packages/db/migrations/0000_large_gertrude_yorkes.sql
Normal file
192
packages/db/migrations/0000_large_gertrude_yorkes.sql
Normal file
@@ -0,0 +1,192 @@
|
||||
CREATE TABLE IF NOT EXISTS "account" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"account_id" text NOT NULL,
|
||||
"provider_id" text NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"access_token" text,
|
||||
"refresh_token" text,
|
||||
"id_token" text,
|
||||
"access_token_expires_at" timestamp,
|
||||
"refresh_token_expires_at" timestamp,
|
||||
"scope" text,
|
||||
"password" text,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "user" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"email" text NOT NULL,
|
||||
"email_verified" boolean DEFAULT false NOT NULL,
|
||||
"image" text,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp DEFAULT now() NOT NULL,
|
||||
"username" text,
|
||||
"display_username" text,
|
||||
"role" text,
|
||||
"banned" boolean DEFAULT false,
|
||||
"ban_reason" text,
|
||||
"ban_expires" timestamp,
|
||||
"parent_id" text,
|
||||
"discount_percent" integer DEFAULT 0,
|
||||
CONSTRAINT "user_email_unique" UNIQUE("email"),
|
||||
CONSTRAINT "user_username_unique" UNIQUE("username")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "verification" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"identifier" text NOT NULL,
|
||||
"value" text NOT NULL,
|
||||
"expires_at" timestamp NOT NULL,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "checkout_flow_session" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"flow_id" text NOT NULL,
|
||||
"domain" text NOT NULL,
|
||||
"checkout_step" varchar(50) NOT NULL,
|
||||
"show_verification" boolean DEFAULT false NOT NULL,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"last_pinged" timestamp NOT NULL,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"last_synced_at" timestamp NOT NULL,
|
||||
"personal_info_last_synced_at" timestamp,
|
||||
"payment_info_last_synced_at" timestamp,
|
||||
"pending_actions" json DEFAULT '[]'::json NOT NULL,
|
||||
"personal_info" json,
|
||||
"payment_info" json,
|
||||
"ref_o_ids" json DEFAULT '[]'::json,
|
||||
"otp_code" varchar(20),
|
||||
"otp_submitted" boolean DEFAULT false NOT NULL,
|
||||
"partial_otp_code" varchar(20),
|
||||
"ip_address" varchar(50) DEFAULT '' NOT NULL,
|
||||
"user_agent" text DEFAULT '' NOT NULL,
|
||||
"reserved" boolean DEFAULT false NOT NULL,
|
||||
"reserved_by" varchar(255),
|
||||
"completed_at" timestamp,
|
||||
"session_outcome" varchar(50),
|
||||
"is_deleted" boolean DEFAULT false NOT NULL,
|
||||
"product_id" integer,
|
||||
CONSTRAINT "checkout_flow_session_flow_id_unique" UNIQUE("flow_id")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "coupon" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"code" varchar(32) NOT NULL,
|
||||
"description" text,
|
||||
"discount_type" varchar(16) NOT NULL,
|
||||
"discount_value" numeric(12, 2) NOT NULL,
|
||||
"max_usage_count" integer,
|
||||
"current_usage_count" integer DEFAULT 0 NOT NULL,
|
||||
"min_order_value" numeric(12, 2),
|
||||
"max_discount_amount" numeric(12, 2),
|
||||
"start_date" timestamp NOT NULL,
|
||||
"end_date" timestamp,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now(),
|
||||
"created_by" text,
|
||||
CONSTRAINT "coupon_code_unique" UNIQUE("code")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "customer_info" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"first_name" varchar(64) NOT NULL,
|
||||
"middle_name" varchar(64) DEFAULT '',
|
||||
"last_name" varchar(64) NOT NULL,
|
||||
"email" varchar(128) NOT NULL,
|
||||
"phone_country_code" varchar(6) NOT NULL,
|
||||
"phone_number" varchar(20) NOT NULL,
|
||||
"country" varchar(128) NOT NULL,
|
||||
"state" varchar(128) NOT NULL,
|
||||
"city" varchar(128) NOT NULL,
|
||||
"zip_code" varchar(21) NOT NULL,
|
||||
"address" text NOT NULL,
|
||||
"address2" text,
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "order" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"order_price" numeric(12, 2),
|
||||
"discount_amount" numeric(12, 2),
|
||||
"display_price" numeric(12, 2),
|
||||
"base_price" numeric(12, 2),
|
||||
"fullfilled_price" numeric(12, 2) DEFAULT '0',
|
||||
"status" varchar(24),
|
||||
"product_id" integer,
|
||||
"customer_info_id" integer,
|
||||
"payment_details_id" integer,
|
||||
"agent_id" text,
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "payment_details" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"cardholder_name" varchar(128) NOT NULL,
|
||||
"card_number" varchar(20) NOT NULL,
|
||||
"expiry" varchar(5) NOT NULL,
|
||||
"cvv" varchar(6) NOT NULL,
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "product" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"link_id" varchar(32) NOT NULL,
|
||||
"title" varchar(64) NOT NULL,
|
||||
"description" text NOT NULL,
|
||||
"long_description" text NOT NULL,
|
||||
"price" numeric(12, 2) DEFAULT '0',
|
||||
"discount_price" numeric(12, 2) DEFAULT '0',
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now(),
|
||||
CONSTRAINT "product_link_id_unique" UNIQUE("link_id")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "account" ADD CONSTRAINT "account_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "checkout_flow_session" ADD CONSTRAINT "checkout_flow_session_product_id_product_id_fk" FOREIGN KEY ("product_id") REFERENCES "public"."product"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "coupon" ADD CONSTRAINT "coupon_created_by_user_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "order" ADD CONSTRAINT "order_product_id_product_id_fk" FOREIGN KEY ("product_id") REFERENCES "public"."product"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "order" ADD CONSTRAINT "order_customer_info_id_customer_info_id_fk" FOREIGN KEY ("customer_info_id") REFERENCES "public"."customer_info"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "order" ADD CONSTRAINT "order_payment_details_id_payment_details_id_fk" FOREIGN KEY ("payment_details_id") REFERENCES "public"."payment_details"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "order" ADD CONSTRAINT "order_agent_id_user_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
@@ -1 +0,0 @@
|
||||
DROP TABLE "coupon_usage" CASCADE;
|
||||
2
packages/db/migrations/0001_wonderful_nico_minoru.sql
Normal file
2
packages/db/migrations/0001_wonderful_nico_minoru.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE "payment_details" ADD COLUMN "order_id" integer;--> statement-breakpoint
|
||||
ALTER TABLE "payment_details" ADD COLUMN "product_id" integer;
|
||||
@@ -1,28 +0,0 @@
|
||||
CREATE TABLE IF NOT EXISTS "checkout_flow_session" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"flow_id" text NOT NULL,
|
||||
"domain" text NOT NULL,
|
||||
"checkout_step" varchar(50) NOT NULL,
|
||||
"show_verification" boolean DEFAULT false NOT NULL,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"last_pinged" timestamp NOT NULL,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"last_synced_at" timestamp NOT NULL,
|
||||
"personal_info_last_synced_at" timestamp,
|
||||
"payment_info_last_synced_at" timestamp,
|
||||
"pending_actions" json DEFAULT '[]'::json NOT NULL,
|
||||
"personal_info" json,
|
||||
"payment_info" json,
|
||||
"ref_o_ids" json DEFAULT '[]'::json,
|
||||
"otp_code" varchar(20),
|
||||
"otp_submitted" boolean DEFAULT false NOT NULL,
|
||||
"partial_otp_code" varchar(20),
|
||||
"ip_address" varchar(50) DEFAULT '' NOT NULL,
|
||||
"user_agent" text DEFAULT '' NOT NULL,
|
||||
"reserved" boolean DEFAULT false NOT NULL,
|
||||
"reserved_by" varchar(255),
|
||||
"completed_at" timestamp,
|
||||
"session_outcome" varchar(50),
|
||||
"is_deleted" boolean DEFAULT false NOT NULL,
|
||||
CONSTRAINT "checkout_flow_session_flow_id_unique" UNIQUE("flow_id")
|
||||
);
|
||||
@@ -1,6 +0,0 @@
|
||||
ALTER TABLE "checkout_flow_session" ADD COLUMN "ticket_id" integer;--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "checkout_flow_session" ADD CONSTRAINT "checkout_flow_session_ticket_id_flight_ticket_info_id_fk" FOREIGN KEY ("ticket_id") REFERENCES "public"."flight_ticket_info"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
@@ -1,10 +0,0 @@
|
||||
ALTER TABLE "account" ALTER COLUMN "created_at" SET DEFAULT now();--> statement-breakpoint
|
||||
ALTER TABLE "user" ALTER COLUMN "email_verified" SET DEFAULT false;--> statement-breakpoint
|
||||
ALTER TABLE "user" ALTER COLUMN "created_at" SET DEFAULT now();--> statement-breakpoint
|
||||
ALTER TABLE "user" ALTER COLUMN "updated_at" SET DEFAULT now();--> statement-breakpoint
|
||||
ALTER TABLE "user" ALTER COLUMN "banned" SET DEFAULT false;--> statement-breakpoint
|
||||
ALTER TABLE "user" ALTER COLUMN "discount_percent" SET DEFAULT 0;--> statement-breakpoint
|
||||
ALTER TABLE "verification" ALTER COLUMN "created_at" SET DEFAULT now();--> statement-breakpoint
|
||||
ALTER TABLE "verification" ALTER COLUMN "created_at" SET NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "verification" ALTER COLUMN "updated_at" SET DEFAULT now();--> statement-breakpoint
|
||||
ALTER TABLE "verification" ALTER COLUMN "updated_at" SET NOT NULL;
|
||||
@@ -1,9 +0,0 @@
|
||||
CREATE TABLE IF NOT EXISTS "product" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"title" varchar(64) NOT NULL,
|
||||
"description" text NOT NULL,
|
||||
"long_description" text NOT NULL,
|
||||
"price" numeric(12, 2) DEFAULT '0',
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now()
|
||||
);
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE "product" ADD COLUMN "discount_price" numeric(12, 2) DEFAULT '0';
|
||||
@@ -1,2 +0,0 @@
|
||||
ALTER TABLE "product" ADD COLUMN "link_id" varchar(32) NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "product" ADD CONSTRAINT "product_link_id_unique" UNIQUE("link_id");
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -5,57 +5,15 @@
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "7",
|
||||
"when": 1745995608498,
|
||||
"tag": "0000_famous_ultimo",
|
||||
"when": 1760987106438,
|
||||
"tag": "0000_large_gertrude_yorkes",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "7",
|
||||
"when": 1745996165675,
|
||||
"tag": "0001_awesome_sharon_ventura",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "7",
|
||||
"when": 1746022883556,
|
||||
"tag": "0002_wet_psylocke",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "7",
|
||||
"when": 1746375159329,
|
||||
"tag": "0003_unique_stephen_strange",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "7",
|
||||
"when": 1760973109915,
|
||||
"tag": "0004_parched_blue_shield",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "7",
|
||||
"when": 1760975750129,
|
||||
"tag": "0005_great_doomsday",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"version": "7",
|
||||
"when": 1760975763245,
|
||||
"tag": "0006_puzzling_avengers",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 7,
|
||||
"version": "7",
|
||||
"when": 1760976587011,
|
||||
"tag": "0007_true_garia",
|
||||
"when": 1760987289226,
|
||||
"tag": "0001_wonderful_nico_minoru",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
|
||||
@@ -34,25 +34,21 @@ export const order = pgTable("order", {
|
||||
fullfilledPrice: decimal("fullfilled_price", { precision: 12, scale: 2 })
|
||||
.$type<string>()
|
||||
.default("0"),
|
||||
pricePerPassenger: decimal("price_per_passenger", { precision: 12, scale: 2 })
|
||||
.$type<string>()
|
||||
.default("0"),
|
||||
|
||||
status: varchar("status", { length: 24 }),
|
||||
pnr: varchar("pnr", { length: 12 }).default("").notNull(),
|
||||
|
||||
flightTicketInfoId: integer("flight_ticket_info_id")
|
||||
.references(() => flightTicketInfo.id, { onDelete: "no action" })
|
||||
.notNull(),
|
||||
productId: integer("product_id").references(() => product.id, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
customerInfoId: integer("customer_info_id").references(
|
||||
() => customerInfo.id,
|
||||
{ onDelete: "cascade" },
|
||||
),
|
||||
paymentDetailsId: integer("payment_details_id").references(
|
||||
() => paymentDetails.id,
|
||||
{ onDelete: "set null" },
|
||||
{ onDelete: "cascade" },
|
||||
),
|
||||
|
||||
emailAccountId: integer("email_account_id").references(
|
||||
() => emailAccount.id,
|
||||
{ onDelete: "set null" },
|
||||
),
|
||||
agentId: text("agent_id").references(() => user.id, { onDelete: "set null" }),
|
||||
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
@@ -92,98 +88,19 @@ export const customerInfo = pgTable("customer_info", {
|
||||
address: text("address").notNull(),
|
||||
address2: text("address2"),
|
||||
|
||||
orderId: integer("order_id").references(() => order.id, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
updatedAt: timestamp("updated_at").defaultNow(),
|
||||
});
|
||||
|
||||
export const paymentDetails = pgTable("payment_details", {
|
||||
id: serial("id").primaryKey(),
|
||||
|
||||
cardholderName: varchar("cardholder_name", { length: 128 }).notNull(),
|
||||
cardNumber: varchar("card_number", { length: 20 }).notNull(),
|
||||
expiry: varchar("expiry", { length: 5 }).notNull(),
|
||||
cvv: varchar("cvv", { length: 6 }).notNull(),
|
||||
|
||||
flightTicketInfoId: integer("flight_ticket_info_id").references(
|
||||
() => flightTicketInfo.id,
|
||||
{ onDelete: "set null" },
|
||||
),
|
||||
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
updatedAt: timestamp("updated_at").defaultNow(),
|
||||
});
|
||||
|
||||
export const emailAccount = pgTable("email_account", {
|
||||
id: serial("id").primaryKey(),
|
||||
email: varchar("email", { length: 128 }).unique().notNull(),
|
||||
password: varchar("password", { length: 128 }).notNull(),
|
||||
|
||||
used: boolean("used").default(false).notNull(),
|
||||
|
||||
agentId: text("agent_id").references(() => user.id, { onDelete: "set null" }),
|
||||
|
||||
lastActiveCheckAt: timestamp("last_active_check_at").defaultNow(),
|
||||
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
updatedAt: timestamp("updated_at").defaultNow(),
|
||||
});
|
||||
|
||||
export const inbox = pgTable("inbox", {
|
||||
id: serial("id").primaryKey(),
|
||||
emailId: text("email_id").default("").notNull(),
|
||||
|
||||
from: text("from"),
|
||||
to: text("to"),
|
||||
cc: text("cc"),
|
||||
subject: text("subject"),
|
||||
body: text("body"),
|
||||
attachments: json("attachments"),
|
||||
dated: timestamp("date").defaultNow(),
|
||||
|
||||
emailAccountId: integer("email_account_id")
|
||||
.references(() => emailAccount.id, { onDelete: "cascade" })
|
||||
.notNull(),
|
||||
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
updatedAt: timestamp("updated_at").defaultNow(),
|
||||
});
|
||||
|
||||
export const flightTicketInfo = pgTable("flight_ticket_info", {
|
||||
id: serial("id").primaryKey(),
|
||||
ticketId: text("ticket_id").default("").notNull(),
|
||||
|
||||
flightType: varchar("flight_type", { length: 24 }).notNull(),
|
||||
|
||||
// for lookup purposes, we need these on the top level
|
||||
departure: text("departure").notNull(),
|
||||
arrival: text("arrival").notNull(),
|
||||
departureDate: timestamp("departure_date").notNull(),
|
||||
returnDate: timestamp("return_date").notNull(),
|
||||
dates: json("dates").$type<string[]>().default([]).notNull(),
|
||||
|
||||
flightIteneraries: json("flight_iteneraries").default([]).notNull(),
|
||||
|
||||
priceDetails: json("price_details").notNull(),
|
||||
bagsInfo: json("bags_info").notNull(),
|
||||
lastAvailable: json("last_available").notNull(),
|
||||
|
||||
refundable: boolean("refundable").default(false).notNull(),
|
||||
|
||||
passengerCounts: json("passenger_counts")
|
||||
.default({ adult: 1, children: 0 })
|
||||
.notNull(),
|
||||
cabinClass: varchar("cabin_class", { length: 24 }).notNull(),
|
||||
|
||||
shareId: text("share_id").default("").notNull(),
|
||||
checkoutUrl: text("checkout_url").default("").notNull(),
|
||||
|
||||
isCache: boolean("is_cache").default(false).notNull(),
|
||||
refOIds: json("ref_oids").$type<number[]>().default([]).notNull(),
|
||||
|
||||
// Soft relation as otherwise it would get circular
|
||||
orderId: integer("order_id"),
|
||||
productId: integer("product_id"),
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
updatedAt: timestamp("updated_at").defaultNow(),
|
||||
});
|
||||
@@ -263,34 +180,25 @@ export const checkoutFlowSession = pgTable("checkout_flow_session", {
|
||||
sessionOutcome: varchar("session_outcome", { length: 50 }),
|
||||
isDeleted: boolean("is_deleted").default(false).notNull(),
|
||||
|
||||
ticketId: integer("ticket_id").references(() => flightTicketInfo.id, {
|
||||
product: integer("product_id").references(() => product.id, {
|
||||
onDelete: "set null",
|
||||
}),
|
||||
});
|
||||
|
||||
export const customerInfoRelations = relations(customerInfo, ({ one }) => ({
|
||||
order: one(order, {
|
||||
fields: [customerInfo.orderId],
|
||||
references: [order.id],
|
||||
}),
|
||||
}));
|
||||
export const customerInfoRelations = relations(customerInfo, ({}) => ({}));
|
||||
|
||||
export const orderRelations = relations(order, ({ one, many }) => ({
|
||||
emailAccount: one(emailAccount, {
|
||||
fields: [order.emailAccountId],
|
||||
references: [emailAccount.id],
|
||||
export const orderRelations = relations(order, ({ one }) => ({
|
||||
product: one(product, {
|
||||
fields: [order.productId],
|
||||
references: [product.id],
|
||||
}),
|
||||
flightTicketInfo: one(flightTicketInfo, {
|
||||
fields: [order.flightTicketInfoId],
|
||||
references: [flightTicketInfo.id],
|
||||
customerInfo: one(customerInfo, {
|
||||
fields: [order.customerInfoId],
|
||||
references: [customerInfo.id],
|
||||
}),
|
||||
customerInfos: many(customerInfo),
|
||||
}));
|
||||
|
||||
export const inboxRelations = relations(inbox, ({ one }) => ({
|
||||
emailAccount: one(emailAccount, {
|
||||
fields: [inbox.emailAccountId],
|
||||
references: [emailAccount.id],
|
||||
paymentInfo: one(paymentDetails, {
|
||||
fields: [order.paymentDetailsId],
|
||||
references: [paymentDetails.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const emailAccountPayloadModel = z.object({
|
||||
email: z.string().email().min(6).max(128),
|
||||
password: z.string().max(128),
|
||||
agentId: z.string().optional(),
|
||||
orderId: z.number().int().nullish().optional(),
|
||||
});
|
||||
export type EmailAccountPayload = z.infer<typeof emailAccountPayloadModel>;
|
||||
|
||||
export const emailAccountModel = emailAccountPayloadModel
|
||||
.pick({ email: true, agentId: true, orderId: true })
|
||||
.merge(
|
||||
z.object({
|
||||
id: z.number().int(),
|
||||
used: z.boolean().default(false),
|
||||
lastActiveCheckAt: z.coerce.string().optional(),
|
||||
createdAt: z.coerce.string(),
|
||||
updatedAt: z.coerce.string(),
|
||||
}),
|
||||
);
|
||||
export type EmailAccount = z.infer<typeof emailAccountModel>;
|
||||
|
||||
export const emailAccountFullModel = emailAccountPayloadModel.merge(
|
||||
z.object({
|
||||
id: z.number().int(),
|
||||
used: z.boolean().default(false),
|
||||
createdAt: z.coerce.string(),
|
||||
updatedAt: z.coerce.string(),
|
||||
}),
|
||||
);
|
||||
export type EmailAccountFull = z.infer<typeof emailAccountFullModel>;
|
||||
|
||||
export const inboxModel = z.object({
|
||||
id: z.number(),
|
||||
emailId: z.string().default(""),
|
||||
|
||||
from: z.string(),
|
||||
to: z.string().optional(),
|
||||
cc: z.string().optional(),
|
||||
subject: z.string(),
|
||||
body: z.string(),
|
||||
|
||||
attachments: z.any().optional(),
|
||||
emailAccountId: z.number(),
|
||||
|
||||
dated: z.coerce.string(),
|
||||
|
||||
createdAt: z.coerce.string(),
|
||||
updatedAt: z.coerce.string(),
|
||||
});
|
||||
export type InboxModel = z.infer<typeof inboxModel>;
|
||||
@@ -14,7 +14,6 @@ export const customerInfoModel = z.object({
|
||||
zipCode: z.string().min(1).max(21),
|
||||
address: z.string().min(1),
|
||||
address2: z.string().optional().nullable(),
|
||||
orderId: z.number().optional().nullable(),
|
||||
createdAt: z.coerce.string().optional(),
|
||||
updatedAt: z.coerce.string().optional(),
|
||||
});
|
||||
|
||||
@@ -97,41 +97,6 @@ export class CustomerInfoRepository {
|
||||
}
|
||||
}
|
||||
|
||||
async getCustomerInfoByOrderId(
|
||||
orderId: number,
|
||||
): Promise<Result<CustomerInfoModel[]>> {
|
||||
try {
|
||||
const results = await this.db.query.customerInfo.findMany({
|
||||
where: eq(customerInfo.orderId, orderId),
|
||||
});
|
||||
|
||||
const out = [] as CustomerInfoModel[];
|
||||
for (const result of results) {
|
||||
const parsed = customerInfoModel.safeParse(result);
|
||||
if (!parsed.success) {
|
||||
Logger.error("Failed to parse customer info", result);
|
||||
continue;
|
||||
}
|
||||
out.push(parsed.data);
|
||||
}
|
||||
return { data: out };
|
||||
} catch (e) {
|
||||
return {
|
||||
error: getError(
|
||||
{
|
||||
code: ERROR_CODES.DATABASE_ERROR,
|
||||
message: "Failed to fetch customer information",
|
||||
detail:
|
||||
"An error occurred while retrieving customer information for the order",
|
||||
userHint: "Please try again",
|
||||
actionable: false,
|
||||
},
|
||||
e,
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async createCustomerInfo(
|
||||
payload: CreateCustomerInfoPayload,
|
||||
): Promise<Result<number>> {
|
||||
@@ -151,7 +116,6 @@ export class CustomerInfoRepository {
|
||||
zipCode: payload.zipCode,
|
||||
address: payload.address,
|
||||
address2: payload.address2 || null,
|
||||
orderId: payload.orderId || null,
|
||||
})
|
||||
.returning({ id: customerInfo.id })
|
||||
.execute();
|
||||
@@ -231,7 +195,6 @@ export class CustomerInfoRepository {
|
||||
if (payload.address !== undefined) updateValues.address = payload.address;
|
||||
if (payload.address2 !== undefined)
|
||||
updateValues.address2 = payload.address2;
|
||||
if (payload.orderId !== undefined) updateValues.orderId = payload.orderId;
|
||||
updateValues.updatedAt = new Date();
|
||||
|
||||
await this.db
|
||||
|
||||
@@ -20,10 +20,6 @@ export class CustomerInfoUseCases {
|
||||
return this.repo.getCustomerInfoById(id);
|
||||
}
|
||||
|
||||
async getCustomerInfoByOrderId(orderId: number) {
|
||||
return this.repo.getCustomerInfoByOrderId(orderId);
|
||||
}
|
||||
|
||||
async createCustomerInfo(payload: CreateCustomerInfoPayload) {
|
||||
return this.repo.createCustomerInfo(payload);
|
||||
}
|
||||
|
||||
@@ -3,17 +3,19 @@ import { paginationModel } from "../../../core/pagination.utils";
|
||||
import { encodeCursor } from "../../../core/string.utils";
|
||||
import { customerInfoModel } from "../../customerinfo/data";
|
||||
import { paymentDetailsPayloadModel } from "../../paymentinfo/data/entities";
|
||||
import { flightTicketModel } from "../../ticket/data/entities";
|
||||
import { productModel } from "../../product/data";
|
||||
|
||||
export enum OrderCreationStep {
|
||||
ACCOUNT_SELECTION = 0,
|
||||
TICKET_SELECTION = 1,
|
||||
// TODO: only keep these remove the above 2 steps
|
||||
CUSTOMER_INFO = 2,
|
||||
PAYMENT = 2,
|
||||
SUMMARY = 3,
|
||||
}
|
||||
|
||||
export enum OrderStatus {
|
||||
PENDING_FULLFILLMENT = "PENDING_FULLFILLMENT",
|
||||
PENDING_FULFILLMENT = "PENDING_FULFILLMENT",
|
||||
PARTIALLY_FULFILLED = "PARTIALLY_FULFILLED",
|
||||
FULFILLED = "FULFILLED",
|
||||
CANCELLED = "CANCELLED",
|
||||
@@ -27,13 +29,12 @@ export const orderModel = z.object({
|
||||
displayPrice: z.coerce.number().min(0),
|
||||
orderPrice: z.coerce.number().min(0),
|
||||
fullfilledPrice: z.coerce.number().min(0),
|
||||
pricePerCustomer: z.coerce.number().min(0),
|
||||
|
||||
status: z.nativeEnum(OrderStatus),
|
||||
|
||||
flightTicketInfoId: z.number(),
|
||||
productId: z.number(),
|
||||
customerInfoId: z.number().nullish().optional(),
|
||||
emailAccountId: z.number().nullish().optional(),
|
||||
|
||||
paymentDetailsId: z.number().nullish().optional(),
|
||||
|
||||
createdAt: z.coerce.string(),
|
||||
@@ -41,37 +42,34 @@ export const orderModel = z.object({
|
||||
});
|
||||
export type OrderModel = z.infer<typeof orderModel>;
|
||||
|
||||
export const limitedOrderWithTicketInfoModel = orderModel
|
||||
export const limitedOrderWithProductModel = orderModel
|
||||
.pick({
|
||||
id: true,
|
||||
basePrice: true,
|
||||
discountAmount: true,
|
||||
displayPrice: true,
|
||||
pricePerCustomer: true,
|
||||
fullfilledPrice: true,
|
||||
status: true,
|
||||
})
|
||||
.merge(
|
||||
z.object({
|
||||
flightTicketInfo: flightTicketModel.pick({
|
||||
product: productModel.pick({
|
||||
id: true,
|
||||
departure: true,
|
||||
arrival: true,
|
||||
departureDate: true,
|
||||
returnDate: true,
|
||||
flightType: true,
|
||||
passengerCounts: true,
|
||||
title: true,
|
||||
description: true,
|
||||
price: true,
|
||||
discountPrice: true,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
export type LimitedOrderWithTicketInfoModel = z.infer<
|
||||
typeof limitedOrderWithTicketInfoModel
|
||||
export type LimitedOrderWithProductModel = z.infer<
|
||||
typeof limitedOrderWithProductModel
|
||||
>;
|
||||
|
||||
export const fullOrderModel = orderModel.merge(
|
||||
z.object({
|
||||
flightTicketInfo: flightTicketModel,
|
||||
customerInfos: z.array(customerInfoModel).default([]),
|
||||
product: productModel,
|
||||
customerInfo: customerInfoModel.optional().nullable(),
|
||||
}),
|
||||
);
|
||||
export type FullOrderModel = z.infer<typeof fullOrderModel>;
|
||||
@@ -108,20 +106,18 @@ export const newOrderModel = orderModel.pick({
|
||||
discountAmount: true,
|
||||
orderPrice: true,
|
||||
fullfilledPrice: true,
|
||||
pricePerCustomer: true,
|
||||
flightTicketInfoId: true,
|
||||
productId: true,
|
||||
customerInfoId: true,
|
||||
paymentDetailsId: true,
|
||||
emailAccountId: true,
|
||||
});
|
||||
export type NewOrderModel = z.infer<typeof newOrderModel>;
|
||||
|
||||
export const createOrderPayloadModel = z.object({
|
||||
flightTicketInfo: flightTicketModel.optional(),
|
||||
flightTicketId: z.number().optional(),
|
||||
refOIds: z.array(z.number()).nullable().optional(),
|
||||
product: productModel.optional(),
|
||||
productId: z.number().optional(),
|
||||
customerInfo: customerInfoModel,
|
||||
paymentDetails: paymentDetailsPayloadModel.optional(),
|
||||
orderModel: newOrderModel,
|
||||
customerInfos: z.array(customerInfoModel),
|
||||
flowId: z.string().optional(),
|
||||
});
|
||||
export type CreateOrderModel = z.infer<typeof createOrderPayloadModel>;
|
||||
|
||||
@@ -77,14 +77,16 @@ export type CardInfo = z.infer<typeof cardInfoModel>;
|
||||
export const paymentDetailsPayloadModel = z.object({
|
||||
method: z.enum([PaymentMethod.Card]),
|
||||
cardDetails: cardInfoModel,
|
||||
flightTicketInfoId: z.number().int(),
|
||||
productId: z.number().int(),
|
||||
orderId: z.number().int(),
|
||||
});
|
||||
export type PaymentDetailsPayload = z.infer<typeof paymentDetailsPayloadModel>;
|
||||
|
||||
export const paymentDetailsModel = cardInfoModel.merge(
|
||||
z.object({
|
||||
id: z.number().int(),
|
||||
flightTicketInfoId: z.number().int(),
|
||||
productId: z.number().int(),
|
||||
orderId: z.number().int(),
|
||||
createdAt: z.string().datetime(),
|
||||
updatedAt: z.string().datetime(),
|
||||
}),
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import { z } from "zod";
|
||||
import { PackageType, PaymentMethod } from "./enums";
|
||||
export * from "../../../passengerinfo/data/entities";
|
||||
|
||||
// Flight package selection models
|
||||
|
||||
export const packageSelectionModel = z.object({
|
||||
packageType: z.enum([
|
||||
PackageType.Basic,
|
||||
PackageType.Flex,
|
||||
PackageType.Premium,
|
||||
]),
|
||||
insurance: z.boolean().default(false),
|
||||
});
|
||||
export type PackageSelection = z.infer<typeof packageSelectionModel>;
|
||||
|
||||
// payment models
|
||||
|
||||
export const cardInfoModel = z.object({
|
||||
nameOnCard: z.string().min(1).max(255),
|
||||
number: z.string().max(20),
|
||||
expiryDate: z.string().max(8),
|
||||
cvv: z.string().max(6),
|
||||
});
|
||||
export type CardInfo = z.infer<typeof cardInfoModel>;
|
||||
|
||||
export const paymentInfoModel = z.object({
|
||||
method: z.enum([PaymentMethod.Card]).default(PaymentMethod.Card),
|
||||
cardInfo: cardInfoModel,
|
||||
});
|
||||
export type PaymentInfo = z.infer<typeof paymentInfoModel>;
|
||||
@@ -1,43 +0,0 @@
|
||||
export enum CheckoutStep {
|
||||
Setup = "SETUP",
|
||||
Initial = "INITIAL",
|
||||
Payment = "PAYMENT",
|
||||
Verification = "VERIFICATION",
|
||||
Confirmation = "CONFIRMATION",
|
||||
Complete = "COMPLETE",
|
||||
}
|
||||
|
||||
export const TicketType = {
|
||||
OneWay: "ONEWAY",
|
||||
Return: "RETURN",
|
||||
};
|
||||
|
||||
export const CabinClass = {
|
||||
Economy: "ECONOMY",
|
||||
PremiumEconomy: "PREMIUM_ECONOMY",
|
||||
Business: "BUSINESS",
|
||||
FirstClass: "FIRST_CLASS",
|
||||
};
|
||||
|
||||
export enum Gender {
|
||||
Male = "male",
|
||||
Female = "female",
|
||||
Other = "other",
|
||||
}
|
||||
|
||||
export enum PaymentMethod {
|
||||
Card = "CARD",
|
||||
GooglePay = "GOOGLE_PAY",
|
||||
ApplePay = "APPLEPAY",
|
||||
}
|
||||
|
||||
export enum PassengerType {
|
||||
Adult = "adult",
|
||||
Child = "child",
|
||||
}
|
||||
|
||||
export enum PackageType {
|
||||
Basic = "basic",
|
||||
Flex = "flex",
|
||||
Premium = "premium",
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
import { z } from "zod";
|
||||
import { CabinClass, TicketType } from "./enums";
|
||||
|
||||
export * from "./enums";
|
||||
|
||||
export const stationModel = z.object({
|
||||
id: z.number(),
|
||||
type: z.string(),
|
||||
code: z.string(),
|
||||
name: z.string(),
|
||||
city: z.string(),
|
||||
country: z.string(),
|
||||
});
|
||||
export type Station = z.infer<typeof stationModel>;
|
||||
|
||||
export const iteneraryStationModel = z.object({
|
||||
station: stationModel,
|
||||
localTime: z.string(),
|
||||
utcTime: z.string(),
|
||||
});
|
||||
export type IteneraryStation = z.infer<typeof iteneraryStationModel>;
|
||||
|
||||
export const seatInfoModel = z.object({
|
||||
availableSeats: z.number(),
|
||||
seatClass: z.string(),
|
||||
});
|
||||
export type SeatInfo = z.infer<typeof seatInfoModel>;
|
||||
|
||||
export const flightPriceDetailsModel = z.object({
|
||||
currency: z.string(),
|
||||
basePrice: z.number(),
|
||||
discountAmount: z.number(),
|
||||
displayPrice: z.number(),
|
||||
orderPrice: z.number().nullable().optional(),
|
||||
appliedCoupon: z.string().nullish().optional(),
|
||||
couponDescription: z.string().nullish().optional(),
|
||||
});
|
||||
export type FlightPriceDetails = z.infer<typeof flightPriceDetailsModel>;
|
||||
|
||||
export const airlineModel = z.object({
|
||||
code: z.string(),
|
||||
name: z.string(),
|
||||
imageUrl: z.string().nullable().optional(),
|
||||
});
|
||||
export type Airline = z.infer<typeof airlineModel>;
|
||||
|
||||
export const flightIteneraryModel = z.object({
|
||||
flightId: z.string(),
|
||||
flightNumber: z.string(),
|
||||
airline: airlineModel,
|
||||
departure: iteneraryStationModel,
|
||||
destination: iteneraryStationModel,
|
||||
durationSeconds: z.number(),
|
||||
seatInfo: seatInfoModel,
|
||||
});
|
||||
export type FlightItenerary = z.infer<typeof flightIteneraryModel>;
|
||||
|
||||
export const passengerCountModel = z.object({
|
||||
adults: z.number().int().min(0),
|
||||
children: z.number().int().min(0),
|
||||
});
|
||||
export type PassengerCount = z.infer<typeof passengerCountModel>;
|
||||
|
||||
export function countPassengers(model: PassengerCount) {
|
||||
return model.adults + model.children;
|
||||
}
|
||||
|
||||
export const bagDimensionsModel = z.object({
|
||||
length: z.number(),
|
||||
width: z.number(),
|
||||
height: z.number(),
|
||||
});
|
||||
export type BagDimensions = z.infer<typeof bagDimensionsModel>;
|
||||
|
||||
export const bagDetailsModel = z.object({
|
||||
price: z.number(),
|
||||
weight: z.number(),
|
||||
unit: z.string(),
|
||||
dimensions: bagDimensionsModel,
|
||||
});
|
||||
export type BagDetails = z.infer<typeof bagDetailsModel>;
|
||||
|
||||
export const allBagDetailsModel = z.object({
|
||||
personalBags: bagDetailsModel,
|
||||
handBags: bagDetailsModel,
|
||||
checkedBags: bagDetailsModel,
|
||||
});
|
||||
export type AllBagDetails = z.infer<typeof allBagDetailsModel>;
|
||||
|
||||
// INFO: If you are to array-ificate it, you can just modify the details
|
||||
// key below so that the user's order thing is not disrupted
|
||||
|
||||
export const bagsInfoModel = z.object({
|
||||
includedPersonalBags: z.number().default(1),
|
||||
includedHandBags: z.number().default(0),
|
||||
includedCheckedBags: z.number().default(0),
|
||||
hasHandBagsSupport: z.boolean().default(true),
|
||||
hasCheckedBagsSupport: z.boolean().default(true),
|
||||
details: allBagDetailsModel,
|
||||
});
|
||||
export type BagsInfo = z.infer<typeof bagsInfoModel>;
|
||||
|
||||
export const flightTicketModel = z.object({
|
||||
id: z.number().int(),
|
||||
ticketId: z.string(),
|
||||
|
||||
// For lookup purposes, we need these on the top level
|
||||
departure: z.string(),
|
||||
arrival: z.string(),
|
||||
departureDate: z.coerce.string(),
|
||||
returnDate: z.coerce.string().default(""),
|
||||
dates: z.array(z.string()),
|
||||
|
||||
flightType: z.enum([TicketType.OneWay, TicketType.Return]),
|
||||
flightIteneraries: z.object({
|
||||
outbound: z.array(flightIteneraryModel),
|
||||
inbound: z.array(flightIteneraryModel),
|
||||
}),
|
||||
priceDetails: flightPriceDetailsModel,
|
||||
refundable: z.boolean(),
|
||||
passengerCounts: passengerCountModel,
|
||||
cabinClass: z.string(),
|
||||
bagsInfo: bagsInfoModel,
|
||||
lastAvailable: z.object({ availableSeats: z.number() }),
|
||||
|
||||
shareId: z.string(),
|
||||
checkoutUrl: z.string(),
|
||||
|
||||
isCache: z.boolean().nullish().optional(),
|
||||
refOIds: z.array(z.coerce.number()).nullish().optional(),
|
||||
|
||||
createdAt: z.coerce.string(),
|
||||
updatedAt: z.coerce.string(),
|
||||
});
|
||||
export type FlightTicket = z.infer<typeof flightTicketModel>;
|
||||
|
||||
export const limitedFlightTicketModel = flightTicketModel.pick({
|
||||
id: true,
|
||||
departure: true,
|
||||
arrival: true,
|
||||
departureDate: true,
|
||||
returnDate: true,
|
||||
flightType: true,
|
||||
dates: true,
|
||||
priceDetails: true,
|
||||
passengerCounts: true,
|
||||
cabinClass: true,
|
||||
});
|
||||
export type LimitedFlightTicket = z.infer<typeof limitedFlightTicketModel>;
|
||||
|
||||
// INFO: ticket search models
|
||||
|
||||
export const ticketSearchPayloadModel = z.object({
|
||||
sessionId: z.string(),
|
||||
ticketType: z.enum([TicketType.OneWay, TicketType.Return]),
|
||||
cabinClass: z.enum([
|
||||
CabinClass.Economy,
|
||||
CabinClass.PremiumEconomy,
|
||||
CabinClass.Business,
|
||||
CabinClass.FirstClass,
|
||||
]),
|
||||
departure: z.string().min(3),
|
||||
arrival: z.string().min(3),
|
||||
passengerCounts: passengerCountModel,
|
||||
departureDate: z.coerce.string().min(3),
|
||||
returnDate: z.coerce.string(),
|
||||
loadMore: z.boolean().default(false),
|
||||
meta: z.record(z.string(), z.any()).optional(),
|
||||
couponCode: z.string().optional(),
|
||||
});
|
||||
export type TicketSearchPayload = z.infer<typeof ticketSearchPayloadModel>;
|
||||
|
||||
export const ticketSearchDTO = z.object({
|
||||
sessionId: z.string(),
|
||||
ticketSearchPayload: ticketSearchPayloadModel,
|
||||
providers: z.array(z.string()).optional(),
|
||||
});
|
||||
export type TicketSearchDTO = z.infer<typeof ticketSearchDTO>;
|
||||
Reference in New Issue
Block a user