Update article page to handle image uploads and display articles from text files. Refactor currency and date formatting, and add a method to fetch prediction markets by ID. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 0fb68265-c270-4198-9584-3d9be9bddb41 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3df548ff-50ae-432f-9be4-25d34eccc983/0fb68265-c270-4198-9584-3d9be9bddb41/rOJiPGe
225 lines
8.0 KiB
TypeScript
225 lines
8.0 KiB
TypeScript
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<typeof insertMediaOutletSchema>;
|
|
export type MediaOutlet = typeof mediaOutlets.$inferSelect;
|
|
export type InsertArticle = z.infer<typeof insertArticleSchema>;
|
|
export type Article = typeof articles.$inferSelect;
|
|
export type InsertPredictionMarket = z.infer<typeof insertPredictionMarketSchema>;
|
|
export type PredictionMarket = typeof predictionMarkets.$inferSelect;
|
|
export type InsertAuction = z.infer<typeof insertAuctionSchema>;
|
|
export type Auction = typeof auctions.$inferSelect;
|
|
export type InsertBid = z.infer<typeof insertBidSchema>;
|
|
export type Bid = typeof bids.$inferSelect;
|
|
export type InsertMediaOutletRequest = z.infer<typeof insertMediaOutletRequestSchema>;
|
|
export type MediaOutletRequest = typeof mediaOutletRequests.$inferSelect;
|
|
export type InsertComment = z.infer<typeof insertCommentSchema>;
|
|
export type Comment = typeof comments.$inferSelect;
|
|
export type InsertPredictionBet = z.infer<typeof insertPredictionBetSchema>;
|
|
export type PredictionBet = typeof predictionBets.$inferSelect;
|