[Developer] #533 언급 적은 식당 제외 필터 (min_mentions + video_count)
- backend: findAll 응답에 video_count(strong/unknown 링크수) + min_mentions 서버필터 - Restaurant.videoCount, RestaurantMapper(xml/iface), Service, Controller(+cache key) - frontend: Restaurant.video_count 타입 + 데스크톱 툴바 "언급"(2/3/5회+) 클라 필터 - 검증: min_mentions=2→116, =3→36 (위반 0). 빌드/tsc 통과 - 설계서 docs/design/533-min-mentions-filter/README.md Refs #533 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
44
docs/design/533-min-mentions-filter/README.md
Normal file
44
docs/design/533-min-mentions-filter/README.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# #533 — 언급 적은(관련도 낮은) 식당 제외 필터
|
||||
|
||||
## 배경 / 문제
|
||||
영상에서 잠깐·우연히 언급된(=관련도 낮은) 식당까지 모두 노출되어 신호 대비 잡음이 큼.
|
||||
사용자가 "언급이 충분한 식당만" 보도록 제외 필터 제공.
|
||||
|
||||
## 신호 정의
|
||||
"의미있는 언급 수(`video_count`)" = 해당 식당의 `video_restaurants` 링크 중
|
||||
**relevance ∈ ('strong','unknown')** 개수. (weak/incidental = 곁다리 언급 → 제외)
|
||||
→ 기존 `findVideoLinks` 기본 노출 정책(strong/unknown)과 일관.
|
||||
|
||||
## 범위
|
||||
- **백엔드**: 식당 목록 응답에 `video_count` 포함 + `min_mentions` 서버 필터 파라미터.
|
||||
- **프론트**: `Restaurant.video_count` 타입 + 클라이언트 필터 UI(전체/2회+/3회+).
|
||||
- 서버사이드 필터 일원화(현 클라 필터 패턴 통일)는 **#535**로 분리.
|
||||
|
||||
## 함수/변경 설계
|
||||
|
||||
### 백엔드
|
||||
1. `domain/Restaurant.java` — `Integer videoCount` 필드 추가(전이 enrichment).
|
||||
2. `mapper/RestaurantMapper.xml`
|
||||
- `restaurantMap` resultMap: `<result property="videoCount" column="video_count"/>`
|
||||
- `findAll` SELECT에 스칼라 서브쿼리 추가:
|
||||
`(SELECT COUNT(*) FROM video_restaurants vrc WHERE vrc.restaurant_id = r.id AND vrc.relevance IN ('strong','unknown')) AS video_count`
|
||||
- `findAll` `<where>`에 optional 필터:
|
||||
`<if test="minMentions != null and minMentions > 0"> AND (위 서브쿼리) >= #{minMentions} </if>`
|
||||
3. `mapper/RestaurantMapper.java` — `@Param("minMentions") Integer minMentions` 추가.
|
||||
4. `service/RestaurantService.java` — `findAll(..., Integer minMentions, boolean includeHidden)`로 스레드. 5-arg 오버로드는 `null, false` 전달.
|
||||
5. `controller/RestaurantController.java` — `@RequestParam("min_mentions") Integer minMentions` + 캐시 키에 `mm=` 포함.
|
||||
|
||||
### 프론트
|
||||
6. `lib/api.ts` — `Restaurant.video_count?: number | null`; `getRestaurants` 파라미터 `min_mentions?`(미래/서버필터용).
|
||||
7. `app/page.tsx` — 필터 상태 `minMentions`(0/2/3) + `filteredRestaurants`에 `(r.video_count ?? 0) >= minMentions` 가드 + UI 컨트롤 + useMemo deps 추가.
|
||||
|
||||
## 엣지케이스
|
||||
- `video_count` 미산정(findById 등) → null. 클라 필터는 `?? 0`로 안전.
|
||||
- minMentions=0(기본) → 필터 미적용(기존 동작 유지).
|
||||
- DISTINCT + 스칼라 서브쿼리: r.id 단위라 결과 불변.
|
||||
|
||||
## 검증
|
||||
- 백엔드 빌드 성공 → PM2 재시작.
|
||||
- `GET /api/restaurants?min_mentions=2` 가 2회 미만 식당 제외하는지.
|
||||
- 응답에 `video_count` 포함 확인.
|
||||
- 프론트 토글로 목록/지도가 줄어드는지.
|
||||
Reference in New Issue
Block a user