schema update with coin, portfolio, transaction and price history

This commit is contained in:
Face 2025-05-22 14:26:12 +03:00
parent 2485ae8816
commit 6b6a1d170e
7 changed files with 634 additions and 459 deletions

View file

@ -1,50 +1,105 @@
import { pgTable, text, timestamp, boolean } from "drizzle-orm/pg-core";
import { pgTable, text, timestamp, boolean, decimal, serial, varchar, integer, primaryKey, pgEnum } from "drizzle-orm/pg-core";
export const transactionTypeEnum = pgEnum('transaction_type', ['BUY', 'SELL']);
export const user = pgTable("user", {
id: text("id").primaryKey(),
name: text('name').notNull(),
email: text('email').notNull().unique(),
emailVerified: boolean('email_verified').notNull(),
image: text('image'),
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull(),
isAdmin: boolean('is_admin'),
isBanned: boolean('is_banned'),
banReason: text('ban_reason')
id: serial("id").primaryKey(),
name: text("name").notNull(),
email: text("email").notNull().unique(),
emailVerified: boolean("email_verified").notNull().default(false),
image: text("image"),
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
isAdmin: boolean("is_admin").default(false),
isBanned: boolean("is_banned").default(false),
banReason: text("ban_reason"),
baseCurrencyBalance: decimal("base_currency_balance", {
precision: 19,
scale: 4,
}).notNull().default("10000.0000"), // 10,000 *BUSS
});
export const session = pgTable("session", {
id: text("id").primaryKey(),
expiresAt: timestamp('expires_at').notNull(),
token: text('token').notNull().unique(),
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull(),
ipAddress: text('ip_address'),
userAgent: text('user_agent'),
userId: text('user_id').notNull().references(() => user.id)
expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
token: text("token").notNull().unique(),
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
ipAddress: text("ip_address"),
userAgent: text("user_agent"),
userId: serial("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
});
export const account = pgTable("account", {
id: text("id").primaryKey(),
accountId: text('account_id').notNull(),
providerId: text('provider_id').notNull(),
userId: text('user_id').notNull().references(() => user.id),
accessToken: text('access_token'),
refreshToken: text('refresh_token'),
idToken: text('id_token'),
accessTokenExpiresAt: timestamp('access_token_expires_at'),
refreshTokenExpiresAt: timestamp('refresh_token_expires_at'),
scope: text('scope'),
password: text('password'),
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull()
accountId: text("account_id").notNull(),
providerId: text("provider_id").notNull(),
userId: serial("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
accessToken: text("access_token"),
refreshToken: text("refresh_token"),
idToken: text("id_token"),
accessTokenExpiresAt: timestamp("access_token_expires_at", { withTimezone: true, }),
refreshTokenExpiresAt: timestamp("refresh_token_expires_at", { withTimezone: true, }),
scope: text("scope"),
password: text("password"),
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
});
export const verification = pgTable("verification", {
id: text("id").primaryKey(),
identifier: text('identifier').notNull(),
value: text('value').notNull(),
expiresAt: timestamp('expires_at').notNull(),
createdAt: timestamp('created_at'),
updatedAt: timestamp('updated_at')
identifier: text("identifier").notNull(),
value: text("value").notNull(),
expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow(),
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow(),
});
export const coin = pgTable("coin", {
id: serial("id").primaryKey(),
name: varchar("name", { length: 255 }).notNull(),
symbol: varchar("symbol", { length: 10 }).notNull().unique(),
creatorId: serial("creator_id").references(() => user.id, { onDelete: "set null", }), // Coin can exist even if creator is deleted
initialSupply: decimal("initial_supply", { precision: 28, scale: 8 }).notNull(),
circulatingSupply: decimal("circulating_supply", { precision: 28, scale: 8 }).notNull(),
currentPrice: decimal("current_price", { precision: 19, scale: 8 }).notNull(), // Price in base currency
marketCap: decimal("market_cap", { precision: 28, scale: 4 }).notNull(),
volume24h: decimal("volume_24h", { precision: 28, scale: 4 }).default("0.0000"),
change24h: decimal("change_24h", { precision: 8, scale: 4 }).default("0.0000"), // Percentage
poolCoinAmount: decimal("pool_coin_amount", { precision: 28, scale: 8 }).notNull().default("0.00000000"),
poolBaseCurrencyAmount: decimal("pool_base_currency_amount", { precision: 28, scale: 4, }).notNull().default("0.0000"),
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
isListed: boolean("is_listed").default(true).notNull(),
});
export const userPortfolio = pgTable("user_portfolio", {
userId: serial("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
coinId: integer("coin_id").notNull().references(() => coin.id, { onDelete: "cascade" }),
quantity: decimal("quantity", { precision: 28, scale: 8 }).notNull(),
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
},
(table) => {
return {
pk: primaryKey({ columns: [table.userId, table.coinId] }),
};
},
);
export const transaction = pgTable("transaction", {
id: serial("id").primaryKey(),
userId: serial("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
coinId: integer("coin_id").notNull().references(() => coin.id, { onDelete: "cascade" }),
type: transactionTypeEnum("type").notNull(),
quantity: decimal("quantity", { precision: 28, scale: 8 }).notNull(),
pricePerCoin: decimal("price_per_coin", { precision: 19, scale: 8 }).notNull(),
totalBaseCurrencyAmount: decimal("total_base_currency_amount", { precision: 28, scale: 4 }).notNull(),
timestamp: timestamp("timestamp", { withTimezone: true }).notNull().defaultNow(),
});
export const priceHistory = pgTable("price_history", {
id: serial("id").primaryKey(),
coinId: integer("coin_id").notNull().references(() => coin.id, { onDelete: "cascade" }),
price: decimal("price", { precision: 19, scale: 8 }).notNull(),
timestamp: timestamp("timestamp", { withTimezone: true }).notNull().defaultNow(),
});