# Issue #269 해결 기록: `/{locale}/` 도입 후 query parameter 유실 ## 개요 - 대상 이슈: `#269` - 증상: locale 보정 또는 비로그인 리다이렉트 과정에서 GET query parameter가 유실되거나 형태가 변형됨 - 영향: OIDC 로그인 연계 파라미터(`login_challenge`, `redirect_uri`, `notice` 등) 전달 실패 가능 ## 원인 1. 비로그인 리다이렉트 시 `login_challenge`만 선택 보존하고 나머지 query를 폐기 2. locale 경로 재작성 시 `uri.queryParameters` 기반 재직렬화로 원본 query 문자열(중복 key, 순서, 인코딩) 보존 실패 3. `head.length == 2` 휴리스틱으로 locale이 아닌 2글자 경로 prefix까지 locale로 오인 가능 ## 수정 사항 ### 1) 비로그인 리다이렉트에서 raw query 전체 보존 - 파일: `userfront/lib/main.dart` - 변경: `state.uri.query`를 그대로 `/[locale]/signin`에 연결 ```dart final rawQuery = state.uri.query; if (rawQuery.isNotEmpty) { return '/$locale/signin?$rawQuery'; } return '/$locale/signin'; ``` ### 2) locale 경로 재작성 시 raw query/fragment 보존 - 파일: `userfront/lib/core/i18n/locale_utils.dart` - 변경: `queryParameters` 재직렬화 제거, `uri.query`/`uri.fragment` 원문 유지 ```dart final queryPart = uri.hasQuery ? '?${uri.query}' : ''; final fragmentPart = uri.fragment.isNotEmpty ? '#${uri.fragment}' : ''; return '$path$queryPart$fragmentPart'; ``` ### 3) locale 판별 조건 엄격화 - 파일: `userfront/lib/core/i18n/locale_utils.dart` - 변경: `head.length == 2` 휴리스틱 제거, `supportedLocaleCodes.contains(head)`만 허용 ## 테스트 보강 - 파일: `userfront/test/locale_utils_test.dart` - 추가/변경: - raw query 순서 및 중복 key(`a=1&a=2`) 보존 - fragment 보존 - unknown 2-letter prefix(`zz`)를 locale로 제거하지 않음 ## 기대 결과 - `/signin?redirect_uri=...¬ice=...` -> locale 보정 후 query 100% 유지 - 비로그인 보호 경로 -> `/[locale]/signin` 이동 시 기존 query 유지 - 인코딩된 nested `redirect_uri`, 중복 query key, fragment 보존