import { pgTable, serial, varchar, timestamp, text, foreignKey, integer, boolean, jsonb, index, uniqueIndex, unique, primaryKey } from "drizzle-orm/pg-core" import { sql } from "drizzle-orm" export const pgmigrations = pgTable("pgmigrations", { id: serial().primaryKey().notNull(), name: varchar({ length: 255 }).notNull(), runOn: timestamp("run_on", { mode: 'string' }).notNull(), }); export const adminSettings = pgTable("admin_settings", { key: text().primaryKey().notNull(), value: text().notNull(), updatedAt: timestamp("updated_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), }); export const itemImages = pgTable("item_images", { id: serial().primaryKey().notNull(), itemId: integer("item_id").notNull(), imagePath: text("image_path").notNull(), sortOrder: integer("sort_order").default(0).notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), }, (table) => [ foreignKey({ columns: [table.itemId], foreignColumns: [items.id], name: "item_images_item_id_fkey" }).onDelete("cascade"), ]); export const shippingAddresses = pgTable("shipping_addresses", { id: serial().primaryKey().notNull(), customerId: integer("customer_id").notNull(), fullName: text("full_name").notNull(), addressLine1: text("address_line1").notNull(), addressLine2: text("address_line2"), city: text().notNull(), state: text().notNull(), postalCode: text("postal_code").notNull(), country: text().default('US').notNull(), isDefault: boolean("is_default").default(false).notNull(), uspsValidated: boolean("usps_validated").default(false).notNull(), uspsStandardized: jsonb("usps_standardized"), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), }, (table) => [ foreignKey({ columns: [table.customerId], foreignColumns: [customers.id], name: "shipping_addresses_customer_id_fkey" }).onDelete("cascade"), ]); export const items = pgTable("items", { id: serial().primaryKey().notNull(), name: text().notNull(), description: text(), priceCents: integer("price_cents").notNull(), status: text().default('pending').notNull(), reservedUntil: timestamp("reserved_until", { withTimezone: true, mode: 'string' }), soldAt: timestamp("sold_at", { withTimezone: true, mode: 'string' }), paypalOrderId: text("paypal_order_id"), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), categoryId: integer("category_id"), conditionNote: text("condition_note"), }, (table) => [ index("items_category_id_idx").using("btree", table.categoryId.asc().nullsLast().op("int4_ops")), foreignKey({ columns: [table.categoryId], foreignColumns: [categories.id], name: "items_category_id_fkey" }).onDelete("set null"), ]); export const tags = pgTable("tags", { id: serial().primaryKey().notNull(), name: text().notNull(), color: text().notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), }, () => [ uniqueIndex("tags_name_uniq").using("btree", sql`lower(name)`), ]); export const categories = pgTable("categories", { id: serial().primaryKey().notNull(), name: text().notNull(), parentId: integer("parent_id"), sortOrder: integer("sort_order").default(0).notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), }, (table) => [ uniqueIndex("categories_child_name_uniq").using("btree", sql`parent_id`, sql`lower(name)`).where(sql`(parent_id IS NOT NULL)`), index("categories_parent_id_idx").using("btree", table.parentId.asc().nullsLast().op("int4_ops")), uniqueIndex("categories_root_name_uniq").using("btree", sql`lower(name)`).where(sql`(parent_id IS NULL)`), foreignKey({ columns: [table.parentId], foreignColumns: [table.id], name: "categories_parent_id_fkey" }).onDelete("cascade"), ]); export const orders = pgTable("orders", { id: serial().primaryKey().notNull(), itemId: integer("item_id"), customerId: integer("customer_id"), checkoutId: integer("checkout_id"), processor: text().notNull(), processorOrderId: text("processor_order_id"), amountCents: integer("amount_cents"), status: text(), rawEvent: jsonb("raw_event"), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), }, (table) => [ foreignKey({ columns: [table.itemId], foreignColumns: [items.id], name: "orders_item_id_fkey" }), foreignKey({ columns: [table.customerId], foreignColumns: [customers.id], name: "orders_customer_id_fkey" }).onDelete("set null"), foreignKey({ columns: [table.checkoutId], foreignColumns: [checkouts.id], name: "orders_checkout_id_fkey" }).onDelete("set null"), ]); export const cartItems = pgTable("cart_items", { id: serial().primaryKey().notNull(), cartId: integer("cart_id").notNull(), itemId: integer("item_id").notNull(), addedAt: timestamp("added_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), expiresAt: timestamp("expires_at", { withTimezone: true, mode: 'string' }).notNull(), lastReminderSentAt: timestamp("last_reminder_sent_at", { withTimezone: true, mode: 'string' }), }, (table) => [ foreignKey({ columns: [table.cartId], foreignColumns: [carts.id], name: "cart_items_cart_id_fkey" }).onDelete("cascade"), foreignKey({ columns: [table.itemId], foreignColumns: [items.id], name: "cart_items_item_id_fkey" }).onDelete("cascade"), unique("cart_items_item_id_key").on(table.itemId), ]); export const carts = pgTable("carts", { id: serial().primaryKey().notNull(), customerId: integer("customer_id").notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), updatedAt: timestamp("updated_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), }, (table) => [ foreignKey({ columns: [table.customerId], foreignColumns: [customers.id], name: "carts_customer_id_fkey" }).onDelete("cascade"), unique("carts_customer_id_key").on(table.customerId), ]); export const customerTokens = pgTable("customer_tokens", { token: text().primaryKey().notNull(), customerId: integer("customer_id").notNull(), kind: text().notNull(), expiresAt: timestamp("expires_at", { withTimezone: true, mode: 'string' }).notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), }, (table) => [ foreignKey({ columns: [table.customerId], foreignColumns: [customers.id], name: "customer_tokens_customer_id_fkey" }).onDelete("cascade"), ]); export const checkouts = pgTable("checkouts", { id: serial().primaryKey().notNull(), customerId: integer("customer_id"), shippingAddressId: integer("shipping_address_id"), processor: text().notNull(), processorOrderId: text("processor_order_id"), amountCents: integer("amount_cents"), status: text().default('pending').notNull(), rawEvent: jsonb("raw_event"), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), }, (table) => [ foreignKey({ columns: [table.customerId], foreignColumns: [customers.id], name: "checkouts_customer_id_fkey" }).onDelete("set null"), foreignKey({ columns: [table.shippingAddressId], foreignColumns: [shippingAddresses.id], name: "checkouts_shipping_address_id_fkey" }).onDelete("set null"), ]); export const customerSessions = pgTable("customer_sessions", { token: text().primaryKey().notNull(), customerId: integer("customer_id").notNull(), expiresAt: timestamp("expires_at", { withTimezone: true, mode: 'string' }).notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), }, (table) => [ foreignKey({ columns: [table.customerId], foreignColumns: [customers.id], name: "customer_sessions_customer_id_fkey" }).onDelete("cascade"), ]); export const customers = pgTable("customers", { id: serial().primaryKey().notNull(), email: text().notNull(), passwordHash: text("password_hash").notNull(), emailVerified: boolean("email_verified").default(false).notNull(), marketingConsent: boolean("marketing_consent").default(false).notNull(), marketingConsentAt: timestamp("marketing_consent_at", { withTimezone: true, mode: 'string' }), marketingConsentText: text("marketing_consent_text"), unsubscribeToken: text("unsubscribe_token").notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), disabledAt: timestamp("disabled_at", { withTimezone: true, mode: 'string' }), favoriteAlerts: boolean("favorite_alerts").default(false).notNull(), favoriteAlertsAt: timestamp("favorite_alerts_at", { withTimezone: true, mode: 'string' }), favoriteAlertsText: text("favorite_alerts_text"), firstName: text("first_name"), lastName: text("last_name"), }, (table) => [ index("customers_disabled_at_idx").using("btree", table.disabledAt.asc().nullsLast().op("timestamptz_ops")).where(sql`(disabled_at IS NOT NULL)`), unique("customers_email_key").on(table.email), unique("customers_unsubscribe_token_key").on(table.unsubscribeToken), ]); export const itemTags = pgTable("item_tags", { itemId: integer("item_id").notNull(), tagId: integer("tag_id").notNull(), }, (table) => [ index("item_tags_tag_id_idx").using("btree", table.tagId.asc().nullsLast().op("int4_ops")), foreignKey({ columns: [table.itemId], foreignColumns: [items.id], name: "item_tags_item_id_fkey" }).onDelete("cascade"), foreignKey({ columns: [table.tagId], foreignColumns: [tags.id], name: "item_tags_tag_id_fkey" }).onDelete("cascade"), primaryKey({ columns: [table.itemId, table.tagId], name: "item_tags_pkey"}), ]); export const favorites = pgTable("favorites", { customerId: integer("customer_id").notNull(), itemId: integer("item_id").notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), }, (table) => [ index("favorites_item_id_idx").using("btree", table.itemId.asc().nullsLast().op("int4_ops")), foreignKey({ columns: [table.customerId], foreignColumns: [customers.id], name: "favorites_customer_id_fkey" }).onDelete("cascade"), foreignKey({ columns: [table.itemId], foreignColumns: [items.id], name: "favorites_item_id_fkey" }).onDelete("cascade"), primaryKey({ columns: [table.customerId, table.itemId], name: "favorites_pkey"}), ]); export const checkoutItems = pgTable("checkout_items", { checkoutId: integer("checkout_id").notNull(), itemId: integer("item_id").notNull(), priceCents: integer("price_cents").notNull(), }, (table) => [ foreignKey({ columns: [table.checkoutId], foreignColumns: [checkouts.id], name: "checkout_items_checkout_id_fkey" }).onDelete("cascade"), foreignKey({ columns: [table.itemId], foreignColumns: [items.id], name: "checkout_items_item_id_fkey" }).onDelete("cascade"), primaryKey({ columns: [table.checkoutId, table.itemId], name: "checkout_items_pkey"}), ]);