관리자 미디어 카드 썸네일 탭 분리

This commit is contained in:
2026-06-08 14:57:38 +09:00
parent 664d2f98aa
commit eb4018f92c
11 changed files with 332 additions and 41 deletions

View File

@@ -1,5 +1,11 @@
# 업데이트 요약
## v1.5.79
- 관리자 미디어에서 카드 썸네일을 별도 탭으로 분리했다.
- 카드 썸네일 사용 여부를 원본 대표 이미지 사용처와 연결해 미사용으로 잘못 표시되지 않게 했다.
- 썸네일이 없어 목록에서 원본을 불러오는 대표 이미지를 구분해 표시하도록 했다.
## v1.5.78
- 게시물 목록 카드에서 원본 대표 이미지 대신 생성된 카드용 썸네일을 우선 사용하도록 개선했다.

View File

@@ -1,6 +1,6 @@
# 배포 가이드
> 로컬 기준 v1.5.78에서 `npm run lint`, `npm run build` 검증을 통과했다. NAS 실제 컨테이너 기동과 도메인/프록시 접속 검증은 운영 배포 단계에서 진행한다.
> 로컬 기준 v1.5.79에서 `npm run lint`, `npm run build` 검증을 통과했다. NAS 실제 컨테이너 기동과 도메인/프록시 접속 검증은 운영 배포 단계에서 진행한다.
## 빌드 유형
@@ -16,6 +16,14 @@
## 로컬 개발
### v1.5.79 참고
- 추가 DB 마이그레이션은 없다.
- 관리자 미디어 화면에서 일반 미디어 라이브러리에 `thumbs/*-card.webp` 파일이 섞이지 않고, 카드 썸네일 탭에만 표시되는지 확인한다.
- 대표 이미지로 사용 중인 원본에 카드 썸네일이 있으면 카드 썸네일 탭에서 사용 중으로 표시되고 삭제가 차단되는지 확인한다.
- 대표 이미지로 사용 중인 원본에 카드 썸네일이 없으면 원본 항목에 `원본` 배지와 fallback 상태가 표시되는지 확인한다.
- 운영 기존 업로드 중 fallback 상태가 보이면 `npm run images:backfill-post-thumbnails`를 실행한다.
### v1.5.78 참고
- 추가 DB 마이그레이션은 없다.

View File

@@ -1,5 +1,9 @@
# 의사결정 이력
## 2026-06-08 v1.5.79 — 카드 썸네일은 별도 탭과 원본 연결 사용처로 관리한다
게시물 카드 썸네일은 사용자가 직접 본문에 삽입하는 원본 미디어가 아니라 목록 성능을 위해 자동 생성되는 파생 파일이다. 일반 미디어 라이브러리에 원본과 썸네일을 함께 노출하면 같은 이미지가 두 개씩 보이고, 미사용 정리 과정에서 실제 목록에 쓰는 썸네일을 삭제할 위험이 있다. 따라서 카드 썸네일을 별도 탭으로 분리하고, 사용 여부는 썸네일 URL 자체가 아니라 원본 대표 이미지 사용처에 연결해 판단한다. 원본이 대표 이미지로 쓰이지만 썸네일이 없으면 목록에서 원본을 불러오는 fallback 상태로 표시해 백필 필요 여부를 구분한다.
## 2026-06-08 v1.5.78 — 공개 목록 이미지는 원본 대신 카드 썸네일을 우선 사용한다
대표 이미지는 상세 화면, OG 이미지, RSS 같은 원본 품질이 필요한 경로에서도 쓰인다. 하지만 메인·목록·태그 카드에서는 작은 썸네일만 필요하므로 사이트 접속만으로 큰 원본 이미지를 내려받는 비용이 크다. 업로드 시점에 640×360 WebP 카드 썸네일을 함께 만들고, 공개 목록 응답에는 파일이 실제로 존재할 때만 `featuredImageThumbnail`을 추가해 기존 이미지와 외부 URL의 fallback을 유지한다. 기존 업로드 파일은 운영 볼륨에 저장되므로 저장소에 포함하지 않고 백필 명령으로 생성한다.

View File

@@ -152,7 +152,7 @@
| pages/admin/pages/index.vue | 페이지 목록, 상태 표시, 화면 기준 행 more vert 메뉴(수정·삭제) |
| pages/admin/pages/new.vue | 전체 화면 페이지 작성, HTML 문서 기본 모드 저장, 저장 토스트 |
| pages/admin/pages/[id].vue | 전체 화면 페이지 수정, HTML 문서/일반 텍스트 모드 저장, 설정 패널 삭제, 저장/삭제 토스트 |
| pages/admin/media/index.vue | 미디어 관리, **미디어 라이브러리/프로필 이미지** 탭, 글·멤버 목록과 같은 검색창, 파일 직접 추가, 현재 필터 결과 전체 선택·선택 삭제, 이미지·비디오·오디오·파일 종류 필터, 미사용 필터, 비디오 프레임 썸네일, 폴더 트리 more vert(폴더 삭제), 검색·드래그·상세 모달 등 |
| pages/admin/media/index.vue | 미디어 관리, **미디어 라이브러리/카드 썸네일/프로필 이미지** 탭, 글·멤버 목록과 같은 검색창, 파일 직접 추가, 현재 필터 결과 전체 선택·선택 삭제, 이미지·비디오·오디오·파일 종류 필터, 미사용 필터, 원본 fallback·카드 썸네일 사용 배지, 비디오 프레임 썸네일, 폴더 트리 more vert(폴더 삭제), 검색·드래그·상세 모달 등 |
| pages/admin/navigation/index.vue | 메뉴 관리: 상단/하단/추천 탭, 추천 사이트 대체 텍스트·썸네일 URL, 행 more vert(메뉴 항목 삭제), 드래그 정렬, `useAdminToast` |
| components/admin/AdminRowMoreMenu.vue | 관리자 행 more vert 메뉴(트리거·화면 기준 팝오버) |
| composables/useAdminRowMenu.js | 관리자 행 메뉴 열림 상태·바깥 클릭 닫기 |
@@ -275,7 +275,7 @@
| server/utils/site-settings.js | 사이트 설정 기본값 유틸리티 |
| server/utils/navigation-items.js | DB 없을 때 기본 네비 항목(UUID id·parentId·isFolder) |
| server/utils/navigation-tree.js | 네비 검증·삽입 순서·공개 primary 트리·DFS sort_order 재부여 |
| server/utils/media-library.js | 업로드 미디어·논리 폴더(`미분류`, 예약 `썸네일``avatarOwner` 부착·아바타 삭제/이름변경 차단 |
| server/utils/media-library.js | 업로드 미디어·논리 폴더(`미분류`, 예약 `썸네일``avatarOwner` 부착·아바타 삭제/이름변경 차단·게시물 카드 썸네일 사용처 연결 |
| server/repositories/postgres-client.js | PostgreSQL 클라이언트 |
| server/repositories/content-repository.js | 콘텐츠 조회 저장소 |
| server/repositories/post-export-repository.js | 게시물 Export 작업·분할 파일 계획·ZIP 생성 워커 저장소 |

View File

@@ -240,7 +240,9 @@ components/content/
- 파일: `:::file` ~ `:::` (`url`, `title`, `description`, `name`, `size`) — 다운로드 링크 카드
- 렌더링: `ProseVideo.vue`, `ProseAudio.vue`, `ProseFile.vue`
- 관리자 슬래시: `/video`, `/audio`, `/file`로 빈 템플릿 삽입 후 URL·메타 수정
- 관리자 미디어 화면은 미디어 라이브러리 탭에서 전체·이미지·영상·음악·파일 종류 필터와 미사용 필터를 제공한다. 미사용은 게시물·페이지·사이트 설정·회원 프로필에서 참조되지 않는 항목을 의미한다. 비디오 항목은 브라우저에서 초반 프레임을 캔버스로 추출해 목록 썸네일로 표시하고, 추출 실패 시 `video` placeholder를 유지한다.
- 관리자 미디어 화면은 미디어 라이브러리·카드 썸네일·프로필 이미지 탭으로 구분한다. 미디어 라이브러리 탭은 원본 업로드 파일만 표시하고, 게시물 목록용 `thumbs/*-card.webp` 파생 파일은 카드 썸네일 탭에만 표시한다.
- 관리자 미디어 화면의 미디어 라이브러리 탭은 전체·이미지·영상·음악·파일 종류 필터와 미사용 필터를 제공한다. 미사용은 게시물·페이지·사이트 설정·회원 프로필에서 참조되지 않는 항목을 의미한다. 비디오 항목은 브라우저에서 초반 프레임을 캔버스로 추출해 목록 썸네일로 표시하고, 추출 실패 시 `video` placeholder를 유지한다.
- 카드 썸네일 탭의 항목은 원본 대표 이미지가 사용 중이면 `목록 카드 썸네일` 사용처를 가진 것으로 판정한다. 원본 대표 이미지가 사용 중이지만 카드 썸네일 파일이 없으면 원본 항목에 `원본` 배지와 “목록에서 원본 이미지를 불러옴” 상태를 표시한다. 카드 썸네일은 원본과의 연결을 유지하기 위해 폴더 이동과 파일명 변경을 막고, 사용 중이면 삭제도 막는다.
- 문단과 줄바꿈
- 관리자 Markdown-first 에디터에서 Enter는 새 문단(마크다운 한 줄)만 사용한다. Shift+Enter·문단 내 hard break는 지원하지 않는다.
- 공개 본문 렌더러는 마크다운 한 줄을 한 문단으로 렌더링한다(레거시 줄끝 `\\`/공백 2개 표식은 표시 시 제거).
@@ -842,7 +844,7 @@ components/content/
- 관리자 미디어 업로드 API는 이미지·비디오·오디오·문서 확장자를 허용한다(에디터 슬래시·미디어 모달과 동일 목록).
- 업로드 파일 크기 제한은 종류별 환경 변수를 따른다. 이미지·아바타·로고 등은 `MAX_FILE_SIZE`(기본 10MB), 비디오는 `MAX_VIDEO_FILE_SIZE`(기본 200MB), 오디오는 `MAX_AUDIO_FILE_SIZE`(기본 50MB), 문서·ZIP 등은 `MAX_DOCUMENT_FILE_SIZE`(기본 50MB).
- 로컬 개발 업로드 파일은 `public/uploads/posts/YYYY/MM/` 아래 저장하고 `/uploads/posts/YYYY/MM/filename` URL로 제공한다.
- 관리자 미디어 화면 상단에 **미디어 라이브러리** 탭과 **프로필 이미지** 탭을 두어, 라이브러리 탭에서는 게시물·기타 이미지만, 프로필 이미지 탭에서는 `/members/avatars/` 파일만 검색·탐색한다.
- 관리자 미디어 화면 상단에 **미디어 라이브러리**·**카드 썸네일**·**프로필 이미지** 탭을 두어, 라이브러리 탭에서는 원본 업로드 파일만, 카드 썸네일 탭에서는 `/posts/YYYY/MM/thumbs/*-card.webp` 파일만, 프로필 이미지 탭에서는 `/members/avatars/` 파일만 검색·탐색한다.
- 미디어 라이브러리 탭은 왼쪽 폴더 트리와 오른쪽 고밀도 썸네일 갤러리, 검색, 파일명 변경, 개별 삭제를 제공한다.
- 관리자는 폴더 추가 버튼으로 모달에서 새 폴더·하위 폴더 이름을 입력해 만들 수 있으며, `미분류`·`썸네일`(및 그 하위)을 제외한 폴더는 목록에서 삭제할 수 있다. 폴더 삭제 시 해당 경로 및 하위 경로로 분류돼 있던 미디어 메타는 모두 `미분류`로 되돌린다.
- 썸네일 본문(이미지·파일명) 한 번 클릭 시 상세(미리보기) 모달이 열리고, 썸네일 좌측 상단 **선택 토글**로 개별 선택한다. Shift+클릭으로 범위 선택이 가능하다.

View File

@@ -1,5 +1,12 @@
# 업데이트 이력
## v1.5.79
- 관리자 미디어: 게시물 카드 썸네일을 일반 미디어 목록에서 분리해 `카드 썸네일` 탭으로 표시하도록 수정.
- 관리자 미디어: 카드 썸네일도 원본 대표 이미지 사용처에 연결해 사용 중으로 판정하도록 수정.
- 관리자 미디어: 원본 대표 이미지에 카드 썸네일이 없으면 목록에서 원본을 불러오는 상태를 `원본` 배지와 상세 상태로 구분하도록 추가.
- 관리자 미디어: 카드 썸네일 폴더 이동·파일명 변경을 차단하고, 사용 중인 카드 썸네일 삭제를 차단하도록 보강.
## v1.5.78
- 게시물 이미지 업로드: JPG·PNG·WebP 업로드 시 목록 카드용 WebP 썸네일 자동 생성 추가.