DEVessi commited on
Commit
ba475c6
·
verified ·
1 Parent(s): ec8b2ca

Upload folder using huggingface_hub

Browse files
scenario_config.json CHANGED
@@ -7,24 +7,45 @@
7
  "temperature": 0.2,
8
  "max_tokens": 256,
9
  "max_steps_per_task": 8,
10
- "system_prompt": "You are an expert DevOps engineer and Node.js developer. You have been dropped into a Linux container with a broken Express.js backend in /app. Your goal is to diagnose and fix bugs so the app runs correctly. Respond ONLY with a JSON object: {\"command\": \"<bash command>\"}. Use standard bash/Linux commands. Do NOT use interactive editors (vi, nano). Be methodical: read files first, understand the bug, then fix it.",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  "tasks": [
12
  {
13
  "task_name": "easy",
14
- "description": "Fix the port configuration bug so the app starts on port 3000 and /health returns HTTP 200.",
15
- "hints": ["Check config.json for wrong settings"],
16
- "expected_bugs": ["config.json has port set to 9999 instead of 3000"],
 
 
 
 
 
 
 
17
  "verifiers": [
18
  {
19
  "name": "Config Port Fixed",
20
- "description": "Ensures config.json has port set to 3000",
21
  "verification_type": "file_content",
22
  "file_path": "/app/config.json",
23
  "expected_content": "3000"
24
  },
25
  {
26
- "name": "Health Endpoint Responds",
27
- "description": "GET /health returns HTTP 200",
28
  "verification_type": "http_check",
29
  "endpoint": "/health",
30
  "expected_status": 200
@@ -33,33 +54,36 @@
33
  },
34
  {
35
  "task_name": "medium",
36
- "description": "Fix the port config AND the syntax error in routes/users.js so /api/users returns valid JSON.",
37
- "hints": [
38
- "Check config.json for wrong settings",
39
- "Look for syntax errors in routes/users.js — missing closing parenthesis"
40
- ],
41
- "expected_bugs": [
42
- "config.json has port set to 9999 instead of 3000",
43
- "routes/users.js is missing a closing parenthesis on the router.get() call"
 
 
 
 
 
 
44
  ],
45
  "verifiers": [
46
  {
47
  "name": "Config Port Fixed",
48
- "description": "Ensures config.json has port set to 3000",
49
  "verification_type": "file_content",
50
  "file_path": "/app/config.json",
51
  "expected_content": "3000"
52
  },
53
  {
54
  "name": "Syntax Error Fixed",
55
- "description": "routes/users.js has closing parenthesis on router.get",
56
  "verification_type": "file_content",
57
  "file_path": "/app/routes/users.js",
58
  "expected_content": "});"
59
  },
60
  {
61
- "name": "Users Endpoint Responds",
62
- "description": "GET /api/users returns HTTP 200 with users array",
63
  "verification_type": "http_check",
64
  "endpoint": "/api/users",
65
  "expected_status": 200,
@@ -69,49 +93,67 @@
69
  },
70
  {
71
  "task_name": "hard",
72
- "description": "Fix ALL three bugs: port config, syntax error, and missing await in the async data handler.",
73
- "hints": [
74
- "Check config.json for wrong settings",
75
- "Look for syntax errors that prevent startup",
76
- "Watch out for async/await issues in routes/data.js"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  ],
78
- "expected_bugs": [
79
- "config.json has port set to 9999 instead of 3000",
80
- "routes/users.js is missing a closing parenthesis on the router.get() call",
81
- "routes/data.js is missing 'await' before fetchDataFromDB() causing a pending Promise"
 
 
 
 
 
 
 
 
 
82
  ],
83
  "verifiers": [
84
  {
85
  "name": "Config Port Fixed",
86
- "description": "Ensures config.json has port set to 3000",
87
  "verification_type": "file_content",
88
  "file_path": "/app/config.json",
89
  "expected_content": "3000"
90
  },
91
  {
92
  "name": "Syntax Error Fixed",
93
- "description": "routes/users.js has closing parenthesis",
94
  "verification_type": "file_content",
95
  "file_path": "/app/routes/users.js",
96
  "expected_content": "});"
97
  },
98
  {
99
  "name": "Await Added",
100
- "description": "routes/data.js uses await before fetchDataFromDB()",
101
  "verification_type": "file_content",
102
  "file_path": "/app/routes/data.js",
103
- "expected_content": "await fetchDataFromDB"
104
  },
105
  {
106
  "name": "Health Endpoint",
107
- "description": "GET /health returns HTTP 200",
108
  "verification_type": "http_check",
109
  "endpoint": "/health",
110
  "expected_status": 200
111
  },
112
  {
113
  "name": "Users Endpoint",
114
- "description": "GET /api/users returns valid JSON with users",
115
  "verification_type": "http_check",
116
  "endpoint": "/api/users",
117
  "expected_status": 200,
@@ -119,7 +161,6 @@
119
  },
120
  {
121
  "name": "Data Endpoint",
122
- "description": "GET /api/data returns valid JSON with records",
123
  "verification_type": "http_check",
124
  "endpoint": "/api/data",
125
  "expected_status": 200,
 
7
  "temperature": 0.2,
8
  "max_tokens": 256,
9
  "max_steps_per_task": 8,
10
+ "system_prompt": "You are an expert DevOps engineer responding to a production incident. A Node.js Express backend is broken and you must diagnose and fix it using bash commands. The app directory is /app. It contains config files, route handlers, middleware, .env, and old logs. NOT everything is broken — focus on actual root causes, not red herrings. Respond ONLY with a JSON object: {\"command\": \"<bash command>\"}. Use sed, echo, cat, grep never interactive editors.",
11
+ "app_structure": {
12
+ "files": [
13
+ "/app/config.json",
14
+ "/app/server.js",
15
+ "/app/package.json",
16
+ "/app/.env",
17
+ "/app/routes/users.js",
18
+ "/app/routes/data.js",
19
+ "/app/routes/status.js",
20
+ "/app/middleware/logger.js",
21
+ "/app/middleware/rateLimit.js",
22
+ "/app/logs/error.log"
23
+ ],
24
+ "bug_files": ["config.json", "routes/users.js", "routes/data.js"],
25
+ "red_herrings": [".env", "middleware/logger.js", "middleware/rateLimit.js", "routes/status.js", "logs/error.log"]
26
+ },
27
  "tasks": [
28
  {
29
  "task_name": "easy",
30
+ "severity": "LOW",
31
+ "bugs_count": 1,
32
+ "description": "The app fails to bind to the expected port. Fix it so the app starts on port 3000 and GET /health returns 200.",
33
+ "bugs": [
34
+ {
35
+ "file": "config.json",
36
+ "type": "misconfiguration",
37
+ "description": "Port is set to 9999 instead of 3000"
38
+ }
39
+ ],
40
  "verifiers": [
41
  {
42
  "name": "Config Port Fixed",
 
43
  "verification_type": "file_content",
44
  "file_path": "/app/config.json",
45
  "expected_content": "3000"
46
  },
47
  {
48
+ "name": "Health Endpoint",
 
49
  "verification_type": "http_check",
50
  "endpoint": "/health",
51
  "expected_status": 200
 
54
  },
55
  {
56
  "task_name": "medium",
57
+ "severity": "MEDIUM",
58
+ "bugs_count": 2,
59
+ "description": "App crashes on startup. Fix the crash AND a config issue so all endpoints up to /api/users work.",
60
+ "bugs": [
61
+ {
62
+ "file": "config.json",
63
+ "type": "misconfiguration",
64
+ "description": "Port is set to 9999 instead of 3000"
65
+ },
66
+ {
67
+ "file": "routes/users.js",
68
+ "type": "syntax_error",
69
+ "description": "Missing closing parenthesis on router.get() call causes SyntaxError on import"
70
+ }
71
  ],
72
  "verifiers": [
73
  {
74
  "name": "Config Port Fixed",
 
75
  "verification_type": "file_content",
76
  "file_path": "/app/config.json",
77
  "expected_content": "3000"
78
  },
79
  {
80
  "name": "Syntax Error Fixed",
 
81
  "verification_type": "file_content",
82
  "file_path": "/app/routes/users.js",
83
  "expected_content": "});"
84
  },
85
  {
86
+ "name": "Users Endpoint",
 
87
  "verification_type": "http_check",
88
  "endpoint": "/api/users",
89
  "expected_status": 200,
 
93
  },
94
  {
95
  "task_name": "hard",
96
+ "severity": "HIGH",
97
+ "bugs_count": 3,
98
+ "description": "Multiple issues: app crashes, endpoints return errors. Misleading logs present. Fix ALL root causes.",
99
+ "bugs": [
100
+ {
101
+ "file": "config.json",
102
+ "type": "misconfiguration",
103
+ "description": "Port is set to 9999 instead of 3000"
104
+ },
105
+ {
106
+ "file": "routes/users.js",
107
+ "type": "syntax_error",
108
+ "description": "Missing closing parenthesis on router.get() call"
109
+ },
110
+ {
111
+ "file": "routes/data.js",
112
+ "type": "async_bug",
113
+ "description": "Missing 'await' before fetchRecordsFromDB() — returns Promise instead of data"
114
+ }
115
  ],
116
+ "red_herrings": [
117
+ {
118
+ "file": "logs/error.log",
119
+ "description": "Old error log with misleading entries about port fallback and database connections"
120
+ },
121
+ {
122
+ "file": ".env",
123
+ "description": "Environment file with DB_HOST and CORS settings — not actually used by the app"
124
+ },
125
+ {
126
+ "file": "middleware/rateLimit.js",
127
+ "description": "Working rate limiter — might look suspicious but has generous limits"
128
+ }
129
  ],
130
  "verifiers": [
131
  {
132
  "name": "Config Port Fixed",
 
133
  "verification_type": "file_content",
134
  "file_path": "/app/config.json",
135
  "expected_content": "3000"
136
  },
137
  {
138
  "name": "Syntax Error Fixed",
 
139
  "verification_type": "file_content",
140
  "file_path": "/app/routes/users.js",
141
  "expected_content": "});"
142
  },
143
  {
144
  "name": "Await Added",
 
145
  "verification_type": "file_content",
146
  "file_path": "/app/routes/data.js",
147
+ "expected_content": "await fetchRecordsFromDB"
148
  },
149
  {
150
  "name": "Health Endpoint",
 
151
  "verification_type": "http_check",
152
  "endpoint": "/health",
153
  "expected_status": 200
154
  },
155
  {
156
  "name": "Users Endpoint",
 
157
  "verification_type": "http_check",
158
  "endpoint": "/api/users",
159
  "expected_status": 200,
 
161
  },
162
  {
163
  "name": "Data Endpoint",
 
164
  "verification_type": "http_check",
165
  "endpoint": "/api/data",
166
  "expected_status": 200,
server/devops_sandbox_environment.py CHANGED
@@ -59,6 +59,13 @@ BUG_FILES = {
59
  "routes/data.js": "await",
60
  }
61
 
 
 
 
 
 
 
 
62
 
63
  class DevOpsSandbox(Environment):
64
  """
@@ -132,9 +139,9 @@ class DevOpsSandbox(Environment):
132
  self._snapshot_file_hashes()
133
  self._inject_grader_script()
134
 
135
- # Gather initial observation
136
  init_stdout = self._exec_cmd(
137
- f"ls -la {self._app_dir} && echo '---' && cat {os.path.join(self._app_dir, 'config.json')}"
138
  )
139
 
140
  task_prompt = self._build_task_prompt(init_stdout)
@@ -240,50 +247,55 @@ class DevOpsSandbox(Environment):
240
  def _build_task_prompt(self, init_stdout: str) -> str:
241
  """Build the task prompt based on the current difficulty level."""
242
  base = (
243
- "=== SELF-HEALING DEVOPS SANDBOX ===\n"
244
- f"You have been dropped into a container with a broken Node.js "
245
- f"Express backend in {self._app_dir}.\n\n"
 
 
 
246
  )
247
 
248
  if self._current_task == "easy":
249
  mission = (
250
- "YOUR MISSION [EASY — 1 bug]:\n"
251
- " Fix the port configuration so that:\n"
252
- " 1. The app starts without errors on port 3000\n"
253
- " 2. GET /health returns HTTP 200\n\n"
254
- "HINTS:\n"
255
- " - Check config.json for wrong settings\n"
256
  )
257
  elif self._current_task == "medium":
258
  mission = (
259
- "YOUR MISSION [MEDIUM 2 bugs]:\n"
260
- " Fix BOTH bugs so that:\n"
261
- " 1. The app starts without errors on port 3000\n"
262
- " 2. GET /health returns HTTP 200\n"
263
- " 3. GET /api/users returns HTTP 200 with valid JSON\n\n"
264
- "HINTS:\n"
265
- " - Check config.json for wrong settings\n"
266
- " - Look for syntax errors in routes/users.js\n"
 
 
267
  )
268
  else:
269
  mission = (
270
- "YOUR MISSION [HARD — 3 bugs]:\n"
271
- " Fix ALL bugs so that:\n"
272
- " 1. The app starts without errors on port 3000\n"
273
- " 2. GET /health returns HTTP 200\n"
274
- " 3. GET /api/users returns HTTP 200 with valid JSON\n"
275
- " 4. GET /api/data returns HTTP 200 with valid JSON\n\n"
276
- "HINTS:\n"
277
- " - Check config files for wrong settings\n"
278
- " - Look for syntax errors that prevent startup\n"
279
- " - Watch out for async/await issues\n"
 
 
280
  )
281
 
282
  return (
283
  base + mission +
284
  "\nUse bash commands to explore, edit files, and test.\n"
285
- "When you think you've fixed everything, run: npm start\n\n"
286
- f"--- INITIAL DIRECTORY LISTING ---\n{init_stdout}\n"
287
  )
288
 
289
  def _bugs_for_task(self) -> int:
 
59
  "routes/data.js": "await",
60
  }
61
 
62
+ # All interesting files in the app (bugs + red herrings)
63
+ ALL_TRACKED_FILES = {
64
+ "config.json", "server.js", "routes/users.js", "routes/data.js",
65
+ "routes/status.js", "middleware/logger.js", "middleware/rateLimit.js",
66
+ ".env", "logs/error.log",
67
+ }
68
+
69
 
70
  class DevOpsSandbox(Environment):
71
  """
 
139
  self._snapshot_file_hashes()
140
  self._inject_grader_script()
141
 
142
+ # Gather initial observation — show full file tree
143
  init_stdout = self._exec_cmd(
144
+ f"find {self._app_dir} -type f | head -20 && echo '---' && cat {os.path.join(self._app_dir, 'package.json')}"
145
  )
146
 
147
  task_prompt = self._build_task_prompt(init_stdout)
 
247
  def _build_task_prompt(self, init_stdout: str) -> str:
248
  """Build the task prompt based on the current difficulty level."""
249
  base = (
250
+ "=== DEVOPS INCIDENT RESPONSE ===\n"
251
+ f"ALERT: Production Node.js service in {self._app_dir} is DOWN.\n"
252
+ "You are the on-call engineer. Diagnose and fix the issue(s).\n\n"
253
+ "The app is an Express.js backend with multiple routes, middleware,\n"
254
+ "config files, and logs. Not everything you see is broken — some files\n"
255
+ "are red herrings. Focus on what's actually causing failures.\n\n"
256
  )
257
 
258
  if self._current_task == "easy":
259
  mission = (
260
+ "SEVERITY: LOW (1 known issue)\n"
261
+ "SYMPTOM: App fails to bind to the expected port.\n"
262
+ "EXPECTED: App should listen on port 3000, GET /health returns 200.\n\n"
263
+ "Start by checking configuration and trying to start the app.\n"
 
 
264
  )
265
  elif self._current_task == "medium":
266
  mission = (
267
+ "SEVERITY: MEDIUM (2 known issues)\n"
268
+ "SYMPTOMS:\n"
269
+ " - App crashes immediately on startup\n"
270
+ " - Even after fixing the crash, some routes may not work\n"
271
+ "EXPECTED:\n"
272
+ " - App listens on port 3000\n"
273
+ " - GET /health returns 200\n"
274
+ " - GET /api/users returns 200 with valid JSON\n\n"
275
+ "Check startup logs carefully. The crash message will point you\n"
276
+ "to the first bug, but there may be a config issue too.\n"
277
  )
278
  else:
279
  mission = (
280
+ "SEVERITY: HIGH (3 known issues)\n"
281
+ "SYMPTOMS:\n"
282
+ " - App crashes on startup with an error\n"
283
+ " - Multiple endpoints return errors or bad data\n"
284
+ " - There are misleading old logs in logs/error.log\n"
285
+ "EXPECTED:\n"
286
+ " - App listens on port 3000\n"
287
+ " - GET /health returns 200\n"
288
+ " - GET /api/users returns 200 with JSON containing 'users' array\n"
289
+ " - GET /api/data returns 200 with JSON containing 'records' array\n\n"
290
+ "WARNING: The app has middleware, config files, .env, and old logs.\n"
291
+ "Not everything is broken — isolate the actual root causes.\n"
292
  )
293
 
294
  return (
295
  base + mission +
296
  "\nUse bash commands to explore, edit files, and test.\n"
297
+ "When you think you've fixed everything, run: cd /app && npm start\n\n"
298
+ f"--- INITIAL STATE ---\n{init_stdout}\n"
299
  )
300
 
301
  def _bugs_for_task(self) -> int:
simulated_app/.env ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ NODE_ENV=production
2
+ LOG_LEVEL=info
3
+ DB_HOST=localhost
4
+ DB_PORT=5432
5
+ DB_NAME=sandbox_db
6
+ SESSION_SECRET=s3cr3t_k3y_d0_n0t_sh4r3
7
+ CORS_ORIGIN=http://localhost:3000
simulated_app/config.json CHANGED
@@ -1,5 +1,10 @@
1
  {
2
  "port": 9999,
3
  "appName": "DevOps Sandbox App",
4
- "version": "1.0.0"
 
 
 
 
 
5
  }
 
1
  {
2
  "port": 9999,
3
  "appName": "DevOps Sandbox App",
4
+ "version": "1.0.0",
5
+ "logLevel": "info",
6
+ "rateLimit": {
7
+ "windowMs": 60000,
8
+ "maxRequests": 100
9
+ }
10
  }
simulated_app/middleware/logger.js ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Request logging middleware.
3
+ * Logs method, URL, status code, and response time for every request.
4
+ */
5
+ function requestLogger(req, res, next) {
6
+ const start = Date.now();
7
+ const originalEnd = res.end;
8
+
9
+ res.end = function (...args) {
10
+ const duration = Date.now() - start;
11
+ console.log(`[${new Date().toISOString()}] ${req.method} ${req.originalUrl} ${res.statusCode} ${duration}ms`);
12
+ originalEnd.apply(res, args);
13
+ };
14
+
15
+ next();
16
+ }
17
+
18
+ module.exports = { requestLogger };
simulated_app/middleware/rateLimit.js ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Simple in-memory rate limiter middleware.
3
+ * Tracks request counts per IP within a sliding window.
4
+ */
5
+ const requestCounts = new Map();
6
+
7
+ function rateLimiter(req, res, next) {
8
+ const ip = req.ip || req.connection.remoteAddress || 'unknown';
9
+ const now = Date.now();
10
+ const windowMs = 60000; // 1 minute window
11
+ const maxRequests = 100;
12
+
13
+ if (!requestCounts.has(ip)) {
14
+ requestCounts.set(ip, { count: 1, windowStart: now });
15
+ return next();
16
+ }
17
+
18
+ const record = requestCounts.get(ip);
19
+
20
+ if (now - record.windowStart > windowMs) {
21
+ // Reset window
22
+ record.count = 1;
23
+ record.windowStart = now;
24
+ return next();
25
+ }
26
+
27
+ record.count++;
28
+
29
+ if (record.count > maxRequests) {
30
+ return res.status(429).json({
31
+ error: 'Too many requests',
32
+ retryAfter: Math.ceil((record.windowStart + windowMs - now) / 1000)
33
+ });
34
+ }
35
+
36
+ next();
37
+ }
38
+
39
+ module.exports = { rateLimiter };
simulated_app/routes/data.js CHANGED
@@ -1,36 +1,34 @@
1
  const express = require('express');
2
  const router = express.Router();
3
 
4
- // Simulates fetching data from a database
5
- function fetchDataFromDB() {
6
  return new Promise((resolve) => {
7
  setTimeout(() => {
8
  resolve({
9
  records: [
10
- { id: 1, value: 'sensor_alpha', reading: 42.5 },
11
- { id: 2, value: 'sensor_beta', reading: 17.3 },
12
- { id: 3, value: 'sensor_gamma', reading: 88.1 }
 
13
  ],
14
- timestamp: new Date().toISOString()
 
15
  });
16
  }, 100);
17
  });
18
  }
19
 
20
- // BUG 3 (Hard): The handler is marked async but does NOT await the Promise.
21
- // This means `result` will be a pending Promise object, not the resolved data.
22
- // Express will try to serialize the Promise, resulting in an empty/broken response
23
- // or a 500 error when the client expects valid JSON.
24
-
25
  router.get('/', async (req, res) => {
26
  try {
27
- const result = fetchDataFromDB();
28
  if (!result || !result.records) {
29
- return res.status(500).json({ error: 'Failed to fetch data' });
30
  }
31
  res.json(result);
32
  } catch (err) {
33
- res.status(500).json({ error: 'Internal server error' });
 
34
  }
35
  });
36
 
 
1
  const express = require('express');
2
  const router = express.Router();
3
 
4
+ // Simulates an async database query
5
+ function fetchRecordsFromDB() {
6
  return new Promise((resolve) => {
7
  setTimeout(() => {
8
  resolve({
9
  records: [
10
+ { id: 1, sensor: 'temperature', value: 42.5, unit: 'C', timestamp: new Date().toISOString() },
11
+ { id: 2, sensor: 'humidity', value: 67.3, unit: '%', timestamp: new Date().toISOString() },
12
+ { id: 3, sensor: 'pressure', value: 1013.25, unit: 'hPa', timestamp: new Date().toISOString() },
13
+ { id: 4, sensor: 'wind_speed', value: 12.8, unit: 'km/h', timestamp: new Date().toISOString() }
14
  ],
15
+ total: 4,
16
+ page: 1
17
  });
18
  }, 100);
19
  });
20
  }
21
 
 
 
 
 
 
22
  router.get('/', async (req, res) => {
23
  try {
24
+ const result = fetchRecordsFromDB();
25
  if (!result || !result.records) {
26
+ return res.status(500).json({ error: 'Database query returned empty result' });
27
  }
28
  res.json(result);
29
  } catch (err) {
30
+ console.error(`[DATA] Error fetching records: ${err.message}`);
31
+ res.status(500).json({ error: 'Failed to fetch sensor data' });
32
  }
33
  });
34
 
simulated_app/routes/status.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const express = require('express');
2
+ const router = express.Router();
3
+ const os = require('os');
4
+
5
+ router.get('/', (req, res) => {
6
+ res.json({
7
+ status: 'operational',
8
+ hostname: os.hostname(),
9
+ platform: os.platform(),
10
+ memory: {
11
+ total: Math.round(os.totalmem() / 1024 / 1024),
12
+ free: Math.round(os.freemem() / 1024 / 1024),
13
+ unit: 'MB'
14
+ },
15
+ uptime: Math.round(os.uptime()),
16
+ nodeVersion: process.version
17
+ });
18
+ });
19
+
20
+ module.exports = router;
simulated_app/routes/users.js CHANGED
@@ -1,18 +1,20 @@
1
  const express = require('express');
2
  const router = express.Router();
3
 
4
- // BUG 2 (Medium): There is a syntax error below.
5
- // The closing parenthesis for router.get() is missing,
6
- // which will cause Node.js to crash on startup with a SyntaxError.
7
-
8
  const users = [
9
- { id: 1, name: 'Alice', email: 'alice@example.com' },
10
- { id: 2, name: 'Bob', email: 'bob@example.com' },
11
- { id: 3, name: 'Charlie', email: 'charlie@example.com' }
 
12
  ];
13
 
14
  router.get('/', (req, res) => {
15
- res.json({ users: users });
 
 
 
 
 
16
  };
17
 
18
  module.exports = router;
 
1
  const express = require('express');
2
  const router = express.Router();
3
 
 
 
 
 
4
  const users = [
5
+ { id: 1, name: 'Alice', email: 'alice@example.com', role: 'admin' },
6
+ { id: 2, name: 'Bob', email: 'bob@example.com', role: 'user' },
7
+ { id: 3, name: 'Charlie', email: 'charlie@example.com', role: 'user' },
8
+ { id: 4, name: 'Diana', email: 'diana@example.com', role: 'moderator' }
9
  ];
10
 
11
  router.get('/', (req, res) => {
12
+ const role = req.query.role;
13
+ if (role) {
14
+ const filtered = users.filter(u => u.role === role);
15
+ return res.json({ users: filtered, count: filtered.length });
16
+ }
17
+ res.json({ users: users, count: users.length });
18
  };
19
 
20
  module.exports = router;
simulated_app/server.js CHANGED
@@ -1,22 +1,34 @@
1
  const express = require('express');
2
  const config = require('./config.json');
 
 
3
 
4
  const app = express();
5
  app.use(express.json());
 
 
6
 
7
- // Health check endpoint
8
  app.get('/health', (req, res) => {
9
- res.json({ status: 'ok', uptime: process.uptime() });
10
  });
11
 
12
- // Mount route modules
13
  const usersRouter = require('./routes/users');
14
  const dataRouter = require('./routes/data');
 
15
 
16
  app.use('/api/users', usersRouter);
17
  app.use('/api/data', dataRouter);
 
18
 
19
- // Start server on the port from config
 
 
 
 
 
 
20
  const PORT = config.port;
21
  app.listen(PORT, '0.0.0.0', () => {
22
  console.log(`Server running on port ${PORT}`);
 
1
  const express = require('express');
2
  const config = require('./config.json');
3
+ const { requestLogger } = require('./middleware/logger');
4
+ const { rateLimiter } = require('./middleware/rateLimit');
5
 
6
  const app = express();
7
  app.use(express.json());
8
+ app.use(requestLogger);
9
+ app.use(rateLimiter);
10
 
11
+ // Health check
12
  app.get('/health', (req, res) => {
13
+ res.json({ status: 'ok', uptime: process.uptime(), version: config.version });
14
  });
15
 
16
+ // Mount routes
17
  const usersRouter = require('./routes/users');
18
  const dataRouter = require('./routes/data');
19
+ const statusRouter = require('./routes/status');
20
 
21
  app.use('/api/users', usersRouter);
22
  app.use('/api/data', dataRouter);
23
+ app.use('/api/status', statusRouter);
24
 
25
+ // Error handling middleware
26
+ app.use((err, req, res, next) => {
27
+ console.error(`[ERROR] ${err.message}`);
28
+ res.status(500).json({ error: 'Internal server error' });
29
+ });
30
+
31
+ // Start server
32
  const PORT = config.port;
33
  app.listen(PORT, '0.0.0.0', () => {
34
  console.log(`Server running on port ${PORT}`);