Skip to content

[FEAT] 추천 이유를 앞 단계로 빼고, 백엔드 응답을 그대로 보는 화면을 붙입니다 - #64

Merged
Yena07 merged 2 commits into
devfrom
feat/frontend-log-and-reasons
Aug 10, 2026
Merged

[FEAT] 추천 이유를 앞 단계로 빼고, 백엔드 응답을 그대로 보는 화면을 붙입니다#64
Yena07 merged 2 commits into
devfrom
feat/frontend-log-and-reasons

Conversation

@Yena07

@Yena07 Yena07 commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

개인 저장소에서 코드래빗·Codex 리뷰를 받고 머지한 셋을 옮깁니다. frontend/ 9개 파일만 바뀝니다.


1. 추천 이유를 확인 화면 앞의 독립된 단계로

확인 화면 하나에 확인 카드 · 조건표 · 후보 목록 · 이유가 다 쌓여 있었습니다. 이유를 읽으려면 스크롤을 한참 내려야 했습니다 — 승인 전에 꼭 읽어야 할 것이 가장 읽기 어려운 자리에 있던 셈입니다.

1단계 — 이렇게 찾았어요 (스크롤 필요 없음)

반영한 조건
  반영: 선호하신 이용 방식과 일치하는 메뉴라 우선 추천드립니다.
  반영: 선호하신 맵기와 맞는 메뉴라 우선 추천드립니다.
빼 둔 메뉴와 그 이유
  제외: 알레르기와 겹쳐서 제외됐어요.
  제외: 지금은 품절이라 제외됐어요.

[ 메뉴 고르러 가기 ]

2단계 — 메뉴 선택 · 확인 카드 — 이유는 한 줄 + 이유 N개 더 보기(누르면 1단계로)

확인 화면에 한 줄을 남기는 이유는 킷 가이드가 [필수] 로 정해서입니다 — "추천 결과만 보여주지 마세요. 왜 그런지 함께 보여줘야 합니다." 닭강정 체크리스트의 "추천 이유가 최소 1개 있고 사람이 읽을 수 있다" 도 같은 항목입니다.

2. 이유를 다시 봐도 골라 둔 것을 잃지 않습니다

조건부로 그렸더니 이유를 한 번 더 볼 때 확인 갈래가 언마운트돼서 고른 후보와 확인 표시가 초기화됐습니다. 재확인은 승인 조건이라(CANDIDATE_REQUIRED · CONFIRMATION_REQUIRED) 다시 짚어야만 넘어갑니다 — 이유를 꼼꼼히 읽을수록 번거로워지는 구조였습니다.

display: none 으로 감춥니다. 접근성 트리에서도 빠져서 스크린리더가 감춰진 화면을 읽지 않습니다.

3. 백엔드가 준 것을 그대로 보는 화면

화면만 봐서는 이 문장이 서버에서 온 것인지 앱이 지어낸 것인지 알 수 없습니다. 목도 그럴듯하게 답합니다.

?log=side 앱 옆에 나란히 — 누를 때마다 한 줄씩 쌓이는 게 보입니다
?log=1 앱을 덮는 겹으로 크게
우하단 패널 앱 옆에 띄우기 / 크게 보기

API 10개마다 담당·컨트롤러·역할·화면 어디에 쓰이는지 적었습니다. 담당은 이 저장소 커밋 기록에서 가져왔습니다(git log -- <컨트롤러 파일>) — 짐작하지 않았습니다.

200  POST  /api/v1/recommendations — 추천                     12ms
     담당 Gganii · RecommendationController

이 응답이 화면에서 이렇게 쓰입니다
  확인 화면 · 이래서 골랐어요   선호하신 이용 방식과 일치하는 메뉴라 우선 추천드립니다.
  확인 화면 · 이건 뺐어요       알레르기와 겹쳐서 제외됐어요.
  확신도                        0.5
  1순위 후보                    CHICKEN-003  (화면에는 c1 로 나감)

결과 화면에 서버 문장을 인용합니다

#48summary.status 를 그대로 인용합니다. 앱 말투로 옮기지 않습니다 — 옮기는 순간 서버가 준 것인지 앱이 지어낸 것인지 다시 알 수 없어집니다.

장바구니에 담았어요 · 1개 · 6,000원
  선호하신 이용 방식과 일치하는 메뉴라 우선 추천드립니다.

  키오스크가 보내온 결과
  “정상적으로 장바구니에 추가되었습니다.”

다만 아는 문장 넷만 인용합니다. 서버가 결제 완료 같은 문장을 담아 보내면 그게 곧바로 화면에 뜨는데, 결제 표현은 있기만 해도 실격이라 서버를 믿고 통과시킬 값이 아닙니다.

기록에 남기는 범위

  • 가입·로그인 경로의 본문은 안 남깁니다(비밀번호). 안 남겼다는 사실은 표시해서 '비어 있음'과 구분합니다.
  • userId 는 가립니다 — #61 에 들어간 것과 같습니다.

리뷰에서 나온 것

코드래빗 10건 + Codex 2건. 그중 여럿이 이 화면들을 만들면서 제가 만든 버그였습니다.

없는 칸(reviewSnapshot.itemCount)을 읽어 ?개 로 적음 서버가 준 것만 보여 주겠다는 이 화면의 전제를 스스로 어긴 셈
성공했는데 중단 사유: VERIFY_CART_VERIFIED stopReasonPASS 일 때도 옴 — 마지막 상태 이름이지 중단 사유가 아님
하이라이트가 안 사라짐 2초 안에 다음 요청이 오면 앞 줄이 계속 밝아 구분이 안 됨
중단 결과에 서버 문장을 안 실음 정작 확인이 필요한 쪽이 비어 있었음
성공 응답 JSON.parse 무방비 account.ts 는 막아 두고 여기만 빠뜨림
테스트가 제 주석이 말한 회귀를 못 잡음 forgetAll 이 세션 0건일 때도 부르므로 toHaveBeenCalled() 가 항상 통과

접근성도 함께 고쳤습니다 — 로그 버튼 터치 영역 44×44, 겹 모드에 Esc·초기 포커스·role="dialog".

확인

tsc 0 · 200 tests · build ok

README.mddocs/BACKEND_INTEGRATION.md이 저장소 것이 최신이라 건드리지 않았습니다#61 의 문서 수정이 개인 저장소에는 아직 없어서, 통째로 옮기면 되돌아갑니다.

backend/ 는 건드리지 않았습니다.

Summary by CodeRabbit

  • 새 기능

    • 추천 이유를 확인 단계 전에 살펴보고, 확인 화면에서 요약을 다시 열 수 있습니다.
    • 실행 완료 화면에 서버 상태 안내가 표시됩니다.
    • 백엔드 요청·응답을 확인하는 로그 패널을 화면 위 또는 옆에서 열 수 있습니다.
    • 요청·응답 본문 펼치기, 인증 정보 가림, 로그 삭제, 실서버·목 모드를 지원합니다.
    • 연동 기록 보관량이 늘어나고 기록 전체 삭제 기능이 추가되었습니다.
  • 버그 수정

    • 응답 본문 처리 오류와 잘못된 응답 형식이 적절한 오류로 안내됩니다.
    • 전체 초기화 시 관련 연동 기록도 함께 삭제됩니다.

개인 레포에서 코드래빗.Codex 리뷰를 받고 머지한 셋을 옮긴다.
frontend/ 만 바뀐다.

1. 추천 이유를 확인 화면 앞의 독립된 단계로 (Yena07#11)

  확인 화면 하나에 확인 카드.조건표.후보 목록.이유가 다 쌓여 있었다.
  이유를 읽으려면 스크롤을 한참 내려야 했다 - 승인 전에 꼭 읽어야 할 것이
  가장 읽기 어려운 자리에 있었던 셈이다.

    1단계  이렇게 찾았어요       반영한 조건 / 빼 둔 메뉴와 그 이유
    2단계  메뉴 선택.확인 카드    이유는 한 줄 + '이유 N개 더 보기'

  확인 화면에 한 줄을 남기는 이유는 킷 가이드가 [필수] 로 정해서다 -
  "추천 결과만 보여주지 마세요. 왜 그런지 함께 보여줘야 합니다."

2. 이유를 다시 봐도 골라 둔 것을 잃지 않는다 (Yena07#14)

  조건부로 그렸더니 이유를 한 번 더 볼 때 확인 갈래가 언마운트돼서
  고른 후보와 확인 표시가 초기화됐다. 재확인은 승인 조건이라 다시 짚어야만
  넘어간다 - 이유를 꼼꼼히 읽을수록 번거로워지는 구조였다.
  display:none 으로 감춘다(접근성 트리에서도 빠진다).

3. 백엔드가 준 것을 그대로 보는 화면 (Yena07#12)

  화면만 봐서는 이 문장이 서버에서 온 것인지 앱이 지어낸 것인지 알 수 없다.
  목도 그럴듯하게 답한다.

    ?log=side   앱 옆에 나란히 - 누를 때마다 한 줄씩 쌓이는 게 보인다
    ?log=1      앱을 덮는 겹으로 크게
    구석 패널   앱 옆에 띄우기 / 크게 보기

  API 10개마다 담당.컨트롤러.역할.화면 어디에 쓰이는지. 담당은 이 저장소
  커밋 기록에서 가져왔다(git log -- 컨트롤러 파일).
  오간 요청마다 보낸 것.받은 것 JSON 전문. 응답의 어느 칸이 화면의 어느
  문장이 되는지도 짚어 준다.

  결과 화면에 서버 문장(#48 summary.status)을 인용해서 붙인다. 앱 말투로
  옮기지 않는다 - 옮기면 서버가 준 것인지 앱이 지어낸 것인지 다시 알 수 없다.
  다만 아는 문장 넷만 인용한다. 서버가 결제 문장을 담아 보내면 그대로 뜨는데,
  결제 표현은 있기만 해도 실격이라 서버를 믿고 통과시킬 값이 아니다.

  가입.로그인 경로의 본문은 안 남긴다(비밀번호). 안 남겼다는 사실은 표시해서
  '비어 있음' 과 구분한다. userId 는 가린다 - 이미 #61 로 들어간 것과 같다.

리뷰에서 나온 것

  코드래빗 10건 + Codex 2건. 그중 여럿이 이 화면들을 만들면서 내가 만든
  버그였다 - 없는 칸을 읽어 '?개' 로 적은 것, 성공인데 '중단 사유' 라고
  적은 것, 하이라이트가 안 사라진 것, 중단 결과에 서버 문장을 안 실은 것,
  성공 응답 파싱이 무방비였던 것, 테스트가 제 주석이 말한 회귀를 못 잡던 것.

  접근성도 함께 - 로그 버튼 터치 영역 44, 겹 모드에 Esc.포커스.role=dialog.

README 와 docs 는 이 저장소 것이 최신이라 건드리지 않았다.

tsc 0, 200 tests, build ok
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Yena07, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 17 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 779cddb1-e5e4-4140-9924-0c74cb51a2e9

📥 Commits

Reviewing files that changed from the base of the PR and between 4afc6c4 and 2803924.

📒 Files selected for processing (4)
  • frontend/src/api/devlog.test.ts
  • frontend/src/api/devlog.ts
  • frontend/src/app/App.tsx
  • frontend/src/app/BackendLog.tsx

Walkthrough

백엔드 응답 처리와 연동 기록을 확장했습니다. 인증 본문은 가리고 주문 요청 본문은 기록합니다. 새 로그 화면에서 요청·응답과 화면 표시값을 확인할 수 있습니다. 추천 이유와 서버 상태 문장도 실행 흐름에 표시합니다.

Changes

백엔드 응답과 연동 기록

Layer / File(s) Summary
응답 계약과 오류 처리
frontend/src/api/backend.ts, frontend/src/api/account.ts, frontend/src/domain/types.ts, frontend/src/api/backend.test.ts
응답 본문을 한 번 읽어 성공·실패 처리와 로깅에 재사용합니다. 본문 읽기와 JSON 파싱 실패를 KioBridgeError로 처리합니다. 허용된 serverStatus만 결과에 전달합니다.
요청 기록과 보관 관리
frontend/src/api/devlog.ts, frontend/src/api/account.ts, frontend/src/api/client.ts, frontend/src/api/devlog.test.ts
경로별 본문 기록 정책을 적용합니다. 인증 본문은 가리고 요청·응답 본문을 기록합니다. 보관 한도를 60건으로 변경하고 비우기로 기록을 삭제합니다.

로그 화면과 실행 확인 흐름

Layer / File(s) Summary
백엔드 로그 화면
frontend/src/app/BackendLog.tsx
경로별 설명, 담당자, 응답값, 요청·응답 본문을 표시합니다. 오버레이·나란히 보기, 새 기록 강조, 성공 건수, 기록 삭제를 지원합니다.
추천 이유와 실행 상태 표시
frontend/src/app/App.tsx
추천 이유를 확인 단계 전에 표시하고 다시 열 수 있게 합니다. serverStatus를 성공 화면에 표시합니다. URL 설정과 패널 동작으로 로그 화면을 연결합니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant BackendAPI
  participant 연동기록
  participant BackendLog
  App->>BackendAPI: 백엔드 요청 실행
  BackendAPI->>BackendAPI: 응답 본문을 문자열로 읽음
  BackendAPI->>연동기록: 요청·응답 본문 또는 가림 상태 저장
  연동기록-->>BackendLog: 기록 변경 알림
  BackendLog->>연동기록: 최신 기록 조회
  BackendLog-->>App: 오버레이 또는 나란히 로그 화면 표시
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 추천 이유를 독립 단계로 분리하고 백엔드 응답 로그 화면을 추가한 주요 변경 사항을 정확히 요약합니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/frontend-log-and-reasons

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/src/app/App.tsx (1)

2494-2506: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

승인 전 실행 계획 생성 경로를 제거하세요.

onCancel거절하기를 호출합니다. 거절하기는 승인 버튼을 누르기 전에 api.reject를 호출합니다. 팀 백엔드의 reject/internal/orchestrator/approveapproved: false를 보내고 빈 실행 계획을 조립·제출·검증합니다.

취소 경로에서는 이 API를 호출하지 마세요. 거절 기록이 필요하면 실행 계획을 생성하거나 제출하지 않는 별도 API를 사용하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/app/App.tsx` around lines 2494 - 2506, Update the cancellation
flow for OrderExact and OrderClarification so onCancel no longer invokes 거절하기,
which triggers api.reject and the approval execution-plan path. Use a separate
cancellation or rejection-recording API that does not assemble, submit, or
validate an execution plan, while preserving the existing approve handlers.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/api/backend.ts`:
- Around line 459-462: Update the ExecFailed flow in App.tsx to accept and
forward the serverStatus returned by getPlanStatus, alongside the existing abort
prop. Render serverStatus on the aborted screen using the same quotation-display
behavior as the successful execution screen, and ensure the backend result
mapping continues preserving e.serverStatus.

In `@frontend/src/api/devlog.ts`:
- Around line 31-41: Change frontend/src/api/devlog.ts:31-41 so 본문을남길까 uses a
default-deny policy and only permits explicitly verified safe request bodies.
Update frontend/src/api/account.ts:338-350 to omit or structurally redact memo
and all user-entered values, and frontend/src/api/backend.ts:684-691 to omit or
apply the same redaction to approval-request profile data. Update
frontend/src/app/BackendLog.tsx:283-297 so unredacted user-input bodies are
never displayed.

In `@frontend/src/app/App.tsx`:
- Around line 3363-3365: Update the BackendLog render in the 로그모드 === "겹" branch
to always pass onClose={() => set로그모드("닫힘")}, including 목 모드 reached through
?log=1. Remove the 팀백엔드모드 conditional so the overlay consistently supports its
close button and Escape handling.

In `@frontend/src/app/BackendLog.tsx`:
- Around line 365-374: Update the close button in
frontend/src/app/BackendLog.tsx lines 365-374 to include minHeight: 44 and
sufficient vertical padding, and update the API description toggle button in
frontend/src/app/BackendLog.tsx lines 413-424 to include minHeight: 44, ensuring
both log-screen buttons have at least a 44×44 touch area.
- Around line 331-337: 겹 모드의 useEffect에서 초기 포커스와 Escape 처리에 더해 Tab 키 포커스 트랩을
구현하여 대화상자 내부 요소 사이에서만 순환하도록 하세요. 겹 모드 진입 전 활성 요소를 저장하고 닫거나 effect가 정리될 때 해당 요소로
포커스를 복원하며, 기존 나란히 조건과 onClose 동작은 유지하세요.

---

Outside diff comments:
In `@frontend/src/app/App.tsx`:
- Around line 2494-2506: Update the cancellation flow for OrderExact and
OrderClarification so onCancel no longer invokes 거절하기, which triggers api.reject
and the approval execution-plan path. Use a separate cancellation or
rejection-recording API that does not assemble, submit, or validate an execution
plan, while preserving the existing approve handlers.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3bd1267d-3a53-4ae1-b7aa-bee4ad401871

📥 Commits

Reviewing files that changed from the base of the PR and between ce90bc5 and 4afc6c4.

📒 Files selected for processing (9)
  • frontend/src/api/account.ts
  • frontend/src/api/backend.test.ts
  • frontend/src/api/backend.ts
  • frontend/src/api/client.ts
  • frontend/src/api/devlog.test.ts
  • frontend/src/api/devlog.ts
  • frontend/src/app/App.tsx
  • frontend/src/app/BackendLog.tsx
  • frontend/src/domain/types.ts

Comment thread frontend/src/api/backend.ts
Comment thread frontend/src/api/devlog.ts
Comment thread frontend/src/app/App.tsx Outdated
Comment thread frontend/src/app/BackendLog.tsx
Comment thread frontend/src/app/BackendLog.tsx
Critical — memo 가 로그 본문에 통째로 남았다

  본문을남길까 는 인증 경로만 뺐다. 그래서 주문표의 자유 입력 memo 가 요청
  본문에 실려 최대 60건 보관되고 로그 화면에 그대로 떴다.

  저장 전에 전화번호.주민등록번호.주소 모양은 걸러 막지만 이름은 모양이 없어
  못 거른다. 못 거른 것이 로그에 남아 화면과 시연 녹화에 그대로 찍힌다.

  값을 가린다. 어느 깊이에 있든 - profile-normalizations 의 profileInput,
  approve 의 profile, users/{id}/profiles 의 본문에 각각 다른 깊이로 있다.
  칸 자체는 남긴다. 무엇을 보냈는지는 알아야 한다.

  JSON 이 아니면 아예 안 남긴다. 모양을 모르는 본문에서 무엇이 남는지 장담할
  수 없다 - 가린다고 해 놓고 일부가 새는 것보다 안 보여 주는 편이 낫다.

Critical — 겹 로그에 갇힌다

  aria-modal 은 포커스를 가두지 않는다. 그 속성은 스크린리더에게 "뒤쪽은 없는
  셈 쳐라" 고 말할 뿐이고 Tab 은 그대로 뒤쪽 앱 버튼으로 넘어간다. 화면은
  덮여 있는데 포커스만 안 보이는 곳으로 가 버린다.

  Tab 을 직접 잡아 겹 안에서만 돌게 한다. 닫을 때는 열기 전 자리로 포커스를
  돌려준다 - 안 그러면 닫고 나서 문서 처음부터 다시 Tab 을 눌러야 한다.

  그리고 목 모드에서 onClose 를 안 넘기던 것도 되돌린다. 다시 못 여는 것보다
  못 나가는 쪽이 훨씬 나쁘다. 겹 모드에는 언제나 닫는 길을 준다.

내가 답변에서 했다고 말해 놓고 안 한 것

  중단 화면(ExecFailed)에 serverStatus 를 붙였다고 앞선 PR 답변에 적었는데,
  실제로는 데이터만 실어 보내고 화면은 안 고쳤다. 받지도 그리지도 않고 있었다.
  성공 화면과 같은 인용 UI 를 붙인다. 멈춘 경우에는 개수.금액이 없어서
  "키오스크가 뭐라고 했는지" 말고는 확인할 방법이 없다 - 오히려 여기가 이 줄이
  가장 필요한 자리다.

터치 영역

  닫기 버튼과 API 설명 토글이 콘텐츠 높이만 썼다. 둘 다 44 로.

tsc 0, 200 -> 202 tests, build ok
@Yena07
Yena07 merged commit b0dc91a into dev Aug 10, 2026
1 check passed
Yena07 added a commit to Yena07/kiobridge-app that referenced this pull request Aug 10, 2026
watTHEBUG/kioBridge#64 가 dev(b0dc91a)에 머지된 것을 가져온다.
팀에서 코드래빗 5건을 더 받아 고친 내용이다.

README 두 줄과 구조 표는 이 저장소 기준으로 되돌렸다.
tsc 0, 202 tests, build ok
@kjp0411
kjp0411 deleted the feat/frontend-log-and-reasons branch August 16, 2026 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant