From cde28b1dd87558c8798bd30529d71f5dad939c4b Mon Sep 17 00:00:00 2001 From: Primakov Alexandr Alexandrovich Date: Tue, 4 Nov 2025 11:18:13 +0300 Subject: [PATCH] Refactor API response structure to include success status and body for all endpoints, ensuring consistent response format across the application. --- stubs/api/data/auth.json | 7 +- stubs/api/data/chains.json | 57 ++++++------- stubs/api/data/queue-status.json | 109 +++++++++++++------------ stubs/api/data/submissions.json | 117 ++++++++++++++------------- stubs/api/data/submit.json | 7 +- stubs/api/data/system-stats.json | 37 +++++---- stubs/api/data/user-stats.json | 115 +++++++++++++------------- stubs/api/data/user-submissions.json | 85 +++++++++---------- stubs/api/index.js | 25 +++--- 9 files changed, 294 insertions(+), 265 deletions(-) diff --git a/stubs/api/data/auth.json b/stubs/api/data/auth.json index 1aa4202..d363744 100644 --- a/stubs/api/data/auth.json +++ b/stubs/api/data/auth.json @@ -1,4 +1,7 @@ { - "ok": true, - "userId": "user-frontend-001" + "success": true, + "body": { + "ok": true, + "userId": "user-frontend-001" + } } diff --git a/stubs/api/data/chains.json b/stubs/api/data/chains.json index 642da32..1059c30 100644 --- a/stubs/api/data/chains.json +++ b/stubs/api/data/chains.json @@ -1,27 +1,30 @@ -[ - { - "id": "chain-frontend", - "_id": "chain-frontend", - "name": "Frontend Basics", - "createdAt": "2024-09-01T08:00:00.000Z", - "updatedAt": "2024-10-12T10:15:00.000Z", - "tasks": [ - { - "id": "task-html-intro", - "_id": "task-html-intro", - "title": "HTML старт", - "description": "# HTML старт\n\nСоздайте базовую HTML-страницу с заголовком и абзацем.", - "createdAt": "2024-09-01T08:05:00.000Z", - "updatedAt": "2024-09-10T12:00:00.000Z" - }, - { - "id": "task-react-component", - "_id": "task-react-component", - "title": "React компонент", - "description": "# React компонент\n\nСоздайте компонент `StatCard` с пропсами `title` и `value`.", - "createdAt": "2024-09-05T11:30:00.000Z", - "updatedAt": "2024-10-01T09:45:00.000Z" - } - ] - } -] +{ + "success": true, + "body": [ + { + "id": "chain-frontend", + "_id": "chain-frontend", + "name": "Frontend Basics", + "createdAt": "2024-09-01T08:00:00.000Z", + "updatedAt": "2024-10-12T10:15:00.000Z", + "tasks": [ + { + "id": "task-html-intro", + "_id": "task-html-intro", + "title": "HTML старт", + "description": "# HTML старт\n\nСоздайте базовую HTML-страницу с заголовком и абзацем.", + "createdAt": "2024-09-01T08:05:00.000Z", + "updatedAt": "2024-09-10T12:00:00.000Z" + }, + { + "id": "task-react-component", + "_id": "task-react-component", + "title": "React компонент", + "description": "# React компонент\n\nСоздайте компонент `StatCard` с пропсами `title` и `value`.", + "createdAt": "2024-09-05T11:30:00.000Z", + "updatedAt": "2024-10-01T09:45:00.000Z" + } + ] + } + ] +} diff --git a/stubs/api/data/queue-status.json b/stubs/api/data/queue-status.json index b5e5ce8..4d4aaed 100644 --- a/stubs/api/data/queue-status.json +++ b/stubs/api/data/queue-status.json @@ -1,57 +1,60 @@ { - "queue-frontend-001": { - "status": "completed", - "position": 0, - "submission": { - "_id": "submission-001", - "id": "submission-001", - "user": "user-frontend-001", - "task": "task-html-intro", - "result": "

Hello

", - "status": "needs_revision", - "queueId": "queue-frontend-001", - "feedback": "Добавьте тег ", - "submittedAt": "2024-10-18T07:10:00.000Z", - "checkedAt": "2024-10-18T07:10:15.000Z", - "attemptNumber": 1 - } - }, - "queue-frontend-002": { - "status": "completed", - "position": 0, - "submission": { - "_id": "submission-002", - "id": "submission-002", - "user": "user-frontend-001", - "task": "task-html-intro", - "result": "<html><head><title>Home

Hello

", - "status": "accepted", - "queueId": "queue-frontend-002", - "feedback": "Отличная работа!", - "submittedAt": "2024-10-18T07:20:00.000Z", - "checkedAt": "2024-10-18T07:20:05.000Z", - "attemptNumber": 2 - } - }, - "queue-frontend-003": { - "status": "waiting", - "position": 3 - }, - "queue-react-001": { - "status": "completed", - "position": 0, - "submission": { - "_id": "submission-004", - "id": "submission-004", - "user": "user-react-777", - "task": "task-react-component", - "result": "export const StatCard = () =>
Stat
;", - "status": "accepted", - "queueId": "queue-react-001", - "feedback": "Добавьте prop-types.", - "submittedAt": "2024-10-17T11:30:00.000Z", - "checkedAt": "2024-10-17T11:30:07.000Z", - "attemptNumber": 1 + "success": true, + "body": { + "queue-frontend-001": { + "status": "completed", + "position": 0, + "submission": { + "_id": "submission-001", + "id": "submission-001", + "user": "user-frontend-001", + "task": "task-html-intro", + "result": "

Hello

", + "status": "needs_revision", + "queueId": "queue-frontend-001", + "feedback": "Добавьте тег ", + "submittedAt": "2024-10-18T07:10:00.000Z", + "checkedAt": "2024-10-18T07:10:15.000Z", + "attemptNumber": 1 + } + }, + "queue-frontend-002": { + "status": "completed", + "position": 0, + "submission": { + "_id": "submission-002", + "id": "submission-002", + "user": "user-frontend-001", + "task": "task-html-intro", + "result": "<html><head><title>Home

Hello

", + "status": "accepted", + "queueId": "queue-frontend-002", + "feedback": "Отличная работа!", + "submittedAt": "2024-10-18T07:20:00.000Z", + "checkedAt": "2024-10-18T07:20:05.000Z", + "attemptNumber": 2 + } + }, + "queue-frontend-003": { + "status": "waiting", + "position": 3 + }, + "queue-react-001": { + "status": "completed", + "position": 0, + "submission": { + "_id": "submission-004", + "id": "submission-004", + "user": "user-react-777", + "task": "task-react-component", + "result": "export const StatCard = () =>
Stat
;", + "status": "accepted", + "queueId": "queue-react-001", + "feedback": "Добавьте prop-types.", + "submittedAt": "2024-10-17T11:30:00.000Z", + "checkedAt": "2024-10-17T11:30:07.000Z", + "attemptNumber": 1 + } } } } diff --git a/stubs/api/data/submissions.json b/stubs/api/data/submissions.json index db2fe23..eb44c71 100644 --- a/stubs/api/data/submissions.json +++ b/stubs/api/data/submissions.json @@ -1,59 +1,62 @@ -[ - { - "_id": "submission-001", - "id": "submission-001", - "user": { - "id": "user-frontend-001", - "nickname": "frontend_ninja" +{ + "success": true, + "body": [ + { + "_id": "submission-001", + "id": "submission-001", + "user": { + "id": "user-frontend-001", + "nickname": "frontend_ninja" + }, + "task": { + "id": "task-html-intro", + "title": "HTML старт" + }, + "result": "

Hello

", + "status": "needs_revision", + "queueId": "queue-frontend-001", + "feedback": "Добавьте тег ", + "submittedAt": "2024-10-18T07:10:00.000Z", + "checkedAt": "2024-10-18T07:10:15.000Z", + "attemptNumber": 1 }, - "task": { - "id": "task-html-intro", - "title": "HTML старт" + { + "_id": "submission-002", + "id": "submission-002", + "user": { + "id": "user-frontend-001", + "nickname": "frontend_ninja" + }, + "task": { + "id": "task-html-intro", + "title": "HTML старт" + }, + "result": "<html><head><title>Home

Hello

", + "status": "accepted", + "queueId": "queue-frontend-002", + "feedback": "Отличная работа!", + "submittedAt": "2024-10-18T07:20:00.000Z", + "checkedAt": "2024-10-18T07:20:05.000Z", + "attemptNumber": 2 }, - "result": "

Hello

", - "status": "needs_revision", - "queueId": "queue-frontend-001", - "feedback": "Добавьте тег ", - "submittedAt": "2024-10-18T07:10:00.000Z", - "checkedAt": "2024-10-18T07:10:15.000Z", - "attemptNumber": 1 - }, - { - "_id": "submission-002", - "id": "submission-002", - "user": { - "id": "user-frontend-001", - "nickname": "frontend_ninja" - }, - "task": { - "id": "task-html-intro", - "title": "HTML старт" - }, - "result": "<html><head><title>Home

Hello

", - "status": "accepted", - "queueId": "queue-frontend-002", - "feedback": "Отличная работа!", - "submittedAt": "2024-10-18T07:20:00.000Z", - "checkedAt": "2024-10-18T07:20:05.000Z", - "attemptNumber": 2 - }, - { - "_id": "submission-004", - "id": "submission-004", - "user": { - "id": "user-react-777", - "nickname": "react_master" - }, - "task": { - "id": "task-react-component", - "title": "React компонент" - }, - "result": "export const StatCard = () =>
Stat
;", - "status": "accepted", - "queueId": "queue-react-001", - "feedback": "Добавьте prop-types.", - "submittedAt": "2024-10-17T11:30:00.000Z", - "checkedAt": "2024-10-17T11:30:07.000Z", - "attemptNumber": 1 - } -] + { + "_id": "submission-004", + "id": "submission-004", + "user": { + "id": "user-react-777", + "nickname": "react_master" + }, + "task": { + "id": "task-react-component", + "title": "React компонент" + }, + "result": "export const StatCard = () =>
Stat
;", + "status": "accepted", + "queueId": "queue-react-001", + "feedback": "Добавьте prop-types.", + "submittedAt": "2024-10-17T11:30:00.000Z", + "checkedAt": "2024-10-17T11:30:07.000Z", + "attemptNumber": 1 + } + ] +} diff --git a/stubs/api/data/submit.json b/stubs/api/data/submit.json index 318334c..da29625 100644 --- a/stubs/api/data/submit.json +++ b/stubs/api/data/submit.json @@ -1,4 +1,7 @@ { - "queueId": "queue-frontend-003", - "submissionId": "submission-003" + "success": true, + "body": { + "queueId": "queue-frontend-003", + "submissionId": "submission-003" + } } diff --git a/stubs/api/data/system-stats.json b/stubs/api/data/system-stats.json index 3378707..4e14631 100644 --- a/stubs/api/data/system-stats.json +++ b/stubs/api/data/system-stats.json @@ -1,20 +1,23 @@ { - "users": 128, - "tasks": 34, - "chains": 5, - "submissions": { - "total": 540, - "accepted": 312, - "rejected": 144, - "pending": 62, - "inProgress": 22 - }, - "averageCheckTimeMs": 5600, - "queue": { - "queueLength": 18, - "waiting": 12, - "inProgress": 6, - "maxConcurrency": 8, - "currentlyProcessing": 6 + "success": true, + "body": { + "users": 128, + "tasks": 34, + "chains": 5, + "submissions": { + "total": 540, + "accepted": 312, + "rejected": 144, + "pending": 62, + "inProgress": 22 + }, + "averageCheckTimeMs": 5600, + "queue": { + "queueLength": 18, + "waiting": 12, + "inProgress": 6, + "maxConcurrency": 8, + "currentlyProcessing": 6 + } } } diff --git a/stubs/api/data/user-stats.json b/stubs/api/data/user-stats.json index ea7f4d4..90c9105 100644 --- a/stubs/api/data/user-stats.json +++ b/stubs/api/data/user-stats.json @@ -1,59 +1,62 @@ { - "user-frontend-001": { - "totalTasksAttempted": 2, - "completedTasks": 1, - "inProgressTasks": 1, - "needsRevisionTasks": 0, - "totalSubmissions": 3, - "averageCheckTimeMs": 4200, - "taskStats": [ - { - "taskId": "task-html-intro", - "taskTitle": "HTML старт", - "attempts": [ - { - "attemptNumber": 1, - "status": "needs_revision", - "submittedAt": "2024-10-18T07:10:00.000Z", - "checkedAt": "2024-10-18T07:10:15.000Z", - "feedback": "Добавьте тег ." - }, - { - "attemptNumber": 2, - "status": "accepted", - "submittedAt": "2024-10-18T07:20:00.000Z", - "checkedAt": "2024-10-18T07:20:05.000Z", - "feedback": "Отличная работа!" - } - ], - "totalAttempts": 2, - "status": "completed", - "lastAttemptAt": "2024-10-18T07:20:00.000Z" - }, - { - "taskId": "task-react-component", - "taskTitle": "React компонент", - "attempts": [ - { - "attemptNumber": 1, - "status": "pending", - "submittedAt": "2024-10-19T09:05:00.000Z", - "feedback": null - } - ], - "totalAttempts": 1, - "status": "pending", - "lastAttemptAt": "2024-10-19T09:05:00.000Z" - } - ], - "chainStats": [ - { - "chainId": "chain-frontend", - "chainName": "Frontend Basics", - "totalTasks": 2, - "completedTasks": 1, - "progress": 50 - } - ] + "success": true, + "body": { + "user-frontend-001": { + "totalTasksAttempted": 2, + "completedTasks": 1, + "inProgressTasks": 1, + "needsRevisionTasks": 0, + "totalSubmissions": 3, + "averageCheckTimeMs": 4200, + "taskStats": [ + { + "taskId": "task-html-intro", + "taskTitle": "HTML старт", + "attempts": [ + { + "attemptNumber": 1, + "status": "needs_revision", + "submittedAt": "2024-10-18T07:10:00.000Z", + "checkedAt": "2024-10-18T07:10:15.000Z", + "feedback": "Добавьте тег <title>." + }, + { + "attemptNumber": 2, + "status": "accepted", + "submittedAt": "2024-10-18T07:20:00.000Z", + "checkedAt": "2024-10-18T07:20:05.000Z", + "feedback": "Отличная работа!" + } + ], + "totalAttempts": 2, + "status": "completed", + "lastAttemptAt": "2024-10-18T07:20:00.000Z" + }, + { + "taskId": "task-react-component", + "taskTitle": "React компонент", + "attempts": [ + { + "attemptNumber": 1, + "status": "pending", + "submittedAt": "2024-10-19T09:05:00.000Z", + "feedback": null + } + ], + "totalAttempts": 1, + "status": "pending", + "lastAttemptAt": "2024-10-19T09:05:00.000Z" + } + ], + "chainStats": [ + { + "chainId": "chain-frontend", + "chainName": "Frontend Basics", + "totalTasks": 2, + "completedTasks": 1, + "progress": 50 + } + ] + } } } diff --git a/stubs/api/data/user-submissions.json b/stubs/api/data/user-submissions.json index bcd5c7b..13a16bc 100644 --- a/stubs/api/data/user-submissions.json +++ b/stubs/api/data/user-submissions.json @@ -1,43 +1,46 @@ { - "user-frontend-001": [ - { - "_id": "submission-001", - "id": "submission-001", - "user": "user-frontend-001", - "task": "task-html-intro", - "result": "<html><head></head><body><h1>Hello</h1></body></html>", - "status": "needs_revision", - "queueId": "queue-frontend-001", - "feedback": "Добавьте тег <title>", - "submittedAt": "2024-10-18T07:10:00.000Z", - "checkedAt": "2024-10-18T07:10:15.000Z", - "attemptNumber": 1 - }, - { - "_id": "submission-002", - "id": "submission-002", - "user": "user-frontend-001", - "task": "task-html-intro", - "result": "<html><head><title>Home

Hello

", - "status": "accepted", - "queueId": "queue-frontend-002", - "feedback": "Отличная работа!", - "submittedAt": "2024-10-18T07:20:00.000Z", - "checkedAt": "2024-10-18T07:20:05.000Z", - "attemptNumber": 2 - }, - { - "_id": "submission-003", - "id": "submission-003", - "user": "user-frontend-001", - "task": "task-react-component", - "result": "export const StatCard = () => null;", - "status": "pending", - "queueId": "queue-frontend-003", - "feedback": null, - "submittedAt": "2024-10-19T09:05:00.000Z", - "checkedAt": null, - "attemptNumber": 1 - } - ] + "success": true, + "body": { + "user-frontend-001": [ + { + "_id": "submission-001", + "id": "submission-001", + "user": "user-frontend-001", + "task": "task-html-intro", + "result": "

Hello

", + "status": "needs_revision", + "queueId": "queue-frontend-001", + "feedback": "Добавьте тег ", + "submittedAt": "2024-10-18T07:10:00.000Z", + "checkedAt": "2024-10-18T07:10:15.000Z", + "attemptNumber": 1 + }, + { + "_id": "submission-002", + "id": "submission-002", + "user": "user-frontend-001", + "task": "task-html-intro", + "result": "<html><head><title>Home

Hello

", + "status": "accepted", + "queueId": "queue-frontend-002", + "feedback": "Отличная работа!", + "submittedAt": "2024-10-18T07:20:00.000Z", + "checkedAt": "2024-10-18T07:20:05.000Z", + "attemptNumber": 2 + }, + { + "_id": "submission-003", + "id": "submission-003", + "user": "user-frontend-001", + "task": "task-react-component", + "result": "export const StatCard = () => null;", + "status": "pending", + "queueId": "queue-frontend-003", + "feedback": null, + "submittedAt": "2024-10-19T09:05:00.000Z", + "checkedAt": null, + "attemptNumber": 1 + } + ] + } } diff --git a/stubs/api/index.js b/stubs/api/index.js index 48fb8f8..f259838 100644 --- a/stubs/api/index.js +++ b/stubs/api/index.js @@ -32,16 +32,18 @@ router.get('/challenge/chains', (req, res) => { }) router.get('/challenge/chain/:id', (req, res) => { - const chains = readJson('chains.json') + 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(chain) + return res.json({ success: true, body: chain }) }) router.get('/challenge/task/:id', (req, res) => { - const chains = readJson('chains.json') + 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) @@ -50,7 +52,7 @@ router.get('/challenge/task/:id', (req, res) => { return sendNotFound(res, `Задание ${req.params.id} не найдено`) } - return res.json(task) + return res.json({ success: true, body: task }) }) router.post('/challenge/submit', (req, res) => { @@ -59,31 +61,34 @@ router.post('/challenge/submit', (req, res) => { }) router.get('/challenge/check-status/:queueId', (req, res) => { - const statuses = readJson('queue-status.json') + const data = readJson('queue-status.json') + const statuses = data.body || data const status = statuses[req.params.queueId] if (!status) { return sendNotFound(res, `Статус очереди ${req.params.queueId} не найден`) } - return res.json(status) + return res.json({ success: true, body: status }) }) router.get('/challenge/user/:userId/stats', (req, res) => { - const statsMap = readJson('user-stats.json') + const data = readJson('user-stats.json') + const statsMap = data.body || data const stats = statsMap[req.params.userId] if (!stats) { return sendNotFound(res, `Статистика пользователя ${req.params.userId} не найдена`) } - return res.json(stats) + return res.json({ success: true, body: stats }) }) router.get('/challenge/user/:userId/submissions', (req, res) => { - const submissionsMap = readJson('user-submissions.json') + const data = readJson('user-submissions.json') + const submissionsMap = data.body || data const submissions = submissionsMap[req.params.userId] || [] - return res.json(submissions) + return res.json({ success: true, body: submissions }) }) router.get('/challenge/stats', (req, res) => {