const fs = require('fs') const path = require('path') const router = require('express').Router() const timer = (time = 100) => (req, res, next) => setTimeout(next, time) const dataDir = path.join(__dirname, 'data') const readJson = (fileName) => { const filePath = path.join(dataDir, fileName) const content = fs.readFileSync(filePath, 'utf-8') return JSON.parse(content) } const sendNotFound = (res, message) => { res.status(404).json({ error: { message }, data: null }) } router.use(timer()) router.use((req, res, next) => { res.type('application/json') next() }) // Challenge API endpoints router.post('/challenge/auth', (req, res) => { res.json(readJson('auth.json')) }) router.get('/challenge/chains', (req, res) => { res.json(readJson('chains.json')) }) router.get('/challenge/chain/:id', (req, res) => { const data = readJson('chains.json') const chains = data.body || data const chain = chains.find((item) => item.id === req.params.id || item._id === req.params.id) if (!chain) { return sendNotFound(res, `Цепочка ${req.params.id} не найдена`) } return res.json({ success: true, body: chain }) }) router.get('/challenge/task/:id', (req, res) => { const data = readJson('chains.json') const chains = data.body || data const task = chains .flatMap((chain) => chain.tasks || []) .find((item) => item.id === req.params.id || item._id === req.params.id) if (!task) { return sendNotFound(res, `Задание ${req.params.id} не найдено`) } return res.json({ success: true, body: task }) }) router.post('/challenge/submit', (req, res) => { const response = readJson('submit.json') const queueId = response.body?.queueId if (queueId) { queueBehaviors[queueId] = queueBehaviors[queueId] ?? { nextFailure: false, attemptNumber: 0 } queueStates[queueId] = { position: 3, initialPosition: 3, pollCount: 0, startTime: Date.now(), } } res.json(response) }) // Храним состояние очереди для каждого queueId const queueStates = {} const queueBehaviors = {} router.get('/challenge/check-status/:queueId', (req, res) => { const queueId = req.params.queueId // Инициализируем состояние очереди, если его нет if (!queueStates[queueId]) { queueStates[queueId] = { position: 3, initialPosition: 3, pollCount: 0, startTime: Date.now() } } const state = queueStates[queueId] state.pollCount++ // Симулируем движение в очереди // Каждый запрос уменьшаем позицию (быстрее) if (state.pollCount >= 1 && state.position > 0) { state.position-- state.pollCount = 0 } // Если позиция 0, переходим к проверке if (state.position === 0 && state.pollCount >= 1) { const behavior = queueBehaviors[queueId] ?? { nextFailure: false, attemptNumber: 0 } const attemptNumber = behavior.attemptNumber + 1 behavior.attemptNumber = attemptNumber const shouldFail = behavior.nextFailure behavior.nextFailure = !shouldFail const baseSubmission = { _id: `submission-${queueId}-${attemptNumber}`, id: `submission-${queueId}-${attemptNumber}`, user: 'user-frontend-001', task: 'task-html-intro', result: '