refactor: large codebase cleanup - consolidate schemas, migrate to Drizzle ORM, extract frontend components, modernize Docker builds
Build & Deploy / build-and-push (discord-gateway) (push) Failing after 2m22s
Build & Deploy / build-and-push (backend) (push) Failing after 3m22s
Build & Deploy / build-and-push (proxy) (push) Successful in 1m36s
Build & Deploy / deploy (push) Skipped
Build & Deploy / build-and-push (discord-gateway) (push) Failing after 2m22s
Build & Deploy / build-and-push (backend) (push) Failing after 3m22s
Build & Deploy / build-and-push (proxy) (push) Successful in 1m36s
Build & Deploy / deploy (push) Skipped
- Consolidate all DB schema definitions into packages/shared as single source of truth - Migrate backend from raw SQL to Drizzle ORM across all modules - Extract frontend inline UI into separate component files - Refactor discord-gateway circuitBreaker into conversationState + moderationState - Convert messageStore to Proxy singleton pattern - Add validateBody/validateQuery middleware + Zod schemas for API endpoints - Modernize Docker builds with multi-stage + pnpm deploy - Migrate CI/CD from deployment to image-based pipeline - Remove 60+ unused/dead files (~15K lines) - Update color scheme from sky-blue to teal-cyan - Move DB connection management to @bete/shared/database Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
63f21513bd
commit
5802d02e29
@@ -1,5 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import {
|
||||
Bot,
|
||||
Loader2,
|
||||
@@ -30,16 +31,28 @@ export function Chatbot() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [messages, setMessages] = useState<ChatHistoryMessage[]>([]);
|
||||
const [input, setInput] = useState("");
|
||||
const [sending, setSending] = useState(false);
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
const qc = useQueryClient();
|
||||
|
||||
const { data: historyMessages = [] } = useQuery({
|
||||
queryKey: ["chatbot-history"],
|
||||
queryFn: () => chatbotApi.getHistory(),
|
||||
enabled: open,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
chatbotApi
|
||||
.getHistory()
|
||||
.then(setMessages)
|
||||
.catch(() => {});
|
||||
}, [open]);
|
||||
if (historyMessages.length > 0) setMessages(historyMessages);
|
||||
}, [historyMessages]);
|
||||
|
||||
const sendMut = useMutation({
|
||||
mutationFn: (text: string) => chatbotApi.send(text),
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: ["chatbot-history"] }),
|
||||
});
|
||||
|
||||
const clearMut = useMutation({
|
||||
mutationFn: () => chatbotApi.clearHistory(),
|
||||
onSuccess: () => qc.setQueryData(["chatbot-history"], []),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (scrollRef.current) {
|
||||
@@ -47,18 +60,13 @@ export function Chatbot() {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleClear = useCallback(async () => {
|
||||
try {
|
||||
await chatbotApi.clearHistory();
|
||||
setMessages([]);
|
||||
} catch (err) {
|
||||
console.error("chatbot/clearHistory:", err);
|
||||
}
|
||||
}, []);
|
||||
const handleClear = useCallback(() => {
|
||||
clearMut.mutate();
|
||||
setMessages([]);
|
||||
}, [clearMut]);
|
||||
|
||||
const handleSend = useCallback(async () => {
|
||||
if (!input.trim() || sending) return;
|
||||
setSending(true);
|
||||
if (!input.trim() || sendMut.isPending) return;
|
||||
const text = input.trim();
|
||||
setInput("");
|
||||
|
||||
@@ -69,7 +77,7 @@ export function Chatbot() {
|
||||
]);
|
||||
|
||||
try {
|
||||
const resp = await chatbotApi.send(text);
|
||||
const resp = await sendMut.mutateAsync(text);
|
||||
setMessages((prev) => [
|
||||
...prev,
|
||||
{
|
||||
@@ -78,8 +86,7 @@ export function Chatbot() {
|
||||
timestamp: resp.timestamp,
|
||||
},
|
||||
]);
|
||||
} catch (err) {
|
||||
console.error("chatbot/send:", err);
|
||||
} catch {
|
||||
setMessages((prev) => [
|
||||
...prev,
|
||||
{
|
||||
@@ -88,10 +95,8 @@ export function Chatbot() {
|
||||
timestamp: new Date().toISOString(),
|
||||
},
|
||||
]);
|
||||
} finally {
|
||||
setSending(false);
|
||||
}
|
||||
}, [input, sending]);
|
||||
}, [input, sendMut]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -170,7 +175,7 @@ export function Chatbot() {
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{sending && (
|
||||
{sendMut.isPending && (
|
||||
<div className="flex items-start gap-2">
|
||||
<Avatar className="size-6 shrink-0">
|
||||
<AvatarFallback className="text-[10px] bg-muted">
|
||||
@@ -199,15 +204,15 @@ export function Chatbot() {
|
||||
placeholder="Ask the mascot…"
|
||||
value={input}
|
||||
onChange={(e) => setInput(e.target.value)}
|
||||
disabled={sending}
|
||||
disabled={sendMut.isPending}
|
||||
className="h-8 flex-1"
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
size="icon-sm"
|
||||
disabled={!input.trim() || sending}
|
||||
disabled={!input.trim() || sendMut.isPending}
|
||||
>
|
||||
{sending ? (
|
||||
{sendMut.isPending ? (
|
||||
<Loader2 className="size-4 animate-spin" />
|
||||
) : (
|
||||
<Send className="size-4" />
|
||||
|
||||
Reference in New Issue
Block a user