fix: address performance and code quality issues in conversation history

Performance improvements:
- Fix N+1 query in get_conversations() using COUNT subquery instead of
  len(c.messages) which triggered lazy loading for each conversation
- Add SQLAlchemy engine caching to avoid creating new database connections
  on every request
- Add React.memo to ChatMessage component to prevent unnecessary re-renders
  during message streaming
- Move BOLD_REGEX to module scope to avoid recreating on each render

Code quality improvements:
- Remove 10+ console.log debug statements from AssistantChat.tsx and
  AssistantPanel.tsx that were left from development
- Add user feedback for delete errors in ConversationHistory - dialog now
  stays open and shows error message instead of silently failing
- Update ConfirmDialog to accept ReactNode for message prop to support
  rich error content

These changes address issues identified in the code review of PR #74
(conversation history feature).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Auto
2026-01-22 09:09:05 +02:00
parent 35ed14dfe3
commit 28e8bd6da8
6 changed files with 91 additions and 55 deletions

View File

@@ -5,6 +5,7 @@
* Supports user, assistant, and system messages with neobrutalism styling.
*/
import { memo } from 'react'
import { Bot, User, Info } from 'lucide-react'
import type { ChatMessage as ChatMessageType } from '../lib/types'
@@ -12,7 +13,10 @@ interface ChatMessageProps {
message: ChatMessageType
}
export function ChatMessage({ message }: ChatMessageProps) {
// Module-level regex to avoid recreating on each render
const BOLD_REGEX = /\*\*(.*?)\*\*/g
export const ChatMessage = memo(function ChatMessage({ message }: ChatMessageProps) {
const { role, content, attachments, timestamp, isStreaming } = message
// Format timestamp
@@ -112,13 +116,13 @@ export function ChatMessage({ message }: ChatMessageProps) {
{content && (
<div className={`whitespace-pre-wrap text-sm leading-relaxed ${config.textColor}`}>
{content.split('\n').map((line, i) => {
// Bold text
const boldRegex = /\*\*(.*?)\*\*/g
// Bold text - use module-level regex, reset lastIndex for each line
BOLD_REGEX.lastIndex = 0
const parts = []
let lastIndex = 0
let match
while ((match = boldRegex.exec(line)) !== null) {
while ((match = BOLD_REGEX.exec(line)) !== null) {
if (match.index > lastIndex) {
parts.push(line.slice(lastIndex, match.index))
}
@@ -196,4 +200,4 @@ export function ChatMessage({ message }: ChatMessageProps) {
</div>
</div>
)
}
})