# Issue #281: locale_storage 리팩터링 계획 ## 목적 - `locale_storage` 관련 로직에서 정책 지식(키, fallback, migration)을 한 곳으로 모아 변경 비용을 줄입니다. - 테스트를 내부 구현 의존(`webStorage`)에서 파사드 의존(`LocaleStorage`) 중심으로 바꿔 회귀 위험을 낮춥니다. - 테스트 강제 훅(`forceMemoryStorageForTests`, `forceSessionStorageForTests`)의 진입점을 단일화합니다. ## 현재 문제 요약 1. 저장 정책 지식이 여러 파일에 분산되어 있습니다. 2. 테스트가 구현 세부사항에 결합되어 정책 변경 시 함께 깨질 가능성이 큽니다. 3. 플랫폼별 훅 wiring이 반복되어 확장 시 누락 가능성이 있습니다. ## 변경 범위 - 대상 파일 - `userfront/lib/core/i18n/locale_storage.dart` - `userfront/lib/core/i18n/locale_storage_stub.dart` - `userfront/lib/core/i18n/locale_storage_web.dart` - `userfront/test/locale_storage_platform_test.dart` - `userfront/test/helpers/web_storage.dart` - `userfront/test/helpers/web_storage_stub.dart` - `userfront/test/helpers/web_storage_web.dart` ## 리팩터링 단계 ### 1) 저장 정책 공통화 - 저장 키 상수(`locale`, legacy `baron_locale`)와 migration 로직을 공통 모듈로 이동합니다. - fallback 순서(local -> session -> memory)를 공통 정책 함수로 추출합니다. - `locale_storage_web.dart`는 정책 모듈 호출 위주로 단순화합니다. ### 2) 테스트 결합도 축소 - 테스트 assertion의 중심을 `LocaleStorage` API로 이동합니다. - `webStorage` 직접 검증은 최소화하고, 필요한 경우 정책 모듈의 관찰 포인트를 제한적으로 제공합니다. ### 3) 테스트 훅 단일 진입 - `LocaleStorage` 파사드에서만 테스트 훅을 제어하도록 정리합니다. - 플랫폼 구현은 훅 내부 세부 정책을 직접 노출하지 않도록 인터페이스를 정돈합니다. ### 4) 회귀 테스트 보강 - legacy key migration(`baron_locale -> locale`) 회귀 테스트를 명시적으로 유지합니다. - storage access 실패/비가용 상황에서 fallback 순서를 검증하는 테스트를 추가합니다. ## 완료 기준(DoD) - 정책 변경 시 수정 포인트가 공통 모듈 중심으로 줄어듭니다. - 기존 locale 저장/조회 동작과 migration 동작이 유지됩니다. - VM 기반 테스트가 안정적으로 통과하며 fallback/migration 회귀 케이스가 포함됩니다. ## 구현 시 주의사항 - 외부에서 사용하는 public API 시그니처는 가능한 유지합니다. - 테스트 편의를 위한 훅은 운영 코드 경로에 영향이 없도록 격리합니다. - 리팩터링 중간 단계에서도 테스트가 통과하도록 작은 단위로 나눠 적용합니다. ## 롤백 기준 - locale 저장/복구가 실패하거나, 웹 환경에서 fallback 동작이 달라지는 경우 즉시 이전 커밋 단위로 되돌립니다. - migration 동작이 깨지는 경우 해당 단계만 우선 revert하고 정책 모듈 분리부터 재진행합니다. ## 구현 결과 (2026-02-20) ### 반영된 코드 변경 - 공통 계약/디버그 상태 타입 추가 - `userfront/lib/core/i18n/locale_storage_backend.dart` - 저장 정책 상수/판단 로직 분리 - `userfront/lib/core/i18n/locale_storage_policy.dart` - 파사드 단일 테스트 진입점 정리 - `userfront/lib/core/i18n/locale_storage.dart` - `setTestModeForTests`, `clearForTests`, `seedLegacyForTests`, `debugStateForTests` 추가 - 기존 `forceMemoryStorageForTests`, `forceSessionStorageForTests` 호환 유지 - 플랫폼 구현 리팩터링 - `userfront/lib/core/i18n/locale_storage_web.dart` - `userfront/lib/core/i18n/locale_storage_stub.dart` - fallback 순서(local -> session -> memory) 유지 - legacy migration 시 legacy key(`baron_locale`)를 local/session/memory 전체에서 정리 - 테스트 정리 - `userfront/test/locale_storage_platform_test.dart`를 `LocaleStorage` API 중심 검증으로 전환 - 삭제: `userfront/test/helpers/web_storage.dart` - 삭제: `userfront/test/helpers/web_storage_stub.dart` - 삭제: `userfront/test/helpers/web_storage_web.dart` ### CI/워크플로우 반영 - 파일: `.gitea/workflows/code_check.yml` - `workflow_dispatch.inputs` 복원 - `run_lint` - `run_backend_tests` - `run_userfront_tests` - 각 job 실행 조건 복원 - lint: `inputs.run_lint` - backend-tests: `inputs.run_backend_tests` - userfront-tests: `inputs.run_userfront_tests` - userfront-tests 정책 정리 - `flutter test` 단일 실행으로 운영 - `locale_storage` 정책 검증은 VM 테스트(`locale_storage_platform_test.dart`)로 통합 - 브라우저 설치/`--platform chrome` 단계 제거 ### 검증 결과 - `cd userfront && flutter analyze --no-fatal-warnings --no-fatal-infos` 통과 - `cd userfront && flutter test` 통과 - `cd userfront && flutter test test/locale_storage_platform_test.dart` 통과