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, insertPredictionBetSchema } from "@shared/schema"; export async function registerRoutes(app: Express): Promise { // Auth middleware await setupAuth(app); // Auth routes app.get('/api/auth/user', isAuthenticated, async (req: any, res) => { try { const user = req.user; res.json(user); } catch (error) { console.error("Error fetching user:", error); res.status(500).json({ message: "Failed to fetch user" }); } }); // Media outlet routes app.get('/api/media-outlets', async (req, res) => { try { const category = req.query.category as string; const outlets = await storage.getMediaOutlets(category); res.json(outlets); } catch (error) { console.error("Error fetching media outlets:", error); res.status(500).json({ message: "Failed to fetch media outlets" }); } }); app.get('/api/media-outlets/:slug', async (req, res) => { try { const outlet = await storage.getMediaOutletBySlug(req.params.slug); if (!outlet) { return res.status(404).json({ message: "Media outlet not found" }); } res.json(outlet); } catch (error) { console.error("Error fetching media outlet:", error); res.status(500).json({ message: "Failed to fetch media outlet" }); } }); // Article routes app.get('/api/media-outlets/:outletId/articles', async (req, res) => { try { const articles = await storage.getArticlesByOutlet(req.params.outletId); res.json(articles); } catch (error) { console.error("Error fetching articles:", error); res.status(500).json({ message: "Failed to fetch articles" }); } }); app.get('/api/media-outlets/:slug/articles', async (req, res) => { try { const outlet = await storage.getMediaOutletBySlug(req.params.slug); if (!outlet) { return res.status(404).json({ message: "Media outlet not found" }); } const articles = await storage.getArticlesByOutlet(outlet.id); res.json(articles); } catch (error) { console.error("Error fetching articles by slug:", error); res.status(500).json({ message: "Failed to fetch articles" }); } }); app.get('/api/articles/:slug', async (req, res) => { try { const article = await storage.getArticleBySlug(req.params.slug); if (!article) { return res.status(404).json({ message: "Article not found" }); } res.json(article); } catch (error) { console.error("Error fetching article:", error); res.status(500).json({ message: "Failed to fetch article" }); } }); app.get('/api/articles/:slug/markets', async (req, res) => { try { const article = await storage.getArticleBySlug(req.params.slug); if (!article) { return res.status(404).json({ message: "Article not found" }); } const markets = await storage.getPredictionMarkets(article.id); res.json(markets); } catch (error) { console.error("Error fetching prediction markets for article:", error); res.status(500).json({ message: "Failed to fetch prediction markets" }); } }); app.get('/api/articles/featured', async (req, res) => { try { const limit = parseInt(req.query.limit as string) || 10; const articles = await storage.getFeaturedArticles(limit); res.json(articles); } catch (error) { console.error("Error fetching featured articles:", error); res.status(500).json({ message: "Failed to fetch featured articles" }); } }); app.post('/api/articles', isAuthenticated, async (req: any, res) => { try { const user = req.user; if (!user || (user.role !== 'admin' && user.role !== 'superadmin')) { return res.status(403).json({ message: "Insufficient permissions" }); } const articleData = insertArticleSchema.parse({ ...req.body, authorId: user.id }); const article = await storage.createArticle(articleData); res.status(201).json(article); } catch (error) { console.error("Error creating article:", error); res.status(500).json({ message: "Failed to create article" }); } }); // Prediction market routes app.get('/api/prediction-markets', async (req, res) => { try { const articleId = req.query.articleId as string; const markets = await storage.getPredictionMarkets(articleId); res.json(markets); } catch (error) { console.error("Error fetching prediction markets:", error); res.status(500).json({ message: "Failed to fetch prediction markets" }); } }); // Auction routes app.get('/api/auctions', async (req, res) => { try { const auctions = await storage.getActiveAuctions(); res.json(auctions); } catch (error) { console.error("Error fetching auctions:", error); res.status(500).json({ message: "Failed to fetch auctions" }); } }); app.get('/api/media-outlets/:slug/auction', async (req, res) => { try { const outlet = await storage.getMediaOutletBySlug(req.params.slug); if (!outlet) { return res.status(404).json({ message: "Media outlet not found" }); } const auction = await storage.getAuctionByMediaOutlet(outlet.id); if (!auction) { return res.status(404).json({ message: "No active auction found for this media outlet" }); } res.json(auction); } catch (error) { console.error("Error fetching auction:", error); res.status(500).json({ message: "Failed to fetch auction" }); } }); app.get('/api/auctions/:id/bids', async (req, res) => { try { const bids = await storage.getBidsByAuctionId(req.params.id); res.json(bids); } catch (error) { console.error("Error fetching bids:", error); res.status(500).json({ message: "Failed to fetch bids" }); } }); app.post('/api/auctions/:id/bid', isAuthenticated, async (req: any, res) => { try { const userId = req.user.claims?.sub || req.user.id; const bidData = insertBidSchema.parse({ ...req.body, auctionId: req.params.id, bidderId: userId }); const bid = await storage.placeBid(bidData); res.status(201).json(bid); } catch (error) { console.error("Error placing bid:", error); res.status(500).json({ message: "Failed to place bid" }); } }); app.post('/api/media-outlets/:slug/auction/bids', isAuthenticated, async (req: any, res) => { try { const outlet = await storage.getMediaOutletBySlug(req.params.slug); if (!outlet) { return res.status(404).json({ message: "Media outlet not found" }); } const auction = await storage.getAuctionByMediaOutlet(outlet.id); if (!auction) { return res.status(404).json({ message: "No active auction found for this media outlet" }); } const userId = req.user.claims?.sub || req.user.id; const bidData = insertBidSchema.parse({ ...req.body, auctionId: auction.id, bidderId: userId }); const bid = await storage.placeBid(bidData); res.status(201).json(bid); } catch (error) { console.error("Error placing bid:", error); res.status(500).json({ message: "Failed to place bid" }); } }); // Prediction market betting endpoints app.post('/api/prediction-markets/:marketId/bets', isAuthenticated, async (req: any, res) => { try { const userId = req.user.claims?.sub || req.user.id; 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 { const userId = req.user.claims?.sub || req.user.id; const user = await storage.getUser(userId); if (!user || user.role !== 'superadmin') { return res.status(403).json({ message: "Insufficient permissions" }); } const status = req.query.status as string; const requests = await storage.getMediaOutletRequests(status); res.json(requests); } catch (error) { console.error("Error fetching requests:", error); res.status(500).json({ message: "Failed to fetch requests" }); } }); app.post('/api/media-outlet-requests', isAuthenticated, async (req: any, res) => { try { const userId = req.user.claims?.sub || req.user.id; const requestData = insertMediaOutletRequestSchema.parse({ ...req.body, requesterId: userId }); const request = await storage.createMediaOutletRequest(requestData); res.status(201).json(request); } catch (error) { console.error("Error creating request:", error); res.status(500).json({ message: "Failed to create request" }); } }); app.patch('/api/media-outlet-requests/:id', isAuthenticated, async (req: any, res) => { try { const userId = req.user.claims?.sub || req.user.id; const user = await storage.getUser(userId); if (!user || user.role !== 'superadmin') { return res.status(403).json({ message: "Insufficient permissions" }); } const { status } = req.body; const request = await storage.updateMediaOutletRequestStatus(req.params.id, status, userId); res.json(request); } catch (error) { console.error("Error updating request:", error); res.status(500).json({ message: "Failed to update request" }); } }); // Comment routes app.get('/api/articles/:articleId/comments', async (req, res) => { try { const comments = await storage.getCommentsByArticle(req.params.articleId); res.json(comments); } catch (error) { console.error("Error fetching comments:", error); res.status(500).json({ message: "Failed to fetch comments" }); } }); app.post('/api/articles/:articleId/comments', isAuthenticated, async (req: any, res) => { try { const userId = req.user.claims?.sub || req.user.id; const commentData = insertCommentSchema.parse({ ...req.body, articleId: req.params.articleId, authorId: userId }); const comment = await storage.createComment(commentData); res.status(201).json(comment); } catch (error) { console.error("Error creating comment:", error); res.status(500).json({ message: "Failed to create comment" }); } }); // Analytics routes app.get('/api/analytics', isAuthenticated, async (req: any, res) => { try { const userId = req.user.claims?.sub || req.user.id; const user = await storage.getUser(userId); if (!user || (user.role !== 'admin' && user.role !== 'superadmin')) { return res.status(403).json({ message: "Insufficient permissions" }); } const analytics = await storage.getAnalytics(); res.json(analytics); } catch (error) { console.error("Error fetching analytics:", error); res.status(500).json({ message: "Failed to fetch analytics" }); } }); // Search routes app.get('/api/search', async (req, res) => { try { const { q } = req.query; if (!q || typeof q !== 'string' || q.trim().length === 0) { return res.json({ outlets: [], articles: [] }); } const results = await storage.search(q.trim()); res.json(results); } catch (error) { console.error("Error performing search:", error); res.status(500).json({ message: "Failed to perform search" }); } }); const httpServer = createServer(app); return httpServer; }