refactor(prisma): soft-delete 활성 필터 공용 where 조각으로 중앙화 - #221
Conversation
이슈 #207 단기 단계. extension이 루트 READ에만 deleted_at을 주입해 nested relation·relation 필터·mutation은 수동 명시에 의존했고, 반복 회귀의 원인이었다. 인라인 리터럴을 공용 조각으로 통일해 표기 흔들림과 누락 위험을 구조적으로 줄인다. - src/prisma/active-where.ts 신설: activeWhere({ deleted_at: null }) / visibleWhere({ is_active: true, deleted_at: null }). @/prisma 배럴 export. - 전수 조사(277라인) 기반 일괄 교체: · nested include/select where 54곳, relation 필터 46곳 → 조각 명시 · updateMany 루트 12곳 → 조각 명시(복원 조건 not: null 2곳은 리터럴 유지) · extension이 커버하는 루트 READ의 중복 명시 63곳 제거 · 공유 where 헬퍼(publicReviewWhere·visibleWishlistWhere 등)는 향후 nested 재사용 가능성이 있어 제거 대신 조각 조합으로 유지 - extension SOFT_DELETE_MODELS에 Region 추가 — deleted_at 보유 50개 모델 중 유일한 미등록(모델 추가 시 목록 갱신 누락). 루트 조회 4곳이 전부 수동 필터 중이라 동작 불변. - 재발 방지: dmmf 대조 테스트 신설 — deleted_at 보유 모델 ↔ 목록 diff 0 강제. - CLAUDE.md Prisma 섹션을 새 컨벤션(루트 READ는 extension 신뢰, 미커버 경로는 조각 명시) 기준으로 갱신. 회귀: 동작 변경 0 — 기존 spec 전체 무변경 green + dmmf 대조 2건 신규 (191 suites / 1,649 tests, yarn validate 통과). Claude-Session: https://claude.ai/code/session_01KfiGgWooJdsa4iPQPmqvBj
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🧹 knip — dead-code 리포트전체 리포트
|
🩺 NestJS Doctor — 89/100 (Good)진단 283건 (error 0).
architecture / security 상위 항목
|
Coverage report
Test suite run success1649 tests passing in 191 suites. Report generated by 🧪jest coverage report action from 39cbe9f |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…ents refactor(prisma): soft-delete 활성 필터 공용 where 조각으로 중앙화
무엇을 왜
soft-delete extension이 자동으로
deleted_at: null을 넣어주는 건 루트 READ 쿼리뿐입니다. nested relation, relation 필터(some/is), mutation, raw SQL은 전부 손으로 명시해야 하고, 실제로 이 지점에서 회귀가 반복돼 CLAUDE.md에 경고까지 박혀 있었습니다. 주의력으로 버티는 구조는 코드가 늘수록 확률적으로 뚫리니, 인라인 리터럴을 공용 조각으로 바꿔 한곳에서 통제하도록 했습니다(#207 단기 단계).작업 전에 repository/service 전체의
deleted_at277라인을 전수 분류했습니다.not: null2건은 유지)공용 조각과 새 컨벤션
src/prisma/active-where.ts에activeWhere({ deleted_at: null })와visibleWhere({ is_active: true, deleted_at: null }, 노출 플래그 보유 모델용) 둘을 두고@/prisma배럴로 내보냈습니다. 가장 많이 반복되던store: { is_active: true, deleted_at: null }같은 리터럴(11회)이store: visibleWhere한 단어로 줄어듭니다.컨벤션은 이렇게 바뀝니다: 루트 READ는 extension을 신뢰해 명시하지 않고, 미커버 경로는 반드시 조각을 명시한다. 중복 명시 59곳을 지운 것도 이 원칙의 일부입니다. 예외로 publicReviewWhere · visibleWishlistWhere 같은 공유 where 헬퍼는 루트 가드를 지우지 않고 조각 조합으로 유지했는데, 이 헬퍼들이 나중에 nested 위치에서 재사용되면 그때는 extension이 못 지켜주기 때문입니다. CLAUDE.md의 soft-delete 안내도 새 컨벤션으로 교체했습니다.
덤으로 잡은 것: Region
deleted_at컬럼을 가진 모델이 스키마에 50개인데 extension 등록 목록에는 49개뿐이었습니다. 빠진 하나가 Region — 이력을 추적해 보니 의도적 제외가 아니라 모델을 나중에 추가하면서 목록 갱신을 빠뜨린 것이었습니다. 다행히 Region 루트 조회 4곳이 전부 수동 필터를 하고 있어서 사고는 없었고, 목록에 등록해도 동작이 변하지 않음을 확인하고 추가했습니다. 같은 실수가 재발하면 이제 테스트가 잡습니다 — dmmf에서deleted_at보유 모델을 뽑아 등록 목록과 diff가 0임을 단언하는 대조 테스트를 넣었습니다.검증
동작 변경이 0이어야 하는 PR이라 기존 spec 전체의 무변경 통과가 곧 증명입니다.
yarn validategreen — 191 suites / 1,649 tests(기존 1,647 전부 무변경, dmmf 대조 2건 신규). 전수 조사에서 함께 발견된 가드 누락(형제 필드는 가드가 있는데 일부만 빠진 곳들)은 동작이 바뀌는 수정이라 별도 fix PR로 분리했습니다.Refs #207