Add detailed statistics API v2 documentation and implement frontend components for displaying statistics
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user