Skip to content

Commit 25b5d52

Browse files
authored
[Refactor] UserWord 기반 낱말 관리 전체 리팩토링 (#92)
2 parents 5316575 + 7a05f7e commit 25b5d52

File tree

6 files changed

+85
-212
lines changed

6 files changed

+85
-212
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- UserWord 테이블에서 word_id, category_id 컬럼 및 외래키 제약조건 제거
2+
ALTER TABLE UserWord
3+
DROP FOREIGN KEY UserWord_word_id_fkey,
4+
DROP FOREIGN KEY UserWord_category_id_fkey;
5+
6+
ALTER TABLE UserWord
7+
DROP COLUMN word_id,
8+
DROP COLUMN category_id;

prisma/schema.prisma

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ model Category {
144144
145145
// Relations
146146
words Word[]
147-
userWords UserWord[]
147+
// userWords relation 제거: UserWord에서 categoryId 삭제됨
148148
149149
@@map("Category")
150150
}
@@ -164,7 +164,7 @@ model Word {
164164
165165
// Relations
166166
category Category @relation(fields: [categoryId], references: [id], onDelete: Cascade)
167-
userWords UserWord[]
167+
// userWords relation 제거: UserWord에서 wordId 삭제됨
168168
169169
@@index([categoryId])
170170
@@index([word])
@@ -204,8 +204,8 @@ model UserCategory {
204204
model UserWord {
205205
id String @id @default(uuid()) @db.Char(36)
206206
userId String @map("user_id") @db.Char(36)
207-
wordId String? @map("word_id") @db.Char(36)
208-
categoryId String? @map("category_id") @db.Char(36)
207+
// wordId 필드 제거: 이제 사용자 낱말만 관리
208+
// categoryId 필드 제거: 이제 사용자 카테고리만 사용
209209
userCategoryId String? @map("user_category_id") @db.Char(36)
210210
partOfSpeech PartOfSpeech @map("part_of_speech")
211211
customWord String? @map("custom_word") @db.VarChar(100)
@@ -218,14 +218,14 @@ model UserWord {
218218
219219
// Relations
220220
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
221-
word Word? @relation(fields: [wordId], references: [id], onDelete: SetNull)
222-
category Category? @relation(fields: [categoryId], references: [id], onDelete: SetNull)
221+
// word relation 제거
222+
// category relation 제거
223223
userCategory UserCategory? @relation(fields: [userCategoryId], references: [id], onDelete: Cascade)
224224
225225
@@index([userId])
226226
@@index([userId, isFavorite])
227227
@@index([userId, isDeleted]) // 삭제된 항목 필터링용
228-
@@index([userCategoryId, displayOrder])
228+
// categoryId 인덱스 제거
229229
@@map("UserWord")
230230
}
231231

src/category/category.service.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,22 @@ export const getCategoryListService = async ({ userId }) => {
7777
categories = await listUserCategories({ userId });
7878
}
7979

80+
// 기본 UserCategory 생성 후, 각 카테고리별 Word를 UserWord로 복사
81+
const wordsRepo = (await import("../words/repositories/words.repository.js")).default;
82+
for (const userCategory of categories.filter(c => c.isDefault)) {
83+
// 기본 카테고리 이름으로 Category 찾기
84+
const category = await prisma.category.findFirst({
85+
where: {
86+
categoryName: userCategory.categoryName,
87+
isDefault: true
88+
}
89+
});
90+
if (category) {
91+
// 해당 Category의 Word를 UserWord로 복사
92+
await wordsRepo.createSnapshotFromWords(userId, userCategory.id);
93+
}
94+
}
95+
8096
return Promise.all(
8197
categories.map(async (c) => {
8298
let wordCount = 0;

src/history/history.repository.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export const findFrequentWords = async (userId, frequentLimit = 80) => {
5959
// 1. 즐겨찾기 데이터 전체 조회 (개수 제한 없음)
6060
const favorites = await prisma.userWord.findMany({
6161
where: { userId, isFavorite: true, isDeleted: false },
62-
include: { category: true, word: true }
62+
include: { userCategory: true }
6363
});
6464

6565
// 2. 최근 3개월 대화 이력 조회

src/words/repositories/words.repository.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,6 @@ export class WordsRepository {
141141
return await prisma.userWord.findMany({
142142
where,
143143
include: {
144-
word: true,
145-
category: true,
146144
userCategory: true
147145
},
148146
orderBy: { displayOrder: 'asc' }
@@ -186,7 +184,6 @@ export class WordsRepository {
186184
return await prisma.userWord.create({
187185
data: {
188186
userId,
189-
categoryId: isUserCategory ? null : categoryId,
190187
userCategoryId: isUserCategory ? categoryId : null,
191188
partOfSpeech: partOfSpeech, // NLP 서비스에서 받은 품사
192189
customWord: word,
@@ -219,8 +216,6 @@ export class WordsRepository {
219216
return await prisma.userWord.findUnique({
220217
where: { id: userWordId },
221218
include: {
222-
word: true,
223-
category: true,
224219
userCategory: true
225220
}
226221
});
@@ -323,8 +318,6 @@ export class WordsRepository {
323318
where: { id: userWordId },
324319
data,
325320
include: {
326-
word: true,
327-
category: true,
328321
userCategory: true
329322
}
330323
});
@@ -382,16 +375,16 @@ export class WordsRepository {
382375
});
383376
const isUserCategory = !!userCategory;
384377

385-
// 3. 각 Word를 참조하는 UserWord 생성 (필드 분기)
378+
// 3. 각 Word를 UserWord로 복사 (wordId, categoryId 제거)
386379
const createPromises = words.map((word, index) =>
387380
prisma.userWord.create({
388381
data: {
389382
userId,
390-
wordId: word.id,
391-
categoryId: isUserCategory ? null : word.categoryId,
392383
userCategoryId: isUserCategory ? categoryId : null,
393384
partOfSpeech: word.partOfSpeech,
394-
displayOrder: index, // 생성 순서대로 0, 1, 2...
385+
customWord: word.word,
386+
customImageUrl: word.imageUrl,
387+
displayOrder: index,
395388
isFavorite: false,
396389
isDeleted: false
397390
}

0 commit comments

Comments
 (0)