import { sql } from 'drizzle-orm'; import { index, jsonb, pgTable, timestamp, varchar, text, integer, boolean, decimal, } from "drizzle-orm/pg-core"; import { createInsertSchema } from "drizzle-zod"; import { z } from "zod"; // Session storage table. // (IMPORTANT) This table is mandatory for Replit Auth, don't drop it. export const sessions = pgTable( "sessions", { sid: varchar("sid").primaryKey(), sess: jsonb("sess").notNull(), expire: timestamp("expire").notNull(), }, (table) => [index("IDX_session_expire").on(table.expire)], ); // User storage table. // (IMPORTANT) This table is mandatory for Replit Auth, don't drop it. export const users = pgTable("users", { id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), email: varchar("email").unique(), firstName: varchar("first_name"), lastName: varchar("last_name"), profileImageUrl: varchar("profile_image_url"), role: varchar("role").default("user"), // user, admin, superadmin createdAt: timestamp("created_at").defaultNow(), updatedAt: timestamp("updated_at").defaultNow(), }); // Media outlets (People, Topics, Companies) export const mediaOutlets = pgTable("media_outlets", { id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), name: varchar("name").notNull(), slug: varchar("slug").notNull().unique(), category: varchar("category").notNull(), // people, topics, companies description: text("description"), imageUrl: varchar("image_url"), tags: text("tags").array(), trafficScore: integer("traffic_score").default(0), // For sorting by traffic isActive: boolean("is_active").default(true), createdAt: timestamp("created_at").defaultNow(), updatedAt: timestamp("updated_at").defaultNow(), }); // Articles within media outlets export const articles = pgTable("articles", { id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), mediaOutletId: varchar("media_outlet_id").notNull(), title: varchar("title").notNull(), slug: varchar("slug").notNull(), excerpt: text("excerpt"), content: text("content").notNull(), imageUrl: varchar("image_url"), authorId: varchar("author_id"), tags: text("tags").array(), isPinned: boolean("is_pinned").default(false), isFeatured: boolean("is_featured").default(false), publishedAt: timestamp("published_at").defaultNow(), createdAt: timestamp("created_at").defaultNow(), updatedAt: timestamp("updated_at").defaultNow(), }); // Prediction markets export const predictionMarkets = pgTable("prediction_markets", { id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), question: varchar("question"), title: varchar("title").notNull(), description: text("description"), articleId: varchar("article_id"), yesPrice: decimal("yes_price", { precision: 5, scale: 4 }).default("0.5"), noPrice: decimal("no_price", { precision: 5, scale: 4 }).default("0.5"), totalVolume: decimal("total_volume", { precision: 12, scale: 2 }).default("0"), totalBets: integer("total_bets").default(0), resolutionDate: timestamp("resolution_date"), volume: decimal("volume", { precision: 12, scale: 2 }), endDate: timestamp("end_date"), isActive: boolean("is_active").default(true), createdAt: timestamp("created_at").defaultNow(), updatedAt: timestamp("updated_at").defaultNow(), }); // Auctions for media outlet management rights export const auctions = pgTable("auctions", { id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), mediaOutletId: varchar("media_outlet_id").notNull(), title: varchar("title").notNull(), description: text("description"), currentBid: decimal("current_bid", { precision: 10, scale: 2 }), qualityScore: integer("quality_score"), highestBidderId: varchar("highest_bidder_id"), endDate: timestamp("end_date").notNull(), duration: integer("duration"), // days isActive: boolean("is_active").default(true), createdAt: timestamp("created_at").defaultNow(), updatedAt: timestamp("updated_at").defaultNow(), }); // Bids for auctions export const bids = pgTable("bids", { id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), auctionId: varchar("auction_id").notNull(), bidderId: varchar("bidder_id").notNull(), amount: decimal("amount", { precision: 10, scale: 2 }).notNull(), qualityScore: integer("quality_score"), createdAt: timestamp("created_at").defaultNow(), }); // Media outlet creation requests export const mediaOutletRequests = pgTable("media_outlet_requests", { id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), name: varchar("name").notNull(), category: varchar("category").notNull(), description: text("description"), requesterId: varchar("requester_id").notNull(), status: varchar("status").default("pending"), // pending, approved, rejected reviewedBy: varchar("reviewed_by"), reviewedAt: timestamp("reviewed_at"), createdAt: timestamp("created_at").defaultNow(), }); // Comments on articles export const comments = pgTable("comments", { id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), articleId: varchar("article_id").notNull(), authorId: varchar("author_id").notNull(), content: text("content").notNull(), isPinned: boolean("is_pinned").default(false), createdAt: timestamp("created_at").defaultNow(), updatedAt: timestamp("updated_at").defaultNow(), }); // Prediction market bets export const predictionBets = pgTable("prediction_bets", { id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), marketId: varchar("market_id").notNull(), userId: varchar("user_id").notNull(), side: varchar("side", { enum: ["yes", "no"] }).notNull(), amount: decimal("amount", { precision: 12, scale: 2 }).notNull(), price: decimal("price", { precision: 5, scale: 4 }).notNull(), // Price at time of bet createdAt: timestamp("created_at").defaultNow(), }); // Insert schemas export const insertUserSchema = createInsertSchema(users).omit({ id: true, createdAt: true, updatedAt: true, }); export const insertMediaOutletSchema = createInsertSchema(mediaOutlets).omit({ id: true, createdAt: true, updatedAt: true, }); export const insertArticleSchema = createInsertSchema(articles).omit({ id: true, createdAt: true, updatedAt: true, }); export const insertPredictionMarketSchema = createInsertSchema(predictionMarkets).omit({ id: true, createdAt: true, updatedAt: true, }); export const insertAuctionSchema = createInsertSchema(auctions).omit({ id: true, createdAt: true, updatedAt: true, }); export const insertBidSchema = createInsertSchema(bids).omit({ id: true, createdAt: true, }); export const insertMediaOutletRequestSchema = createInsertSchema(mediaOutletRequests).omit({ id: true, createdAt: true, }); export const insertCommentSchema = createInsertSchema(comments).omit({ id: true, createdAt: true, updatedAt: true, }); export const insertPredictionBetSchema = createInsertSchema(predictionBets).omit({ id: true, createdAt: true, }); // Types export type UpsertUser = typeof users.$inferInsert; export type User = typeof users.$inferSelect; export type InsertMediaOutlet = z.infer; export type MediaOutlet = typeof mediaOutlets.$inferSelect; export type InsertArticle = z.infer; export type Article = typeof articles.$inferSelect; export type InsertPredictionMarket = z.infer; export type PredictionMarket = typeof predictionMarkets.$inferSelect; export type InsertAuction = z.infer; export type Auction = typeof auctions.$inferSelect; export type InsertBid = z.infer; export type Bid = typeof bids.$inferSelect; export type InsertMediaOutletRequest = z.infer; export type MediaOutletRequest = typeof mediaOutletRequests.$inferSelect; export type InsertComment = z.infer; export type Comment = typeof comments.$inferSelect; export type InsertPredictionBet = z.infer; export type PredictionBet = typeof predictionBets.$inferSelect;