Repository navigation
[Feat/#105] 학생회비 계좌 송금 플로우 화면 구현 - #107
Merged
Merged
Conversation
Figma 설명 문구는 줄바꿈 위치까지 디자인에 포함돼 있는데 `\n`이 공백으로 접혀서 의도와 다른 자리에서 줄이 바뀌었다. 기존 사용처는 모두 한 줄 문구라 렌더링 변화가 없다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
48px 일러스트 둘은 svgAssets가 레이어별로 쪼개져 나와 export(svg)로 받고, 같이 붙어 나온 캔버스 배경 rect와 조상 path를 걷어냈다. 파일 행 아이콘은 WDS IconImage와 글리프가 달라서 Figma 것을 그대로 받았다. 업로드한 파일 행 배경(Atomic/Blue/99)은 기존 primary-subtle(Blue/95)보다 훨씬 옅은 별개 값이라 토큰을 새로 연결한다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
홈의 "학생회비 납부하기"에서 시작하는 5단계 송금 플로우다. PG 결제가 아니라 토스 딥링크로 송금하고 학생회가 수동으로 입금을 확인하는 방식이라, 남은 학기 수와 학점이수현황 캡처를 받은 뒤 토스로 보냈다가 돌아와 확인을 받는다. 다섯 화면이 `뒤로가기 헤더 → 12px → (일러스트) 제목·설명 → 본문 → 하단 고정 버튼` 구조가 같고 간격과 문구만 달라서 FeeTransferStepLayout으로 묶었다. 업로드 전/후와 토스 안내/실패는 각각 한 화면의 상태 차이라 라우트를 나누지 않았고, 확인요청 완료 화면은 체크 모션이 신청 완료 화면들과 같은 Figma 메인 컴포넌트라 공용 ResultScreen을 쓴다. 경로는 화면설계서에 표기가 없어 용어 사전의 `회비 납부 → fee`로 정했다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
github-actions
Bot
requested review from
jjunh33,
leegain1,
sangrae2325 and
tnals0924
October 8, 2026 07:34
예시 이미지를 1배(280x205)로 받아 고해상도 화면에서 흐리게 보였다. 3배(840x615)로 다시 받고, 280px 그림이 335px 카드 안에 정확히 들어가도록 좌우 여백을 27.5px로 맞춘다. "캡처 예시" 라벨은 Figma가 Caption 2/Regular(11px)인데 caption1(12px)로 썼었다. 이 그림은 실제 K-스마트멘토 스크린샷 위에 가림 박스와 가짜 값을 얹어 만든 것이라 레이어가 합쳐진 export만 커밋해야 한다. 가림 박스가 전부 불투명해 밑글씨가 비치지 않는 것을 픽셀로 확인했고, 그 전제를 컴포넌트 주석에 남겼다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
supertoss://send 딥링크로 토스를 열고, 앱에 다녀오면 송금 확인 단계로 넘긴다. 브라우저는 커스텀 스킴이 실제로 열렸는지 알려주지 않는다 — window.open은 앱이 없어도 창 객체를 돌려준다. 그래서 "앱으로 전환되면 탭이 가려진다"는 성질을 쓴다: 1.5초 안에 화면이 가려지면 성공으로 보고 복귀를 기다리고, 가려지지 않은 채 타이머가 울리면 이동 실패 화면을 띄운다. 입금 계좌는 저장소가 public이라 코드에 넣지 않고 VITE_FEE_TOSS_* 환경 변수로 받는다(.env는 .gitignore에 있다). 값이 없으면 빈 URL이라 곧바로 실패 화면이 된다. 금액은 남은 학기 수별 규칙을 아직 못 받아서 목업 상수로 보낸다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
실기기에서만 동작을 확인할 수 있어 검증이 안 된 채로 들어가는 걸 피한다. 토스 화면은 다시 "누르면 바로 이동 실패"로 돌아간다. This reverts commit 7a6cceb.
화면 프레임이 w-full / sm:w-[480px]라 카드 폭이 변하는데 카드 높이를 375 기준 248px로 박고 그림을 w-full로 둬서, 폭이 넓어지면 그림이 같이 커져 아래가 잘렸다 (430px에서 40px, 480px 프레임에서 77px). 반대로 좁으면 아래에 빈 공간이 생겼다. 높이를 내용이 정하게 두고 그림은 Figma 크기인 280px로 고정한다 — 카드가 더 좁으면 preflight의 max-width:100%가 줄여준다. 설계 폭에서는 그대로 248px이 나온다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
get_motion_context를 다섯 프레임 전부 돌려보니 ₩ 아이콘(3562:163025)에도 Figma Motion이 있었다. 송금 확인 화면만 확인하고 넘어가 놓쳤던 것이다. 둘 다 Lottie를 받아야 붙일 수 있어 지금은 정지 SVG다 — 어떤 키프레임이 빠져 있는지 주석에 남겨서 재export 때 무엇을 받아야 하는지 알 수 있게 한다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
디자이너가 LottieFiles 플러그인으로 내보낸 json을 받아 정지 SVG를 대체한다. 둘 다 48x48 / 60fps / 120프레임(2초)이고 텍스트 레이어는 없다. 재생기는 두 아이콘이 공유한다(FeeLottieIcon). 타임라인은 2초지만 실제 움직임은 앞부분에서 끝나서, 모션 줄이기일 때 세울 프레임을 json에서 직접 확인해 넘긴다 — ₩는 키프레임이 66프레임(1.1초)에서 끝나고, 종이비행기는 플러그인이 이징을 매 프레임으로 구워놔서 값이 실제로 고정되는 49프레임(0.82초)을 찾아야 했다. 브라우저에서 재생도 확인했다. ₩는 path d가 11단계로 변하며 획이 그려지고, 종이비행기는 scale 0.816 → 1.024(overshoot) → 1.0으로 잦아들며 770ms에 멈춘다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
# Conflicts: # docs/conventions/wds-component-usage.md
단계마다 라우트를 따로 두면 값을 navigate state로 넘겨야 해서 남은 학기 수가 캡처 단계에서 읽히지 않고 고른 파일도 다음 단계로 넘어가지 않았다. 라우트를 /fee/transfer 하나로 합치고 단계는 ?fee.step=으로 나눠, 두 값을 퍼널 context가 플로우 끝까지 들고 가게 했다. 로그인·가입 퍼널과 같은 구성이다.
tnals0924
reviewed
Oct 27, 2026
fee.ts가 add/add로 충돌해서 양쪽을 합쳤다. main의 카카오 채널 주소도 외부 연동 주소라 FEE_EXTERNAL_LINKS로 묶었다(#107 리뷰).
window.open에 noopener를 주면 스펙상 반환값이 항상 null이라, 토스 링크를 채우면 실제로 열려도 매번 실패 화면이 떴다. 반환값 판정을 버리고 열기만 한 뒤 송금 확인 단계로 넘긴다 — 실패 화면은 링크 주소가 없을 때만 띄운다. 플로우를 끝내고 홈으로 나간 뒤 뒤로가기를 누르면 중간 단계가 context째 되살아나서 송금 확인을 다시 요청할 수 있었다. lib/useFunnel에 useFunnelExit을 두고 쌓인 단계 수만큼 되돌아가게 했다. "다음에 할게요"도 같은 경로를 쓴다.
토스 딥링크·K-스마트멘토·학생회 카카오 채널이 각자 window.open을 부르고 있었다. lib/openExternalLink로 모아서 여는 방식이 바뀔 때 한곳만 고치면 되게 했다 — 앱 WebView에서 시스템 브라우저로 넘기는 브리지 분기도 이 자리에 들어간다. 단계 화면은 어디로 어떻게 여는지 모르고 onOpenGuide·onOpenToss만 부른다. 토스 단계는 링크 유무를 hasTossLink로 받아 실패 화면만 판단한다.
고른 캡처를 단계의 로컬 state와 퍼널 context에 같이 두고 있었다. context를 갈아 끼우면 화면이 새 값으로 다시 그려지니 로컬 state가 필요 없다 — 진실의 출처를 하나로 줄여서 나중에 퍼널 밖에서 context를 바꿔도 어긋나지 않는다.
첫 단계의 뒤로가기가 navigate(-1)이라, 딥링크·앱 WebView 진입·주소 직접 입력으로 들어오면 돌아갈 기록이 없어 아무 일도 하지 않았다. 다른 화면들과 같이 useBackNavigation으로 바꿔서 그런 경우 홈으로 보낸다.
컴포넌트 컨벤션의 "Tailwind 단계 → 토큰 → 구조 → 주석 달린 예외" 순서를 따른다. h-[46px]→h-11.5, size-[18px]→size-4.5, gap-[13px]→gap-3.25, w-[280px]→w-70. rounded-[10px]만 단계가 없어서 임의값으로 남기고 주석을 달았다.
오버레이가 떠 있는 동안 초점이 뒤 화면에 그대로 있어서, 키보드·스크린리더로는 가려진 화면을 계속 조작할 수 있었다. 열릴 때 닫기 버튼으로 초점을 옮기고 닫힐 때 미리보기를 연 파일 행으로 되돌린다.
미납 상태의 "학생회비 납부하기" 줄이 누를 수 없는 채로 있었다(화면이 없어서 남겨 둔 TODO). 계좌 송금 플로우가 들어왔으니 onSelect로 연결한다.
tnals0924
self-requested a review
October 28, 2026 08:40
tnals0924
approved these changes
Oct 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#️⃣연관된 이슈
🎯 해결하려는 문제가 무엇인가요?
홈의 "학생회비 납부하기"(
3147:146285)를 눌렀을 때 갈 화면이 코드에 하나도 없었다. Figma에는 계좌 송금 플로우가 9개 프레임으로 그려져 있다.PG 결제가 아니라 토스 딥링크로 송금 → 학생회가 3일 이내 수동 확인하는 방식이고, 남은 학기 수에 따라 납부 금액이 달라져서 학점이수현황 캡처를 함께 제출받는다.
구현 화면
❓ 왜 해결해야 하나요?
학생회비 납부는 홈 진입점이 이미 디자인에 있는 주요 플로우인데, 눌러도 갈 데가 없다.
⭐ 어떻게 해결했나요?
라우트 하나(
/fee/transfer) +useFunnel퍼널 하나로 묶었다. 단계는 주소의?fee.step=으로 나뉜다 — 로그인·온보딩 퍼널(AuthSignupScreen,/auth)과 같은 구성이다.history.replace로 context만 갈아 끼운다(히스토리가 늘지 않음).guard가 첫 단계로 돌려보낸다. 새로고침·주소 직접 입력에도 학기 수나 캡처 없이 토스 화면이 열리지 않는다.FeeTransferStepLayout으로 네 단계를 묶었다. 전부뒤로가기 헤더 → 12px → (일러스트) 제목·설명 → 본문 → 하단 고정 버튼구조가 같고 간격과 문구만 다르다. 간격은 Figma가 화면마다 8/12/16으로 다르게 잡아둬서contentGap유니온 타입으로 받는다. 뒤로가기는onBackprop으로 받아서 퍼널이 단계에 맞는 동작을 넘긴다.ResultScreen을 쓴다. 체크 모션이 신청 완료 화면들과 같은 Figma 메인 컴포넌트(Circle Check Motion 1712:192849)의 인스턴스라CompleteCheck를 그대로 재사용했다. 뒤로가기(←)가 아니라 X로 닫는 화면이라 이 단계만FeeTransferStepLayout을 쓰지 않는다.ConfirmModal이다. Figma 인스턴스(3562:162972)가 기존Modal(995:34701)과 같은 311×190이다.lib/openExternalLink로 모았다. 단계 화면은 어디로 어떻게 여는지 모르고onOpenGuide·onOpenToss만 부른다. 앱 WebView에서 시스템 브라우저로 넘기는 브리지 분기도 이 자리에 들어간다.File을 context에 그대로 담는다. 구조화 복제가 되는 값이라history.state에 실린다.guard가instanceof File로 확인해서, 되살아나지 못하면 첫 단계로 돌아간다.라우트를 새로 정한 근거
화면설계서(
687:20584)에는 경로 컬럼이 아예 없다. 7개 페이지 텍스트 노드 약 19,000개를/경로패턴으로 훑어도 라우트 문자열이 0건이다. 그래서 용어 사전(terminology.md)의회비 납부 → fee와 "프론트 라우트 경로:/{코드 용어}" 규칙으로 정했다.🧩 이 PR의 한계 & 트레이드오프
FEE_EXTERNAL_LINKS상수에 빈 문자열로 두고 값이 있을 때만 열도록 했다(빈 창이 뜨지 않는다). 토스 딥링크는 학생회 계좌와 납부 금액 규칙(남은 학기 수에 따라 달라진다)이 정해져야 만들 수 있다.objectURL로 띄운다(언마운트 시revokeObjectURL). 연동할 때FeeTransferTranscriptStep에서 업로드 요청을 보내면 된다. 그때는File대신 서버가 준 식별자를 context에 담는 쪽이 안전하다 —history.state는 브라우저마다 크기 상한이 있다(Firefox 16MiB).1~99로 뒀다. 실제 학적 기준이 있으면 맞춰야 한다.⛓️ 기존 기능에 미치는 영향
router.tsx에 라우트가 1개 추가됐다(/fee/transfer).ConfirmModal·ResultScreen설명에whitespace-pre-line을 붙여\n을 살렸다. 기존 사용처(행사·사물함 결과 화면, 빌릴게·열린피드백 모달)는 모두 한 줄 문구라 렌더링 변화가 없다(description=에\n을 쓰는 곳이 0건인 것을 grep으로 확인).index.css에--color-blue-99토큰이 하나 늘었다. 기존 토큰은 건드리지 않았다.lib/useFunnel.ts에useFunnelExit을 추가했다. 로그인·가입 퍼널도 같은 문제(끝내고 나간 뒤 뒤로가기로 단계 복귀)가 있어서 이어서 쓸 수 있지만, 이 PR에서는 계좌 송금만 쓴다.lib/openExternalLink.ts를 새로 만들고 납부내역 화면의 카카오 채널 열기도 여기로 바꿨다.window.open직접 호출은 이제 이 파일 하나뿐이다.HomeInfoList의 미납 상태 "학생회비 납부하기" 줄에onSelect를 연결했다(#117이 남긴 TODO 해소). 나머지 줄은 그대로다.features/fee/constants/fee.ts가 add/add로 충돌해서 양쪽을 합치고, 카카오 채널 주소도 외부 연동 주소라FEE_EXTERNAL_LINKS로 묶었다.🔀 Edge Case & 실패 시나리오
0이면 "다음"이 비활성이다.input.value를 비워서change가 다시 터지게 했다).guard가 첫 단계로 돌려보낸다.useBackNavigation).useFunnelExit) — 나간 뒤 뒤로가기를 눌러도 단계가 되살아나지 않는다.📋 검토한 대안과 선택 이유
/fee/transfer/semester등 5개). 그러면 단계 사이 값을navigate(..., { state })로 넘겨야 해서 남은 학기 수가 캡처 단계에서 읽히지 않고 고른 파일도 다음 단계로 넘어가지 않았다. 퍼널 context로 바꾸면서 두 값이 플로우 끝까지 이어진다.Button의 outlined로 대체하는 것도 봤지만 radius·높이가 달라서 Stream 로컬로 만들었다. 파일 행 아이콘도 WDSIconImage는 외곽선 스타일이라 글리프가 달라 Figma 것을 받았다.border로 그리면box-sizing때문에 Figma의 335×104 / 303px 행이 333×102 / 301px가 된다 —outline-1 -outline-offset-1로 바꿨다.💬 리뷰 포인트
[c]일러스트 모션의 반복 설정을 확인 부탁드립니다. Figma는 둘 다 2초loop인데 1회 재생(loop={false})으로 맞췄습니다 — 기존 완료 체크 모션과 같은 판단입니다. 계속 반복되는 게 의도면 알려주세요.[c]라우트 경로(/fee/transfer)를 새로 정했습니다. 설계서에 근거가 없어 용어 사전 규칙으로 정한 거라, 백엔드 엔드포인트와 맞는지 확인 부탁드립니다.[c]납부 금액 규칙과 토스 계좌가 정해지면 알려주세요. 딥링크를 만들려면 둘 다 필요합니다.[a]리뷰 지적 9건을 반영했습니다(토스 열림 판정, 퍼널 탈출 히스토리,fee.ts충돌 통합, 첫 단계 뒤로가기, 캡처 파일 단일 출처, 외부 링크lib통합, px 임의값 → Tailwind 단계, 미리보기 초점, 홈 진입점 연결). 작업 단위로 커밋을 나눴습니다.[a]외부 링크를 앱 셸로 넘기는 브리지 메시지는 넣지 않았습니다 — 앱 쪽 핸들러가 같이 들어가야 동작해서(lib/bridge/bridge.ts메시지 추가 절차) 별도 이슈로 이어가는 게 맞아 보입니다.