From e1254c6b5fe92b605b67b31d1c1c509da8b3cf70 Mon Sep 17 00:00:00 2001 From: zenn Date: Fri, 1 May 2026 23:49:47 +0900 Subject: [PATCH] =?UTF-8?q?=EB=AF=B8=EB=94=94=EC=96=B4=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=20=ED=98=84=ED=99=A9=20=ED=91=9C=EC=8B=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/history.md | 8 +++ docs/spec.md | 4 +- docs/todo.md | 2 +- docs/update.md | 8 +++ package-lock.json | 4 +- package.json | 2 +- pages/admin/media/index.vue | 45 ++++++++++++++-- server/utils/media-library.js | 96 ++++++++++++++++++++++++++++++++++- 8 files changed, 160 insertions(+), 9 deletions(-) diff --git a/docs/history.md b/docs/history.md index 54d3b32..46fae11 100644 --- a/docs/history.md +++ b/docs/history.md @@ -1,5 +1,13 @@ # 의사결정 이력 +## 2026-05-01 v0.0.16 + +### 미디어 사용처 표시와 삭제 보호 결정 + +미디어 라이브러리에서 파일명 변경과 삭제를 제공하면, 해당 이미지가 글 본문이나 대표 이미지에 사용 중인지 먼저 보여줘야 한다. 현재 콘텐츠는 이미지 URL을 게시물/페이지의 `content`와 `featuredImage`에 직접 저장하므로, 사용 중인 파일을 변경하거나 삭제하면 공개 화면의 이미지가 깨진다. + +따라서 1차 사용처 추적은 게시물과 페이지를 대상으로 본문, 대표 이미지 위치를 표시한다. 사용 중인 미디어의 파일명 변경과 삭제는 차단하고, 미사용 파일만 정리할 수 있도록 한다. 프로필이나 사이트 설정 이미지는 아직 해당 데이터 모델이 없으므로 설정 기능 구현 시 사용처 추적에 추가한다. + ## 2026-05-01 v0.0.15 ### 미디어 라이브러리 1차 범위 결정 diff --git a/docs/spec.md b/docs/spec.md index 330a5a6..3b79e6f 100644 --- a/docs/spec.md +++ b/docs/spec.md @@ -250,7 +250,9 @@ components/content/ - 로컬 개발 업로드 파일은 `public/uploads/posts/YYYY/MM/` 아래 저장하고 `/uploads/posts/YYYY/MM/filename` URL로 제공한다. - 관리자 미디어 화면은 업로드 이미지 목록, 검색, 파일명 변경, 개별 삭제를 제공한다. - 글쓰기 미디어 선택 창은 업로드 미디어 목록에서 이미지를 선택해 단일 이미지 또는 갤러리에 삽입한다. -- 향후 미디어 라이브러리는 카테고리 분류와 이미지 사용처 추적을 제공한다. +- 미디어 사용 현황은 게시물/페이지의 대표 이미지와 본문 내 URL을 기준으로 표시한다. +- 사용 중인 미디어는 저장된 콘텐츠 URL이 깨지지 않도록 파일명 변경과 삭제를 차단한다. +- 향후 미디어 라이브러리는 카테고리 분류와 프로필/사이트 설정 이미지 사용처 추적을 제공한다. --- diff --git a/docs/todo.md b/docs/todo.md index 69dfb94..7a3bf90 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -15,7 +15,7 @@ - [ ] 사이트 설정 - [ ] 메뉴/네비게이션 관리 - [ ] 미디어 라이브러리 카테고리 분류 -- [ ] 미디어 라이브러리 이미지 사용처 추적 +- [ ] 미디어 라이브러리 프로필/사이트 설정 이미지 사용처 추적 ## 3차 관리자 개발 diff --git a/docs/update.md b/docs/update.md index 7dd046d..668da80 100644 --- a/docs/update.md +++ b/docs/update.md @@ -1,5 +1,13 @@ # 업데이트 이력 +## v0.0.16 + +- 관리자 미디어 목록에 게시물/페이지 사용 현황 표시 추가. +- 미디어 사용처를 대표 이미지와 본문 위치로 구분해 표시. +- 사용 중인 미디어의 파일명 변경과 삭제를 차단하도록 수정. +- 미디어 검색 대상에 사용 중인 게시물/페이지 제목 추가. +- 패키지 버전을 0.0.16으로 갱신. + ## v0.0.15 - 관리자 블록 에디터 `/` 메뉴 항목 제목 색상을 진한 본문색으로 수정. diff --git a/package-lock.json b/package-lock.json index a72bdba..0ebcab4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sori.studio", - "version": "0.0.15", + "version": "0.0.16", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sori.studio", - "version": "0.0.15", + "version": "0.0.16", "hasInstallScript": true, "dependencies": { "@nuxtjs/tailwindcss": "^6.14.0", diff --git a/package.json b/package.json index 5f80415..60e9ccb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sori.studio", - "version": "0.0.15", + "version": "0.0.16", "private": true, "type": "module", "scripts": { diff --git a/pages/admin/media/index.vue b/pages/admin/media/index.vue index f1318d6..c5830ad 100644 --- a/pages/admin/media/index.vue +++ b/pages/admin/media/index.vue @@ -23,7 +23,8 @@ const filteredMediaItems = computed(() => { return mediaItems.value.filter((item) => [ item.name, item.url, - item.category + item.category, + ...item.usage.map((usage) => usage.title) ].some((value) => value.toLowerCase().includes(query))) }) @@ -69,6 +70,13 @@ const cancelRename = () => { * @returns {Promise} */ const renameMedia = async () => { + const editingItem = mediaItems.value.find((item) => item.url === editingUrl.value) + + if (editingItem?.usage.length) { + errorMessage.value = '사용 중인 미디어는 파일명을 변경할 수 없습니다.' + return + } + errorMessage.value = '' try { @@ -92,6 +100,11 @@ const renameMedia = async () => { * @returns {Promise} */ const deleteMedia = async (item) => { + if (item.usage.length) { + errorMessage.value = '사용 중인 미디어는 삭제할 수 없습니다.' + return + } + if (!confirm(`"${item.name}" 파일을 삭제할까요?`)) { return } @@ -166,14 +179,40 @@ const deleteMedia = async (item) => {

{{ item.category }} · {{ formatFileSize(item.size) }}

+
+ + 사용 현황 {{ item.usage.length }}곳 + +
    +
  • + + {{ usage.title }} + + {{ usage.title }} + · {{ usage.typeLabel }} · {{ usage.label }} +
  • +
+

+ 사용 중인 곳이 없습니다. +

+
-