[refactor/MAT-305-309] 인증 레이어 안정화 및 정리#309
Merged
sterdsterd merged 10 commits intodevelopfrom May 3, 2026
Merged
Conversation
handwriting/pointing 관련 신규 endpoint와 PointingCommentContentResp 타입을 동기화한다.
부팅 시 useLoadAssets effect re-run 또는 RN StrictMode 환경에서 verifySession 이 중복 호출되면 verifyStudentSession 이 동시 실행돼 /me 와 refresh 가 중복 트리거된다. 모듈 레벨 promise 로 dedupe 하고, 세션 검증 본문은 runVerifySession / runStudentVerification / applyStudentVerified 로 분리해 cognitive complexity 를 낮춘다. Refs: MAT-437
verifyStudentSession 의 catch 블록은 모든 실패를 동일하게 처리해 서버 5xx/네트워크 장애 시 사용자가 의도치 않게 로그아웃되는 결함이 있다. - refreshAndPersistTokens 의 결과 타입을 success / (transient | non-transient) 실패로 확장한다. - fetchStudentMe 헬퍼를 분리해 응답 status 를 보고 auth(401/4xx) 와 transient(5xx/network) 를 구분한다. - runStudentVerification 은 transient 일 때 캐시된 프로필로 낙관적 인증을 유지하고, 명시적 auth 실패에서만 clearAuthState 를 호출한다. - authMiddleware reissueStudentToken 도 transient refresh 실패 시 signOut 하지 않고 401 을 그대로 caller 에 전달한다. Refs: MAT-438
postRefreshToken 은 외부 caller 가 없는 dead export 였다. authMiddleware/authStore 가 모두 refreshAndPersistTokens 만 사용하므로 중복 정의를 제거하고 refresh 흐름을 단일 진입점으로 통일한다. Refs: MAT-440
postEmailSignup/postSignUpLocal 은 동일한 /api/student/auth/signup/local 엔드포인트를 호출하면서 응답 래핑 형태만 다른 중복 함수다. caller 가 하나뿐이므로 openapi-fetch 표준 응답 형태로 caller 를 마이그레이션해 래퍼를 제거한다. Refs: MAT-441
client.POST 결과의 data 분기는 throw 하지 않으므로 try/catch 가 도달 불가 코드였다. 단순 if 분기로 정리하고 catch-all 별칭 '@/apis/client' 경고도 '@apis/client' 로 교정한다. Refs: MAT-442
부팅 직후 인증된 다중 요청이 동시에 onRequest 를 통과하면 캐시된 name/grade 가 비어있는 상태에서 각 요청이 별도로 /me 를 호출한다. 모듈 레벨 promise 로 in-flight /me 를 dedupe 해 단일 호출로 합친다. Refs: MAT-443
OMC code-review medium 후속: - ensureStudentProfile 의 setName/setGrade 가 setItem 시그니처상 string|null 만 허용하므로 schema optional 인 data.name/grade 가 undefined 인 경우 authStore.applyStudentVerified 와 동일하게 undefined 가드를 적용한다. - verifySession dedupe 의 check~IIFE 동기 할당 사이에 await 가 추가되면 race window 가 생기는 점을 인라인 주석으로 명시한다. Refs: MAT-437, MAT-443
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
There was a problem hiding this comment.
Pull request overview
학생 인증 레이어를 안정화하고(중복 호출 dedupe, 서버 장애 시 비의도적 로그아웃 방지) 사용되지 않는/중복된 인증 API 코드를 정리하는 PR입니다.
Changes:
authStore.verifySession및/api/student/me호출에 in-flight dedupe(모듈 레벨 promise) 추가, 학생 세션 검증 로직 분리로 복잡도 완화- refresh 실패를
401/4xx(로그아웃) vs5xx/네트워크(transient, 자격증명 보존)로 분기하도록 개선 - dead/duplicate API 래퍼 제거 및 signup caller를
postSignUpLocal표준 응답 형태로 마이그레이션, 스키마 재생성 반영
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| apps/native/src/types/api/schema.d.ts | handwriting/pointing 관련 스키마 동기화 및 오류 응답 스키마 변경 반영 |
| apps/native/src/stores/authStore.ts | verifySession in-flight dedupe 및 학생 세션 검증 로직(refactor + transient 처리) 반영 |
| apps/native/src/features/auth/signup/screens/SignupPasswordScreen.tsx | 이메일 회원가입 호출을 postSignUpLocal 기반(openapi-fetch 표준 응답)으로 변경 |
| apps/native/src/apis/refreshAndPersistTokens.ts | refresh 결과에 transient 플래그 추가(5xx/네트워크 vs 4xx 구분) |
| apps/native/src/apis/controller/student/auth/postSocialLogin.ts | client import 별칭 정리 및 도달 불가 try/catch 제거 |
| apps/native/src/apis/controller/student/auth/postRefreshToken.ts | 사용처 없는 refresh 래퍼 제거 |
| apps/native/src/apis/controller/student/auth/postEmailSignup.ts | 사용처 없는 signup 래퍼 제거 |
| apps/native/src/apis/controller/student/auth/index.ts | 제거된 래퍼 export 정리 |
| apps/native/src/apis/authMiddleware.ts | refresh transient 실패 시 signOut 방지 + /me 호출 dedupe 헬퍼 추가 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let studentMePromise: Promise<void> | null = null; | ||
|
|
||
| const ensureStudentProfile = async (accessToken: string): Promise<void> => { | ||
| if (getName() || getGrade()) return; |
코드리뷰 후속 P1 2건 반영: - ensureStudentProfile 가 name/grade 중 한쪽만 캐시된 상태일 때 early return 해 다른 한쪽이 영원히 비어 있는 결함을 수정. 둘 다 채워졌을 때만 fetch 를 생략하도록 조건을 && 로 변경한다. - reissueStudentToken 의 forceRefresh 분기에서 refresh 시도 전에 access token 을 null 로 비우던 동작을 제거. transient 실패 시 PR body 의 '자격증명 보존' 약속이 깨지고, 5xx 가 짧게 지나가도 기존 토큰으로 복구할 수 없는 문제가 있었다. refreshAndPersistTokens 가 성공 시 새 토큰으로 교체하고, 명시적 실패 시 signOut 이 정리하므로 preemptive clear 는 불필요하다. Refs: MAT-438, MAT-443
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 9 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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.
Summary
학생 인증 레이어 안정화 및 dead/duplicate 코드 정리. verifySession in-flight dedupe, refresh 5xx vs 401 분기로 서버 장애 시 비의도적 로그아웃 차단, /me 동시 호출 dedupe, 사용처 없는 refresh/signup 래퍼 제거.
Linear
Changes
runVerifySession/runStudentVerification/applyStudentVerified로 분리해 cognitive complexity 정리RefreshResultdiscriminated union 에transientflag 추가. 5xx/네트워크 장애 시 캐시된 자격증명 보존, 4xx (refresh token 무효) 일 때만 로그아웃/me응답 status 를 보고auth(401/4xx) 와transient(5xx/network) 구분, 낙관적 인증 유지signOut하지 않고 401 을 그대로 caller 에 전달ensureStudentProfile모듈 레벨 promise 로 동시 다중 요청 시 단일 /me 호출.data.name/data.gradeundefined 가드도 함께 적용postRefreshToken.ts,postEmailSignup.ts삭제.postSignUpLocalopenapi-fetch 표준 응답 형태로 caller (SignupPasswordScreen) 마이그레이션@/apis/client→@apis/client별칭 교정PointingCommentContentResp타입 동기화Testing
pnpm tsc --noEmit(apps/native) — exit 0Risk / Impact
postRefreshToken/postEmailSignupimport 제거. 외부 caller 가 없음을 grep 으로 확인했지만, 푸시 전 한번 더 확인 권장