nac-presale/drizzle/schema.ts

68 lines
2.8 KiB
TypeScript

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 }),
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;