Add detailed statistics API v2 documentation and implement frontend components for displaying statistics

This commit is contained in:
Primakov Alexandr Alexandrovich
2025-11-04 21:37:03 +03:00
parent b91ee56bf0
commit fd55d5a214
16 changed files with 2233 additions and 29 deletions

View File

@@ -29,6 +29,7 @@ let chainsCache = null;
let usersCache = null;
let submissionsCache = null;
let statsCache = null;
let statsV2Cache = null;
const getTasks = () => {
if (!tasksCache) tasksCache = loadJSON('tasks.json');
@@ -55,6 +56,11 @@ const getStats = () => {
return statsCache;
};
const getStatsV2 = () => {
if (!statsV2Cache) statsV2Cache = loadJSON('stats-v2.json');
return statsV2Cache;
};
router.use(timer());
// ============= TASKS =============
@@ -282,6 +288,46 @@ router.get('/challenge/stats', (req, res) => {
respond(res, stats);
});
// GET /api/challenge/stats/v2
router.get('/challenge/stats/v2', (req, res) => {
const statsV2 = getStatsV2();
const chainId = req.query.chainId;
// Если chainId не передан, возвращаем все данные
if (!chainId) {
respond(res, statsV2);
return;
}
// Фильтруем данные по выбранной цепочке
const filteredChain = statsV2.chainsDetailed.find(c => c.chainId === chainId);
if (!filteredChain) {
return respondError(res, 'Chain not found', 404);
}
// Фильтруем tasksTable - только задания из этой цепочки
const chainTaskIds = new Set(filteredChain.tasks.map(t => t.taskId));
const filteredTasksTable = statsV2.tasksTable.filter(t => chainTaskIds.has(t.taskId));
// Фильтруем activeParticipants - только участники с попытками в этой цепочке
const participantIds = new Set(filteredChain.participantProgress.map(p => p.userId));
const filteredParticipants = statsV2.activeParticipants
.filter(p => participantIds.has(p.userId))
.map(p => ({
...p,
chainProgress: p.chainProgress.filter(cp => cp.chainId === chainId)
}));
// Возвращаем отфильтрованные данные
respond(res, {
...statsV2,
tasksTable: filteredTasksTable,
activeParticipants: filteredParticipants,
chainsDetailed: [filteredChain]
});
});
// GET /api/challenge/user/:userId/stats
router.get('/challenge/user/:userId/stats', (req, res) => {
const users = getUsers();