Modify article API response to include nested media outlet data and update client-side data fetching in Article.tsx to directly access outlet information from the article data, simplifying the component's data loading logic. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 9a264234-c5d7-4dcc-adf3-a954b149b30d Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3df548ff-50ae-432f-9be4-25d34eccc983/9a264234-c5d7-4dcc-adf3-a954b149b30d/uCJPlBt
662 lines
22 KiB
TypeScript
662 lines
22 KiB
TypeScript
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, insertCommunityPostSchema, insertCommunityReplySchema, insertChatMessageSchema } from "@shared/schema";
|
|
import { generateChatbotResponse } from "./chatbot";
|
|
|
|
export async function registerRoutes(app: Express): Promise<Server> {
|
|
// 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" });
|
|
}
|
|
});
|
|
|
|
app.patch('/api/media-outlets/:slug', 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 { description } = req.body;
|
|
const outlet = await storage.getMediaOutletBySlug(req.params.slug);
|
|
|
|
if (!outlet) {
|
|
return res.status(404).json({ message: "Media outlet not found" });
|
|
}
|
|
|
|
await storage.updateMediaOutlet(outlet.id, { description });
|
|
const updated = await storage.getMediaOutletBySlug(req.params.slug);
|
|
res.json(updated);
|
|
} catch (error) {
|
|
console.error("Error updating media outlet:", error);
|
|
res.status(500).json({ message: "Failed to update media outlet" });
|
|
}
|
|
});
|
|
|
|
// Article routes
|
|
app.get('/api/articles', async (req, res) => {
|
|
try {
|
|
const articles = await storage.getArticles();
|
|
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" });
|
|
}
|
|
const allOutlets = await storage.getMediaOutlets();
|
|
const outlet = allOutlets.find(o => o.id === article.mediaOutletId);
|
|
res.json({ ...article, outlet });
|
|
} 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" });
|
|
}
|
|
});
|
|
|
|
app.patch('/api/articles/:id', 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 article = await storage.getArticleById(req.params.id);
|
|
if (!article) {
|
|
return res.status(404).json({ message: "Article not found" });
|
|
}
|
|
|
|
const articleData = insertArticleSchema.partial().parse(req.body);
|
|
const updated = await storage.updateArticle(req.params.id, articleData);
|
|
res.json(updated);
|
|
} catch (error) {
|
|
console.error("Error updating article:", error);
|
|
res.status(500).json({ message: "Failed to update article" });
|
|
}
|
|
});
|
|
|
|
app.delete('/api/articles/:id', 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 article = await storage.getArticleById(req.params.id);
|
|
if (!article) {
|
|
return res.status(404).json({ message: "Article not found" });
|
|
}
|
|
|
|
await storage.deleteArticle(req.params.id);
|
|
res.status(204).send();
|
|
} catch (error) {
|
|
console.error("Error deleting article:", error);
|
|
res.status(500).json({ message: "Failed to delete 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);
|
|
res.json(auction || null);
|
|
} 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 instanceof Error && 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" });
|
|
}
|
|
});
|
|
|
|
// Community routes
|
|
app.get('/api/media-outlets/:slug/community', 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 sort = req.query.sort as string || 'latest';
|
|
const posts = await storage.getCommunityPostsByOutlet(outlet.id, sort);
|
|
res.json(posts);
|
|
} catch (error) {
|
|
console.error("Error fetching community posts:", error);
|
|
res.status(500).json({ message: "Failed to fetch community posts" });
|
|
}
|
|
});
|
|
|
|
app.get('/api/community/posts/:id', async (req, res) => {
|
|
try {
|
|
const post = await storage.getCommunityPostById(req.params.id);
|
|
if (!post) {
|
|
return res.status(404).json({ message: "Post not found" });
|
|
}
|
|
|
|
// Increment view count
|
|
await storage.incrementPostViews(req.params.id);
|
|
|
|
res.json(post);
|
|
} catch (error) {
|
|
console.error("Error fetching community post:", error);
|
|
res.status(500).json({ message: "Failed to fetch community post" });
|
|
}
|
|
});
|
|
|
|
app.post('/api/media-outlets/:slug/community', 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 userId = req.user.claims?.sub || req.user.id;
|
|
const postData = insertCommunityPostSchema.parse({
|
|
...req.body,
|
|
mediaOutletId: outlet.id,
|
|
authorId: userId
|
|
});
|
|
|
|
const post = await storage.createCommunityPost(postData);
|
|
res.status(201).json(post);
|
|
} catch (error) {
|
|
console.error("Error creating community post:", error);
|
|
res.status(500).json({ message: "Failed to create community post" });
|
|
}
|
|
});
|
|
|
|
app.patch('/api/community/posts/:id', isAuthenticated, async (req: any, res) => {
|
|
try {
|
|
const userId = req.user.claims?.sub || req.user.id;
|
|
const post = await storage.getCommunityPostById(req.params.id);
|
|
|
|
if (!post) {
|
|
return res.status(404).json({ message: "Post not found" });
|
|
}
|
|
|
|
if (post.authorId !== userId) {
|
|
return res.status(403).json({ message: "Not authorized to edit this post" });
|
|
}
|
|
|
|
const updated = await storage.updateCommunityPost(req.params.id, req.body);
|
|
res.json(updated);
|
|
} catch (error) {
|
|
console.error("Error updating community post:", error);
|
|
res.status(500).json({ message: "Failed to update community post" });
|
|
}
|
|
});
|
|
|
|
app.delete('/api/community/posts/:id', isAuthenticated, async (req: any, res) => {
|
|
try {
|
|
const userId = req.user.claims?.sub || req.user.id;
|
|
const user = await storage.getUser(userId);
|
|
const post = await storage.getCommunityPostById(req.params.id);
|
|
|
|
if (!post) {
|
|
return res.status(404).json({ message: "Post not found" });
|
|
}
|
|
|
|
if (post.authorId !== userId && user?.role !== 'admin' && user?.role !== 'superadmin') {
|
|
return res.status(403).json({ message: "Not authorized to delete this post" });
|
|
}
|
|
|
|
await storage.deleteCommunityPost(req.params.id);
|
|
res.status(204).send();
|
|
} catch (error) {
|
|
console.error("Error deleting community post:", error);
|
|
res.status(500).json({ message: "Failed to delete community post" });
|
|
}
|
|
});
|
|
|
|
app.post('/api/community/posts/:id/like', isAuthenticated, async (req: any, res) => {
|
|
try {
|
|
const post = await storage.getCommunityPostById(req.params.id);
|
|
if (!post) {
|
|
return res.status(404).json({ message: "Post not found" });
|
|
}
|
|
|
|
await storage.incrementPostLikes(req.params.id);
|
|
const updated = await storage.getCommunityPostById(req.params.id);
|
|
res.json(updated);
|
|
} catch (error) {
|
|
console.error("Error liking post:", error);
|
|
res.status(500).json({ message: "Failed to like post" });
|
|
}
|
|
});
|
|
|
|
app.get('/api/community/posts/:id/replies', async (req, res) => {
|
|
try {
|
|
const replies = await storage.getRepliesByPost(req.params.id);
|
|
res.json(replies);
|
|
} catch (error) {
|
|
console.error("Error fetching replies:", error);
|
|
res.status(500).json({ message: "Failed to fetch replies" });
|
|
}
|
|
});
|
|
|
|
app.post('/api/community/posts/:id/replies', isAuthenticated, async (req: any, res) => {
|
|
try {
|
|
const post = await storage.getCommunityPostById(req.params.id);
|
|
if (!post) {
|
|
return res.status(404).json({ message: "Post not found" });
|
|
}
|
|
|
|
const userId = req.user.claims?.sub || req.user.id;
|
|
const replyData = insertCommunityReplySchema.parse({
|
|
...req.body,
|
|
postId: req.params.id,
|
|
authorId: userId
|
|
});
|
|
|
|
const reply = await storage.createCommunityReply(replyData);
|
|
res.status(201).json(reply);
|
|
} catch (error) {
|
|
console.error("Error creating reply:", error);
|
|
res.status(500).json({ message: "Failed to create reply" });
|
|
}
|
|
});
|
|
|
|
// Chatbot routes
|
|
app.get('/api/media-outlets/:slug/chat', 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 userId = req.user.claims?.sub || req.user.id;
|
|
const messages = await storage.getChatMessages(outlet.id, userId);
|
|
res.json(messages);
|
|
} catch (error) {
|
|
console.error("Error fetching chat messages:", error);
|
|
res.status(500).json({ message: "Failed to fetch chat messages" });
|
|
}
|
|
});
|
|
|
|
app.post('/api/media-outlets/:slug/chat', 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 userId = req.user.claims?.sub || req.user.id;
|
|
const { content } = req.body;
|
|
|
|
if (!content || typeof content !== 'string') {
|
|
return res.status(400).json({ message: "Invalid message content" });
|
|
}
|
|
|
|
// Save user message
|
|
const userMessage = insertChatMessageSchema.parse({
|
|
mediaOutletId: outlet.id,
|
|
userId,
|
|
role: 'user',
|
|
content
|
|
});
|
|
await storage.createChatMessage(userMessage);
|
|
|
|
// Get chat history
|
|
const chatHistory = await storage.getChatMessages(outlet.id, userId);
|
|
const messages = chatHistory.map(msg => ({
|
|
role: msg.role as 'user' | 'assistant',
|
|
content: msg.content
|
|
}));
|
|
|
|
// Generate AI response
|
|
const aiResponse = await generateChatbotResponse(
|
|
messages,
|
|
outlet.name,
|
|
outlet.category,
|
|
outlet.description || undefined
|
|
);
|
|
|
|
// Save assistant message
|
|
const assistantMessage = insertChatMessageSchema.parse({
|
|
mediaOutletId: outlet.id,
|
|
userId,
|
|
role: 'assistant',
|
|
content: aiResponse
|
|
});
|
|
const savedAssistantMessage = await storage.createChatMessage(assistantMessage);
|
|
|
|
res.status(201).json(savedAssistantMessage);
|
|
} catch (error) {
|
|
console.error("Error processing chat message:", error);
|
|
res.status(500).json({ message: "Failed to process chat message" });
|
|
}
|
|
});
|
|
|
|
const httpServer = createServer(app);
|
|
return httpServer;
|
|
}
|