CRITICAL: listUsers, userFavorites, userReviews, userMemos 4개 GET이 인증만 요구하고 admin 검사가 없어, 일반 사용자 토큰으로 전체 사용자 목록 및 타인 활동 조회 가능했음. 각 메서드 첫 줄에 AuthUtil.requireAdmin() 호출 추가 → non-admin은 403. 함께 커밋(이전 미커밋 작업): - Logger 등록 (감사 로그용) - AuthUtil/Logger/HttpStatus/ResponseStatusException import 정리 - updateAdmin: 자기 자신 admin 변경 차단 + 감사 로그 (이미 동작 중이던 변경이나 git 미커밋 상태였음) 문서: - 설계서 §3 인수조건에 권한 강제 항목 추가, 상태 Draft → Approved - CHANGELOG.md 2026-06-15 핫픽스 항목 추가 검증: - Anonymous GET /api/admin/users → 403 ✓ - Bad-token GET /api/admin/users → 403 ✓ - 백엔드 빌드 성공, tasteby-api 재시작 완료 Refs: #267
6.6 KiB
6.6 KiB
Tasteby 작업 기록
작업 내용, 이슈, 해결 방법을 기록하는 문서. 커밋/배포 시 참고용.
2026-06-15
🔴 보안 핫픽스 #267 — AdminUserController GET 4종 권한 우회
listUsers,userFavorites,userReviews,userMemos가 인증만 요구하고 admin 검사를 하지 않아 일반 사용자 토큰으로 전체 사용자 목록 및 타인 활동 조회 가능했음- 4개 메서드 첫 줄에
AuthUtil.requireAdmin()추가 → non-admin 호출 시 403 - 설계서 §3 인수조건에
/api/admin/users/**권한 강제 항목 추가 - Refs: #267 (현행화 Reviewer 반려 → Developer 수정 → 다시 통과)
ch-bootstrap 적용 (페르소나 파이프라인 + Design-First)
- Redmine 8단계 페르소나 큐(
01-Planner~09-Done) + 9개 카테고리 자동 생성 - Design-First 게이트(설계서 없으면 코드 작성 금지) 도입
.claude/agents/8개 페르소나 +.claude/workflows/persona-pipeline.js- 안전-최대 권한 정책(
.claude/settings.json) docs/{design,adr,pipeline}/골격 +scripts/enqueue.sh- 기존 Tasteby 고유 규칙(존댓말, CHANGELOG, 디자인 패턴, CORS, PM2)은
CLAUDE.md0/7/8장으로 보존 - Redmine 프로젝트 description + Wiki 4페이지(Overview/Dev-Env/Prod-Env/Deploy) 작성
tasteby 기존 18개 기능 Design-First 현행화
- 백엔드 12개(auth/user/restaurant/video/extract-pipeline/search/review-memo/channel/stats/daemon/cache/health) + 프론트 6개(map/restaurant-detail/filter/review-memo/admin/login)
- 각 기능별
docs/design/<issue>-<slug>/README.md12개 섹션 채움 (총 3,830줄) - 추적성: 각 설계서가 구현 파일/Redmine 이슈/커밋 SHA와 연결됨
- Reviewer 결과: 17 PASS w/notes, 1 REJECT (#267 admin 권한 critical)
- 후속 17개 개선 이슈(#289~#305) 자동 등록 — 결함 총 124건(critical 3 / major 46 / minor 75) 백로그 반영
- 코드 변경 없음 — 문서화 + 백로그화 전용
2026-04-04
코드 리뷰 스크립트 추가 + 리뷰 지적사항 반영
scripts/code_review.py: 페르소나 기반 코드 리뷰 스크립트 (OpenRouter API, 프론트/백엔드/보안/아키텍처 4관점)UserService.updateAdmin(): 존재하지 않는 userId에 대해 404 응답 추가AdminUserController.updateAdmin(): 자기 자신 admin 권한 변경 차단 + 감사 로그 추가 + 응답에 변경 결과 포함JsonUtil.normalizeEvaluation(): evaluation 정규화 로직을 공통 유틸로 통합 (RestaurantService, VideoService 중복 제거)RestaurantService.linkVideoRestaurant(): evaluation 저장 시 평문→JSON 정규화 + 300자 제한
가격대 필터 5단계 세분화
- 기존 3단계(저렴/보통/고가) → 5단계(저렴/가성비/보통/프리미엄/럭셔리)
PRICE_GROUPS상수 수정, 정규식 패턴 세분화
모바일 터치 영역 개선 (44×44px 통일)
- 별점 선택기: 0.5단위 10개 숫자 버튼(24px) → 별 아이콘 5개(44px), 탭으로 정수/반점수 전환
- FilterSheet 닫기 버튼:
p-1→p-2(터치 영역 확대) - RestaurantDetail 찜 버튼: 패딩 추가 +
touch-manipulation적용 - 필터 초기화 X 버튼: 아이콘 12px → 14px + 패딩 추가
채널 필터 시 식당이 3개만 나오는 버그 수정
- 원인: 전체 식당 500개만 가져와서 클라이언트 필터링 → 특정 채널 식당이 상위 500개에 일부만 포함
- 수정:
page.tsx에서 채널 필터 변경 시 서버에channel파라미터를 보내 서버 사이드 필터링 적용
2026-03-29
식당 평가(evaluation) 표시 안 되는 버그 수정
- 원인: LLM이 추출한 evaluation이 대부분 평문 문자열로 DB에 저장되어 있었으나, 프론트에서
evaluation.text로 접근하여 표시되지 않음 - 수정:
JsonUtil.parseMap(): JSON 파싱 실패 시{"text":"원본문자열"}로 감싸서 반환VideoService.findDetail():VideoRestaurantLink의 evaluation 평문을 JSON 객체로 정규화
2026-03-16
Admin 유저 관리 — 관리자 권한 토글 기능 추가
- Backend
UserMapper.xml:findAllWithCounts에is_admin컬럼 추가,updateAdmin쿼리 추가UserMapper.java:updateAdmin()메서드 추가UserService.java:updateAdmin()메서드 추가AdminUserController.java:PATCH /api/admin/users/{userId}/admin엔드포인트 추가
- Frontend
api.ts:updateAdminUserAdmin()API 함수 추가, 유저 타입에is_admin필드 추가admin/page.tsx: 유저 테이블에 "관리자" 컬럼 + ON/OFF 토글 버튼 추가
CORS PATCH 메서드 허용
- 문제: PATCH 요청 시 CORS preflight(OPTIONS)에서 403 차단
- 원인:
WebConfig.java의allowedMethods에PATCH가 빠져 있었음 - 해결:
List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")→"PATCH"추가
Icon 시스템 개선
- Material Symbols
sake아이콘 종횡비 문제 수정 —width/height를fontSize와 동일하게 고정 +overflow: hidden - 이자카야 아이콘:
sake→local_bar(술잔 모양으로 변경) - 삼겹살/돼지구이, 족발/보쌈, 돈카츠:
PiggyBank→food:pig(커스텀 돼지 SVG)
LLM 추출 프롬프트 수정
ExtractorService.java:evaluation필드 → "평가 내용을 100자 이내로 요약"으로 변경
브랜드 가이드 문서 생성
frontend/docs/brand-guide.md: 브랜드 아이덴티티, 컬러, 타이포, 아이콘 정책 등 정리
PM2 프론트엔드 포트 고정
- 문제:
pm2 restart후 Next.js가 3000(Gitea 포트)으로 fallback → nginx 502 - 해결: PM2에
PORT=3001환경변수 고정하여 재등록 +pm2 save
2026-03-14
홈 탭 장르 카드 픽토그램 적용
- Phosphor Icons (
@phosphor-icons/react) + 커스텀 SVG FoodIcon 시스템 구축 cuisine-icons.ts에getPhosphorCuisineIcon()함수 추가 (46개 소분류 매핑)FoodIcon.tsx생성 — jjigae, tteok, noodle, tempura, pig 커스텀 SVG 아이콘food:접두어로 Phosphor vs 커스텀 SVG 분기 처리
지역 필터 추가 + 배포
- 홈 탭에 지역 필터 드롭다운 추가
- v0.1.11로 OKE 배포 완료
참고: 주의사항
| 항목 | 내용 |
|---|---|
| 새 HTTP 메서드 추가 시 | WebConfig.java의 CORS allowedMethods에 반드시 추가 |
| 백엔드 코드 수정 후 | bootJar 빌드 성공 확인 → pm2 restart tasteby-api |
| 프론트엔드 dev 포트 | 3001 고정 (3000은 Gitea) |
| tasteby-web 실행 방식 | npm run dev (standalone 아님) |