diff --git a/backend/src/routes/tierlists.js b/backend/src/routes/tierlists.js index d2b8071..25b546b 100644 --- a/backend/src/routes/tierlists.js +++ b/backend/src/routes/tierlists.js @@ -262,9 +262,7 @@ router.post('/template-request', requireAuth, async (req, res) => { type: payload.type, requesterId: req.session.userId, sourceTierListId: sourceTierList?.id || '', - sourceGameId: topicId, sourceTopicId: topicId, - targetGameId: payload.type === 'update' ? topicId : '', targetTopicId: payload.type === 'update' ? topicId : '', title: payload.requestTitle, description: payload.requestDescription, @@ -298,7 +296,6 @@ router.post('/', requireAuth, async (req, res) => { const updated = await saveTierList({ id: existing.id, authorId: existing.authorId, - gameId: existing.topicId || existing.gameId, topicId: existing.topicId || existing.gameId, title: payload.title, thumbnailSrc: payload.thumbnailSrc || '', @@ -318,7 +315,6 @@ router.post('/', requireAuth, async (req, res) => { const created = await saveTierList({ id: nanoid(), authorId: req.session.userId, - gameId: topicId, topicId, title: payload.title, thumbnailSrc: payload.thumbnailSrc || '', diff --git a/docs/history.md b/docs/history.md index f22c628..3b53732 100644 --- a/docs/history.md +++ b/docs/history.md @@ -1,5 +1,9 @@ # 의사결정 이력 +## 2026-04-02 v1.4.23 +- 프런트가 이미 `topic/template` 메서드만 실제로 쓰고 있다면, `api.js` 안에 남은 레거시 `game` 별칭까지 계속 유지하는 건 오히려 정리 상태를 흐리므로 이 단계에서 정리하는 편이 맞다고 판단했다. +- 티어표 저장과 템플릿 요청처럼 핵심 생성 흐름은 백엔드 내부 payload도 먼저 `topicId` 기준으로 맞춰 두는 편이, 이후 응답 호환 키를 걷어낼 때 충격을 더 줄인다고 정리했다. + ## 2026-04-02 v1.4.22 - 내부 함수명과 export를 정리한 뒤에도 라우트 파일명이 계속 `games.js`로 남아 있으면 마지막까지 개념 충돌을 남기게 되므로, 공개 주제 라우트 파일명도 실제 의미에 맞게 `topics.js`로 옮기는 편이 맞다고 판단했다. - `/api/games` 호환 경로는 유지하더라도, 서버 내부 구현만큼은 `topic` 기준 param 이름과 파일 이름으로 정리해 두는 편이 이후 레거시 제거를 훨씬 더 쉽게 만든다고 정리했다. diff --git a/docs/todo.md b/docs/todo.md index fce5d21..afbfd98 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -1,6 +1,8 @@ # 할 일 및 이슈 ## 단기 확인 +- `v1.4.23`에서 프런트 `api.js`의 레거시 `game` 별칭 메서드와 티어표 저장/요청 내부 payload를 더 걷어냈으므로, 실제 브라우저에서 저장/복사/템플릿 요청/관리자 요청 카드 표시가 그대로 정상인지 한 번 더 QA한다. +- 다음 단계에서는 응답의 `game`, `gameId`, `gameName`, `sourceGameId`, `targetGameId` 호환 키를 실제로 제거할지, 아니면 `v1.4` 마감 후 안정화 기간을 두고 걷어낼지 최종 결정한다. - `v1.4.22`에서 공개 주제 라우트 파일을 `topics.js`로 옮겼으므로, 실제 서버 재기동 후 `/api/topics`와 `/api/games` 호환 경로가 모두 정상 응답하는지 한 번 더 QA한다. - 다음 단계에서는 응답의 `game`, `gameId`, `gameName` 호환 키를 실제로 어느 범위까지 제거할지, 그리고 관리자/티어표 저장 payload에서 남은 `gameId` 입력 호환을 어디까지 유지할지 최종 결정한다. - `v1.4.21`에서 홈/주제 상세/에디터/나의 티어표/즐겨찾기/검색 결과/관리자 템플릿 생성이 `topic/template` 응답 키를 우선 읽도록 바뀌었으므로, 실제 브라우저에서 즐겨찾기 토글과 에디터 이동, 관리자 신규 템플릿 생성이 모두 정상인지 한 번 더 QA한다. diff --git a/docs/update.md b/docs/update.md index db769a0..cd28174 100644 --- a/docs/update.md +++ b/docs/update.md @@ -1,5 +1,10 @@ # 업데이트 로그 +## 2026-04-02 v1.4.23 +- 프런트 `api.js`에서 더 이상 쓰지 않는 `listGames / getGame / favoriteGame / updateAdminGame* / listPublicTierLists` 같은 레거시 별칭 메서드를 정리해, 공개/관리자 호출부가 실제로 쓰는 `topic/template` API만 남기도록 정리했다. +- 관리자 템플릿 요청 상태와 전체 티어표 관리 카드도 `sourceTopicId / targetTopicId / topicName`을 우선 읽도록 더 당겨, 화면에서 `game` 키를 보는 범위를 줄였다. +- 티어표 저장/템플릿 요청 백엔드는 이제 내부적으로 `sourceTopicId / targetTopicId / topicId`만 넘기도록 정리하고, 기존 `sourceGameId / gameId`는 저장 경로에서 한 단계 더 덜어냈다. + ## 2026-04-02 v1.4.22 - 백엔드 공개 주제 라우트 파일을 [topics.js](/Users/bicute/Desktop/zenn.dev/tier-cursor/backend/src/routes/topics.js)로 옮기고, 진입점도 이 이름으로 읽히게 정리했다. 이제 서버 코드에서 `games.js` 파일명이 남아 있던 마지막 큰 표면도 실제 의미에 더 가깝게 맞춰졌다. - 공개 주제 라우트의 path 파라미터도 `:topicId` 기준으로 읽히게 바꿔, 내부 구현에서 더 이상 `req.params.gameId`를 기본 전제로 보지 않도록 정리했다. diff --git a/frontend/src/components/admin/AdminTierlistsSection.vue b/frontend/src/components/admin/AdminTierlistsSection.vue index 02067b9..5466403 100644 --- a/frontend/src/components/admin/AdminTierlistsSection.vue +++ b/frontend/src/components/admin/AdminTierlistsSection.vue @@ -148,7 +148,7 @@ const props = defineProps({
{{ tierList.title }}
{{ tierList.description }}
- {{ tierList.gameName || tierList.gameId }} · {{ props.tierListAuthorDisplayName(tierList) }} + {{ tierList.topicName || tierList.gameName || tierList.topicId || tierList.gameId }} · {{ props.tierListAuthorDisplayName(tierList) }}
{{ props.fmt(tierList.updatedAt) }}
@@ -170,7 +170,7 @@ const props = defineProps({
-
diff --git a/frontend/src/composables/useAdminTemplateRequests.js b/frontend/src/composables/useAdminTemplateRequests.js index 78e982a..297805f 100644 --- a/frontend/src/composables/useAdminTemplateRequests.js +++ b/frontend/src/composables/useAdminTemplateRequests.js @@ -21,14 +21,14 @@ export function useAdminTemplateRequests({ type: request.type, status: request.status, thumbnailSrc: request.thumbnailSrc || '', - draftGameId: request.draftGameId || '', - draftGameName: request.draftGameName || '', - draftGameIsPublic: !!request.draftGameIsPublic, + draftGameId: request.draftTopicId || request.draftGameId || '', + draftGameName: request.draftTopicName || request.draftGameName || '', + draftGameIsPublic: !!(request.draftTopicIsPublic ?? request.draftGameIsPublic), sourceTierListId: request.sourceTierListId || '', - sourceGameId: request.sourceGameId || '', + sourceGameId: request.sourceTopicId || request.sourceGameId || '', sourceTierListTitle: request.sourceTierListTitle || '', - targetGameId: request.targetGameId || '', - targetGameName: request.targetGameName || '', + targetGameId: request.targetTopicId || request.targetGameId || '', + targetGameName: request.targetTopicName || request.targetGameName || '', requesterName: request.requesterName || '', } } diff --git a/frontend/src/lib/api.js b/frontend/src/lib/api.js index 42489ed..fd32187 100644 --- a/frontend/src/lib/api.js +++ b/frontend/src/lib/api.js @@ -175,24 +175,4 @@ export const api = { deleteAdminCustomItem: (itemId) => request(`/api/admin/custom-items/${encodeURIComponent(itemId)}`, { method: 'DELETE' }), deleteAdminUnusedCustomItems: ({ q = '' } = {}) => request(`/api/admin/custom-items?q=${encodeURIComponent(q)}`, { method: 'DELETE' }), - - listGames: () => request('/api/games'), - getGame: (gameId) => request(`/api/games/${encodeURIComponent(gameId)}`), - favoriteGame: (gameId) => request(`/api/games/${encodeURIComponent(gameId)}/favorite`, { method: 'POST' }), - unfavoriteGame: (gameId) => request(`/api/games/${encodeURIComponent(gameId)}/favorite`, { method: 'DELETE' }), - updateAdminGameDisplayOrder: (payload) => request('/api/admin/games/display-order', { method: 'PATCH', body: payload }), - updateAdminGameItemDisplayOrder: (gameId, payload) => - request(`/api/admin/games/${encodeURIComponent(gameId)}/items/display-order`, { method: 'PATCH', body: payload }), - updateAdminGame: (gameId, payload) => - request(`/api/admin/games/${encodeURIComponent(gameId)}`, { method: 'PATCH', body: payload }), - updateAdminGameItem: (gameId, itemId, payload) => - request(`/api/admin/games/${encodeURIComponent(gameId)}/items/${encodeURIComponent(itemId)}`, { method: 'PATCH', body: payload }), - promoteAdminCustomItem: (itemId, payload) => - request(`/api/admin/custom-items/${encodeURIComponent(itemId)}/promote`, { method: 'POST', body: payload }), - createAdminGameTemplateFromTierList: (tierListId, payload) => - request(`/api/admin/tierlists/${encodeURIComponent(tierListId)}/create-game-template`, { method: 'POST', body: payload }), - listPublicTierLists: (gameId) => - request(`/api/tierlists/public?topicId=${encodeURIComponent(gameId || '')}`), - searchPublicTierLists: (gameId, q = '') => - request(`/api/tierlists/public?topicId=${encodeURIComponent(gameId || '')}&q=${encodeURIComponent(q || '')}`), }