fix: Complete automation v2 page runtime error fixes
- Fixed ES modules error by converting automation-with-learning-v2.js to pure ES6 - Fixed singleton pattern in automation-singleton.js for proper async handling - Fixed EnhancedAILearningPanel to handle recommendation objects correctly - Updated API routes to use correct import paths (../../../../lib/) - Created proper db.js utility with ES6 exports - Fixed simplified-stop-loss-learner imports and exports Automation v2 page now loads without errors AI learning system fully integrated and operational Learning status API working with detailed reports Recommendation rendering fixed for object structure
This commit is contained in:
@@ -5,7 +5,7 @@ import { NextResponse } from 'next/server';
|
|||||||
async function getAutomationInstance() {
|
async function getAutomationInstance() {
|
||||||
try {
|
try {
|
||||||
// Import the singleton automation instance
|
// Import the singleton automation instance
|
||||||
const { getAutomationInstance } = await import('../../../lib/automation-singleton.js');
|
const { getAutomationInstance } = await import('../../../../lib/automation-singleton.js');
|
||||||
return getAutomationInstance();
|
return getAutomationInstance();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Could not get automation instance:', error);
|
console.error('❌ Could not get automation instance:', error);
|
||||||
@@ -44,9 +44,9 @@ export async function GET() {
|
|||||||
success: true,
|
success: true,
|
||||||
learningSystem: {
|
learningSystem: {
|
||||||
...learningStatus,
|
...learningStatus,
|
||||||
automationRunning: automationStatus.isRunning,
|
automationRunning: automationStatus.isActive || automationStatus.isRunning,
|
||||||
totalCycles: automationStatus.stats.totalCycles,
|
totalCycles: automationStatus.totalCycles || automationStatus.stats?.totalCycles || 0,
|
||||||
totalTrades: automationStatus.stats.totalTrades
|
totalTrades: automationStatus.totalTrades || automationStatus.stats?.totalTrades || 0
|
||||||
},
|
},
|
||||||
visibility: {
|
visibility: {
|
||||||
decisionTrackingActive: learningStatus.activeDecisions > 0,
|
decisionTrackingActive: learningStatus.activeDecisions > 0,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { NextResponse } from 'next/server';
|
|||||||
// Import singleton automation manager
|
// Import singleton automation manager
|
||||||
async function getAutomationInstance() {
|
async function getAutomationInstance() {
|
||||||
try {
|
try {
|
||||||
const { getAutomationInstance } = await import('../../../lib/automation-singleton.js');
|
const { getAutomationInstance } = await import('../../../../lib/automation-singleton.js');
|
||||||
return await getAutomationInstance();
|
return await getAutomationInstance();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Could not get automation instance:', error);
|
console.error('❌ Could not get automation instance:', error);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { NextResponse } from 'next/server';
|
|||||||
// Import singleton automation manager
|
// Import singleton automation manager
|
||||||
async function getAutomationInstance() {
|
async function getAutomationInstance() {
|
||||||
try {
|
try {
|
||||||
const { getAutomationInstance } = await import('../../../lib/automation-singleton.js');
|
const { getAutomationInstance } = await import('../../../../lib/automation-singleton.js');
|
||||||
return await getAutomationInstance();
|
return await getAutomationInstance();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Could not get automation instance:', error);
|
console.error('❌ Could not get automation instance:', error);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Import singleton automation manager
|
// Import singleton automation manager
|
||||||
async function getAutomationInstance() {
|
async function getAutomationInstance() {
|
||||||
try {
|
try {
|
||||||
const { getAutomationInstance } = await import('../../../lib/automation-singleton.js');
|
const { getAutomationInstance } = await import('../../../../lib/automation-singleton.js');
|
||||||
return await getAutomationInstance();
|
return await getAutomationInstance();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Could not get automation instance:', error);
|
console.error('❌ Could not get automation instance:', error);
|
||||||
|
|||||||
@@ -17,7 +17,11 @@ interface LearningData {
|
|||||||
thresholds?: any;
|
thresholds?: any;
|
||||||
confidenceLevel?: number;
|
confidenceLevel?: number;
|
||||||
};
|
};
|
||||||
recommendations?: string[];
|
recommendations?: Array<{
|
||||||
|
type: string;
|
||||||
|
message: string;
|
||||||
|
priority: string;
|
||||||
|
} | string>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
visibility?: {
|
visibility?: {
|
||||||
@@ -47,15 +51,43 @@ const EnhancedAILearningPanel = () => {
|
|||||||
const learningData = await learningResponse.json();
|
const learningData = await learningResponse.json();
|
||||||
const statusData = await statusResponse.json();
|
const statusData = await statusResponse.json();
|
||||||
|
|
||||||
setLearningData({
|
// Ensure we have a proper data structure even if APIs return errors
|
||||||
...learningData,
|
const safeData = {
|
||||||
|
learningSystem: learningData.learningSystem || {
|
||||||
|
enabled: false,
|
||||||
|
message: learningData.message || 'Learning system not available',
|
||||||
|
activeDecisions: 0
|
||||||
|
},
|
||||||
|
visibility: learningData.visibility || {
|
||||||
|
decisionTrackingActive: false,
|
||||||
|
learningDatabaseConnected: false,
|
||||||
|
aiEnhancementsActive: false,
|
||||||
|
lastUpdateTime: new Date().toISOString()
|
||||||
|
},
|
||||||
automationStatus: statusData
|
automationStatus: statusData
|
||||||
});
|
};
|
||||||
|
|
||||||
|
setLearningData(safeData);
|
||||||
setError(null);
|
setError(null);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error fetching learning status:', err);
|
console.error('Error fetching learning status:', err);
|
||||||
setError(err instanceof Error ? err.message : 'Unknown error');
|
setError(err instanceof Error ? err.message : 'Unknown error');
|
||||||
|
|
||||||
|
// Set default data structure on error
|
||||||
|
setLearningData({
|
||||||
|
learningSystem: {
|
||||||
|
enabled: false,
|
||||||
|
message: 'Failed to fetch learning status',
|
||||||
|
activeDecisions: 0
|
||||||
|
},
|
||||||
|
visibility: {
|
||||||
|
decisionTrackingActive: false,
|
||||||
|
learningDatabaseConnected: false,
|
||||||
|
aiEnhancementsActive: false,
|
||||||
|
lastUpdateTime: new Date().toISOString()
|
||||||
|
},
|
||||||
|
automationStatus: null
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@@ -109,8 +141,23 @@ const EnhancedAILearningPanel = () => {
|
|||||||
|
|
||||||
const { learningSystem, visibility } = learningData;
|
const { learningSystem, visibility } = learningData;
|
||||||
|
|
||||||
|
// Safety check for learningSystem
|
||||||
|
if (!learningSystem) {
|
||||||
|
return (
|
||||||
|
<div className="bg-gradient-to-br from-gray-900/20 to-gray-800/20 rounded-xl p-6 border border-gray-500/30">
|
||||||
|
<div className="flex items-center space-x-3 mb-4">
|
||||||
|
<div className="w-3 h-3 bg-gray-500 rounded-full"></div>
|
||||||
|
<h3 className="text-lg font-semibold bg-gradient-to-r from-purple-400 to-blue-400 bg-clip-text text-transparent">
|
||||||
|
🧠 AI Learning System
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div className="text-gray-400">Loading learning system data...</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const renderLearningStatus = () => {
|
const renderLearningStatus = () => {
|
||||||
if (!learningSystem.enabled) {
|
if (!learningSystem || !learningSystem.enabled) {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
@@ -120,9 +167,9 @@ const EnhancedAILearningPanel = () => {
|
|||||||
|
|
||||||
<div className="bg-yellow-900/20 rounded-lg p-4 border border-yellow-500/30">
|
<div className="bg-yellow-900/20 rounded-lg p-4 border border-yellow-500/30">
|
||||||
<div className="text-yellow-300 text-sm">
|
<div className="text-yellow-300 text-sm">
|
||||||
{learningSystem.message || 'The AI learning system is not currently integrated with the automation.'}
|
{learningSystem?.message || 'The AI learning system is not currently integrated with the automation.'}
|
||||||
</div>
|
</div>
|
||||||
{learningSystem.recommendation && (
|
{learningSystem?.recommendation && (
|
||||||
<div className="text-yellow-400 text-sm mt-2 font-medium">
|
<div className="text-yellow-400 text-sm mt-2 font-medium">
|
||||||
💡 {learningSystem.recommendation}
|
💡 {learningSystem.recommendation}
|
||||||
</div>
|
</div>
|
||||||
@@ -145,7 +192,7 @@ const EnhancedAILearningPanel = () => {
|
|||||||
<span className="text-green-400 font-medium">AI Learning Active</span>
|
<span className="text-green-400 font-medium">AI Learning Active</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{learningSystem.report && (
|
{learningSystem?.report && (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
<div className="bg-blue-900/20 rounded-lg p-4 border border-blue-500/30">
|
<div className="bg-blue-900/20 rounded-lg p-4 border border-blue-500/30">
|
||||||
<div className="text-blue-300 text-sm font-medium">Total Decisions</div>
|
<div className="text-blue-300 text-sm font-medium">Total Decisions</div>
|
||||||
@@ -192,15 +239,15 @@ const EnhancedAILearningPanel = () => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<div className={`w-2 h-2 rounded-full ${(learningSystem.activeDecisions || 0) > 0 ? 'bg-blue-500' : 'bg-gray-500'}`}></div>
|
<div className={`w-2 h-2 rounded-full ${(learningSystem?.activeDecisions || 0) > 0 ? 'bg-blue-500' : 'bg-gray-500'}`}></div>
|
||||||
<span className={(learningSystem.activeDecisions || 0) > 0 ? 'text-blue-400' : 'text-gray-400'}>
|
<span className={(learningSystem?.activeDecisions || 0) > 0 ? 'text-blue-400' : 'text-gray-400'}>
|
||||||
Active Decisions ({learningSystem.activeDecisions || 0})
|
Active Decisions ({learningSystem?.activeDecisions || 0})
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{learningSystem.report?.insights && (
|
{learningSystem?.report?.insights && (
|
||||||
<div className="bg-purple-900/20 rounded-lg p-4 border border-purple-500/30">
|
<div className="bg-purple-900/20 rounded-lg p-4 border border-purple-500/30">
|
||||||
<div className="text-purple-300 text-sm font-medium mb-2">🎯 Learning Insights</div>
|
<div className="text-purple-300 text-sm font-medium mb-2">🎯 Learning Insights</div>
|
||||||
<div className="text-sm text-gray-300">
|
<div className="text-sm text-gray-300">
|
||||||
@@ -214,13 +261,13 @@ const EnhancedAILearningPanel = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{learningSystem.report?.recommendations && learningSystem.report.recommendations.length > 0 && (
|
{learningSystem?.report?.recommendations && learningSystem.report.recommendations.length > 0 && (
|
||||||
<div className="bg-yellow-900/20 rounded-lg p-4 border border-yellow-500/30">
|
<div className="bg-yellow-900/20 rounded-lg p-4 border border-yellow-500/30">
|
||||||
<div className="text-yellow-300 text-sm font-medium mb-2">💡 AI Recommendations</div>
|
<div className="text-yellow-300 text-sm font-medium mb-2">💡 AI Recommendations</div>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
{learningSystem.report.recommendations.map((rec: string, index: number) => (
|
{learningSystem.report.recommendations.map((rec: any, index: number) => (
|
||||||
<div key={index} className="text-sm text-yellow-400">
|
<div key={index} className="text-sm text-yellow-400">
|
||||||
• {rec}
|
• {typeof rec === 'string' ? rec : rec.message || rec.type || 'No message'}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -234,7 +281,7 @@ const EnhancedAILearningPanel = () => {
|
|||||||
<div className="bg-gradient-to-br from-purple-900/20 to-blue-900/20 rounded-xl p-6 border border-purple-500/30">
|
<div className="bg-gradient-to-br from-purple-900/20 to-blue-900/20 rounded-xl p-6 border border-purple-500/30">
|
||||||
<div className="flex items-center justify-between mb-6">
|
<div className="flex items-center justify-between mb-6">
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
<div className={`w-3 h-3 rounded-full ${learningSystem.enabled ? 'bg-green-500 animate-pulse' : 'bg-yellow-500'}`}></div>
|
<div className={`w-3 h-3 rounded-full ${learningSystem?.enabled ? 'bg-green-500 animate-pulse' : 'bg-yellow-500'}`}></div>
|
||||||
<h3 className="text-lg font-semibold bg-gradient-to-r from-purple-400 to-blue-400 bg-clip-text text-transparent">
|
<h3 className="text-lg font-semibold bg-gradient-to-r from-purple-400 to-blue-400 bg-clip-text text-transparent">
|
||||||
🧠 AI Learning System
|
🧠 AI Learning System
|
||||||
</h3>
|
</h3>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ let automationInstance = null;
|
|||||||
async function createAutomationInstance() {
|
async function createAutomationInstance() {
|
||||||
try {
|
try {
|
||||||
// Try to import the learning-enhanced automation first
|
// Try to import the learning-enhanced automation first
|
||||||
const AutomationWithLearning = require('./automation-with-learning-v2.js');
|
const AutomationWithLearning = (await import('./automation-with-learning-v2.js')).default;
|
||||||
console.log('✅ Creating automation instance with AI learning system');
|
console.log('✅ Creating automation instance with AI learning system');
|
||||||
return new AutomationWithLearning();
|
return new AutomationWithLearning();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -23,24 +23,24 @@ async function createAutomationInstance() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAutomationInstance() {
|
async function getAutomationInstance() {
|
||||||
if (!automationInstance) {
|
if (!automationInstance) {
|
||||||
automationInstance = createAutomationInstance();
|
automationInstance = await createAutomationInstance();
|
||||||
}
|
}
|
||||||
return automationInstance;
|
return automationInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetAutomationInstance() {
|
async function resetAutomationInstance() {
|
||||||
if (automationInstance) {
|
if (automationInstance) {
|
||||||
console.log('🔄 Resetting automation instance');
|
console.log('🔄 Resetting automation instance');
|
||||||
if (typeof automationInstance.stop === 'function') {
|
if (typeof automationInstance.stop === 'function') {
|
||||||
automationInstance.stop();
|
await automationInstance.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
automationInstance = null;
|
automationInstance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
export {
|
||||||
getAutomationInstance,
|
getAutomationInstance,
|
||||||
resetAutomationInstance
|
resetAutomationInstance
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -445,4 +445,4 @@ class AutomationWithLearning {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = AutomationWithLearning;
|
export default AutomationWithLearning;
|
||||||
|
|||||||
42
lib/db.js
42
lib/db.js
@@ -1,46 +1,12 @@
|
|||||||
/**
|
import { PrismaClient } from '@prisma/client';
|
||||||
* Database utility for Prisma client
|
|
||||||
*
|
|
||||||
* Provides a global Prisma instance to avoid connection issues
|
|
||||||
*/
|
|
||||||
|
|
||||||
const { PrismaClient } = require('@prisma/client');
|
let prisma;
|
||||||
|
|
||||||
// Global Prisma instance
|
function getDB() {
|
||||||
let prisma = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the global Prisma database instance
|
|
||||||
*/
|
|
||||||
async function getDB() {
|
|
||||||
if (!prisma) {
|
if (!prisma) {
|
||||||
prisma = new PrismaClient();
|
prisma = new PrismaClient();
|
||||||
|
|
||||||
// Test the connection
|
|
||||||
try {
|
|
||||||
await prisma.$connect();
|
|
||||||
console.log('✅ Database connection established');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ Database connection failed:', error.message);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return prisma;
|
return prisma;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export { getDB };
|
||||||
* Close the database connection
|
|
||||||
*/
|
|
||||||
async function closeDB() {
|
|
||||||
if (prisma) {
|
|
||||||
await prisma.$disconnect();
|
|
||||||
prisma = null;
|
|
||||||
console.log('✅ Database connection closed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
getDB,
|
|
||||||
closeDB
|
|
||||||
};
|
|
||||||
@@ -5,8 +5,8 @@
|
|||||||
* without complex statistical analysis.
|
* without complex statistical analysis.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { PrismaClient } = require('@prisma/client');
|
import { PrismaClient } from '@prisma/client';
|
||||||
const getDB = require('./database-util');
|
import { getDB } from './db.js';
|
||||||
|
|
||||||
class SimplifiedStopLossLearner {
|
class SimplifiedStopLossLearner {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -527,4 +527,4 @@ class SimplifiedStopLossLearner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = SimplifiedStopLossLearner;
|
export { SimplifiedStopLossLearner };
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user