import { bigint, boolean, decimal, int, mysqlEnum, mysqlTable, text, timestamp, varchar, } from "drizzle-orm/mysql-core"; /** * Core user table backing auth flow. * Extend this file with additional tables as your product grows. * Columns use camelCase to match both database fields and generated types. */ export const users = mysqlTable("users", { /** * Surrogate primary key. Auto-incremented numeric value managed by the database. * Use this for relations between tables. */ id: int("id").autoincrement().primaryKey(), /** Manus OAuth identifier (openId) returned from the OAuth callback. Unique per user. */ openId: varchar("openId", { length: 64 }).notNull().unique(), name: text("name"), email: varchar("email", { length: 320 }), loginMethod: varchar("loginMethod", { length: 64 }), role: mysqlEnum("role", ["user", "admin"]).default("user").notNull(), createdAt: timestamp("createdAt").defaultNow().notNull(), updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(), lastSignedIn: timestamp("lastSignedIn").defaultNow().notNull(), }); export type User = typeof users.$inferSelect; export type InsertUser = typeof users.$inferInsert; // TRC20 purchase records — monitored from TRON network export const trc20Purchases = mysqlTable("trc20_purchases", { id: int("id").autoincrement().primaryKey(), txHash: varchar("txHash", { length: 128 }).notNull().unique(), fromAddress: varchar("fromAddress", { length: 64 }).notNull(), usdtAmount: decimal("usdtAmount", { precision: 20, scale: 6 }).notNull(), xicAmount: decimal("xicAmount", { precision: 30, scale: 6 }).notNull(), blockNumber: bigint("blockNumber", { mode: "number" }), status: mysqlEnum("status", ["pending", "confirmed", "distributed", "failed"]) .default("pending") .notNull(), distributedAt: timestamp("distributedAt"), distributeTxHash: varchar("distributeTxHash", { length: 128 }), evmAddress: varchar("evmAddress", { length: 64 }), // EVM address provided by buyer for token distribution createdAt: timestamp("createdAt").defaultNow().notNull(), updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(), }); export type Trc20Purchase = typeof trc20Purchases.$inferSelect; export type InsertTrc20Purchase = typeof trc20Purchases.$inferInsert; // Presale stats cache — refreshed from on-chain every 60 seconds export const presaleStatsCache = mysqlTable("presale_stats_cache", { id: int("id").autoincrement().primaryKey(), chain: varchar("chain", { length: 16 }).notNull(), usdtRaised: decimal("usdtRaised", { precision: 30, scale: 6 }).default("0"), tokensSold: decimal("tokensSold", { precision: 30, scale: 6 }).default("0"), weiRaised: decimal("weiRaised", { precision: 30, scale: 6 }).default("0"), lastUpdated: timestamp("lastUpdated").defaultNow().notNull(), }); export type PresaleStatsCache = typeof presaleStatsCache.$inferSelect;