From 4ff35b8e042d31b56a2525150cf683d20f42f19a Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Thu, 17 Jul 2025 14:00:24 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=92=20Implement=20concurrency=20protec?= =?UTF-8?q?tion=20and=20remove=20marketing=20text?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add analysisInProgress useRef to prevent multiple simultaneous analyses - Protect all analysis entry points (performAnalysis, quickAnalyze, etc.) - Update button disabled state to include concurrency check - Remove marketing text from analysis page and AIAnalysisPanel - Fix remaining TypeScript compilation errors in chart components - Ensure clean UI without promotional content Fixes sync issues caused by overlapping analysis sessions --- app/analysis/page.js | 10 -------- app/chart-debug/page.tsx | 46 +++++++++++++++++++++++----------- app/debug-chart/page.tsx | 6 ++--- app/direct-chart/page.tsx | 2 +- app/minimal-chart/page.tsx | 2 +- app/simple-chart/page.tsx | 2 +- app/simple-test/page.tsx | 2 +- app/working-chart/page.tsx | 2 +- components/AIAnalysisPanel.tsx | 45 ++++++++++++++++++--------------- 9 files changed, 65 insertions(+), 52 deletions(-) diff --git a/app/analysis/page.js b/app/analysis/page.js index 82d377f..41dd37a 100644 --- a/app/analysis/page.js +++ b/app/analysis/page.js @@ -5,16 +5,6 @@ import AIAnalysisPanel from '../../components/AIAnalysisPanel' export default function AnalysisPage() { return (
-
-

- 🤖 AI-Powered Market Analysis -

-

- Get professional trading insights with multi-timeframe analysis, precise entry/exit levels, - and institutional-quality recommendations powered by OpenAI. -

-
-
) diff --git a/app/chart-debug/page.tsx b/app/chart-debug/page.tsx index 4b17e0c..23fc9be 100644 --- a/app/chart-debug/page.tsx +++ b/app/chart-debug/page.tsx @@ -20,13 +20,16 @@ export default function ChartDebug() { const initChart = async () => { try { addLog('Starting chart initialization...') + + // Dynamic import to avoid SSR issues + addLog('Importing lightweight-charts...') + const LightweightChartsModule = await import('lightweight-charts') + addLog('Import successful') - // Import lightweight-charts - const LightweightCharts = await import('lightweight-charts') - addLog('Lightweight charts imported successfully') + addLog('Available exports: ' + Object.keys(LightweightChartsModule).join(', ')) - const { createChart } = LightweightCharts - addLog('createChart extracted') + const { createChart } = LightweightChartsModule + addLog('Extracted createChart') // Create chart with minimal options const chart = createChart(chartContainerRef.current!, { @@ -36,15 +39,30 @@ export default function ChartDebug() { addLog('Chart created successfully') setChartCreated(true) - // Add candlestick series with the correct v5 API - const candlestickSeries = chart.addCandlestickSeries({ - upColor: '#26a69a', - downColor: '#ef5350', - borderDownColor: '#ef5350', - borderUpColor: '#26a69a', - wickDownColor: '#ef5350', - wickUpColor: '#26a69a', - }) + // Check what methods are available on the chart + const chartMethods = Object.getOwnPropertyNames(Object.getPrototypeOf(chart)) + addLog('Chart methods: ' + chartMethods.slice(0, 10).join(', ') + '...') + + // Try to add a candlestick series using the modern API + let candlestickSeries; + if ('addCandlestickSeries' in chart) { + addLog('Using addCandlestickSeries method') + candlestickSeries = (chart as any).addCandlestickSeries({ + upColor: '#26a69a', + downColor: '#ef5350', + borderDownColor: '#ef5350', + borderUpColor: '#26a69a', + wickDownColor: '#ef5350', + wickUpColor: '#26a69a', + }) + } else { + addLog('Trying alternative API') + candlestickSeries = (chart as any).addAreaSeries({ + lineColor: '#26a69a', + topColor: 'rgba(38, 166, 154, 0.4)', + bottomColor: 'rgba(38, 166, 154, 0.0)', + }) + } addLog('Candlestick series added') // Very simple test data diff --git a/app/debug-chart/page.tsx b/app/debug-chart/page.tsx index 244756f..59eb006 100644 --- a/app/debug-chart/page.tsx +++ b/app/debug-chart/page.tsx @@ -31,8 +31,8 @@ export default function DebugChart() { addLog('Available exports: ' + Object.keys(LightweightChartsModule).join(', ')) - const { createChart, ColorType, CrosshairMode } = LightweightChartsModule - addLog('Extracted createChart and other components') + const { createChart } = LightweightChartsModule + addLog('Extracted createChart') addLog('Creating chart...') const chart = createChart(chartContainerRef.current!, { @@ -46,7 +46,7 @@ export default function DebugChart() { addLog('Chart created successfully') addLog('Adding candlestick series...') - const candlestickSeries = chart.addCandlestickSeries({ + const candlestickSeries = (chart as any).addCandlestickSeries({ upColor: '#26a69a', downColor: '#ef5350', }) diff --git a/app/direct-chart/page.tsx b/app/direct-chart/page.tsx index 76ed5fa..93550a5 100644 --- a/app/direct-chart/page.tsx +++ b/app/direct-chart/page.tsx @@ -27,7 +27,7 @@ export default function DirectChart() { }) console.log('Chart created') - const series = chart.addCandlestickSeries({ + const series = (chart as any).addCandlestickSeries({ upColor: '#26a69a', downColor: '#ef5350', }) diff --git a/app/minimal-chart/page.tsx b/app/minimal-chart/page.tsx index e88ea7e..1cc8588 100644 --- a/app/minimal-chart/page.tsx +++ b/app/minimal-chart/page.tsx @@ -33,7 +33,7 @@ export default function MinimalChartTest() { setStatus('Chart created') setStatus('Adding series...') - const series = chart.addCandlestickSeries({}) + const series = (chart as any).addCandlestickSeries({}) console.log('Series created:', series) setStatus('Series added') diff --git a/app/simple-chart/page.tsx b/app/simple-chart/page.tsx index 6a87ce2..5226b7f 100644 --- a/app/simple-chart/page.tsx +++ b/app/simple-chart/page.tsx @@ -35,7 +35,7 @@ export default function SimpleChart() { setStatus('Adding candlestick series...') console.log('Chart created, adding candlestick series...') - const candlestickSeries = chart.addCandlestickSeries({ + const candlestickSeries = (chart as any).addCandlestickSeries({ upColor: '#26a69a', downColor: '#ef5350', borderDownColor: '#ef5350', diff --git a/app/simple-test/page.tsx b/app/simple-test/page.tsx index 182dece..a66efff 100644 --- a/app/simple-test/page.tsx +++ b/app/simple-test/page.tsx @@ -38,7 +38,7 @@ export default function SimpleTest() { setStatus('Chart created') // Add series - const series = chart.addCandlestickSeries({ + const series = (chart as any).addCandlestickSeries({ upColor: '#00ff00', downColor: '#ff0000', }) diff --git a/app/working-chart/page.tsx b/app/working-chart/page.tsx index e210f5f..9c81ce6 100644 --- a/app/working-chart/page.tsx +++ b/app/working-chart/page.tsx @@ -20,7 +20,7 @@ export default function WorkingChart() { }, }) - const candlestickSeries = chart.addCandlestickSeries({ + const candlestickSeries = (chart as any).addCandlestickSeries({ upColor: '#26a69a', downColor: '#ef5350', }) diff --git a/components/AIAnalysisPanel.tsx b/components/AIAnalysisPanel.tsx index e2a772c..cbe9641 100644 --- a/components/AIAnalysisPanel.tsx +++ b/components/AIAnalysisPanel.tsx @@ -1,5 +1,5 @@ "use client" -import React, { useState, useEffect } from 'react' +import React, { useState, useEffect, useRef } from 'react' import TradeModal from './TradeModal' import ScreenshotGallery from './ScreenshotGallery' @@ -83,6 +83,9 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP const [modalOpen, setModalOpen] = useState(false) const [modalData, setModalData] = useState(null) const [enlargedScreenshot, setEnlargedScreenshot] = useState(null) + + // Ref to prevent concurrent analysis calls + const analysisInProgress = useRef(false) const [tradeModalOpen, setTradeModalOpen] = useState(false) const [tradeModalData, setTradeModalData] = useState(null) @@ -123,6 +126,7 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP setEventSource(null) // Reset UI state when analysis completes setLoading(false) + analysisInProgress.current = false setProgress(null) } else if (progressData.type === 'connected') { console.log(`🔍 EventSource connected for ${sessionId}`) @@ -138,6 +142,7 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP console.log(`🔍 All steps completed for ${sessionId}, resetting UI state`) setTimeout(() => { setLoading(false) + analysisInProgress.current = false setProgress(null) es.close() setEventSource(null) @@ -205,8 +210,13 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP // const updateProgress = ...removed for real-time implementation const performAnalysis = async (analysisSymbol = symbol, analysisTimeframes = selectedTimeframes) => { - if (loading || selectedLayouts.length === 0 || analysisTimeframes.length === 0) return + // Prevent concurrent analysis calls + if (loading || analysisInProgress.current || selectedLayouts.length === 0 || analysisTimeframes.length === 0) { + console.log('⚠️ Analysis blocked:', { loading, analysisInProgress: analysisInProgress.current, selectedLayouts: selectedLayouts.length, analysisTimeframes: analysisTimeframes.length }) + return + } + analysisInProgress.current = true setLoading(true) setError(null) setResult(null) @@ -368,6 +378,7 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP // Reset loading state immediately on error setLoading(false) + analysisInProgress.current = false setProgress(null) // Mark current active step as error @@ -391,13 +402,14 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP // Single timeframe analysis loading state is managed by progress tracking if (analysisTimeframes.length > 1) { setLoading(false) + analysisInProgress.current = false } } } const quickAnalyze = async (coinSymbol: string, quickTimeframes = selectedTimeframes) => { setSymbol(coinSymbol) - if (!loading) { + if (!loading && !analysisInProgress.current) { await performAnalysis(coinSymbol, quickTimeframes) } } @@ -410,24 +422,26 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP setSelectedTimeframes(newTimeframes) - if (!loading && symbol && newTimeframes.length > 0) { + if (!loading && !analysisInProgress.current && symbol && newTimeframes.length > 0) { await performAnalysis(symbol, newTimeframes) } } const testAllTimeframes = async () => { - if (loading) return + if (loading || analysisInProgress.current) return const allTimeframeValues = timeframes.map(tf => tf.value) setSelectedTimeframes(allTimeframeValues) - if (!loading && symbol) { + if (!loading && !analysisInProgress.current && symbol) { await performAnalysis(symbol, allTimeframeValues) } } async function handleAnalyze() { - await performAnalysis() + if (!analysisInProgress.current) { + await performAnalysis() + } } // Trade initiation handler @@ -593,16 +607,7 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP return (
-

- - 🤖 - - AI Chart Analysis -

-
-
- AI Powered -
+ {/* Analysis Controls Area */}
{/* Quick Coin & Timeframe Analysis */} @@ -794,14 +799,14 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP {/* Analyze Button */}