From 820fc614bb5e4ba3dac727f2d5dfe68995b233fc Mon Sep 17 00:00:00 2001 From: Chandini Date: Mon, 22 Sep 2025 10:24:28 +0530 Subject: [PATCH] backend changes --- config/urls.js | 8 +- docker-compose.yml | 1 + services/api-gateway/.env .prod | 4 +- services/api-gateway/src/server.js | 79 ++++- services/requirement-processor/src/main.py | 69 +++++ services/template-manager/package-lock.json | 111 +++++++ services/template-manager/package.json | 1 + services/template-manager/src/ai-service.js | 289 +++++++++++++++++ services/template-manager/src/app.js | 327 +++++++++++++++++++- 9 files changed, 880 insertions(+), 9 deletions(-) create mode 100644 services/template-manager/src/ai-service.js diff --git a/config/urls.js b/config/urls.js index 7e1afd9..0631516 100644 --- a/config/urls.js +++ b/config/urls.js @@ -6,14 +6,14 @@ // ======================================== // LIVE PRODUCTION URLS (Currently Active) // ======================================== -const FRONTEND_URL = 'https://dashboard.codenuk.com'; -const BACKEND_URL = 'https://backend.codenuk.com'; +// const FRONTEND_URL = 'https://dashboard.codenuk.com'; +// const BACKEND_URL = 'https://backend.codenuk.com'; // ======================================== // LOCAL DEVELOPMENT URLS // ======================================== -// const FRONTEND_URL = 'http://192.168.1.16:3001'; -// const BACKEND_URL = 'http://192.168.1.16:8000'; +const FRONTEND_URL = 'http://192.168.1.17:3001'; +const BACKEND_URL = 'http://192.168.1.17:8000'; // ======================================== // CORS CONFIGURATION (Auto-generated) diff --git a/docker-compose.yml b/docker-compose.yml index e2127e9..96381b9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -553,6 +553,7 @@ services: - REDIS_PASSWORD=redis_secure_2024 - NODE_ENV=development - JWT_ACCESS_SECRET=access-secret-key-2024-tech4biz-secure_pipeline_2024 + - CLAUDE_API_KEY=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 networks: - pipeline_network depends_on: diff --git a/services/api-gateway/.env .prod b/services/api-gateway/.env .prod index 7e542a5..51f650b 100644 --- a/services/api-gateway/.env .prod +++ b/services/api-gateway/.env .prod @@ -28,10 +28,10 @@ RABBITMQ_USER=pipeline_admin RABBITMQ_PASSWORD=secure_rabbitmq_password # CORS -FRONTEND_URL=http://192.168.1.16:3001 +FRONTEND_URL=http://192.168.1.17:3001 # CORS Configuration -CORS_ORIGIN=http://192.168.1.16:3001 +CORS_ORIGIN=http://192.168.1.17:3001 CORS_METHODS=GET,POST,PUT,DELETE,PATCH,OPT IONS CORS_CREDENTIALS=true \ No newline at end of file diff --git a/services/api-gateway/src/server.js b/services/api-gateway/src/server.js index 99f2dd0..9162b07 100644 --- a/services/api-gateway/src/server.js +++ b/services/api-gateway/src/server.js @@ -55,7 +55,7 @@ global.io = io; // Service targets configuration const serviceTargets = { USER_AUTH_URL: process.env.USER_AUTH_URL || 'http://localhost:8011', - TEMPLATE_MANAGER_URL: process.env.TEMPLATE_MANAGER_URL || 'http://localhost:8009', + TEMPLATE_MANAGER_URL: process.env.TEMPLATE_MANAGER_URL || 'http://192.168.1.17:8009', GIT_INTEGRATION_URL: process.env.GIT_INTEGRATION_URL || 'http://localhost:8012', REQUIREMENT_PROCESSOR_URL: process.env.REQUIREMENT_PROCESSOR_URL || 'http://localhost:8001', TECH_STACK_SELECTOR_URL: process.env.TECH_STACK_SELECTOR_URL || 'http://localhost:8002', @@ -93,6 +93,10 @@ app.use(helmet({ // CORS is already configured via corsMiddleware above +// Global body parser for all routes - MUST be first +app.use(express.json({ limit: '10mb' })); +app.use(express.urlencoded({ extended: true })); + // Request parsing middleware - only for non-proxy routes app.use('/api/websocket', express.json({ limit: '10mb' })); app.use('/api/gateway', express.json({ limit: '10mb' })); @@ -102,6 +106,7 @@ app.use('/api/features', express.json({ limit: '10mb' })); app.use('/api/admin', express.json({ limit: '10mb' })); app.use('/api/github', express.json({ limit: '10mb' })); app.use('/api/mockup', express.json({ limit: '10mb' })); +app.use('/api/ai', express.json({ limit: '10mb' })); app.use('/health', express.json({ limit: '10mb' })); // Trust proxy for accurate IP addresses @@ -434,7 +439,77 @@ app.use('/api/admin', } ); -// Requirement Processor Service +// AI Feature Analysis - Specific route for analyze-feature endpoint +console.log('🔧 Registering /api/ai/analyze-feature proxy route...'); +app.use('/api/ai/analyze-feature', + createServiceLimiter(300), + // Allow unauthenticated access for AI analysis (public feature in builder) + (req, res, next) => { + console.log(`🤖 [AI ANALYSIS PROXY] ${req.method} ${req.originalUrl}`); + console.log(`📦 [AI ANALYSIS PROXY] Request body type:`, typeof req.body); + console.log(`📦 [AI ANALYSIS PROXY] Request body:`, JSON.stringify(req.body, null, 2)); + console.log(`📦 [AI ANALYSIS PROXY] Content-Type:`, req.headers['content-type']); + return next(); + }, + (req, res, next) => { + const templateManagerUrl = serviceTargets.TEMPLATE_MANAGER_URL; + // Map /api/requirements/analyze-feature to /api/analyze-feature in template-manager + const targetUrl = `${templateManagerUrl}/api/analyze-feature`; + console.log(`🔥 [AI ANALYSIS PROXY] ${req.method} ${req.originalUrl} → ${targetUrl}`); + + res.setTimeout(30000, () => { + console.error('❌ [AI ANALYSIS PROXY] Response timeout'); + if (!res.headersSent) { + res.status(504).json({ error: 'Gateway timeout', service: 'template-manager' }); + } + }); + + const options = { + method: req.method, + url: targetUrl, + headers: { + 'Content-Type': 'application/json', + 'User-Agent': 'API-Gateway/1.0', + 'Connection': 'keep-alive', + 'Authorization': req.headers.authorization, + 'X-User-ID': req.user?.id || req.user?.userId, + 'X-User-Role': req.user?.role, + }, + timeout: 25000, + validateStatus: () => true, + maxRedirects: 0 + }; + + if (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH') { + options.data = req.body || {}; + console.log(`📦 [AI ANALYSIS PROXY] Request body:`, JSON.stringify(req.body)); + } + + axios(options) + .then(response => { + console.log(`✅ [AI ANALYSIS PROXY] Response: ${response.status} for ${req.method} ${req.originalUrl}`); + if (!res.headersSent) { + res.status(response.status).json(response.data); + } + }) + .catch(error => { + console.error(`❌ [AI ANALYSIS PROXY ERROR]:`, error.message); + if (!res.headersSent) { + if (error.response) { + res.status(error.response.status).json(error.response.data); + } else { + res.status(502).json({ + error: 'AI analysis service unavailable', + message: error.code || error.message, + service: 'template-manager' + }); + } + } + }); + } +); + +// Requirement Processor Service - General routes (MUST come after specific routes) app.use('/api/requirements', createServiceLimiter(300), authMiddleware.verifyToken, diff --git a/services/requirement-processor/src/main.py b/services/requirement-processor/src/main.py index ffd632d..0bcc302 100644 --- a/services/requirement-processor/src/main.py +++ b/services/requirement-processor/src/main.py @@ -1396,6 +1396,75 @@ def extract_all_data(data: Dict[str, Any]) -> tuple[list, dict, dict]: return all_features, scale_info, complete_requirements + +async def intelligent_fallback_analysis(feature_name: str, description: str, requirements: list, project_type: str): + """Intelligent fallback analysis when Claude is not available""" + + # Analyze complexity based on keywords + complexity_indicators = { + "high": ["encryption", "hipaa", "compliance", "security", "integration", "real-time", "ai", "machine learning", "blockchain"], + "medium": ["crud", "database", "api", "authentication", "validation", "search", "filter"], + "low": ["display", "show", "view", "list", "basic"] + } + + text_to_analyze = f"{feature_name} {description} {' '.join(requirements)}".lower() + + complexity = "medium" # default + for level, keywords in complexity_indicators.items(): + if any(keyword in text_to_analyze for keyword in keywords): + complexity = level + break + + # Generate logical business rules based on project type and requirements + logic_rules = [] + + if project_type.lower() == "healthcare": + logic_rules.extend([ + "Only authorized caregivers can access patient data", + "All patient data access must be logged for HIPAA compliance", + "Patient data must be encrypted at rest and in transit" + ]) + + if "crud" in text_to_analyze or "manage" in text_to_analyze: + logic_rules.append("Users can only modify data they have created or been granted access to") + + if "patient" in text_to_analyze: + logic_rules.extend([ + "Patient information can only be accessed by assigned caregivers", + "All patient data modifications require audit trail" + ]) + + # Remove duplicates + logic_rules = list(set(logic_rules)) + + analysis = { + "feature_name": feature_name or "Enhanced Feature", + "complexity": complexity, + "logicRules": logic_rules, + "implementation_details": [ + f"Implement {feature_name} with proper validation", + "Add error handling and logging", + "Include unit and integration tests" + ], + "technical_requirements": [ + "Database schema design", + "API endpoint implementation", + "Frontend component development" + ], + "estimated_effort": "2-3 weeks" if complexity == "high" else "1-2 weeks", + "dependencies": ["User authentication", "Database setup"], + "api_endpoints": [f"POST /api/{feature_name.lower().replace(' ', '-')}", f"GET /api/{feature_name.lower().replace(' ', '-')}"], + "database_tables": [f"{feature_name.lower().replace(' ', '_')}_table"], + "confidence_score": 0.75 + } + + logger.info(f"✅ Fallback analysis completed: {complexity} complexity with {len(logic_rules)} logic rules") + + return { + "success": True, + "analysis": analysis + } + if __name__ == "__main__": import uvicorn diff --git a/services/template-manager/package-lock.json b/services/template-manager/package-lock.json index 02a715c..68fefb7 100644 --- a/services/template-manager/package-lock.json +++ b/services/template-manager/package-lock.json @@ -8,6 +8,7 @@ "name": "template-manager", "version": "1.0.0", "dependencies": { + "axios": "^1.12.2", "cors": "^2.8.5", "dotenv": "^16.0.3", "express": "^4.18.0", @@ -179,6 +180,23 @@ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -352,6 +370,18 @@ "node": ">=0.10.0" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -417,6 +447,15 @@ "ms": "2.0.0" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -577,6 +616,21 @@ "node": ">= 0.4" } }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -669,6 +723,42 @@ "node": ">= 0.8" } }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -804,6 +894,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -1429,6 +1534,12 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", diff --git a/services/template-manager/package.json b/services/template-manager/package.json index 5902f31..cca6c3a 100644 --- a/services/template-manager/package.json +++ b/services/template-manager/package.json @@ -10,6 +10,7 @@ "seed": "node src/seeders/seed.js" }, "dependencies": { + "axios": "^1.12.2", "cors": "^2.8.5", "dotenv": "^16.0.3", "express": "^4.18.0", diff --git a/services/template-manager/src/ai-service.js b/services/template-manager/src/ai-service.js new file mode 100644 index 0000000..125a9f3 --- /dev/null +++ b/services/template-manager/src/ai-service.js @@ -0,0 +1,289 @@ +const express = require('express'); +const cors = require('cors'); +const axios = require('axios'); + +const app = express(); +const PORT = process.env.PORT || 8009; + +// Claude API configuration +const CLAUDE_API_KEY = process.env.CLAUDE_API_KEY || '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'; +const CLAUDE_AVAILABLE = !!CLAUDE_API_KEY; + +// Middleware +app.use(cors({ + origin: "*", + credentials: true, + methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], + allowedHeaders: ['Content-Type', 'Authorization', 'X-User-ID', 'X-User-Role'] +})); +app.use(express.json({ limit: '10mb' })); +app.use(express.urlencoded({ extended: true })); + +// Health check endpoint +app.get('/health', (req, res) => { + res.status(200).json({ + status: 'healthy', + service: 'template-manager-ai', + version: '1.0.0', + timestamp: new Date().toISOString(), + uptime: process.uptime(), + features: { + ai_analysis: true + } + }); +}); + +// AI Feature Analysis endpoint +app.post('/api/analyze-feature', async (req, res) => { + try { + console.log('🤖 [Template Manager AI] AI Analysis request received'); + + const { featureName, description, requirements = [], projectType } = req.body; + + // Ensure requirements is always an array + const safeRequirements = Array.isArray(requirements) ? requirements : []; + + console.log('📋 [Template Manager AI] Analyzing feature:', featureName); + console.log('📋 [Template Manager AI] Project type:', projectType); + console.log('📋 [Template Manager AI] Requirements:', safeRequirements); + + let analysis; + + // Try Claude AI first if available + if (CLAUDE_AVAILABLE) { + try { + console.log('🤖 [Template Manager AI] Using Claude AI for analysis...'); + analysis = await analyzeWithClaude(featureName, description, safeRequirements, projectType); + } catch (claudeError) { + console.warn('⚠️ [Template Manager AI] Claude AI failed, falling back to rule-based analysis:', claudeError.message); + analysis = await analyzeWithRules(featureName, description, safeRequirements, projectType); + } + } else { + console.log('📋 [Template Manager AI] Using rule-based analysis (Claude not available)'); + analysis = await analyzeWithRules(featureName, description, safeRequirements, projectType); + } + + console.log('✅ [Template Manager AI] Analysis completed:', analysis.complexity, 'complexity'); + + res.json({ + success: true, + analysis: analysis + }); + + } catch (error) { + console.error('❌ [Template Manager AI] AI Analysis error:', error); + res.status(500).json({ + success: false, + error: error.message, + message: 'AI analysis failed' + }); + } +}); + +// Claude AI Analysis function +async function analyzeWithClaude(featureName, description, requirements, projectType) { + const safeRequirements = Array.isArray(requirements) ? requirements : []; + const requirementsText = safeRequirements.length > 0 ? safeRequirements.map(req => `- ${req}`).join('\n') : 'No specific requirements provided'; + + const prompt = `Analyze this custom feature for a ${projectType || 'web application'} project: + +Feature Name: ${featureName || 'Custom Feature'} +Description: ${description || 'No description provided'} + +Detailed Requirements: +${requirementsText} + +Based on these requirements, provide a detailed analysis in JSON format: +{ + "feature_name": "Improved technical name", + "complexity": "low|medium|high", + "logicRules": ["Business rule 1", "Business rule 2", "Business rule 3"], + "implementation_details": ["Technical detail 1", "Technical detail 2", "Technical detail 3"], + "technical_requirements": ["Requirement 1", "Requirement 2", "Requirement 3"], + "estimated_effort": "1-2 weeks|2-3 weeks|3-4 weeks|4+ weeks", + "dependencies": ["Dependency 1", "Dependency 2"], + "api_endpoints": ["POST /api/endpoint1", "GET /api/endpoint2"], + "database_tables": ["table1", "table2"], + "confidence_score": 0.85 +} + +For complexity assessment: +- "low": Simple CRUD, basic features, minimal business logic +- "medium": Moderate business logic, some integrations, standard features +- "high": Complex business rules, external integrations, security requirements, real-time features + +For logicRules, generate specific business rules based on the requirements like: +- Access control and authorization rules +- Data validation and business logic rules +- Workflow and process rules +- Security and compliance requirements + +Return ONLY the JSON object, no other text.`; + + try { + const response = await axios.post('https://api.anthropic.com/v1/messages', { + model: 'claude-3-5-sonnet-20241022', + max_tokens: 2000, + temperature: 0.1, + messages: [{ role: 'user', content: prompt }] + }, { + headers: { + 'x-api-key': CLAUDE_API_KEY, + 'Content-Type': 'application/json', + 'anthropic-version': '2023-06-01' + } + }); + + const responseText = response.data.content[0].text.trim(); + + // Extract JSON from response + const jsonMatch = responseText.match(/\{[\s\S]*\}/); + if (jsonMatch) { + const analysis = JSON.parse(jsonMatch[0]); + console.log('✅ [Template Manager AI] Claude analysis successful'); + return analysis; + } else { + throw new Error('No valid JSON found in Claude response'); + } + } catch (error) { + console.error('❌ [Template Manager AI] Claude API error:', error.message); + throw error; + } +} + +// Rule-based analysis function +async function analyzeWithRules(featureName, description, requirements, projectType) { + const complexity = analyzeComplexity(description, requirements); + const logicRules = generateLogicRules(featureName, description, requirements, projectType); + + return { + feature_name: featureName || 'Custom Feature', + complexity: complexity, + logicRules: logicRules, + implementation_details: [ + `Implement ${featureName || 'Custom Feature'} with proper validation`, + 'Add error handling and logging', + 'Include unit and integration tests' + ], + technical_requirements: [ + 'Database schema design', + 'API endpoint implementation', + 'Frontend component development' + ], + estimated_effort: complexity === 'high' ? '3-4 weeks' : complexity === 'low' ? '1-2 weeks' : '2-3 weeks', + dependencies: ['User authentication', 'Database setup'], + api_endpoints: [ + `POST /api/${(featureName || 'custom-feature').toLowerCase().replace(/\s+/g, '-')}`, + `GET /api/${(featureName || 'custom-feature').toLowerCase().replace(/\s+/g, '-')}` + ], + database_tables: [`${(featureName || 'custom_feature').toLowerCase().replace(/\s+/g, '_')}_table`], + confidence_score: 0.75 + }; +} + +// Helper function to analyze complexity +function analyzeComplexity(description, requirements) { + const safeRequirements = Array.isArray(requirements) ? requirements : []; + const text = `${description || ''} ${safeRequirements.join(' ')}`.toLowerCase(); + + const highComplexityKeywords = ['encryption', 'hipaa', 'compliance', 'security', 'integration', 'real-time', 'ai', 'machine learning', 'blockchain', 'payment', 'transaction']; + const mediumComplexityKeywords = ['crud', 'database', 'api', 'authentication', 'validation', 'search', 'filter', 'workflow', 'approval']; + const lowComplexityKeywords = ['display', 'show', 'view', 'list', 'basic', 'simple']; + + if (highComplexityKeywords.some(keyword => text.includes(keyword))) { + return 'high'; + } else if (mediumComplexityKeywords.some(keyword => text.includes(keyword))) { + return 'medium'; + } else if (lowComplexityKeywords.some(keyword => text.includes(keyword))) { + return 'low'; + } + + return 'medium'; // default +} + +// Helper function to generate logic rules +function generateLogicRules(featureName, description, requirements, projectType) { + const rules = []; + const safeRequirements = Array.isArray(requirements) ? requirements : []; + const text = `${description || ''} ${safeRequirements.join(' ')}`.toLowerCase(); + + // Project type specific rules + if (projectType?.toLowerCase() === 'healthcare') { + rules.push('Only authorized caregivers can access patient data'); + rules.push('All patient data access must be logged for HIPAA compliance'); + rules.push('Patient data must be encrypted at rest and in transit'); + } + + if (projectType?.toLowerCase() === 'ecommerce') { + rules.push('Payment information must be PCI DSS compliant'); + rules.push('Order status updates must be real-time'); + rules.push('Inventory levels must be validated before purchase'); + } + + // Feature specific rules + if (text.includes('crud') || text.includes('manage')) { + rules.push('Users can only modify data they have created or been granted access to'); + } + + if (text.includes('patient') || text.includes('medical')) { + rules.push('Patient information can only be accessed by assigned caregivers'); + rules.push('All patient data modifications require audit trail'); + } + + if (text.includes('payment') || text.includes('transaction')) { + rules.push('All financial transactions must be logged and auditable'); + rules.push('Payment processing must include fraud detection'); + } + + if (text.includes('approval') || text.includes('workflow')) { + rules.push('Approval workflows must have configurable escalation rules'); + rules.push('All approval decisions must be logged with timestamps'); + } + + // Generic rules + if (rules.length === 0) { + rules.push('Data validation must be performed on all inputs'); + rules.push('User permissions must be checked before data access'); + rules.push('All operations must be logged for audit purposes'); + } + + return rules; +} + +// Root endpoint +app.get('/', (req, res) => { + res.json({ + message: 'Template Manager AI Service - AI Feature Analysis', + version: '1.0.0', + endpoints: { + health: '/health', + ai_analysis: '/api/analyze-feature' + } + }); +}); + +// Error handling middleware +app.use((err, req, res, next) => { + console.error('❌ Error:', err.stack); + res.status(500).json({ + error: 'Internal Server Error', + message: process.env.NODE_ENV === 'development' ? err.message : 'Something went wrong' + }); +}); + +// 404 handler +app.use('*', (req, res) => { + res.status(404).json({ + error: 'Not Found', + message: `Route ${req.originalUrl} not found` + }); +}); + +// Start server +app.listen(PORT, '0.0.0.0', () => { + console.log('🚀 Template Manager AI Service started'); + console.log(`📡 Server running on http://0.0.0.0:${PORT}`); + console.log('🏥 Health check: http://0.0.0.0:8009/health'); + console.log('🤖 AI Analysis endpoint: http://0.0.0.0:8009/api/analyze-feature'); + console.log('🎯 AI Feature Analysis ready!'); +}); diff --git a/services/template-manager/src/app.js b/services/template-manager/src/app.js index 92ef50c..3e1d75c 100644 --- a/services/template-manager/src/app.js +++ b/services/template-manager/src/app.js @@ -5,6 +5,7 @@ const helmet = require('helmet'); const morgan = require('morgan'); const http = require('http'); const { Server } = require('socket.io'); +const axios = require('axios'); // Import database const database = require('./config/database'); @@ -91,11 +92,335 @@ app.get('/health', (req, res) => { feature_learning: true, usage_tracking: true, self_improving: true, - admin_approval_workflow: true + admin_approval_workflow: true, + ai_analysis: true } }); }); +// AI Feature Analysis endpoint +app.post('/api/analyze-feature', async (req, res) => { + try { + console.log('🤖 [Template Manager] AI Analysis request received'); + + const { featureName, feature_name, description, requirements = [], projectType, project_type } = req.body; + + // Handle both parameter name variations + const actualFeatureName = featureName || feature_name; + const actualProjectType = projectType || project_type; + + // Ensure requirements is always an array + const safeRequirements = Array.isArray(requirements) ? requirements : []; + + console.log('📋 [Template Manager] Analyzing feature:', actualFeatureName); + console.log('📋 [Template Manager] Project type:', actualProjectType); + console.log('📋 [Template Manager] Requirements:', safeRequirements); + + // Use Claude AI for intelligent analysis + let analysis; + const CLAUDE_API_KEY = process.env.CLAUDE_API_KEY || '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'; + const CLAUDE_AVAILABLE = !!CLAUDE_API_KEY; + + console.log('🔍 [Template Manager] Claude available:', CLAUDE_AVAILABLE); + console.log('🔍 [Template Manager] Claude API key present:', !!process.env.CLAUDE_API_KEY); + + if (CLAUDE_AVAILABLE) { + try { + console.log('🤖 [Template Manager] Using Claude AI for analysis...'); + analysis = await analyzeWithClaude(actualFeatureName, description, safeRequirements, actualProjectType); + console.log('✅ [Template Manager] Claude AI analysis completed successfully'); + } catch (claudeError) { + console.warn('⚠️ [Template Manager] Claude AI failed, falling back to rule-based analysis:', claudeError.message); + console.error('❌ [Template Manager] Claude error details:', claudeError); + analysis = await analyzeWithRules(actualFeatureName, description, safeRequirements, actualProjectType); + } + } else { + console.log('📋 [Template Manager] Using rule-based analysis (Claude not available)'); + analysis = await analyzeWithRules(actualFeatureName, description, safeRequirements, actualProjectType); + } + + console.log('✅ [Template Manager] Analysis completed:', analysis.complexity, 'complexity'); + + res.json({ + success: true, + analysis: analysis + }); + + } catch (error) { + console.error('❌ [Template Manager] AI Analysis error:', error); + res.status(500).json({ + success: false, + error: error.message, + message: 'AI analysis failed' + }); + } +}); + +// Claude AI Analysis function +async function analyzeWithClaude(featureName, description, requirements, projectType) { + const CLAUDE_API_KEY = process.env.CLAUDE_API_KEY || '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'; + + const safeRequirements = Array.isArray(requirements) ? requirements : []; + const requirementsText = safeRequirements.length > 0 ? safeRequirements.map(req => `- ${req}`).join('\n') : 'No specific requirements provided'; + + const prompt = `Analyze this custom feature for a ${projectType || 'web application'} project: + +Feature Name: ${featureName || 'Custom Feature'} +Description: ${description || 'No description provided'} + +Detailed Requirements: +${requirementsText} + +Based on these requirements, provide a detailed analysis in JSON format: +{ + "feature_name": "Improved technical name", + "complexity": "low|medium|high", + "logicRules": ["Business rule 1", "Business rule 2", "Business rule 3"], + "implementation_details": ["Technical detail 1", "Technical detail 2", "Technical detail 3"], + "technical_requirements": ["Requirement 1", "Requirement 2", "Requirement 3"], + "estimated_effort": "1-2 weeks|2-3 weeks|3-4 weeks|4+ weeks", + "dependencies": ["Dependency 1", "Dependency 2"], + "api_endpoints": ["POST /api/endpoint1", "GET /api/endpoint2"], + "database_tables": ["table1", "table2"], + "confidence_score": 0.85 +} + +For complexity assessment: +- "low": Simple CRUD, basic features, minimal business logic +- "medium": Moderate business logic, some integrations, standard features +- "high": Complex business rules, external integrations, security requirements, real-time features + +For logicRules, generate specific business rules based on the requirements like: +- Access control and authorization rules +- Data validation and business logic rules +- Workflow and process rules +- Security and compliance requirements + +Return ONLY the JSON object, no other text.`; + + try { + console.log('🔍 [Template Manager] Making Claude API request...'); + console.log('🔍 [Template Manager] API Key length:', CLAUDE_API_KEY ? CLAUDE_API_KEY.length : 0); + console.log('🔍 [Template Manager] Prompt length:', prompt.length); + + const response = await axios.post('https://api.anthropic.com/v1/messages', { + model: 'claude-3-5-sonnet-20241022', + max_tokens: 2000, + temperature: 0.1, + messages: [{ role: 'user', content: prompt }] + }, { + headers: { + 'x-api-key': CLAUDE_API_KEY, + 'Content-Type': 'application/json', + 'anthropic-version': '2023-06-01' + }, + timeout: 30000 + }); + + console.log('✅ [Template Manager] Claude API response received'); + console.log('🔍 [Template Manager] Response status:', response.status); + + const responseText = response.data.content[0].text.trim(); + console.log('🔍 [Template Manager] Raw Claude response:', responseText.substring(0, 200) + '...'); + + // Extract JSON from response + const jsonMatch = responseText.match(/\{[\s\S]*\}/); + if (jsonMatch) { + const analysis = JSON.parse(jsonMatch[0]); + console.log('✅ [Template Manager] Claude analysis successful'); + console.log('🔍 [Template Manager] Parsed analysis:', JSON.stringify(analysis, null, 2)); + return analysis; + } else { + console.error('❌ [Template Manager] No valid JSON found in Claude response'); + console.error('🔍 [Template Manager] Full response:', responseText); + throw new Error('No valid JSON found in Claude response'); + } + } catch (error) { + console.error('❌ [Template Manager] Claude API error:', error.message); + console.error('🔍 [Template Manager] Error details:', { + status: error.response?.status, + statusText: error.response?.statusText, + data: error.response?.data, + code: error.code + }); + throw error; + } +} + +// Rule-based analysis function (fallback) +async function analyzeWithRules(featureName, description, requirements, projectType) { + const complexity = analyzeComplexity(description, requirements); + const logicRules = generateLogicRules(featureName, description, requirements, projectType); + + return { + feature_name: featureName || 'Custom Feature', + complexity: complexity, + logicRules: logicRules, + implementation_details: [ + `Implement ${featureName || 'Custom Feature'} with proper validation`, + 'Add error handling and logging', + 'Include unit and integration tests' + ], + technical_requirements: [ + 'Database schema design', + 'API endpoint implementation', + 'Frontend component development' + ], + estimated_effort: complexity === 'high' ? '3-4 weeks' : complexity === 'low' ? '1-2 weeks' : '2-3 weeks', + dependencies: ['User authentication', 'Database setup'], + api_endpoints: [ + `POST /api/${(featureName || 'custom-feature').toLowerCase().replace(/\s+/g, '-')}`, + `GET /api/${(featureName || 'custom-feature').toLowerCase().replace(/\s+/g, '-')}` + ], + database_tables: [`${(featureName || 'custom_feature').toLowerCase().replace(/\s+/g, '_')}_table`], + confidence_score: 0.75 + }; +} + +// Helper function to analyze complexity +function analyzeComplexity(description, requirements) { + const safeRequirements = Array.isArray(requirements) ? requirements : []; + const text = `${description || ''} ${safeRequirements.join(' ')}`.toLowerCase(); + + const highComplexityKeywords = ['encryption', 'hipaa', 'compliance', 'security', 'integration', 'real-time', 'ai', 'machine learning', 'blockchain', 'payment', 'transaction']; + const mediumComplexityKeywords = ['crud', 'database', 'api', 'authentication', 'validation', 'search', 'filter', 'workflow', 'approval']; + const lowComplexityKeywords = ['display', 'show', 'view', 'list', 'basic', 'simple']; + + if (highComplexityKeywords.some(keyword => text.includes(keyword))) { + return 'high'; + } else if (mediumComplexityKeywords.some(keyword => text.includes(keyword))) { + return 'medium'; + } else if (lowComplexityKeywords.some(keyword => text.includes(keyword))) { + return 'low'; + } + + return 'medium'; // default +} + +// Helper function to generate logic rules +function generateLogicRules(featureName, description, requirements, projectType) { + const rules = []; + const safeRequirements = Array.isArray(requirements) ? requirements : []; + const text = `${description || ''} ${safeRequirements.join(' ')}`.toLowerCase(); + const featureText = `${featureName || ''}`.toLowerCase(); + + console.log('🔍 [Template Manager] Generating rules for:', featureName); + console.log('🔍 [Template Manager] Description:', description); + console.log('🔍 [Template Manager] Requirements:', safeRequirements); + console.log('🔍 [Template Manager] Project type:', projectType); + + // Project type specific rules + if (projectType?.toLowerCase() === 'healthcare') { + rules.push('Only authorized caregivers can access patient data'); + rules.push('All patient data access must be logged for HIPAA compliance'); + rules.push('Patient data must be encrypted at rest and in transit'); + } + + if (projectType?.toLowerCase() === 'ecommerce') { + rules.push('Payment information must be PCI DSS compliant'); + rules.push('Order status updates must be real-time'); + rules.push('Inventory levels must be validated before purchase'); + } + + if (projectType?.toLowerCase() === 'finance' || projectType?.toLowerCase() === 'fintech') { + rules.push('All financial data must be encrypted and access-controlled'); + rules.push('Transaction processing must include fraud detection'); + rules.push('Audit trails must be maintained for all financial operations'); + } + + // Dynamic feature-specific rules based on content analysis + if (text.includes('user') || text.includes('account') || text.includes('profile')) { + rules.push(`User authentication is required to access ${featureName || 'this feature'}`); + rules.push('User data must be validated before storage'); + rules.push('Users can only access their own data unless explicitly authorized'); + } + + if (text.includes('crud') || text.includes('manage') || text.includes('create') || text.includes('edit') || text.includes('delete')) { + rules.push(`Only authorized users can perform ${featureName || 'data'} operations`); + rules.push('All data modifications must be validated and sanitized'); + rules.push('Delete operations should be soft deletes with audit trails'); + } + + if (text.includes('search') || text.includes('filter') || text.includes('query')) { + rules.push('Search queries must be sanitized to prevent injection attacks'); + rules.push('Search results must respect user permissions and data visibility'); + rules.push('Search performance should be optimized with proper indexing'); + } + + if (text.includes('upload') || text.includes('file') || text.includes('document')) { + rules.push('File uploads must be validated for type, size, and content'); + rules.push('Uploaded files must be scanned for malware'); + rules.push('File access must be controlled based on user permissions'); + } + + if (text.includes('notification') || text.includes('email') || text.includes('alert')) { + rules.push('Notification preferences must be configurable by users'); + rules.push('Email notifications must comply with anti-spam regulations'); + rules.push('Notification delivery must be reliable and trackable'); + } + + if (text.includes('report') || text.includes('analytics') || text.includes('dashboard')) { + rules.push('Report data must be filtered based on user access permissions'); + rules.push('Analytics data must be anonymized where required'); + rules.push('Report generation must be optimized for performance'); + } + + if (text.includes('api') || text.includes('integration') || text.includes('webhook')) { + rules.push('API endpoints must be secured with proper authentication'); + rules.push('Rate limiting must be implemented to prevent abuse'); + rules.push('API responses must not expose sensitive internal data'); + } + + if (text.includes('payment') || text.includes('transaction') || text.includes('billing')) { + rules.push('All financial transactions must be logged and auditable'); + rules.push('Payment processing must include fraud detection'); + rules.push('Transaction data must be encrypted and PCI compliant'); + } + + if (text.includes('approval') || text.includes('workflow') || text.includes('review')) { + rules.push('Approval workflows must have configurable escalation rules'); + rules.push('All approval decisions must be logged with timestamps'); + rules.push('Workflow states must be clearly defined and trackable'); + } + + if (text.includes('patient') || text.includes('medical') || text.includes('health')) { + rules.push('Patient information can only be accessed by assigned caregivers'); + rules.push('All patient data modifications require audit trail'); + rules.push('Medical data must comply with HIPAA regulations'); + } + + // Dynamic rules based on requirements content + safeRequirements.forEach((req, index) => { + const reqText = req.toLowerCase(); + if (reqText.includes('security') || reqText.includes('secure')) { + rules.push(`Security requirement ${index + 1}: ${req} must be implemented with proper access controls`); + } + if (reqText.includes('performance') || reqText.includes('fast') || reqText.includes('speed')) { + rules.push(`Performance requirement ${index + 1}: ${req} must be optimized for scalability`); + } + if (reqText.includes('compliance') || reqText.includes('regulation')) { + rules.push(`Compliance requirement ${index + 1}: ${req} must be implemented according to regulatory standards`); + } + }); + + // Generic rules if no specific ones were added + if (rules.length === 0) { + rules.push(`${featureName || 'This feature'} must implement proper data validation on all inputs`); + rules.push(`User permissions must be verified before accessing ${featureName || 'feature'} functionality`); + rules.push(`All ${featureName || 'feature'} operations must be logged for audit and debugging purposes`); + rules.push(`${featureName || 'This feature'} must handle errors gracefully and provide meaningful feedback`); + } + + // Ensure we always have at least 3-5 rules for better analysis + if (rules.length < 3) { + rules.push(`${featureName || 'This feature'} must be tested thoroughly before deployment`); + rules.push(`${featureName || 'This feature'} must follow established coding standards and best practices`); + } + + console.log('✅ [Template Manager] Generated rules:', rules); + return rules; +} + // Root endpoint app.get('/', (req, res) => { res.json({