Skip to content

Cursor#4

Merged
chpeu merged 6 commits into
claude2from
cursor
Nov 10, 2025
Merged

Cursor#4
chpeu merged 6 commits into
claude2from
cursor

Conversation

@chpeu

@chpeu chpeu commented Nov 10, 2025

Copy link
Copy Markdown
Owner

PR Type

Enhancement, Bug fix


Description

  • Complete migration from Socket.IO to native WebSocket implementation

  • Removed all Socket.IO dependencies and legacy fallback code

  • Added bidirectional configuration parameter synchronization between frontend and backend

  • Implemented WebSocket-based state management with automatic reconnection and heartbeat


Diagram Walkthrough

flowchart LR
  A["Socket.IO<br/>Legacy Code"] -->|"Remove"| B["Native WebSocket<br/>Implementation"]
  C["Frontend Config<br/>Changes"] -->|"Sync via WS"| D["Backend Trading<br/>Config"]
  D -->|"Emit config_updated"| C
  E["Position Updates"] -->|"WebSocket Events"| F["Frontend State"]
  G["Scanner Events"] -->|"WebSocket Events"| F
  B -->|"Heartbeat +<br/>Reconnection"| H["Reliable<br/>Connection"]
Loading

File Walkthrough

Relevant files
Bug fix
2 files
dashboard.py
Remove Socket.IO legacy code and dependencies                       
+8/-27   
+page.svelte
Fix WebSocket type handling and add config update listener
+40/-3   
Enhancement
9 files
scanner.py
Replace Socket.IO with WebSocket manager                                 
+13/-7   
position_check_loop.py
Migrate position updates to native WebSocket                         
+9/-11   
scalability_refresh.py
Update top pairs emission to WebSocket native                       
+3/-3     
scanner_loop.py
Remove Socket.IO fallback from scanner events                       
+3/-13   
main.py
Add bidirectional config parameter synchronization             
+141/-0 
SettingsPanel.svelte
Listen to backend config updates via WebSocket                     
+49/-1   
VariablesPanel.svelte
Implement bidirectional config synchronization listener   
+21/-4   
websocket-impl.ts
New native WebSocket implementation with bidirectional support
+302/-0 
websocket.ts
Refactor as re-export wrapper for websocket-impl                 
+28/-421
Dependencies
2 files
package.json
Remove Socket.IO client dependency                                             
+1/-2     
requirements.txt
Remove Socket.IO server dependencies                                         
+3/-2     

@chpeu chpeu merged commit f641faf into claude2 Nov 10, 2025
@qodo-code-review

Copy link
Copy Markdown

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Unreliable heartbeat reconnection

Description: Heartbeat logic can force-close the WebSocket after missing a pong using an
interval-derived comparison that may be unreliable across tab sleep or throttling,
potentially causing repeated reconnect storms and resource exhaustion in backgrounded
browsers.
websocket-impl.ts [235-246]

Referred Code
    this.stopHeartbeat(); // S'assurer qu'il n'y a qu'un seul intervalle
    this.pingInterval = window.setInterval(() => {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            this.sendRaw(JSON.stringify({ type: 'ping' }));
            // Si pas de pong en retour, considérer comme déconnecté
            if (Date.now() - this.lastPing > (this.pingInterval as number) * 2) {
                console.warn('⚠️ Pas de pong reçu, reconnexion forcée.');
                this.ws.close(); // Force la reconnexion via onclose
            }
        }
    }, 10000); // Envoyer un ping toutes les 10 secondes
}
Config data exposure

Description: Emitting 'config_updated' over WebSocket with the entire 'updated' dict may leak sensitive
configuration if any secret-like fields are added in the future; ensure strict
allow-listing of emitted config keys.
main.py [2485-2488]

Referred Code
await ws_manager.emit('config_updated', {
    'updated': updated,
    'timestamp': time.time()
})
Insecure WS trust assumptions

Description: The component prioritizes loading configuration via WebSocket without authentication
context shown, which could allow an attacker controlling a WS endpoint (through DNS or
mixed content misconfig) to influence client settings; ensure WS is same-origin, secure
(wss), and authenticated.
SettingsPanel.svelte [41-63]

Referred Code
const { getWebSocket, sendRequestViaWS } = await import('$lib/utils/websocket');
const ws = getWebSocket();
if (ws && ws.connected) {
	try {
		const stateData = await sendRequestViaWS('state', {});
		if (stateData && stateData.config) {
			backendConfig = stateData.config;
			// ✅ Synchroniser les paramètres qui existent dans le backend
			if (stateData.config.sl_percent !== undefined) {
				updateSetting('stopLossPercent', stateData.config.sl_percent);
			}
			if (stateData.config.tp_percent !== undefined) {
				updateSetting('takeProfitPercent', stateData.config.tp_percent);
			}
			if (stateData.config.trailing_trigger_pnl !== undefined) {
				updateSetting('trailingStopPercent', stateData.config.trailing_trigger_pnl);
			}
			return;
		}
	} catch (wsErr) {
		console.warn('⚠️ Erreur chargement config via WebSocket, fallback REST:', wsErr);


 ... (clipped 2 lines)
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Missing audit context: New config-changing commands emit events and some logs but do not consistently include
authenticated user identity or sufficient context to reconstruct who performed critical
changes.

Referred Code
# 🔥 BIDIRECTIONNEL: Émettre événement de mise à jour de config pour synchroniser le frontend
await ws_manager.emit('config_updated', {
    'updated': updated,
    'timestamp': time.time()
})

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Input validation gaps: The new config update branches cast incoming params with float() and bool() without
guarding against invalid types or missing keys, which may raise unhandled ValueError and
lack per-field error responses.

Referred Code
    val = float(params['escalier_level1_pnl'])
    val = max(0.0, min(5.0, val))  # Clamp 0.0-5.0%
    TRADING_CONFIG['escalier_level1_pnl'] = val
    updated['escalier_level1_pnl'] = val

if 'escalier_level1_size' in params:
    val = float(params['escalier_level1_size'])
    val = max(0.0, min(100.0, val))  # Clamp 0-100%
    TRADING_CONFIG['escalier_level1_size'] = val
    updated['escalier_level1_size'] = val

if 'escalier_level2_pnl' in params:
    val = float(params['escalier_level2_pnl'])
    val = max(0.0, min(5.0, val))
    TRADING_CONFIG['escalier_level2_pnl'] = val
    updated['escalier_level2_pnl'] = val

if 'escalier_level2_size' in params:
    val = float(params['escalier_level2_size'])
    val = max(0.0, min(100.0, val))
    TRADING_CONFIG['escalier_level2_size'] = val


 ... (clipped 54 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Trusts WS state: The UI directly applies backend-sent config values over local settings without schema
validation, which could propagate malformed or unauthorized data if the WS stream is
compromised.

Referred Code
if (stateData.config.sl_percent !== undefined) {
	updateSetting('stopLossPercent', stateData.config.sl_percent);
}
if (stateData.config.tp_percent !== undefined) {
	updateSetting('takeProfitPercent', stateData.config.tp_percent);
}
if (stateData.config.trailing_trigger_pnl !== undefined) {
	updateSetting('trailingStopPercent', stateData.config.trailing_trigger_pnl);
}

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review

Copy link
Copy Markdown

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Missing audit logs: New configuration mutation commands add many critical changes but only some paths call
add_log, and several updates (e.g., numerous TRADING_CONFIG flags) lack explicit audit
logging including user identity and outcome.

Referred Code
# 🔥 BIDIRECTIONNEL: Patterns Techniques (use_breakout, use_snr, use_wick, use_divergence)
if 'use_breakout' in params:
    TRADING_CONFIG['use_breakout'] = bool(params['use_breakout'])
    updated['use_breakout'] = TRADING_CONFIG['use_breakout']

if 'use_snr' in params:
    TRADING_CONFIG['use_snr'] = bool(params['use_snr'])
    updated['use_snr'] = TRADING_CONFIG['use_snr']

if 'use_wick' in params:
    TRADING_CONFIG['use_wick'] = bool(params['use_wick'])
    updated['use_wick'] = TRADING_CONFIG['use_wick']

if 'use_divergence' in params:
    TRADING_CONFIG['use_divergence'] = bool(params['use_divergence'])
    updated['use_divergence'] = TRADING_CONFIG['use_divergence']

# 🔥 BIDIRECTIONNEL: Patterns de Bougies
if 'use_engulfing' in params:
    TRADING_CONFIG['use_engulfing'] = bool(params['use_engulfing'])
    updated['use_engulfing'] = TRADING_CONFIG['use_engulfing']


 ... (clipped 119 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Reconnect edge cases: The WebSocket reconnection and heartbeat logic lacks explicit timeouts on command/request
promises and may leave pending callbacks on prolonged disconnects, risking silent
failures.

Referred Code
private scheduleReconnect(): void {
    if (this.isReconnecting) return;

    this.isReconnecting = true;
    this.reconnectTimeout = window.setTimeout(() => {
        if (this.reconnectAttempts < this.maxReconnectAttempts) {
            this.reconnectAttempts++;
            console.log(`🔄 Tentative de reconnexion WebSocket #${this.reconnectAttempts}...`);
            this.connect();
        } else {
            console.error('❌ Nombre maximal de tentatives de reconnexion WebSocket atteint.');
            this.emit('error', new Error('Max reconnect attempts reached'));
        }
        this.isReconnecting = false;
    }, this.reconnectDelay * Math.pow(2, this.reconnectAttempts)); // Backoff exponentiel
}

private startHeartbeat(): void {
    this.stopHeartbeat(); // S'assurer qu'il n'y a qu'un seul intervalle
    this.pingInterval = window.setInterval(() => {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {


 ... (clipped 10 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Verbose logging: Console logs print full backend configuration updates which may include sensitive
settings, potentially exposing them in client logs.

Referred Code
console.log('🔄 Config mise à jour depuis backend dans SettingsPanel:', data.updated);
// Synchroniser les paramètres avec les changements du backend
if (data.updated) {
	if (data.updated.sl_percent !== undefined) {
		updateSetting('stopLossPercent', data.updated.sl_percent);
	}
	if (data.updated.tp_percent !== undefined) {
		updateSetting('takeProfitPercent', data.updated.tp_percent);
	}
	if (data.updated.trailing_trigger_pnl !== undefined) {
		updateSetting('trailingStopPercent', data.updated.trailing_trigger_pnl);
	}
	// Mettre à jour backendConfig pour affichage
	backendConfig = { ...backendConfig, ...data.updated };
}

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Weak type coercion: Numerous TRADING_CONFIG updates cast incoming params directly with float()/bool() without
explicit schema validation or authentication context, risking invalid or unauthorized
changes.

Referred Code
# 🔥 BIDIRECTIONNEL: Patterns Techniques (use_breakout, use_snr, use_wick, use_divergence)
if 'use_breakout' in params:
    TRADING_CONFIG['use_breakout'] = bool(params['use_breakout'])
    updated['use_breakout'] = TRADING_CONFIG['use_breakout']

if 'use_snr' in params:
    TRADING_CONFIG['use_snr'] = bool(params['use_snr'])
    updated['use_snr'] = TRADING_CONFIG['use_snr']

if 'use_wick' in params:
    TRADING_CONFIG['use_wick'] = bool(params['use_wick'])
    updated['use_wick'] = TRADING_CONFIG['use_wick']

if 'use_divergence' in params:
    TRADING_CONFIG['use_divergence'] = bool(params['use_divergence'])
    updated['use_divergence'] = TRADING_CONFIG['use_divergence']

# 🔥 BIDIRECTIONNEL: Patterns de Bougies
if 'use_engulfing' in params:
    TRADING_CONFIG['use_engulfing'] = bool(params['use_engulfing'])
    updated['use_engulfing'] = TRADING_CONFIG['use_engulfing']


 ... (clipped 109 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review

Copy link
Copy Markdown

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix an undefined variable error

Define the global variable _ws_manager and add a set_websocket_manager function
in core/callbacks/position_check_loop.py to prevent a NameError.

core/callbacks/position_check_loop.py [167-169]

 # 🔥 MIGRATION COMPLÈTE: Utiliser WebSocket natif uniquement
-if _ws_manager:
-    await _ws_manager.emit('position_closed', result)
+if _sio: # Using _sio as a placeholder for the corrected _ws_manager
+    await _sio.emit('position_closed', result)
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies that the variable _ws_manager is used without being defined in the file's scope, which will cause a NameError and break a core functionality.

High
Fix incorrect heartbeat timeout logic

In the startHeartbeat function, use the hardcoded interval duration (10000ms)
for the timeout calculation instead of the interval ID this.pingInterval.

frontend/src/lib/utils/websocket-impl.ts [234-246]

 private startHeartbeat(): void {
     this.stopHeartbeat(); // S'assurer qu'il n'y a qu'un seul intervalle
+    const pingFrequency = 10000; // Envoyer un ping toutes les 10 secondes
     this.pingInterval = window.setInterval(() => {
         if (this.ws && this.ws.readyState === WebSocket.OPEN) {
             this.sendRaw(JSON.stringify({ type: 'ping' }));
             // Si pas de pong en retour, considérer comme déconnecté
-            if (Date.now() - this.lastPing > (this.pingInterval as number) * 2) {
+            if (Date.now() - this.lastPing > pingFrequency * 2) {
                 console.warn('⚠️ Pas de pong reçu, reconnexion forcée.');
                 this.ws.close(); // Force la reconnexion via onclose
             }
         }
-    }, 10000); // Envoyer un ping toutes les 10 secondes
+    }, pingFrequency);
 }
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a bug where the interval ID is used for timeout calculation instead of the interval duration, which would cause faulty connection health checks.

Medium
High-level
Consider using a library for WebSocket management

The new custom WebSocket client in websocket-impl.ts is complex and reinvents
common features. To reduce complexity and improve reliability, consider using a
dedicated library for WebSocket management.

Examples:

frontend/src/lib/utils/websocket-impl.ts [27-302]
export class BidirectionalWebSocket {
    private baseUrl: string;
    private url: string;
    private ws: WebSocket | null = null;
    private reconnectAttempts: number = 0;
    private maxReconnectAttempts: number = 10;
    private reconnectDelay: number = 1000;
    private messageQueue: any[] = [];
    private commandCallbacks: Map<number, CommandCallback> = new Map();
    private commandIdCounter: number = 0;

 ... (clipped 266 lines)

Solution Walkthrough:

Before:

// In frontend/src/lib/utils/websocket-impl.ts
export class BidirectionalWebSocket {
    private ws: WebSocket | null = null;
    private messageQueue: any[] = [];
    private commandCallbacks: Map<number, CommandCallback> = new Map();
    
    constructor(...) { ... }
    connect(): void { ... }
    private setupEventHandlers(): void { ... } // Manages onopen, onmessage, onclose, onerror
    private sendRaw(message: string): void { ... }
    private flushQueue(): void { ... }
    sendCommand(...): Promise<any> { ... } // Manual request/response logic
    private scheduleReconnect(): void { ... } // Manual reconnect logic with exponential backoff
    private startHeartbeat(): void { ... } // Manual ping/pong logic
    ...
}

After:

// Using a library like 'reconnecting-websocket'
import ReconnectingWebSocket from 'reconnecting-websocket';

// Simplified wrapper class
export class WebSocketManager {
    private ws: ReconnectingWebSocket;
    private commandCallbacks = new Map();

    constructor(url) {
        this.ws = new ReconnectingWebSocket(url);
        this.ws.onmessage = this.handleMessage.bind(this);
    }

    // Much of the complex logic for reconnect, queueing, etc. is handled by the library.
    
    sendCommand(command, params) {
        // Simplified request/response logic built on top of the library
    }
    ...
}
Suggestion importance[1-10]: 6

__

Why: The suggestion makes a valid architectural point about the complexity and maintenance burden of the custom WebSocket client, proposing a simpler, more robust solution using a library.

Low
  • More

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant