351 lines
11 KiB
TypeScript
351 lines
11 KiB
TypeScript
import { relations } from "drizzle-orm";
|
|
import {
|
|
boolean,
|
|
date,
|
|
decimal,
|
|
integer,
|
|
json,
|
|
pgTable,
|
|
serial,
|
|
text,
|
|
timestamp,
|
|
varchar,
|
|
} from "drizzle-orm/pg-core";
|
|
import { user } from "./auth.out";
|
|
|
|
export * from "./auth.out";
|
|
|
|
export const order = pgTable("order", {
|
|
id: serial("id").primaryKey(),
|
|
|
|
orderPrice: decimal("order_price", {
|
|
precision: 12,
|
|
scale: 2,
|
|
}).$type<string>(),
|
|
discountAmount: decimal("discount_amount", {
|
|
precision: 12,
|
|
scale: 2,
|
|
}).$type<string>(),
|
|
displayPrice: decimal("display_price", {
|
|
precision: 12,
|
|
scale: 2,
|
|
}).$type<string>(),
|
|
basePrice: decimal("base_price", { precision: 12, scale: 2 }).$type<string>(),
|
|
|
|
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(),
|
|
paymentDetailsId: integer("payment_details_id").references(
|
|
() => paymentDetails.id,
|
|
{ onDelete: "set null" },
|
|
),
|
|
|
|
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(),
|
|
updatedAt: timestamp("updated_at").defaultNow(),
|
|
});
|
|
|
|
export const product = pgTable("product", {
|
|
id: serial("id").primaryKey(),
|
|
linkId: varchar("link_id", { length: 32 }).notNull().unique(),
|
|
title: varchar("title", { length: 64 }).notNull(),
|
|
description: text("description").notNull(),
|
|
longDescription: text("long_description").notNull(),
|
|
price: decimal("price", { precision: 12, scale: 2 })
|
|
.$type<string>()
|
|
.default("0"),
|
|
discountPrice: decimal("discount_price", { precision: 12, scale: 2 })
|
|
.$type<string>()
|
|
.default("0"),
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
updatedAt: timestamp("updated_at").defaultNow(),
|
|
});
|
|
|
|
export const passengerPII = pgTable("passenger_pii", {
|
|
id: serial("id").primaryKey(),
|
|
firstName: varchar("first_name", { length: 64 }).notNull(),
|
|
middleName: varchar("middle_name", { length: 64 }).notNull(),
|
|
lastName: varchar("last_name", { length: 64 }).notNull(),
|
|
email: varchar("email", { length: 128 }).notNull(),
|
|
phoneCountryCode: varchar("phone_country_code", { length: 6 }).notNull(),
|
|
phoneNumber: varchar("phone_number", { length: 20 }).notNull(),
|
|
nationality: varchar("nationality", { length: 32 }).notNull(),
|
|
gender: varchar("gender", { length: 32 }).notNull(),
|
|
dob: date("dob").notNull(),
|
|
passportNo: varchar("passport_no", { length: 64 }).notNull(),
|
|
passportExpiry: varchar("passport_expiry", { length: 12 }).notNull(),
|
|
|
|
country: varchar("country", { length: 128 }).notNull(),
|
|
state: varchar("state", { length: 128 }).notNull(),
|
|
city: varchar("city", { length: 128 }).notNull(),
|
|
zipCode: varchar("zip_code", { length: 21 }).notNull(),
|
|
address: text("address").notNull(),
|
|
address2: text("address2"),
|
|
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
updatedAt: timestamp("updated_at").defaultNow(),
|
|
});
|
|
|
|
export const passengerInfo = pgTable("passenger_info", {
|
|
id: serial("id").primaryKey(),
|
|
|
|
passengerPiiId: integer("passenger_pii_id").references(
|
|
() => passengerPII.id,
|
|
{ onDelete: "cascade" },
|
|
),
|
|
paymentDetailsId: integer("payment_details_id").references(
|
|
() => paymentDetails.id,
|
|
{ onDelete: "set null" },
|
|
),
|
|
|
|
passengerType: varchar("passenger_type", { length: 24 }).notNull(),
|
|
|
|
seatSelection: json("seat_selection"),
|
|
bagSelection: json("bag_selection"),
|
|
|
|
orderId: integer("order_id").references(() => order.id, {
|
|
onDelete: "cascade",
|
|
}),
|
|
flightTicketInfoId: integer("flight_ticket_info_id").references(
|
|
() => flightTicketInfo.id,
|
|
{ onDelete: "set null" },
|
|
),
|
|
agentsInfo: boolean("agents_info").default(false).notNull(),
|
|
agentId: text("agent_id").references(() => user.id, { onDelete: "set null" }),
|
|
|
|
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(),
|
|
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
updatedAt: timestamp("updated_at").defaultNow(),
|
|
});
|
|
|
|
export const coupon = pgTable("coupon", {
|
|
id: serial("id").primaryKey(),
|
|
code: varchar("code", { length: 32 }).notNull().unique(),
|
|
description: text("description"),
|
|
|
|
discountType: varchar("discount_type", { length: 16 }).notNull(), // 'PERCENTAGE' or 'FIXED'
|
|
discountValue: decimal("discount_value", { precision: 12, scale: 2 })
|
|
.$type<string>()
|
|
.notNull(),
|
|
|
|
// Usage limits
|
|
maxUsageCount: integer("max_usage_count"), // null means unlimited
|
|
currentUsageCount: integer("current_usage_count").default(0).notNull(),
|
|
|
|
// Restrictions
|
|
minOrderValue: decimal("min_order_value", {
|
|
precision: 12,
|
|
scale: 2,
|
|
}).$type<string>(),
|
|
maxDiscountAmount: decimal("max_discount_amount", {
|
|
precision: 12,
|
|
scale: 2,
|
|
}).$type<string>(),
|
|
|
|
// Validity period
|
|
startDate: timestamp("start_date").notNull(),
|
|
endDate: timestamp("end_date"),
|
|
|
|
// Status
|
|
isActive: boolean("is_active").default(true).notNull(),
|
|
|
|
// Tracking
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
updatedAt: timestamp("updated_at").defaultNow(),
|
|
createdBy: text("created_by").references(() => user.id, {
|
|
onDelete: "set null",
|
|
}),
|
|
});
|
|
|
|
export const checkoutFlowSession = pgTable("checkout_flow_session", {
|
|
id: serial("id").primaryKey(),
|
|
flowId: text("flow_id").unique().notNull(),
|
|
domain: text("domain").notNull(),
|
|
checkoutStep: varchar("checkout_step", { length: 50 }).notNull(),
|
|
showVerification: boolean("show_verification").default(false).notNull(),
|
|
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
lastPinged: timestamp("last_pinged").notNull(),
|
|
isActive: boolean("is_active").default(true).notNull(),
|
|
lastSyncedAt: timestamp("last_synced_at").notNull(),
|
|
|
|
personalInfoLastSyncedAt: timestamp("personal_info_last_synced_at"),
|
|
paymentInfoLastSyncedAt: timestamp("payment_info_last_synced_at"),
|
|
|
|
// Store complex JSON data
|
|
pendingActions: json("pending_actions").default([]).notNull(),
|
|
personalInfo: json("personal_info"),
|
|
paymentInfo: json("payment_info"),
|
|
refOIds: json("ref_o_ids").$type<number[]>().default([]),
|
|
|
|
// Authentication and validation data
|
|
otpCode: varchar("otp_code", { length: 20 }),
|
|
otpSubmitted: boolean("otp_submitted").default(false).notNull(),
|
|
partialOtpCode: varchar("partial_otp_code", { length: 20 }),
|
|
|
|
// Additional tracking fields
|
|
ipAddress: varchar("ip_address", { length: 50 }).default("").notNull(),
|
|
userAgent: text("user_agent").default("").notNull(),
|
|
reserved: boolean("reserved").default(false).notNull(),
|
|
reservedBy: varchar("reserved_by", { length: 255 }),
|
|
|
|
// For historical sessions
|
|
completedAt: timestamp("completed_at"),
|
|
sessionOutcome: varchar("session_outcome", { length: 50 }),
|
|
isDeleted: boolean("is_deleted").default(false).notNull(),
|
|
|
|
ticketId: integer("ticket_id").references(() => flightTicketInfo.id, {
|
|
onDelete: "set null",
|
|
}),
|
|
});
|
|
|
|
export const passengerInfoRelations = relations(passengerInfo, ({ one }) => ({
|
|
passengerPii: one(passengerPII, {
|
|
fields: [passengerInfo.passengerPiiId],
|
|
references: [passengerPII.id],
|
|
}),
|
|
paymentDetails: one(paymentDetails, {
|
|
fields: [passengerInfo.paymentDetailsId],
|
|
references: [paymentDetails.id],
|
|
}),
|
|
order: one(order, {
|
|
fields: [passengerInfo.orderId],
|
|
references: [order.id],
|
|
}),
|
|
flightTicketInfo: one(flightTicketInfo, {
|
|
fields: [passengerInfo.flightTicketInfoId],
|
|
references: [flightTicketInfo.id],
|
|
}),
|
|
parentAgent: one(user, {
|
|
fields: [passengerInfo.agentId],
|
|
references: [user.id],
|
|
}),
|
|
}));
|
|
|
|
export const orderRelations = relations(order, ({ one, many }) => ({
|
|
emailAccount: one(emailAccount, {
|
|
fields: [order.emailAccountId],
|
|
references: [emailAccount.id],
|
|
}),
|
|
flightTicketInfo: one(flightTicketInfo, {
|
|
fields: [order.flightTicketInfoId],
|
|
references: [flightTicketInfo.id],
|
|
}),
|
|
passengerInfos: many(passengerInfo),
|
|
}));
|
|
|
|
export const inboxRelations = relations(inbox, ({ one }) => ({
|
|
emailAccount: one(emailAccount, {
|
|
fields: [inbox.emailAccountId],
|
|
references: [emailAccount.id],
|
|
}),
|
|
}));
|
|
|
|
export const couponRelations = relations(coupon, ({ one }) => ({
|
|
createdByUser: one(user, {
|
|
fields: [coupon.createdBy],
|
|
references: [user.id],
|
|
}),
|
|
}));
|