import { pgTable, uuid, varchar, timestamp, pgEnum, numeric, uniqueIndex, date } from "drizzle-orm/pg-core"; export const users = pgTable("users", { id: uuid("id").primaryKey().$defaultFn(() => crypto.randomUUID()), username: varchar("username", { length: 50 }).notNull().unique(), passwordHash: varchar("password_hash", { length: 255 }).notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: "date" }) .defaultNow() .notNull(), }); export const assetTypeEnum = pgEnum("asset_type_enum", [ "STOCK", "CRYPTO", "CASH", ]); export const assets = pgTable("assets", { id: uuid("id").primaryKey().$defaultFn(() => crypto.randomUUID()), symbol: varchar("symbol", { length: 20 }).notNull().unique(), name: varchar("name", { length: 100 }), type: assetTypeEnum("type").notNull(), exchange: varchar("exchange", { length: 10 }).default('US'), baseCurrency: varchar("base_currency", { length: 10 }).notNull(), latestPrice: numeric("latest_price", { precision: 36, scale: 18 }).default('0').notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: "date" }) .defaultNow(), }); export const transactionTypeEnum = pgEnum("transaction_type_enum", [ "BUY", "SELL", "DIVIDEND", "AIRDROP", "FEE", ]); export const transactions = pgTable("transactions", { id: uuid("id").primaryKey().$defaultFn(() => crypto.randomUUID()), assetId: uuid("asset_id") .notNull() .references(() => assets.id), txType: transactionTypeEnum("tx_type").notNull(), quantity: numeric("quantity", { precision: 36, scale: 18 }).notNull(), price: numeric("price", { precision: 36, scale: 18 }).notNull(), fee: numeric("fee", { precision: 36, scale: 18 }) .notNull() .default("0"), txCurrency: varchar("tx_currency", { length: 10 }).notNull(), exchangeRate: numeric("exchange_rate", { precision: 20, scale: 8 }) .notNull() .default("1"), executedAt: timestamp("executed_at", { withTimezone: true }).notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: "date" }) .defaultNow(), }); export const exchangeRates = pgTable("exchange_rates", { id: uuid("id").primaryKey().$defaultFn(() => crypto.randomUUID()), fromCurrency: varchar("from_currency", { length: 10 }).notNull(), toCurrency: varchar("to_currency", { length: 10 }).notNull(), rate: numeric("rate", { precision: 20, scale: 8 }).notNull(), updatedAt: timestamp("updated_at", { withTimezone: true, mode: "date" }) .defaultNow(), }, (table) => [ uniqueIndex("currency_pair_idx").on(table.fromCurrency, table.toCurrency), ]); export const portfolioSnapshots = pgTable("portfolio_snapshots", { id: uuid("id").primaryKey().$defaultFn(() => crypto.randomUUID()), date: date("date", { mode: "string" }).notNull().unique(), totalValueCny: numeric("total_value_cny", { precision: 36, scale: 18 }).notNull(), totalCostCny: numeric("total_cost_cny", { precision: 36, scale: 18 }).notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: "date" }) .defaultNow() .notNull(), updatedAt: timestamp("updated_at", { withTimezone: true, mode: "date" }) .defaultNow() .notNull(), }); export const assetPricesHistory = pgTable("asset_prices_history", { id: uuid("id").primaryKey().$defaultFn(() => crypto.randomUUID()), assetId: uuid("asset_id") .notNull() .references(() => assets.id), price: numeric("price", { precision: 36, scale: 18 }).notNull(), date: date("date", { mode: "string" }).notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: "date" }) .defaultNow() .notNull(), }, (table) => [ uniqueIndex("asset_price_date_idx").on(table.assetId, table.date), ]); export const exchangeRatesHistory = pgTable("exchange_rates_history", { id: uuid("id").primaryKey().$defaultFn(() => crypto.randomUUID()), fromCurrency: varchar("from_currency", { length: 10 }).notNull(), toCurrency: varchar("to_currency", { length: 10 }).notNull(), rate: numeric("rate", { precision: 20, scale: 8 }).notNull(), fetchTime: timestamp("fetch_time", { withTimezone: true, mode: "date" }) .notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: "date" }) .defaultNow() .notNull(), });