관리자 목록과 이미지 설정 개선

This commit is contained in:
2026-07-20 12:37:53 +09:00
parent cf7d6ca0de
commit ad38644171
19 changed files with 788 additions and 92 deletions

View File

@@ -141,12 +141,12 @@ const countPostLinkReferences = (content, slug) => {
}
/**
* 대상 게시물별 백링크 게시물 개수 맵을 생성한다.
* 대상 게시물별 백링크 콘텐츠 개수 맵을 생성한다.
* @param {Array<{ id: string, slug: string }>} targetPosts - 백링크 개수를 계산할 게시물 목록
* @param {Array<{ id: string, content?: string }>} sourcePosts - 링크 출처 게시물 목록
* @returns {Map<string, number>} 게시물 ID별 백링크 게시물 개수
* @param {Array<{ id: string, sourceType?: 'post'|'page', content?: string }>} sourceItems - 링크 출처 콘텐츠 목록
* @returns {Map<string, number>} 게시물 ID별 백링크 콘텐츠 개수
*/
const createAdminPostBacklinkCountMap = (targetPosts, sourcePosts) => {
const createAdminPostBacklinkCountMap = (targetPosts, sourceItems) => {
const countMap = new Map(targetPosts.map((post) => [post.id, 0]))
for (const targetPost of targetPosts) {
@@ -154,9 +154,9 @@ const createAdminPostBacklinkCountMap = (targetPosts, sourcePosts) => {
continue
}
const backlinkCount = sourcePosts.filter((sourcePost) => {
return sourcePost.id !== targetPost.id
&& countPostLinkReferences(sourcePost.content, targetPost.slug) > 0
const backlinkCount = sourceItems.filter((sourceItem) => {
return !(sourceItem.sourceType === 'post' && sourceItem.id === targetPost.id)
&& countPostLinkReferences(sourceItem.content, targetPost.slug) > 0
}).length
countMap.set(targetPost.id, backlinkCount)
@@ -166,9 +166,9 @@ const createAdminPostBacklinkCountMap = (targetPosts, sourcePosts) => {
}
/**
* 관리자 글 목록 대상의 백링크 게시물 개수를 조회한다.
* 관리자 글 목록 대상의 백링크 콘텐츠 개수를 조회한다.
* @param {Array<{ id: string, slug: string }>} targetPosts - 백링크 개수를 계산할 게시물 목록
* @returns {Promise<Map<string, number>>} 게시물 ID별 백링크 게시물 개수
* @returns {Promise<Map<string, number>>} 게시물 ID별 백링크 콘텐츠 개수
*/
const getAdminPostBacklinkCountMap = async (targetPosts) => {
const sql = getPostgresClient()
@@ -178,17 +178,29 @@ const getAdminPostBacklinkCountMap = async (targetPosts) => {
}
if (!sql) {
return createAdminPostBacklinkCountMap(targetPosts, getSamplePosts())
return createAdminPostBacklinkCountMap(targetPosts, [
...getSamplePosts().map((post) => ({ ...post, sourceType: 'post' })),
...getSamplePages().map((page) => ({ ...page, sourceType: 'page' }))
])
}
const sourceRows = await sql`
SELECT id, content
SELECT id, 'post' AS source_type, content
FROM posts
WHERE content IS NOT NULL
AND content <> ''
UNION ALL
SELECT id, 'page' AS source_type, content
FROM pages
WHERE content IS NOT NULL
AND content <> ''
`
return createAdminPostBacklinkCountMap(targetPosts, sourceRows)
return createAdminPostBacklinkCountMap(targetPosts, sourceRows.map((row) => ({
id: row.id,
sourceType: row.source_type,
content: row.content
})))
}
/**
@@ -914,9 +926,9 @@ export const listMediaReferencePosts = async () => {
}
/**
* 게시물을 링크하고 있는 관리자 게시물 목록을 조회한다.
* 게시물을 링크하고 있는 관리자 콘텐츠 목록을 조회한다.
* @param {string} id - 참조 대상 게시물 ID
* @returns {Promise<{ target: { id: string, title: string, slug: string }, posts: Array<{ id: string, title: string, slug: string, status: string, publishedAt: string | null, updatedAt: string }> } | null>} 참조 게시물 목록
* @returns {Promise<{ target: { id: string, title: string, slug: string }, posts: Array<{ id: string, title: string, slug: string, status: string, publishedAt: string | null, updatedAt: string }>, pages: Array<{ id: string, title: string, slug: string, status: string, updatedAt: string }> } | null>} 참조 콘텐츠 목록
*/
export const listAdminPostReferences = async (id) => {
const sql = getPostgresClient()
@@ -941,6 +953,16 @@ export const listAdminPostReferences = async (id) => {
})
const removeReferenceCount = ({ referenceCount, ...post }) => post
const mapReferencePageRow = (page) => ({
id: page.id,
title: toAdminPostFormTitle(page.title),
slug: page.slug,
status: page.status,
updatedAt: page.updated_at
? page.updated_at.toISOString()
: page.updatedAt || '',
referenceCount: countPostLinkReferences(page.content, target.slug)
})
if (!sql) {
const posts = getSamplePosts()
@@ -948,6 +970,10 @@ export const listAdminPostReferences = async (id) => {
.map(mapReferenceRow)
.filter((post) => post.referenceCount > 0)
.map(removeReferenceCount)
const pages = getSamplePages()
.map(mapReferencePageRow)
.filter((page) => page.referenceCount > 0)
.map(removeReferenceCount)
return {
target: {
@@ -955,7 +981,8 @@ export const listAdminPostReferences = async (id) => {
title: target.title,
slug: target.slug
},
posts
posts,
pages
}
}
@@ -973,6 +1000,18 @@ export const listAdminPostReferences = async (id) => {
AND content ILIKE ${`%/post/${target.slug}%`}
ORDER BY updated_at DESC
`
const pageRows = await sql`
SELECT
id,
title,
slug,
status,
updated_at,
content
FROM pages
WHERE content ILIKE ${`%/post/${target.slug}%`}
ORDER BY updated_at DESC
`
return {
target: {
@@ -983,6 +1022,10 @@ export const listAdminPostReferences = async (id) => {
posts: rows
.map(mapReferenceRow)
.filter((post) => post.referenceCount > 0)
.map(removeReferenceCount),
pages: pageRows
.map(mapReferencePageRow)
.filter((page) => page.referenceCount > 0)
.map(removeReferenceCount)
}
}