59 lines
1.5 KiB
JavaScript
59 lines
1.5 KiB
JavaScript
|
|
/**
|
||
|
|
* 어드민 통계 라우트
|
||
|
|
*/
|
||
|
|
export default async function statsRoutes(fastify, opts) {
|
||
|
|
const { db } = fastify;
|
||
|
|
|
||
|
|
// 모든 라우트에 인증 적용
|
||
|
|
fastify.addHook('preHandler', fastify.authenticate);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 대시보드 통계 조회
|
||
|
|
* GET /api/admin/stats
|
||
|
|
*/
|
||
|
|
fastify.get('/', async (request, reply) => {
|
||
|
|
try {
|
||
|
|
// 멤버 수 (현재 활동 중인 멤버만)
|
||
|
|
const [[{ memberCount }]] = await db.query(
|
||
|
|
'SELECT COUNT(*) as memberCount FROM members WHERE is_former = 0'
|
||
|
|
);
|
||
|
|
|
||
|
|
// 앨범 수
|
||
|
|
const [[{ albumCount }]] = await db.query(
|
||
|
|
'SELECT COUNT(*) as albumCount FROM albums'
|
||
|
|
);
|
||
|
|
|
||
|
|
// 컨셉 포토 수
|
||
|
|
const [[{ photoCount }]] = await db.query(
|
||
|
|
'SELECT COUNT(*) as photoCount FROM album_photos'
|
||
|
|
);
|
||
|
|
|
||
|
|
// 티저 수
|
||
|
|
const [[{ teaserCount }]] = await db.query(
|
||
|
|
'SELECT COUNT(*) as teaserCount FROM album_teasers'
|
||
|
|
);
|
||
|
|
|
||
|
|
// 일정 수 (전체)
|
||
|
|
const [[{ scheduleCount }]] = await db.query(
|
||
|
|
'SELECT COUNT(*) as scheduleCount FROM schedules'
|
||
|
|
);
|
||
|
|
|
||
|
|
// 트랙 수
|
||
|
|
const [[{ trackCount }]] = await db.query(
|
||
|
|
'SELECT COUNT(*) as trackCount FROM tracks'
|
||
|
|
);
|
||
|
|
|
||
|
|
return {
|
||
|
|
members: memberCount,
|
||
|
|
albums: albumCount,
|
||
|
|
photos: photoCount + teaserCount,
|
||
|
|
schedules: scheduleCount,
|
||
|
|
tracks: trackCount,
|
||
|
|
};
|
||
|
|
} catch (err) {
|
||
|
|
fastify.log.error(err);
|
||
|
|
return reply.status(500).send({ error: '통계 조회 실패' });
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|