릴리스: v1.4.27 내부 레거시 이름층 정리
This commit is contained in:
@@ -1468,22 +1468,6 @@ async function createCustomItem({ id, ownerId, src, label }) {
|
||||
return { id, ownerId, src, label, origin: 'custom', createdAt }
|
||||
}
|
||||
|
||||
const listGames = listTopics
|
||||
const findGameById = findTopicById
|
||||
const listGameItems = listTopicItems
|
||||
const findGameItemById = findTopicItemById
|
||||
const getGameDetail = getTopicDetail
|
||||
const createGame = createTopic
|
||||
const updateGameThumbnail = updateTopicThumbnail
|
||||
const updateGameVisibility = updateTopicVisibility
|
||||
const createGameItem = createTopicItem
|
||||
const updateGameItemLabel = updateTopicItemLabel
|
||||
const updateGameItemDisplayOrder = updateTopicItemDisplayOrder
|
||||
const countTierListsUsingGameItem = countTierListsUsingTopicItem
|
||||
const deleteGameItem = deleteTopicItem
|
||||
const deleteGame = deleteTopic
|
||||
const updateGameDisplayOrder = updateTopicDisplayOrder
|
||||
|
||||
async function syncOwnedCustomItemLabels({ ownerId, items }) {
|
||||
const customItems = Array.from(
|
||||
new Map(
|
||||
@@ -2522,9 +2506,6 @@ async function unfavoriteTopic({ userId, topicId }) {
|
||||
await query('DELETE FROM favorite_topics WHERE user_id = ? AND topic_id = ?', [userId, topicId])
|
||||
}
|
||||
|
||||
const favoriteGame = favoriteTopic
|
||||
const unfavoriteGame = unfavoriteTopic
|
||||
|
||||
module.exports = {
|
||||
DB_NAME,
|
||||
ensureData,
|
||||
@@ -2547,14 +2528,6 @@ module.exports = {
|
||||
createTopic,
|
||||
updateTopicThumbnail,
|
||||
updateTopicVisibility,
|
||||
listGames,
|
||||
findGameById,
|
||||
listGameItems,
|
||||
findGameItemById,
|
||||
getGameDetail,
|
||||
createGame,
|
||||
updateGameThumbnail,
|
||||
updateGameVisibility,
|
||||
findImageAssetByHash,
|
||||
findImageAssetBySrc,
|
||||
findImageAssetById,
|
||||
@@ -2578,15 +2551,8 @@ module.exports = {
|
||||
deleteTopicItem,
|
||||
deleteTopic,
|
||||
updateTopicDisplayOrder,
|
||||
createGameItem,
|
||||
updateGameItemLabel,
|
||||
updateGameItemDisplayOrder,
|
||||
countTierListsUsingGameItem,
|
||||
updateCustomItemLabel,
|
||||
updateImageAssetLabel,
|
||||
deleteGameItem,
|
||||
deleteGame,
|
||||
updateGameDisplayOrder,
|
||||
createCustomItem,
|
||||
findCustomItemById,
|
||||
listCustomItems,
|
||||
@@ -2602,8 +2568,6 @@ module.exports = {
|
||||
unfavoriteTopic,
|
||||
favoriteTierList,
|
||||
unfavoriteTierList,
|
||||
favoriteGame,
|
||||
unfavoriteGame,
|
||||
deleteTierList,
|
||||
findCustomItemsByIds,
|
||||
deleteCustomItems,
|
||||
@@ -2614,5 +2578,4 @@ module.exports = {
|
||||
listAdminTemplateRequests,
|
||||
updateTemplateRequestStatus,
|
||||
updateTemplateRequestTargetTopic,
|
||||
updateTemplateRequestTargetGame: updateTemplateRequestTargetTopic,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# 의사결정 이력
|
||||
|
||||
## 2026-04-02 v1.4.27
|
||||
- 공개/관리자 API 표면까지 `topic/template`로 정리된 뒤에는, 관리자 내부 상태 이름과 DB export alias에 남은 `game` 흔적도 계속 유지할 이유가 작아졌으므로 이 단계에서 함께 걷어내는 편이 맞다고 판단했다.
|
||||
- 다만 외부에서 직접 참조할 수 있는 공개 북마크와 달리, `adminGames`, `game-admin`, `favoriteGame` 같은 이름은 내부 구현 용어라서 이번 단계에서 정리해도 위험이 낮다고 정리했다.
|
||||
|
||||
## 2026-04-02 v1.4.26
|
||||
- `topic/template` 표면을 거의 마감한 시점에서는 관리자 API와 관리자 화면 경로까지 계속 `/games` alias를 유지하는 편보다, 실제 사용하는 `templates` 경로만 남기고 예전 관리자 주소는 redirect로만 정리하는 편이 더 일관되고 안전하다고 판단했다.
|
||||
- 공개 사용자 북마크는 여전히 `/games -> /topics` redirect가 필요하지만, 백엔드 API의 `/api/games`까지 계속 유지할 이유는 작아졌으므로 이 단계에서 `/api/topics`만 남기는 편이 맞다고 정리했다.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# 할 일 및 이슈
|
||||
|
||||
## 단기 확인
|
||||
- `v1.4.27`에서 관리자 내부 탭/라우트 이름과 DB alias export까지 더 정리했으므로, 관리자 템플릿 탭 이동, 커스텀 아이템에서 템플릿 관리로 점프, 템플릿 요청 확인하기 이동이 모두 정상인지 한 번 더 확인한다.
|
||||
- `v1.4.26`에서 관리자 기본 경로를 `/admin/templates`로 바꾸고 `/api/admin/templates`만 남겼으므로, 관리자 진입/새로고침/뒤로가기와 템플릿 생성·썸네일 업로드·아이템 추가가 모두 정상인지 확인한다.
|
||||
- `v1.4.26`에서 공개 API `/api/games`를 제거했으므로, 실제 서버 재시작 후 홈/주제 상세/티어표 편집기에서 `/api/topics`만으로 모두 정상 동작하는지 확인한다.
|
||||
- 오래된 관리자 주소 `/admin/games`는 redirect만 남겼으므로, 북마크로 직접 진입해도 `/admin/templates`로 자연스럽게 바뀌는지 본다.
|
||||
@@ -33,7 +34,6 @@
|
||||
- 프런트 API 호출부는 `topic/template` 의미 이름으로 옮겼으므로, 다음 단계에서는 `api.js` 안의 레거시 alias를 얼마나 더 유지할지와 백엔드 API 경로를 실제로 바꿀지 범위를 정한다.
|
||||
- 관리자 템플릿/주제 화면과 홈·에디터·즐겨찾기에서 새 API 이름층으로 바뀐 뒤에도 저장, 즐겨찾기, 템플릿 생성, 아이템 정렬 흐름이 자연스러운지 한 번 더 QA한다.
|
||||
- `topicHub / topicId`를 기본 라우트 기준으로 세웠으므로, 기존 `/games/...` 북마크와 새 `/topics/...` 주소 양쪽에서 주제 상세와 에디터 진입이 모두 자연스럽게 이어지는지 한 번 더 QA한다.
|
||||
- 다음 단계에서는 `api.getGame`, `listGames`, `favoriteGame`처럼 남아 있는 프런트 API 이름을 어느 수준까지 `topic/template` 의미로 감쌀지 정리한다.
|
||||
- 경로 헬퍼를 사용자 주요 화면에 연결했으므로, 로그인 리다이렉트·공유 프리뷰·복사본 이동·주제 복귀 흐름이 실제 브라우저에서 모두 같은 주소 체계로 자연스럽게 이어지는지 한 번 더 QA한다.
|
||||
- 다음 단계에서는 `router/index.js`의 `gameHub`, `route.params.gameId`, `api.getGame`처럼 남아 있는 프런트 내부 이름도 어디까지 `topic/template` 의미로 감쌀지 범위를 더 좁힌다.
|
||||
- 주제 상세 화면 제목은 ID fallback 대신 로딩 문구를 쓰도록 바꿨으므로, 직접 진입·뒤로가기·다른 주제로 연속 이동할 때 헤더가 깜빡이거나 이전 제목을 잠깐 유지하지 않는지 한 번 더 QA한다.
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# 업데이트 로그
|
||||
|
||||
## 2026-04-02 v1.4.27
|
||||
- 관리자 내부 탭/라우트 이름도 `template-admin`, `adminTemplates`, `/admin/templates` 기준으로 더 정리해, 화면 상태값과 라우트 이름에 남아 있던 `game-admin`, `adminGames` 흔적을 줄였다.
|
||||
- 더 이상 참조되지 않는 DB alias export(`listGames`, `createGame`, `favoriteGame` 등)와 `updateTemplateRequestTargetGame` 별칭도 제거해, 백엔드 모듈 표면에서 남아 있던 레거시 `game` 이름층을 더 걷어냈다.
|
||||
- 커스텀 아이템 모달 내부 클래스명도 `createTemplateButton` 기준으로 정리해, 관리자 코드 검색에서 남는 `createGame` 흔적을 줄였다.
|
||||
|
||||
## 2026-04-02 v1.4.26
|
||||
- 관리자 API 레거시 `/games` alias를 걷어내고 `POST /api/admin/templates`, `.../templates/:templateId/...`만 남기도록 정리했다. 관리자 템플릿 연결/가져오기 액션도 `link-template`, `create-template` path로 바꿨다.
|
||||
- 백엔드 공개 주제 라우트도 이제 `/api/topics`만 마운트하고, 오래된 `/api/games` 경로는 제거했다. 관리자 화면 URL 역시 `/admin/games` 대신 `/admin/templates`를 기본 경로로 쓰고, 예전 주소는 redirect만 남겼다.
|
||||
|
||||
@@ -100,7 +100,7 @@ export function useAdminCustomItems({
|
||||
function jumpToTemplateAdmin(templateId) {
|
||||
if (!templateId) return
|
||||
closeCustomItemModal()
|
||||
setTab('game-admin')
|
||||
setTab('template-admin')
|
||||
nextTick(() => {
|
||||
selectAdminTemplate(templateId)
|
||||
})
|
||||
|
||||
@@ -62,7 +62,7 @@ export function useAdminTemplateRequests({
|
||||
Object.assign(request, syncedRequest)
|
||||
request.status = syncedRequest.status || 'reviewing'
|
||||
updateActiveTemplateRequest(syncedRequest)
|
||||
setTab('game-admin')
|
||||
setTab('template-admin')
|
||||
|
||||
if (request.type === 'create') {
|
||||
const linkedTopicId = syncedRequest.targetTopicId || ''
|
||||
|
||||
@@ -27,7 +27,7 @@ export function createRouter() {
|
||||
{ path: '/admin', redirect: '/admin/featured' },
|
||||
{ path: '/admin/featured', name: 'adminFeatured', component: AdminView },
|
||||
{ path: '/admin/games', redirect: '/admin/templates' },
|
||||
{ path: '/admin/templates', name: 'adminGames', component: AdminView },
|
||||
{ path: '/admin/templates', name: 'adminTemplates', component: AdminView },
|
||||
{ path: '/admin/items', name: 'adminItems', component: AdminView },
|
||||
{ path: '/admin/tierlists', name: 'adminTierlists', component: AdminView },
|
||||
{ path: '/admin/users', name: 'adminUsers', component: AdminView },
|
||||
|
||||
@@ -36,7 +36,7 @@ const selectedTemplateId = ref('')
|
||||
const selectedTemplate = ref(null)
|
||||
const featuredTemplateIds = ref([])
|
||||
const templatePickerModalOpen = ref(false)
|
||||
const templatePickerMode = ref('game-admin')
|
||||
const templatePickerMode = ref('template-admin')
|
||||
const templatePickerQuery = ref('')
|
||||
const templatePickerSort = ref('recent')
|
||||
|
||||
@@ -215,7 +215,7 @@ const customItemTargetTemplate = computed(() => templates.value.find((template)
|
||||
const importModalItemCount = computed(() => importModalItems.value.length)
|
||||
const activeTabTitle = computed(() => {
|
||||
if (activeTab.value === 'featured') return '목록 관리'
|
||||
if (activeTab.value === 'game-admin') return '템플릿 관리'
|
||||
if (activeTab.value === 'template-admin') return '템플릿 관리'
|
||||
if (activeTab.value === 'items') return '아이템 관리'
|
||||
if (activeTab.value === 'tierlists') {
|
||||
return tierlistsMode.value === 'requests' ? '템플릿 요청 관리' : '전체 티어표 관리'
|
||||
@@ -226,7 +226,7 @@ const activeTabDescription = computed(() => {
|
||||
if (activeTab.value === 'featured') {
|
||||
return '홈 화면 상단에 고정 노출되는 템플릿 순서를 따로 관리합니다.'
|
||||
}
|
||||
if (activeTab.value === 'game-admin') {
|
||||
if (activeTab.value === 'template-admin') {
|
||||
return '템플릿 생성, 선택, 썸네일, 기본 아이템 관리를 전용 작업 화면으로 분리했습니다.'
|
||||
}
|
||||
if (activeTab.value === 'items') {
|
||||
@@ -251,7 +251,7 @@ const adminOverviewStats = computed(() => {
|
||||
{ label: '추가 가능', value: `${Math.max(0, 50 - featuredTemplateIds.value.length)}` },
|
||||
]
|
||||
}
|
||||
if (activeTab.value === 'game-admin') {
|
||||
if (activeTab.value === 'template-admin') {
|
||||
return [
|
||||
{ label: '전체 템플릿', value: `${templates.value.length}` },
|
||||
{ label: '티어표 전체', value: `${selectedTemplateTierListStats.value.total || 0}` },
|
||||
@@ -305,14 +305,14 @@ const isAnyModalOpen = computed(
|
||||
)
|
||||
const adminRouteNameByTab = {
|
||||
featured: 'adminFeatured',
|
||||
'game-admin': 'adminGames',
|
||||
'template-admin': 'adminTemplates',
|
||||
items: 'adminItems',
|
||||
tierlists: 'adminTierlists',
|
||||
users: 'adminUsers',
|
||||
}
|
||||
|
||||
function tabFromAdminRoute(name) {
|
||||
if (name === 'adminGames') return 'game-admin'
|
||||
if (name === 'adminTemplates') return 'template-admin'
|
||||
if (name === 'adminItems') return 'items'
|
||||
if (name === 'adminTierlists') return 'tierlists'
|
||||
if (name === 'adminUsers') return 'users'
|
||||
@@ -423,7 +423,7 @@ watch(
|
||||
() => route.name,
|
||||
(name) => {
|
||||
activeTab.value = tabFromAdminRoute(name)
|
||||
if (name === 'adminGames') {
|
||||
if (name === 'adminTemplates') {
|
||||
const nextTopicId = typeof route.query.topicId === 'string' ? route.query.topicId : ''
|
||||
if (nextTopicId && nextTopicId !== selectedTemplateId.value) {
|
||||
selectedTemplateId.value = nextTopicId
|
||||
@@ -446,7 +446,7 @@ watch(
|
||||
watch(
|
||||
() => selectedTemplateId.value,
|
||||
(templateId) => {
|
||||
if (route.name !== 'adminGames') return
|
||||
if (route.name !== 'adminTemplates') return
|
||||
syncAdminRouteQuery({ topicId: templateId || undefined })
|
||||
}
|
||||
)
|
||||
@@ -481,7 +481,7 @@ watch(
|
||||
watch(
|
||||
() => activeTab.value,
|
||||
async (tab) => {
|
||||
if (tab === 'game-admin' && selectedTemplateId.value && !selectedTemplate.value?.game?.id) {
|
||||
if (tab === 'template-admin' && selectedTemplateId.value && !selectedTemplate.value?.game?.id) {
|
||||
await loadTemplate()
|
||||
return
|
||||
}
|
||||
@@ -732,7 +732,7 @@ function setTab(tab) {
|
||||
const nextRouteName = adminRouteNameByTab[tab]
|
||||
if (nextRouteName && route.name !== nextRouteName) {
|
||||
const nextQuery =
|
||||
tab === 'game-admin'
|
||||
tab === 'template-admin'
|
||||
? { topicId: selectedTemplateId.value || undefined }
|
||||
: tab === 'tierlists' && tierlistsMode.value === 'all'
|
||||
? { mode: 'all' }
|
||||
@@ -1312,7 +1312,7 @@ function setAdminTierListGameId(topicId) {
|
||||
refreshAdminTierLists()
|
||||
}
|
||||
|
||||
function openTemplatePickerModal(mode = 'game-admin') {
|
||||
function openTemplatePickerModal(mode = 'template-admin') {
|
||||
templatePickerMode.value = mode
|
||||
templatePickerQuery.value = ''
|
||||
templatePickerSort.value = 'recent'
|
||||
@@ -1701,7 +1701,7 @@ function userAvatarFallback(user) {
|
||||
/>
|
||||
|
||||
<AdminGamesSection
|
||||
v-else-if="activeTab === 'game-admin'"
|
||||
v-else-if="activeTab === 'template-admin'"
|
||||
:active-template-request="activeTemplateRequest"
|
||||
:template-request-source-url="templateRequestSourceUrl"
|
||||
:staged-request-draft-count="stagedRequestDraftCount"
|
||||
@@ -1981,7 +1981,7 @@ function userAvatarFallback(user) {
|
||||
</div>
|
||||
<div class="customItemModal__pickerActions">
|
||||
<button class="btn btn--ghost" type="button" @click="openTemplatePickerModal('custom-item-target')">템플릿 선택</button>
|
||||
<button class="btn btn--ghost btn--small customItemModal__createGameButton" type="button" @click="openTemplateCreateModal">새 템플릿 만들기</button>
|
||||
<button class="btn btn--ghost btn--small customItemModal__createTemplateButton" type="button" @click="openTemplateCreateModal">새 템플릿 만들기</button>
|
||||
</div>
|
||||
</aside>
|
||||
<div class="customItemModal__body">
|
||||
@@ -2223,18 +2223,18 @@ function userAvatarFallback(user) {
|
||||
<div class="adminSidebar__label">Mode</div>
|
||||
<div class="adminSidebar__tabs">
|
||||
<button class="tab" :class="{ 'tab--active': activeTab === 'featured' }" @click="setTab('featured')">목록 관리</button>
|
||||
<button class="tab" :class="{ 'tab--active': activeTab === 'game-admin' }" @click="setTab('game-admin')">템플릿 관리</button>
|
||||
<button class="tab" :class="{ 'tab--active': activeTab === 'template-admin' }" @click="setTab('template-admin')">템플릿 관리</button>
|
||||
<button class="tab" :class="{ 'tab--active': activeTab === 'items' }" @click="setTab('items')">아이템 관리</button>
|
||||
<button class="tab" :class="{ 'tab--active': activeTab === 'tierlists' }" @click="setTab('tierlists')">티어표 관리</button>
|
||||
<button class="tab" :class="{ 'tab--active': activeTab === 'users' }" @click="setTab('users')">회원 관리</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section v-if="activeTab === 'game-admin'" class="adminSidebar__panel">
|
||||
<section v-if="activeTab === 'template-admin'" class="adminSidebar__panel">
|
||||
<div class="adminSidebar__label">Template</div>
|
||||
<div class="adminSidebar__group">
|
||||
<button class="btn btn--primary" @click="openTemplateCreateModal">새 템플릿 생성</button>
|
||||
<button class="btn btn--ghost" @click="openTemplatePickerModal('game-admin')">템플릿 선택</button>
|
||||
<button class="btn btn--ghost" @click="openTemplatePickerModal('template-admin')">템플릿 선택</button>
|
||||
<div v-if="selectedTemplate?.game" class="adminSelectionCard">
|
||||
<div class="adminSelectionCard__label">선택한 템플릿</div>
|
||||
<div class="adminSelectionCard__title">{{ selectedTemplate.game.name }}</div>
|
||||
@@ -3493,7 +3493,7 @@ function userAvatarFallback(user) {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
.adminUiScope .customItemModal__createGameButton {
|
||||
.adminUiScope .customItemModal__createTemplateButton {
|
||||
justify-self: start;
|
||||
}
|
||||
.adminUiScope .customItemModal__body {
|
||||
|
||||
Reference in New Issue
Block a user