ecom / shared /schema.ts
shashwatIDR's picture
Upload 147 files
b89a86e verified
import { sql } from "drizzle-orm";
import { pgTable, text, varchar, integer, decimal, timestamp, boolean, uuid } from "drizzle-orm/pg-core";
import { relations } from "drizzle-orm";
import { createInsertSchema } from "drizzle-zod";
import { z } from "zod";
// Users table - customers only
export const users = pgTable("users", {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
username: varchar("username", { length: 100 }).notNull().unique(),
email: varchar("email", { length: 255 }).notNull().unique(),
password: text("password").notNull(),
firstName: varchar("first_name", { length: 100 }).notNull(),
lastName: varchar("last_name", { length: 100 }).notNull(),
phone: varchar("phone", { length: 20 }).notNull(),
street: text("street"),
city: varchar("city", { length: 100 }),
state: varchar("state", { length: 100 }),
pinCode: varchar("pin_code", { length: 20 }),
country: varchar("country", { length: 100 }),
// Automatic location detection fields
latitude: decimal("latitude", { precision: 10, scale: 8 }),
longitude: decimal("longitude", { precision: 11, scale: 8 }),
googleMapsUrl: text("google_maps_url"),
locationDetectedAutomatically: boolean("location_detected_automatically").default(false),
createdAt: timestamp("created_at").defaultNow(),
});
// Sellers table - admin-created accounts
export const sellers = pgTable("sellers", {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
username: varchar("username", { length: 100 }).notNull().unique(),
password: text("password").notNull(),
plainTextPassword: text("plain_text_password"), // For admin access recovery
createdAt: timestamp("created_at").defaultNow(),
});
// Categories table - admin managed
export const categories = pgTable("categories", {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
name: varchar("name", { length: 100 }).notNull().unique(),
icon: varchar("icon", { length: 50 }),
imageUrl: varchar("image_url", { length: 500 }),
createdAt: timestamp("created_at").defaultNow(),
});
// Stores table - seller store information
export const stores = pgTable("stores", {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
sellerId: uuid("seller_id").references(() => sellers.id, { onDelete: "cascade" }).notNull(),
name: varchar("name", { length: 200 }).notNull(),
description: text("description"),
bannerImage: text("banner_image"),
faceImage: text("face_image"),
createdAt: timestamp("created_at").defaultNow(),
});
// Products table
export const products = pgTable("products", {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
sellerId: uuid("seller_id").references(() => sellers.id, { onDelete: "cascade" }).notNull(),
categoryId: uuid("category_id").references(() => categories.id).notNull(),
title: varchar("title", { length: 255 }).notNull(),
description: text("description").notNull(),
price: decimal("price", { precision: 10, scale: 2 }).notNull(),
originalPrice: decimal("original_price", { precision: 10, scale: 2 }),
stock: integer("stock").default(0),
images: text("images").array(),
isActive: boolean("is_active").default(true),
createdAt: timestamp("created_at").defaultNow(),
});
// Orders table
export const orders = pgTable("orders", {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
userId: uuid("user_id").references(() => users.id).notNull(),
status: varchar("status", { length: 50 }).default("pending"), // pending, processing, shipped, delivered, cancelled
paymentStatus: varchar("payment_status", { length: 50 }).default("unpaid"), // unpaid, paid
subtotal: decimal("subtotal", { precision: 10, scale: 2 }).notNull(),
tax: decimal("tax", { precision: 10, scale: 2 }).notNull(),
shipping: decimal("shipping", { precision: 10, scale: 2 }).default("0.00"),
total: decimal("total", { precision: 10, scale: 2 }).notNull(),
shippingAddress: text("shipping_address").notNull(),
paymentMethod: varchar("payment_method", { length: 50 }).default("cod").notNull(), // cod = Cash on Delivery, upi = UPI
createdAt: timestamp("created_at").defaultNow(),
});
// Order Items table
export const orderItems = pgTable("order_items", {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
orderId: uuid("order_id").references(() => orders.id, { onDelete: "cascade" }).notNull(),
productId: uuid("product_id").references(() => products.id).notNull(),
quantity: integer("quantity").notNull(),
price: decimal("price", { precision: 10, scale: 2 }).notNull(),
});
// Cart Items table
export const cartItems = pgTable("cart_items", {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
userId: uuid("user_id").references(() => users.id, { onDelete: "cascade" }).notNull(),
productId: uuid("product_id").references(() => products.id, { onDelete: "cascade" }).notNull(),
quantity: integer("quantity").notNull().default(1),
createdAt: timestamp("created_at").defaultNow(),
});
// Relations
export const usersRelations = relations(users, ({ many }) => ({
orders: many(orders),
cartItems: many(cartItems),
}));
export const sellersRelations = relations(sellers, ({ one, many }) => ({
store: one(stores),
products: many(products),
}));
export const storesRelations = relations(stores, ({ one }) => ({
seller: one(sellers, {
fields: [stores.sellerId],
references: [sellers.id],
}),
}));
export const categoriesRelations = relations(categories, ({ many }) => ({
products: many(products),
}));
export const productsRelations = relations(products, ({ one, many }) => ({
seller: one(sellers, {
fields: [products.sellerId],
references: [sellers.id],
}),
category: one(categories, {
fields: [products.categoryId],
references: [categories.id],
}),
orderItems: many(orderItems),
cartItems: many(cartItems),
}));
export const ordersRelations = relations(orders, ({ one, many }) => ({
user: one(users, {
fields: [orders.userId],
references: [users.id],
}),
orderItems: many(orderItems),
}));
export const orderItemsRelations = relations(orderItems, ({ one }) => ({
order: one(orders, {
fields: [orderItems.orderId],
references: [orders.id],
}),
product: one(products, {
fields: [orderItems.productId],
references: [products.id],
}),
}));
export const cartItemsRelations = relations(cartItems, ({ one }) => ({
user: one(users, {
fields: [cartItems.userId],
references: [users.id],
}),
product: one(products, {
fields: [cartItems.productId],
references: [products.id],
}),
}));
// Insert schemas
export const insertUserSchema = createInsertSchema(users).omit({
id: true,
createdAt: true,
}).extend({
// Make manual address fields optional for automatic location detection
street: z.string().optional(),
city: z.string().optional(),
state: z.string().optional(),
pinCode: z.string().optional(),
country: z.string().optional(),
// Accept both numbers (from geolocation API) and strings (for database)
latitude: z.union([z.number(), z.string()]).optional(),
longitude: z.union([z.number(), z.string()]).optional(),
});
export const insertSellerSchema = createInsertSchema(sellers).omit({
id: true,
createdAt: true,
});
export const insertCategorySchema = createInsertSchema(categories).omit({
id: true,
createdAt: true,
});
export const insertStoreSchema = createInsertSchema(stores).omit({
id: true,
createdAt: true,
});
export const insertProductSchema = createInsertSchema(products).omit({
id: true,
createdAt: true,
});
export const insertOrderSchema = createInsertSchema(orders).omit({
id: true,
createdAt: true,
});
export const insertOrderItemSchema = createInsertSchema(orderItems).omit({
id: true,
});
export const insertCartItemSchema = createInsertSchema(cartItems).omit({
id: true,
createdAt: true,
});
// Types
export type User = typeof users.$inferSelect;
export type InsertUser = z.infer<typeof insertUserSchema>;
export type Seller = typeof sellers.$inferSelect;
export type InsertSeller = z.infer<typeof insertSellerSchema>;
export type Category = typeof categories.$inferSelect;
export type InsertCategory = z.infer<typeof insertCategorySchema>;
export type Store = typeof stores.$inferSelect;
export type InsertStore = z.infer<typeof insertStoreSchema>;
export type Product = typeof products.$inferSelect;
export type InsertProduct = z.infer<typeof insertProductSchema>;
export type Order = typeof orders.$inferSelect;
export type InsertOrder = z.infer<typeof insertOrderSchema>;
export type OrderItem = typeof orderItems.$inferSelect;
export type InsertOrderItem = z.infer<typeof insertOrderItemSchema>;
export type CartItem = typeof cartItems.$inferSelect;
export type InsertCartItem = z.infer<typeof insertCartItemSchema>;