Add betting functionality to prediction markets for users

Integrates prediction market betting with new API endpoints, database schema, and client-side UI elements.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 069d4324-6c40-4355-955e-c714a50de1ea
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3df548ff-50ae-432f-9be4-25d34eccc983/069d4324-6c40-4355-955e-c714a50de1ea/6XTzcDL
This commit is contained in:
kimjaehyeon0101
2025-09-29 19:14:42 +00:00
parent df46319424
commit d6682e32d9
5 changed files with 410 additions and 97 deletions

View File

@ -7,6 +7,7 @@ import {
bids,
mediaOutletRequests,
comments,
predictionBets,
type User,
type UpsertUser,
type MediaOutlet,
@ -23,6 +24,8 @@ import {
type InsertMediaOutletRequest,
type Comment,
type InsertComment,
type PredictionBet,
type InsertPredictionBet,
} from "@shared/schema";
import { db } from "./db";
import { eq, desc, and, ilike, sql } from "drizzle-orm";
@ -61,6 +64,11 @@ export interface IStorage {
getMediaOutletRequests(status?: string): Promise<MediaOutletRequest[]>;
createMediaOutletRequest(request: InsertMediaOutletRequest): Promise<MediaOutletRequest>;
updateMediaOutletRequestStatus(id: string, status: string, reviewerId: string): Promise<MediaOutletRequest>;
// Prediction bet operations
createPredictionBet(bet: InsertPredictionBet): Promise<PredictionBet>;
getPredictionBetsByMarket(marketId: string): Promise<PredictionBet[]>;
getPredictionBetsByUser(userId: string): Promise<PredictionBet[]>;
// Comment operations
getCommentsByArticle(articleId: string): Promise<Comment[]>;
@ -286,6 +294,51 @@ export class DatabaseStorage implements IStorage {
const [newComment] = await db.insert(comments).values(comment).returning();
return newComment;
}
// Prediction bet operations
async createPredictionBet(bet: InsertPredictionBet): Promise<PredictionBet> {
// Get the current market to determine the price
const market = await this.getPredictionMarketById(bet.marketId);
if (!market) {
throw new Error("Prediction market not found");
}
// Use current market price for the bet
const price = bet.side === "yes" ? market.yesPrice : market.noPrice;
const [newBet] = await db.insert(predictionBets).values({
...bet,
price: price.toString()
}).returning();
// Update market volume and bet count
await db
.update(predictionMarkets)
.set({
totalVolume: sql`total_volume + ${bet.amount}`,
totalBets: sql`total_bets + 1`,
updatedAt: new Date()
})
.where(eq(predictionMarkets.id, bet.marketId));
return newBet;
}
async getPredictionBetsByMarket(marketId: string): Promise<PredictionBet[]> {
return await db
.select()
.from(predictionBets)
.where(eq(predictionBets.marketId, marketId))
.orderBy(desc(predictionBets.createdAt));
}
async getPredictionBetsByUser(userId: string): Promise<PredictionBet[]> {
return await db
.select()
.from(predictionBets)
.where(eq(predictionBets.userId, userId))
.orderBy(desc(predictionBets.createdAt));
}
// Analytics operations
async getAnalytics(): Promise<{