From 9901ea3e2dcc41d75eaaca41bc8b67601959d233 Mon Sep 17 00:00:00 2001 From: sirpiglr <49359077-sirpiglr@users.noreply.replit.com> Date: Tue, 16 Dec 2025 00:00:42 +0000 Subject: [PATCH] Add AI chatbot and theme toggle functionality for improved user experience Integrates a new AI chatbot using OpenAI, adds a theme toggle for light/dark modes, and includes a live activity feed for administrators. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 279f1558-c0e3-40e4-8217-be7e9f4c6eca Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: c19480f5-d8f1-4a0b-98ea-7bfe9144b25d Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/b984cb14-1d19-4944-922b-bc79e821ed35/279f1558-c0e3-40e4-8217-be7e9f4c6eca/yVjwaR4 Replit-Helium-Checkpoint-Created: true --- .replit | 1 + client/public/opengraph.jpg | Bin 52102 -> 43122 bytes client/src/App.tsx | 6 + client/src/components/Chatbot.tsx | 210 +++++++++++++++++ client/src/components/ThemeToggle.tsx | 58 +++++ client/src/index.css | 37 +++ client/src/pages/admin-activity.tsx | 277 +++++++++++++++++++++++ client/src/pages/admin-notifications.tsx | 251 ++++++++++++++++++++ client/src/pages/admin.tsx | 2 +- client/src/pages/home.tsx | 2 + package-lock.json | 22 ++ package.json | 1 + server/openai.ts | 59 +++++ server/routes.ts | 41 ++++ 14 files changed, 966 insertions(+), 1 deletion(-) create mode 100644 client/src/components/Chatbot.tsx create mode 100644 client/src/components/ThemeToggle.tsx create mode 100644 client/src/pages/admin-activity.tsx create mode 100644 client/src/pages/admin-notifications.tsx create mode 100644 server/openai.ts diff --git a/.replit b/.replit index d95dcdf..cfe55fd 100644 --- a/.replit +++ b/.replit @@ -41,3 +41,4 @@ waitForPort = 5000 [agent] mockupState = "FULLSTACK" +integrations = ["javascript_openai_ai_integrations:1.0.0"] diff --git a/client/public/opengraph.jpg b/client/public/opengraph.jpg index dc30e0f6c1fb8634a9e497d9b44e9f54175b8d4c..814cfbb9d7c4dfad26c9266e74e604575cd8c8a0 100644 GIT binary patch literal 43122 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 E1GOwGd;kCd diff --git a/client/src/App.tsx b/client/src/App.tsx index 438611a..9a3f249 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -21,6 +21,9 @@ import AdminSites from "@/pages/admin-sites"; import AdminLogs from "@/pages/admin-logs"; import AdminAchievements from "@/pages/admin-achievements"; import AdminApplications from "@/pages/admin-applications"; +import AdminActivity from "@/pages/admin-activity"; +import AdminNotifications from "@/pages/admin-notifications"; +import { Chatbot } from "@/components/Chatbot"; function Router() { return ( @@ -40,6 +43,8 @@ function Router() { + + @@ -53,6 +58,7 @@ function App() { + diff --git a/client/src/components/Chatbot.tsx b/client/src/components/Chatbot.tsx new file mode 100644 index 0000000..dd5e3f5 --- /dev/null +++ b/client/src/components/Chatbot.tsx @@ -0,0 +1,210 @@ +import { useState, useRef, useEffect } from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import { MessageCircle, X, Send, Bot, User, Loader2 } from "lucide-react"; + +interface Message { + id: string; + role: "user" | "assistant"; + content: string; + timestamp: Date; +} + +export function Chatbot() { + const [isOpen, setIsOpen] = useState(false); + const [messages, setMessages] = useState([ + { + id: "welcome", + role: "assistant", + content: "Hi! I'm the AeThex assistant. I can help you navigate the platform, explain our certification system, or answer questions about the ecosystem. How can I help you today?", + timestamp: new Date(), + }, + ]); + const [input, setInput] = useState(""); + const [isLoading, setIsLoading] = useState(false); + const messagesEndRef = useRef(null); + + useEffect(() => { + messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); + }, [messages]); + + const sendMessage = async () => { + if (!input.trim() || isLoading) return; + + const userMessage: Message = { + id: Date.now().toString(), + role: "user", + content: input.trim(), + timestamp: new Date(), + }; + + setMessages((prev) => [...prev, userMessage]); + setInput(""); + setIsLoading(true); + + try { + const conversationHistory = messages.slice(-10).map(m => ({ + role: m.role, + content: m.content + })); + + const response = await fetch("/api/chat", { + method: "POST", + headers: { "Content-Type": "application/json" }, + credentials: "include", + body: JSON.stringify({ + message: userMessage.content, + history: conversationHistory + }), + }); + + if (!response.ok) throw new Error("Failed to get response"); + + const data = await response.json(); + + const assistantMessage: Message = { + id: (Date.now() + 1).toString(), + role: "assistant", + content: data.response || "I apologize, but I'm having trouble responding right now. Please try again.", + timestamp: new Date(), + }; + + setMessages((prev) => [...prev, assistantMessage]); + } catch (error) { + const errorMessage: Message = { + id: (Date.now() + 1).toString(), + role: "assistant", + content: "I'm sorry, I encountered an error. Please try again in a moment.", + timestamp: new Date(), + }; + setMessages((prev) => [...prev, errorMessage]); + } finally { + setIsLoading(false); + } + }; + + const handleKeyPress = (e: React.KeyboardEvent) => { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault(); + sendMessage(); + } + }; + + return ( + <> + {/* Chat Button */} + + {!isOpen && ( + setIsOpen(true)} + className="fixed bottom-6 left-6 z-50 bg-secondary text-background p-4 rounded-full shadow-lg hover:bg-secondary/90 transition-colors" + data-testid="button-open-chatbot" + > + + + )} + + + {/* Chat Window */} + + {isOpen && ( + + {/* Header */} +
+
+
+ +
+
+
AeThex Assistant
+
+ Online +
+
+
+ +
+ + {/* Messages */} +
+ {messages.map((message) => ( +
+
+ {message.role === "user" ? ( + + ) : ( + + )} +
+
+ {message.content} +
+
+ ))} + {isLoading && ( +
+
+ +
+
+ +
+
+ )} +
+
+ + {/* Input */} +
+
+ setInput(e.target.value)} + onKeyPress={handleKeyPress} + placeholder="Ask me anything..." + className="flex-1 bg-black/20 border border-white/10 px-4 py-2 text-sm text-white placeholder:text-muted-foreground focus:outline-none focus:border-secondary/50" + data-testid="input-chat-message" + /> + +
+
+ + )} + + + ); +} diff --git a/client/src/components/ThemeToggle.tsx b/client/src/components/ThemeToggle.tsx new file mode 100644 index 0000000..af79693 --- /dev/null +++ b/client/src/components/ThemeToggle.tsx @@ -0,0 +1,58 @@ +import { useState, useEffect } from "react"; +import { Moon, Sun } from "lucide-react"; + +export function useTheme() { + const [theme, setTheme] = useState<"light" | "dark">("dark"); + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + if (typeof window !== "undefined") { + const stored = localStorage.getItem("aethex_theme"); + if (stored === "light" || stored === "dark") { + setTheme(stored); + } + } + }, []); + + useEffect(() => { + if (!mounted) return; + + const root = document.documentElement; + if (theme === "light") { + root.classList.remove("dark"); + root.classList.add("light"); + } else { + root.classList.remove("light"); + root.classList.add("dark"); + } + if (typeof window !== "undefined") { + localStorage.setItem("aethex_theme", theme); + } + }, [theme, mounted]); + + const toggleTheme = () => { + setTheme((prev) => (prev === "dark" ? "light" : "dark")); + }; + + return { theme, setTheme, toggleTheme }; +} + +export function ThemeToggle() { + const { theme, toggleTheme } = useTheme(); + + return ( + + ); +} diff --git a/client/src/index.css b/client/src/index.css index 96fcee0..b33e184 100644 --- a/client/src/index.css +++ b/client/src/index.css @@ -96,6 +96,43 @@ --chart-5: 0 100% 50%; } +/* LIGHT MODE - AE-THEX THEME */ +.light { + --background: 0 0% 98%; + --foreground: 240 10% 10%; + + --card: 0 0% 100%; + --card-foreground: 240 10% 10%; + + --popover: 0 0% 100%; + --popover-foreground: 240 10% 10%; + + --primary: 45 100% 40%; + --primary-foreground: 0 0% 100%; + + --secondary: 180 80% 35%; + --secondary-foreground: 0 0% 100%; + + --muted: 240 5% 90%; + --muted-foreground: 240 5% 40%; + + --accent: 200 70% 90%; + --accent-foreground: 200 80% 25%; + + --destructive: 0 80% 50%; + --destructive-foreground: 0 0% 100%; + + --border: 240 5% 85%; + --input: 240 5% 85%; + --ring: 45 100% 40%; + + --chart-1: 45 100% 45%; + --chart-2: 180 80% 45%; + --chart-3: 200 80% 45%; + --chart-4: 280 80% 45%; + --chart-5: 0 80% 45%; +} + @layer base { * { @apply border-border; diff --git a/client/src/pages/admin-activity.tsx b/client/src/pages/admin-activity.tsx new file mode 100644 index 0000000..1cc4b92 --- /dev/null +++ b/client/src/pages/admin-activity.tsx @@ -0,0 +1,277 @@ +import { useEffect, useState } from "react"; +import { Link, useLocation } from "wouter"; +import { useQuery } from "@tanstack/react-query"; +import { useAuth } from "@/lib/auth"; +import { + Users, FileCode, Shield, Activity, LogOut, + BarChart3, User, Globe, Award, Key, Inbox, + Circle, Clock, TrendingUp, Wifi +} from "lucide-react"; + +interface ActivityEvent { + id: string; + type: string; + user: string; + action: string; + timestamp: Date; + details?: string; +} + +export default function AdminActivity() { + const { user, isAuthenticated, isLoading: authLoading, logout } = useAuth(); + const [, setLocation] = useLocation(); + const [liveEvents, setLiveEvents] = useState([]); + const [lastRefresh, setLastRefresh] = useState(new Date()); + const [seenEventIds, setSeenEventIds] = useState>(new Set()); + + useEffect(() => { + if (!authLoading && !isAuthenticated) { + setLocation("/login"); + } + }, [authLoading, isAuthenticated, setLocation]); + + const { data: profiles } = useQuery({ + queryKey: ["profiles"], + queryFn: async () => { + const res = await fetch("/api/profiles", { credentials: "include" }); + if (!res.ok) return []; + return res.json(); + }, + enabled: isAuthenticated, + refetchInterval: 10000, + }); + + const { data: authLogs } = useQuery({ + queryKey: ["auth-logs"], + queryFn: async () => { + const res = await fetch("/api/auth-logs", { credentials: "include" }); + if (!res.ok) return []; + return res.json(); + }, + enabled: isAuthenticated, + refetchInterval: 5000, + }); + + const { data: metrics } = useQuery({ + queryKey: ["metrics"], + queryFn: async () => { + const res = await fetch("/api/metrics", { credentials: "include" }); + return res.json(); + }, + refetchInterval: 5000, + }); + + useEffect(() => { + if (authLogs && authLogs.length > 0) { + const newEvents: ActivityEvent[] = []; + const newIds = new Set(seenEventIds); + + for (const log of authLogs.slice(0, 30)) { + const eventId = log.id || `log-${log.created_at}`; + if (!newIds.has(eventId)) { + newIds.add(eventId); + newEvents.push({ + id: eventId, + type: log.event_type?.includes('success') ? 'login' : log.event_type?.includes('fail') ? 'failed' : 'auth', + user: log.username || log.user_id || 'Unknown', + action: log.event_type || 'Activity', + timestamp: new Date(log.created_at), + details: log.ip_address, + }); + } + } + + if (newEvents.length > 0) { + setLiveEvents(prev => [...newEvents, ...prev].slice(0, 50)); + setSeenEventIds(newIds); + } + setLastRefresh(new Date()); + } + }, [authLogs]); + + if (authLoading || !isAuthenticated) { + return ( +
+
Loading...
+
+ ); + } + + const handleLogout = async () => { + await logout(); + setLocation("/"); + }; + + const onlineProfiles = profiles?.filter((p: any) => p.status === 'online') || []; + const recentlyActive = profiles?.filter((p: any) => { + if (!p.last_seen) return false; + const lastSeen = new Date(p.last_seen); + const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000); + return lastSeen > fiveMinutesAgo; + }) || []; + + return ( +
+ + +
+
+
+
+

+ Real-Time Activity +

+

+ Live monitoring of user activity across the platform +

+
+
+
+ + Last updated: {lastRefresh.toLocaleTimeString()} +
+
+ + Live +
+
+
+ +
+
+
+
Online Now
+ +
+
{metrics?.onlineUsers || 0}
+
Active users
+
+
+
Total Architects
+
{metrics?.totalProfiles || 0}
+
Registered
+
+
+
Auth Events
+
{authLogs?.length || 0}
+
Last 100
+
+
+
Verified Users
+
{metrics?.verifiedUsers || 0}
+
Certified
+
+
+ +
+
+

+ + Online Users ({onlineProfiles.length}) +

+
+ {onlineProfiles.length === 0 ? ( +
No users currently online
+ ) : ( + onlineProfiles.map((profile: any) => ( +
+
+
+
+ +
+
+
+
+
{profile.username || profile.display_name}
+
Level {profile.level || 1}
+
+
+
Online
+
+ )) + )} +
+
+ +
+

+ + Live Activity Feed +

+
+ {liveEvents.length === 0 ? ( +
No recent activity
+ ) : ( + liveEvents.map((event) => ( +
+
+
+ {event.user} + — {event.action} +
+
+ {event.timestamp.toLocaleTimeString()} +
+
+ )) + )} +
+
+
+
+
+
+ ); +} + +function Sidebar({ user, onLogout, active }: { user: any; onLogout: () => void; active: string }) { + return ( +
+
+

AeThex

+

Command Center

+
+ +
+
+
+ +
+
+
{user?.username}
+
{user?.isAdmin ? "Administrator" : "Member"}
+
+
+ +
+
+ ); +} + +function NavItem({ icon, label, href, active = false }: { icon: React.ReactNode; label: string; href: string; active?: boolean }) { + return ( + +
+ {icon} + {label} +
+ + ); +} diff --git a/client/src/pages/admin-notifications.tsx b/client/src/pages/admin-notifications.tsx new file mode 100644 index 0000000..8949485 --- /dev/null +++ b/client/src/pages/admin-notifications.tsx @@ -0,0 +1,251 @@ +import { useEffect, useState } from "react"; +import { Link, useLocation } from "wouter"; +import { useAuth } from "@/lib/auth"; +import { + Users, FileCode, Shield, Activity, LogOut, + BarChart3, User, Globe, Award, Key, Inbox, + Bell, Mail, AlertTriangle, CheckCircle, Settings +} from "lucide-react"; + +interface NotificationSetting { + id: string; + name: string; + description: string; + enabled: boolean; + category: "security" | "users" | "system"; +} + +const defaultSettings: NotificationSetting[] = [ + { id: "failed_logins", name: "Failed Login Attempts", description: "Alert when multiple failed login attempts are detected", enabled: true, category: "security" }, + { id: "new_user", name: "New User Registration", description: "Notify when a new architect joins the platform", enabled: true, category: "users" }, + { id: "critical_alert", name: "Critical Security Alerts", description: "Immediate notification for high-severity security events", enabled: true, category: "security" }, + { id: "verification", name: "Verification Requests", description: "Alert when an architect requests credential verification", enabled: false, category: "users" }, + { id: "system_down", name: "System Downtime", description: "Notify when any AeThex service goes offline", enabled: true, category: "system" }, + { id: "weekly_report", name: "Weekly Summary Report", description: "Receive a weekly digest of platform activity", enabled: false, category: "system" }, + { id: "application", name: "New Applications", description: "Alert when new job applications are submitted", enabled: true, category: "users" }, + { id: "threat_detected", name: "Threat Detection", description: "Real-time alerts from Aegis threat monitoring", enabled: true, category: "security" }, +]; + +export default function AdminNotifications() { + const { user, isAuthenticated, isLoading: authLoading, logout } = useAuth(); + const [, setLocation] = useLocation(); + const [settings, setSettings] = useState(() => { + if (typeof window !== "undefined") { + const saved = localStorage.getItem("aethex_notification_settings"); + if (saved) return JSON.parse(saved); + } + return defaultSettings; + }); + const [email, setEmail] = useState(() => { + if (typeof window !== "undefined") { + return localStorage.getItem("aethex_notification_email") || ""; + } + return ""; + }); + const [saved, setSaved] = useState(false); + + useEffect(() => { + if (!authLoading && !isAuthenticated) { + setLocation("/login"); + } + }, [authLoading, isAuthenticated, setLocation]); + + const toggleSetting = (id: string) => { + setSettings((prev) => + prev.map((s) => (s.id === id ? { ...s, enabled: !s.enabled } : s)) + ); + setSaved(false); + }; + + const saveSettings = () => { + localStorage.setItem("aethex_notification_settings", JSON.stringify(settings)); + localStorage.setItem("aethex_notification_email", email); + setSaved(true); + setTimeout(() => setSaved(false), 3000); + }; + + if (authLoading || !isAuthenticated) { + return ( +
+
Loading...
+
+ ); + } + + const handleLogout = async () => { + await logout(); + setLocation("/"); + }; + + const groupedSettings = { + security: settings.filter((s) => s.category === "security"), + users: settings.filter((s) => s.category === "users"), + system: settings.filter((s) => s.category === "system"), + }; + + return ( +
+ + +
+
+
+

+ Notification Settings +

+

+ Configure email alerts for critical system events +

+
+ +
+

+ + Email Configuration +

+
+
+ + { setEmail(e.target.value); setSaved(false); }} + placeholder="admin@example.com" + className="w-full max-w-md bg-black/20 border border-white/10 px-4 py-3 text-white placeholder:text-muted-foreground focus:outline-none focus:border-primary/50" + data-testid="input-notification-email" + /> +
+
+
+ +
+
+

+ + Security Alerts +

+
+ {groupedSettings.security.map((setting) => ( + + ))} +
+
+ +
+

+ + User Activity +

+
+ {groupedSettings.users.map((setting) => ( + + ))} +
+
+ +
+

+ + System Notifications +

+
+ {groupedSettings.system.map((setting) => ( + + ))} +
+
+
+ +
+ + {saved && ( + + Settings saved + + )} +
+
+
+
+ ); +} + +function SettingRow({ setting, onToggle }: { setting: NotificationSetting; onToggle: (id: string) => void }) { + return ( +
+
+
{setting.name}
+
{setting.description}
+
+ +
+ ); +} + +function Sidebar({ user, onLogout, active }: { user: any; onLogout: () => void; active: string }) { + return ( +
+
+

AeThex

+

Command Center

+
+ +
+
+
+ +
+
+
{user?.username}
+
{user?.isAdmin ? "Administrator" : "Member"}
+
+
+ +
+
+ ); +} + +function NavItem({ icon, label, href, active = false }: { icon: React.ReactNode; label: string; href: string; active?: boolean }) { + return ( + +
+ {icon} + {label} +
+ + ); +} diff --git a/client/src/pages/admin.tsx b/client/src/pages/admin.tsx index 552067a..44f4b1c 100644 --- a/client/src/pages/admin.tsx +++ b/client/src/pages/admin.tsx @@ -76,11 +76,11 @@ export default function Admin() {
diff --git a/package-lock.json b/package-lock.json index 228629e..4fc438f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57,6 +57,7 @@ "lucide-react": "^0.545.0", "memorystore": "^1.6.7", "next-themes": "^0.4.6", + "openai": "^6.13.0", "passport": "^0.7.0", "passport-local": "^1.0.0", "pg": "^8.16.3", @@ -6656,6 +6657,27 @@ "node": ">= 0.8" } }, + "node_modules/openai": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-6.13.0.tgz", + "integrity": "sha512-yHbMo+EpNGPG3sRrXvmo0LhUPFN4bAURJw3G17bE+ax1G4tcTFCa9ZjvCWh3cvni0aHY0uWlk2IxcsPH4NR9Ow==", + "license": "Apache-2.0", + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", diff --git a/package.json b/package.json index b32633f..1e15f2e 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "lucide-react": "^0.545.0", "memorystore": "^1.6.7", "next-themes": "^0.4.6", + "openai": "^6.13.0", "passport": "^0.7.0", "passport-local": "^1.0.0", "pg": "^8.16.3", diff --git a/server/openai.ts b/server/openai.ts new file mode 100644 index 0000000..9a1cd14 --- /dev/null +++ b/server/openai.ts @@ -0,0 +1,59 @@ +import OpenAI from "openai"; + +// This is using Replit's AI Integrations service, which provides OpenAI-compatible API access without requiring your own OpenAI API key. +// the newest OpenAI model is "gpt-5" which was released August 7, 2025. do not change this unless explicitly requested by the user +const openai = new OpenAI({ + baseURL: process.env.AI_INTEGRATIONS_OPENAI_BASE_URL, + apiKey: process.env.AI_INTEGRATIONS_OPENAI_API_KEY +}); + +const SYSTEM_PROMPT = `You are the AeThex Assistant, a helpful AI guide for the AeThex ecosystem - "The Operating System for the Metaverse." + +About AeThex: +- AeThex is built on a dual-entity model: The Foundation (non-profit, training) and The Corporation (for-profit, security) +- The "Holy Trinity" consists of: Axiom (The Law - foundational protocol), Codex (The Standard - certification system), and Aegis (The Shield - security layer) +- Architects are certified professionals trained through the Codex curriculum +- The platform offers gamified learning, XP progression, and verified credentials + +You help users with: +- Navigating the platform features (Passport, Terminal, Curriculum, Dashboard) +- Understanding the certification process and how to become an Architect +- Explaining the Aegis security features +- Answering questions about the ecosystem and its mission + +Be concise, friendly, and helpful. Use the platform's terminology when appropriate. If you don't know something specific about the platform, be honest about it.`; + +interface ChatMessage { + role: "user" | "assistant"; + content: string; +} + +export async function getChatResponse(userMessage: string, history?: ChatMessage[]): Promise { + try { + const messages: Array<{ role: "system" | "user" | "assistant"; content: string }> = [ + { role: "system", content: SYSTEM_PROMPT } + ]; + + if (history && Array.isArray(history)) { + for (const msg of history.slice(-8)) { + if (msg.role === "user" || msg.role === "assistant") { + messages.push({ role: msg.role, content: msg.content }); + } + } + } + + messages.push({ role: "user", content: userMessage }); + + const response = await openai.chat.completions.create({ + model: "gpt-4o-mini", + messages, + max_tokens: 500, + temperature: 0.7, + }); + + return response.choices[0]?.message?.content || "I'm sorry, I couldn't generate a response."; + } catch (error: any) { + console.error("OpenAI chat error:", error); + throw new Error("Failed to get AI response"); + } +} diff --git a/server/routes.ts b/server/routes.ts index e4698bc..a144119 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -4,6 +4,7 @@ import { storage } from "./storage"; import { loginSchema } from "@shared/schema"; import bcrypt from "bcrypt"; import crypto from "crypto"; +import { getChatResponse } from "./openai"; // Extend session type declare module 'express-session' { @@ -296,5 +297,45 @@ export async function registerRoutes( } }); + // ========== CHATBOT API (Auth + Rate limited) ========== + + const chatRateLimits = new Map(); + + app.post("/api/chat", requireAuth, async (req, res) => { + try { + const userId = req.session?.userId; + if (!userId) { + return res.status(401).json({ error: "Authentication required" }); + } + + const now = Date.now(); + const rateLimit = chatRateLimits.get(userId); + + if (rateLimit) { + if (now < rateLimit.resetTime) { + if (rateLimit.count >= 30) { + return res.status(429).json({ error: "Rate limit exceeded. Please wait before sending more messages." }); + } + rateLimit.count++; + } else { + chatRateLimits.set(userId, { count: 1, resetTime: now + 60000 }); + } + } else { + chatRateLimits.set(userId, { count: 1, resetTime: now + 60000 }); + } + + const { message, history } = req.body; + if (!message || typeof message !== "string") { + return res.status(400).json({ error: "Message is required" }); + } + + const response = await getChatResponse(message, history); + res.json({ response }); + } catch (err: any) { + console.error("Chat error:", err); + res.status(500).json({ error: "Failed to get response" }); + } + }); + return httpServer; }