관리자 글 목록 백링크 열 추가

This commit is contained in:
2026-07-10 16:32:37 +09:00
parent d708381e09
commit 04c03ad604
7 changed files with 109 additions and 26 deletions

View File

@@ -106,6 +106,7 @@ const mapAdminPostSummaryRow = (row) => ({
publishedAt: row.published_at ? row.published_at.toISOString() : null,
createdAt: row.created_at.toISOString(),
updatedAt: row.updated_at.toISOString(),
backlinkCount: Number(row.backlinkCount || row.backlink_count || 0),
tags: row.tags || []
})
@@ -139,6 +140,57 @@ const countPostLinkReferences = (content, slug) => {
return [...String(content || '').matchAll(createPostLinkReferencePattern(slug))].length
}
/**
* 대상 게시물별 백링크 게시물 개수 맵을 생성한다.
* @param {Array<{ id: string, slug: string }>} targetPosts - 백링크 개수를 계산할 게시물 목록
* @param {Array<{ id: string, content?: string }>} sourcePosts - 링크 출처 게시물 목록
* @returns {Map<string, number>} 게시물 ID별 백링크 게시물 개수
*/
const createAdminPostBacklinkCountMap = (targetPosts, sourcePosts) => {
const countMap = new Map(targetPosts.map((post) => [post.id, 0]))
for (const targetPost of targetPosts) {
if (!targetPost?.id || !targetPost?.slug) {
continue
}
const backlinkCount = sourcePosts.filter((sourcePost) => {
return sourcePost.id !== targetPost.id
&& countPostLinkReferences(sourcePost.content, targetPost.slug) > 0
}).length
countMap.set(targetPost.id, backlinkCount)
}
return countMap
}
/**
* 관리자 글 목록 대상의 백링크 게시물 개수를 조회한다.
* @param {Array<{ id: string, slug: string }>} targetPosts - 백링크 개수를 계산할 게시물 목록
* @returns {Promise<Map<string, number>>} 게시물 ID별 백링크 게시물 개수
*/
const getAdminPostBacklinkCountMap = async (targetPosts) => {
const sql = getPostgresClient()
if (!targetPosts.length) {
return new Map()
}
if (!sql) {
return createAdminPostBacklinkCountMap(targetPosts, getSamplePosts())
}
const sourceRows = await sql`
SELECT id, content
FROM posts
WHERE content IS NOT NULL
AND content <> ''
`
return createAdminPostBacklinkCountMap(targetPosts, sourceRows)
}
/**
* 관리자 글 목록 페이지 표시 개수를 정규화한다.
* @param {unknown} value - 요청 표시 개수
@@ -617,14 +669,23 @@ export const listAdminPosts = async (options = {}) => {
})
if (!paged) {
return samplePosts.map(({ sortAt, ...post }) => post)
const items = samplePosts.map(({ sortAt, ...post }) => post)
const backlinkCounts = createAdminPostBacklinkCountMap(items, getSamplePosts())
return items.map((post) => ({
...post,
backlinkCount: backlinkCounts.get(post.id) || 0
}))
}
const total = samplePosts.length
const items = samplePosts.slice(offset, offset + pageSize).map(({ sortAt, ...post }) => post)
const backlinkCounts = createAdminPostBacklinkCountMap(items, getSamplePosts())
return {
items,
items: items.map((post) => ({
...post,
backlinkCount: backlinkCounts.get(post.id) || 0
})),
pagination: {
page,
pageSize,
@@ -732,8 +793,14 @@ export const listAdminPosts = async (options = {}) => {
OFFSET ${paged ? offset : 0}
`
const backlinkCounts = await getAdminPostBacklinkCountMap(rows)
const mapAdminPostSummaryRowWithBacklinks = (row) => ({
...mapAdminPostSummaryRow(row),
backlinkCount: backlinkCounts.get(row.id) || 0
})
if (!paged) {
return rows.map(mapAdminPostSummaryRow)
return rows.map(mapAdminPostSummaryRowWithBacklinks)
}
const countsRows = await sql`
@@ -791,7 +858,7 @@ export const listAdminPosts = async (options = {}) => {
const total = Number(totalRows[0]?.total || 0)
return {
items: rows.map(mapAdminPostSummaryRow),
items: rows.map(mapAdminPostSummaryRowWithBacklinks),
pagination: {
page,
pageSize,