muthuk1 commited on
Commit
ed94e30
·
verified ·
1 Parent(s): 3b60e51

Upload integration/routes-ml.js

Browse files
Files changed (1) hide show
  1. integration/routes-ml.js +176 -0
integration/routes-ml.js ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * ALWAS ML Routes — Drop-in Express.js routes
3
+ * Add to your server/routes/ directory and mount in app.js
4
+ *
5
+ * Mount: app.use('/api/ml', require('./routes/ml'));
6
+ */
7
+
8
+ const express = require('express');
9
+ const router = express.Router();
10
+ const ml = require('../utils/alwas-ml-client'); // adjust path as needed
11
+ const Block = require('../models/Block');
12
+ const { isAuthenticated, isManager } = require('../middleware/auth');
13
+
14
+ /**
15
+ * POST /api/ml/estimate
16
+ * AI-powered block complexity estimation (replaces Groq API)
17
+ * Access: Manager
18
+ */
19
+ router.post('/estimate', isAuthenticated, isManager, async (req, res) => {
20
+ try {
21
+ const estimate = await ml.estimateBlock(req.body);
22
+ res.json(estimate);
23
+ } catch (error) {
24
+ console.error('ML estimation error:', error.message);
25
+ res.status(500).json({ error: 'ML estimation failed', details: error.message });
26
+ }
27
+ });
28
+
29
+ /**
30
+ * GET /api/ml/block/:id/risk
31
+ * Get bottleneck risk assessment for a specific block
32
+ * Access: User
33
+ */
34
+ router.get('/block/:id/risk', isAuthenticated, async (req, res) => {
35
+ try {
36
+ const block = await Block.findById(req.params.id);
37
+ if (!block) return res.status(404).json({ error: 'Block not found' });
38
+
39
+ // Calculate days in current stage
40
+ const lastTransition = block.transitions?.[block.transitions.length - 1];
41
+ const daysSince = lastTransition
42
+ ? (Date.now() - new Date(lastTransition.timestamp)) / (1000 * 60 * 60 * 24)
43
+ : 0;
44
+
45
+ const riskData = ml.constructor.formatForBottleneck(block, daysSince);
46
+ const risk = await ml.predictBottleneck(riskData);
47
+
48
+ res.json({ blockId: block._id, blockName: block.name, ...risk });
49
+ } catch (error) {
50
+ console.error('ML risk prediction error:', error.message);
51
+ res.status(500).json({ error: 'Risk prediction failed', details: error.message });
52
+ }
53
+ });
54
+
55
+ /**
56
+ * GET /api/ml/block/:id/eta
57
+ * Get estimated completion time for a specific block
58
+ * Access: User
59
+ */
60
+ router.get('/block/:id/eta', isAuthenticated, async (req, res) => {
61
+ try {
62
+ const block = await Block.findById(req.params.id);
63
+ if (!block) return res.status(404).json({ error: 'Block not found' });
64
+ if (block.status === 'Completed') {
65
+ return res.json({ remaining_hours: 0, progress_percent: 100, status: 'completed' });
66
+ }
67
+
68
+ const completionData = ml.constructor.formatForCompletion(block);
69
+ const eta = await ml.predictCompletion(completionData);
70
+
71
+ res.json({ blockId: block._id, blockName: block.name, ...eta });
72
+ } catch (error) {
73
+ console.error('ML completion prediction error:', error.message);
74
+ res.status(500).json({ error: 'Completion prediction failed', details: error.message });
75
+ }
76
+ });
77
+
78
+ /**
79
+ * POST /api/ml/bulk-estimate
80
+ * Bulk estimation for CSV import
81
+ * Access: Manager
82
+ */
83
+ router.post('/bulk-estimate', isAuthenticated, isManager, async (req, res) => {
84
+ try {
85
+ const { blocks } = req.body;
86
+ if (!blocks || !Array.isArray(blocks)) {
87
+ return res.status(400).json({ error: 'blocks array required' });
88
+ }
89
+ if (blocks.length > 200) {
90
+ return res.status(400).json({ error: 'Maximum 200 blocks per request' });
91
+ }
92
+ const estimates = await ml.bulkEstimate(blocks);
93
+ res.json(estimates);
94
+ } catch (error) {
95
+ console.error('ML bulk estimation error:', error.message);
96
+ res.status(500).json({ error: 'Bulk estimation failed', details: error.message });
97
+ }
98
+ });
99
+
100
+ /**
101
+ * GET /api/ml/scan/bottlenecks
102
+ * Scan ALL in-progress blocks for bottleneck risks
103
+ * Access: Manager
104
+ */
105
+ router.get('/scan/bottlenecks', isAuthenticated, isManager, async (req, res) => {
106
+ try {
107
+ const blocks = await Block.find({ status: { $nin: ['Not Started', 'Completed'] } });
108
+ const results = [];
109
+
110
+ for (const block of blocks) {
111
+ const lastTransition = block.transitions?.[block.transitions.length - 1];
112
+ const daysSince = lastTransition
113
+ ? (Date.now() - new Date(lastTransition.timestamp)) / (1000 * 60 * 60 * 24)
114
+ : 0;
115
+
116
+ const riskData = ml.constructor.formatForBottleneck(block, daysSince);
117
+ const risk = await ml.predictBottleneck(riskData);
118
+
119
+ if (risk.risk_level !== 'Low') {
120
+ results.push({
121
+ blockId: block._id,
122
+ blockName: block.name,
123
+ stage: block.status,
124
+ engineer: block.assignedTo,
125
+ ...risk,
126
+ });
127
+ }
128
+ }
129
+
130
+ // Sort by risk (High first)
131
+ results.sort((a, b) => {
132
+ const order = { High: 0, Medium: 1, Low: 2 };
133
+ return (order[a.risk_level] || 2) - (order[b.risk_level] || 2);
134
+ });
135
+
136
+ res.json({
137
+ total_scanned: blocks.length,
138
+ at_risk: results.length,
139
+ high_risk: results.filter(r => r.risk_level === 'High').length,
140
+ medium_risk: results.filter(r => r.risk_level === 'Medium').length,
141
+ blocks: results
142
+ });
143
+ } catch (error) {
144
+ console.error('ML bottleneck scan error:', error.message);
145
+ res.status(500).json({ error: 'Bottleneck scan failed', details: error.message });
146
+ }
147
+ });
148
+
149
+ /**
150
+ * GET /api/ml/health
151
+ * ML service health check
152
+ */
153
+ router.get('/health', async (req, res) => {
154
+ try {
155
+ const health = await ml.healthCheck();
156
+ res.json(health);
157
+ } catch (error) {
158
+ res.status(503).json({ status: 'unhealthy', error: error.message });
159
+ }
160
+ });
161
+
162
+ /**
163
+ * GET /api/ml/metrics
164
+ * Get model performance metrics
165
+ * Access: Manager
166
+ */
167
+ router.get('/metrics', isAuthenticated, isManager, async (req, res) => {
168
+ try {
169
+ const metrics = await ml.getMetrics();
170
+ res.json(metrics);
171
+ } catch (error) {
172
+ res.status(500).json({ error: 'Failed to fetch metrics', details: error.message });
173
+ }
174
+ });
175
+
176
+ module.exports = router;