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:
@ -2,7 +2,7 @@ import type { Express } from "express";
|
||||
import { createServer, type Server } from "http";
|
||||
import { storage } from "./storage";
|
||||
import { setupAuth, isAuthenticated } from "./simpleAuth";
|
||||
import { insertArticleSchema, insertMediaOutletRequestSchema, insertBidSchema, insertCommentSchema } from "@shared/schema";
|
||||
import { insertArticleSchema, insertMediaOutletRequestSchema, insertBidSchema, insertCommentSchema, insertPredictionBetSchema } from "@shared/schema";
|
||||
|
||||
export async function registerRoutes(app: Express): Promise<Server> {
|
||||
// Auth middleware
|
||||
@ -170,7 +170,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
|
||||
app.post('/api/auctions/:id/bid', isAuthenticated, async (req: any, res) => {
|
||||
try {
|
||||
const userId = req.user.id;
|
||||
const userId = req.user.claims.sub;
|
||||
const bidData = insertBidSchema.parse({
|
||||
...req.body,
|
||||
auctionId: req.params.id,
|
||||
@ -197,7 +197,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
return res.status(404).json({ message: "No active auction found for this media outlet" });
|
||||
}
|
||||
|
||||
const userId = req.user.id;
|
||||
const userId = req.user.claims.sub;
|
||||
const bidData = insertBidSchema.parse({
|
||||
...req.body,
|
||||
auctionId: auction.id,
|
||||
@ -212,6 +212,39 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
}
|
||||
});
|
||||
|
||||
// Prediction market betting endpoints
|
||||
app.post('/api/prediction-markets/:marketId/bets', isAuthenticated, async (req: any, res) => {
|
||||
try {
|
||||
const userId = req.user.claims.sub;
|
||||
const { side, amount } = req.body;
|
||||
|
||||
// Validate request
|
||||
if (!side || !amount || !["yes", "no"].includes(side)) {
|
||||
return res.status(400).json({ message: "Invalid bet data" });
|
||||
}
|
||||
|
||||
if (parseFloat(amount) <= 0) {
|
||||
return res.status(400).json({ message: "Bet amount must be positive" });
|
||||
}
|
||||
|
||||
const betData = insertPredictionBetSchema.parse({
|
||||
marketId: req.params.marketId,
|
||||
userId,
|
||||
side,
|
||||
amount: amount.toString()
|
||||
});
|
||||
|
||||
const bet = await storage.createPredictionBet(betData);
|
||||
res.status(201).json(bet);
|
||||
} catch (error) {
|
||||
console.error("Error placing prediction bet:", error);
|
||||
if (error.message === "Prediction market not found") {
|
||||
return res.status(404).json({ message: "Prediction market not found" });
|
||||
}
|
||||
res.status(500).json({ message: "Failed to place bet" });
|
||||
}
|
||||
});
|
||||
|
||||
// Media outlet request routes
|
||||
app.get('/api/media-outlet-requests', isAuthenticated, async (req: any, res) => {
|
||||
try {
|
||||
|
||||
@ -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<{
|
||||
|
||||
Reference in New Issue
Block a user