refactor: code review improvements

- Add 30s timeout to Stockfish evaluation to prevent hanging promises
- Add FEN validation and depth cap (max 30) to Stockfish API route
- Create ErrorBoundary component with specialized fallbacks for chess game and tutor
- Extract useChessSounds hook for better audio management
- Add React.memo to EvaluationBar and CapturedPieces for performance
- Add useMemo to CapturedPieces for sorted pieces calculation
- Improve tacticDetection to return empty array instead of "none" type
- Add filterMeaningfulTactics and hasTactics helper functions
- Translate hardcoded UI strings (stockfishLevel, download, evalChange)
- Update translations for EN, DE, FR, IT, PL
- Add uuid to Jest transformIgnorePatterns for ESM compatibility
- Update tests to use new filterMeaningfulTactics function
This commit is contained in:
Claude
2025-12-10 21:30:28 +00:00
parent 014781e2d0
commit 47c37487b3
17 changed files with 385 additions and 61 deletions
+3 -4
View File
@@ -12,7 +12,7 @@ import { useTranslation } from "@/lib/i18n/useTranslation";
import { Personality, PERSONALITIES } from "@/lib/personalities";
import { Stockfish, StockfishEvaluation } from "@/lib/stockfish";
import { detectChessFormat, ChessFormat } from "@/lib/chessFormatDetector";
import { detectMissedTactics, DetectedTactic, uciToSan } from "@/lib/tacticDetection";
import { detectMissedTactics, DetectedTactic, uciToSan, filterMeaningfulTactics } from "@/lib/tacticDetection";
import { lookupPossibleOpenings, buildMoveSequenceFromSteps, OpeningMetadata } from "@/lib/openings";
import { getGenAIModel } from "@/lib/gemini";
import { ChatSession } from "@google/generative-ai";
@@ -326,8 +326,7 @@ IMPORTANT:
const evalBefore = details.evalBefore!.score / 100;
const evalAfter = details.evalAfter!.score / 100;
const mateInfo = details.evalAfter!.mate !== null ? `Mate in ${details.evalAfter!.mate}` : "No mate detected";
const tactics = (details.missedTactics || [])
.filter(t => t.tactic_type !== "none")
const tactics = filterMeaningfulTactics(details.missedTactics)
.map(t => `${t.tactic_type}${t.material_delta ? ` (~${(t.material_delta / 100).toFixed(1)} pawns)` : ""}`)
.join("; ") || "None";
@@ -406,7 +405,7 @@ INSTRUCTIONS:
};
const currentDetails = currentIndex > 0 ? stepDetails[currentIndex] : undefined;
const tacticSummary = (currentDetails?.missedTactics || []).filter(t => t.tactic_type !== "none");
const tacticSummary = filterMeaningfulTactics(currentDetails?.missedTactics);
return (
<div className="flex flex-col min-h-screen bg-gray-100 dark:bg-gray-900">