132 lines
4.0 KiB
TypeScript
132 lines
4.0 KiB
TypeScript
import { query } from '../../../utils/db'
|
|
import { requireAuth } from '../../../utils/session'
|
|
|
|
/**
|
|
* 프로젝트 커밋 목록 조회
|
|
* GET /api/project/[id]/commits
|
|
*
|
|
* Query params:
|
|
* - startDate: 시작일 (YYYY-MM-DD)
|
|
* - endDate: 종료일 (YYYY-MM-DD)
|
|
* - repoId: 저장소 ID (옵션)
|
|
* - authorId: 작성자 ID (옵션)
|
|
* - page: 페이지 번호 (기본 1)
|
|
* - limit: 페이지당 개수 (기본 50)
|
|
*/
|
|
export default defineEventHandler(async (event) => {
|
|
await requireAuth(event)
|
|
const projectId = parseInt(getRouterParam(event, 'id') || '0')
|
|
const queryParams = getQuery(event)
|
|
|
|
if (!projectId) {
|
|
throw createError({ statusCode: 400, message: '프로젝트 ID가 필요합니다.' })
|
|
}
|
|
|
|
const startDate = queryParams.startDate as string
|
|
const endDate = queryParams.endDate as string
|
|
const repoId = queryParams.repoId ? parseInt(queryParams.repoId as string) : null
|
|
const authorId = queryParams.authorId ? parseInt(queryParams.authorId as string) : null
|
|
const page = parseInt(queryParams.page as string) || 1
|
|
const limit = Math.min(parseInt(queryParams.limit as string) || 50, 100)
|
|
const offset = (page - 1) * limit
|
|
|
|
// 조건 빌드
|
|
const conditions = ['r.project_id = $1']
|
|
const values: any[] = [projectId]
|
|
let paramIndex = 2
|
|
|
|
if (startDate) {
|
|
conditions.push(`c.commit_date >= $${paramIndex++}`)
|
|
values.push(startDate)
|
|
}
|
|
|
|
if (endDate) {
|
|
conditions.push(`c.commit_date <= $${paramIndex++}::date + INTERVAL '1 day'`)
|
|
values.push(endDate)
|
|
}
|
|
|
|
if (repoId) {
|
|
conditions.push(`c.repo_id = $${paramIndex++}`)
|
|
values.push(repoId)
|
|
}
|
|
|
|
if (authorId) {
|
|
conditions.push(`c.employee_id = $${paramIndex++}`)
|
|
values.push(authorId)
|
|
}
|
|
|
|
const whereClause = conditions.join(' AND ')
|
|
|
|
// 커밋 목록 조회
|
|
const commits = await query(`
|
|
SELECT
|
|
c.commit_id, c.commit_hash, c.commit_message, c.commit_author, c.commit_email,
|
|
c.commit_date, c.employee_id, c.files_changed, c.insertions, c.deletions,
|
|
r.repo_id, r.repo_name, r.repo_path,
|
|
s.server_type, s.server_name,
|
|
e.employee_name, e.display_name
|
|
FROM wr_commit_log c
|
|
JOIN wr_repository r ON c.repo_id = r.repo_id
|
|
JOIN wr_vcs_server s ON r.server_id = s.server_id
|
|
LEFT JOIN wr_employee_info e ON c.employee_id = e.employee_id
|
|
WHERE ${whereClause}
|
|
ORDER BY c.commit_date DESC
|
|
LIMIT $${paramIndex++} OFFSET $${paramIndex++}
|
|
`, [...values, limit, offset])
|
|
|
|
// 전체 개수 조회
|
|
const countResult = await query(`
|
|
SELECT COUNT(*) as total
|
|
FROM wr_commit_log c
|
|
JOIN wr_repository r ON c.repo_id = r.repo_id
|
|
WHERE ${whereClause}
|
|
`, values)
|
|
|
|
const total = parseInt(countResult[0]?.total || '0')
|
|
|
|
// 통계 (해당 기간)
|
|
const statsResult = await query(`
|
|
SELECT
|
|
COUNT(*) as commit_count,
|
|
COALESCE(SUM(c.insertions), 0) as total_insertions,
|
|
COALESCE(SUM(c.deletions), 0) as total_deletions,
|
|
COUNT(DISTINCT c.employee_id) as author_count
|
|
FROM wr_commit_log c
|
|
JOIN wr_repository r ON c.repo_id = r.repo_id
|
|
WHERE ${whereClause}
|
|
`, values)
|
|
|
|
return {
|
|
commits: commits.map(c => ({
|
|
commitId: c.commit_id,
|
|
commitHash: c.commit_hash,
|
|
commitMessage: c.commit_message,
|
|
commitAuthor: c.commit_author,
|
|
commitEmail: c.commit_email,
|
|
commitDate: c.commit_date,
|
|
employeeId: c.employee_id,
|
|
employeeName: c.display_name || c.employee_name,
|
|
filesChanged: c.files_changed,
|
|
insertions: c.insertions,
|
|
deletions: c.deletions,
|
|
repoId: c.repo_id,
|
|
repoName: c.repo_name,
|
|
repoPath: c.repo_path,
|
|
serverType: c.server_type,
|
|
serverName: c.server_name
|
|
})),
|
|
pagination: {
|
|
page,
|
|
limit,
|
|
total,
|
|
totalPages: Math.ceil(total / limit)
|
|
},
|
|
stats: {
|
|
commitCount: parseInt(statsResult[0]?.commit_count || '0'),
|
|
totalInsertions: parseInt(statsResult[0]?.total_insertions || '0'),
|
|
totalDeletions: parseInt(statsResult[0]?.total_deletions || '0'),
|
|
authorCount: parseInt(statsResult[0]?.author_count || '0')
|
|
}
|
|
}
|
|
})
|