fix: timeframe handling and progress tracking improvements

- Fix timeframe parameter handling in enhanced-screenshot API route
- Support both 'timeframe' (singular) and 'timeframes' (array) parameters
- Add proper sessionId propagation for real-time progress tracking
- Enhance MACD analysis prompt with detailed crossover definitions
- Add progress tracker service with Server-Sent Events support
- Fix Next.js build errors in chart components (module variable conflicts)
- Change dev environment port from 9000:3000 to 9001:3000
- Improve AI analysis layout detection logic
- Add comprehensive progress tracking through all service layers
This commit is contained in:
mindesbunister
2025-07-17 10:41:18 +02:00
parent 27df0304c6
commit ff4e9737fb
26 changed files with 1656 additions and 277 deletions

View File

@@ -3,12 +3,14 @@ import fs from 'fs/promises'
import path from 'path'
import puppeteer from 'puppeteer'
import { Browser, Page } from 'puppeteer'
import { progressTracker, ProgressStep } from './progress-tracker'
export interface ScreenshotConfig {
symbol: string
timeframe: string
layouts?: string[] // Multiple chart layouts if needed
credentials?: TradingViewCredentials // Optional if using .env
sessionId?: string // For progress tracking
}
// Layout URL mappings for direct navigation
@@ -28,6 +30,13 @@ export class EnhancedScreenshotService {
console.log('📋 Config:', config)
const screenshotFiles: string[] = []
const { sessionId } = config
console.log('🔍 Enhanced Screenshot Service received sessionId:', sessionId)
// Progress tracking (session already created in API)
if (sessionId) {
progressTracker.updateStep(sessionId, 'init', 'active', 'Starting browser sessions...')
}
try {
// Ensure screenshots directory exists
@@ -39,8 +48,13 @@ export class EnhancedScreenshotService {
console.log(`\n🔄 Starting parallel capture of ${layoutsToCapture.length} layouts...`)
if (sessionId) {
progressTracker.updateStep(sessionId, 'init', 'completed', `Started ${layoutsToCapture.length} browser sessions`)
progressTracker.updateStep(sessionId, 'auth', 'active', 'Authenticating with TradingView...')
}
// Create parallel session promises for true dual-session approach
const sessionPromises = layoutsToCapture.map(async (layout) => {
const sessionPromises = layoutsToCapture.map(async (layout, index) => {
const layoutKey = layout.toLowerCase()
let layoutSession: TradingViewAutomation | null = null
@@ -71,6 +85,9 @@ export class EnhancedScreenshotService {
const isLoggedIn = await layoutSession.isLoggedIn()
if (!isLoggedIn) {
console.log(`🔐 Logging in to ${layout} session...`)
if (sessionId && index === 0) {
progressTracker.updateStep(sessionId, 'auth', 'active', `Logging into ${layout} session...`)
}
const loginSuccess = await layoutSession.smartLogin(config.credentials)
if (!loginSuccess) {
throw new Error(`Failed to login to ${layout} session`)
@@ -79,6 +96,12 @@ export class EnhancedScreenshotService {
console.log(`${layout} session already logged in`)
}
// Update auth progress when first session completes auth
if (sessionId && index === 0) {
progressTracker.updateStep(sessionId, 'auth', 'completed', 'TradingView authentication successful')
progressTracker.updateStep(sessionId, 'navigation', 'active', `Navigating to ${config.symbol} chart...`)
}
// Navigate directly to the specific layout URL with symbol and timeframe
const directUrl = `https://www.tradingview.com/chart/${layoutUrl}/?symbol=${config.symbol}&interval=${config.timeframe}`
console.log(`🌐 ${layout.toUpperCase()}: Navigating directly to ${directUrl}`)
@@ -132,6 +155,12 @@ export class EnhancedScreenshotService {
console.log(`${layout.toUpperCase()}: Successfully navigated to layout`)
// Update navigation progress when first session completes navigation
if (sessionId && index === 0) {
progressTracker.updateStep(sessionId, 'navigation', 'completed', 'Chart navigation successful')
progressTracker.updateStep(sessionId, 'loading', 'active', 'Loading chart data and indicators...')
}
// Progressive loading strategy: shorter initial wait, then chart-specific wait
console.log(`${layout.toUpperCase()}: Initial page stabilization (2s)...`)
await new Promise(resolve => setTimeout(resolve, 2000))
@@ -171,6 +200,12 @@ export class EnhancedScreenshotService {
await new Promise(resolve => setTimeout(resolve, 3000))
}
// Update loading progress when first session completes loading
if (sessionId && index === 0) {
progressTracker.updateStep(sessionId, 'loading', 'completed', 'Chart data loaded successfully')
progressTracker.updateStep(sessionId, 'capture', 'active', 'Capturing screenshots...')
}
// Take screenshot with better error handling
const filename = `${config.symbol}_${config.timeframe}_${layout}_${timestamp}.png`
console.log(`📸 Taking ${layout} screenshot: ${filename}`)
@@ -237,11 +272,27 @@ export class EnhancedScreenshotService {
}
})
if (sessionId) {
progressTracker.updateStep(sessionId, 'capture', 'completed', `Captured ${screenshotFiles.length}/${layoutsToCapture.length} screenshots`)
}
console.log(`\n🎯 Parallel capture completed: ${screenshotFiles.length}/${layoutsToCapture.length} screenshots`)
return screenshotFiles
} catch (error) {
console.error('Enhanced parallel screenshot capture failed:', error)
if (sessionId) {
// Mark the current active step as error
const progress = progressTracker.getProgress(sessionId)
if (progress) {
const activeStep = progress.steps.find(step => step.status === 'active')
if (activeStep) {
progressTracker.updateStep(sessionId, activeStep.id, 'error', error instanceof Error ? error.message : 'Unknown error')
}
}
}
throw error
}
}