Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/words/controllers/words.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export class WordsController {
const updateDto = new UpdateWordDto({
word: req.body.word,
imageUrl: req.body.imageUrl,
categoryId: req.body.categoryId
userCategoryId: req.body.categoryId
});

// 유효성 검증
Expand All @@ -108,7 +108,7 @@ export class WordsController {
cardId,
updateDto.word,
updateDto.imageUrl,
updateDto.categoryId
updateDto.userCategoryId
);

return res.success({ word: updatedWord }, '낱말 카드 수정 성공');
Expand Down
6 changes: 3 additions & 3 deletions src/words/dto/words.dto.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@ export class UpdateFavoriteDto {
* PATCH /api/words/:cardId - Update Word Request DTO
*/
export class UpdateWordDto {
constructor({ word, imageUrl, categoryId }) {
constructor({ word, imageUrl, userCategoryId }) {
this.word = word;
this.imageUrl = imageUrl;
this.categoryId = categoryId ? String(categoryId) : null;
this.userCategoryId = userCategoryId ? String(userCategoryId) : null;
}

validate() {
if (!this.word && !this.imageUrl && !this.categoryId) {
if (!this.word && !this.imageUrl && !this.userCategoryId) {
throw new Error('word, imageUrl, categoryId 중 하나는 필수입니다');
}
}
Expand Down
20 changes: 11 additions & 9 deletions src/words/repositories/words.repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,18 +301,20 @@ export class WordsRepository {
}

/**
* UserWord 업데이트 (customWord, customImageUrl, categoryId)
* @param {string} userWordId - UserWord.id
* @param {string|null} customWord
* @param {string|null} customImageUrl
* @param {string|null} categoryId
* @returns {Promise<Object>}
*/
async updateUserWord(userWordId, customWord, customImageUrl, categoryId) {
* UserWord 업데이트 (customWord, customImageUrl, userCategoryId, displayOrder)
* @param {string} userWordId - UserWord.id
* @param {string|null} customWord
* @param {string|null} customImageUrl
* @param {string|null} userCategoryId
* @param {number|undefined} displayOrder
* @returns {Promise<Object>}
*/
async updateUserWord(userWordId, customWord, customImageUrl, userCategoryId, displayOrder) {
const data = {};
if (customWord !== undefined) data.customWord = customWord;
if (customImageUrl !== undefined) data.customImageUrl = customImageUrl;
if (categoryId !== undefined && categoryId !== null) data.categoryId = categoryId;
if (userCategoryId !== undefined && userCategoryId !== null) data.userCategoryId = userCategoryId;
if (displayOrder !== undefined) data.displayOrder = displayOrder;

return await prisma.userWord.update({
where: { id: userWordId },
Expand Down
2 changes: 0 additions & 2 deletions src/words/routes/words.route.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ router.get('/', optionalAuthenticate, wordsController.getWords.bind(wordsControl
* summary: 개인 낱말 카드 추가
* description: 사용자가 직접 낱말 카드를 추가합니다. NLP로 품사를 자동 분석합니다.
* tags: [Words]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
Expand Down
22 changes: 20 additions & 2 deletions src/words/services/words.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,31 @@ export class WordsService {
* @param {string|undefined} categoryId - 변경할 카테고리 ID
* @returns {Promise<WordCardResponseDto>}
*/
async updateWord(userId, cardId, word, imageUrl, categoryId) {
async updateWord(userId, cardId, word, imageUrl, userCategoryId) {
// 무조건 UserWord만 수정: 기본 Word 복사/생성 로직 제거
const userWord = await wordsRepository.findUserWordById(cardId);
if (!userWord) {
throw new Error('존재하지 않는 UserWord입니다');
}
const updatedUserWord = await wordsRepository.updateUserWord(cardId, word, imageUrl, categoryId);

let displayOrder = undefined;
// 카테고리 변경 시 displayOrder 맨 뒤로 이동 및 기존 카테고리 재정렬
if (userCategoryId && userWord.userCategoryId !== userCategoryId) {
// 1. 이동될 카테고리 맨 뒤로
displayOrder = await this.getNextDisplayOrder(userId, null, userCategoryId);

// 2. 기존 카테고리 displayOrder 재정렬
const prevCategoryId = userWord.userCategoryId;
if (prevCategoryId) {
const prevWords = await wordsRepository.findUserWords(userId, prevCategoryId, false, false);
// 이동된 단어 제외
const filtered = prevWords.filter(w => w.id !== cardId);
const updates = filtered.map((w, idx) => ({ userWordId: w.id, displayOrder: idx }));
await wordsRepository.bulkUpdateDisplayOrders(updates);
}
}

const updatedUserWord = await wordsRepository.updateUserWord(cardId, word, imageUrl, userCategoryId, displayOrder);
return new WordCardResponseDto({
cardId: updatedUserWord.id,
categoryId: updatedUserWord.userCategoryId,
Expand Down