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

@ -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 {