이번 주는 기능을 더 얹는 주가 아니었다.
오히려 반대였다. 흔들리는 걸 고정했다.
Turbo Native를 붙이려면, 앱은 먼저 한 가지를 약속해야 한다.
“이 화면은 탭으로 간다.”
“이 화면은 모달로 뜬다.”
“이 화면은 로그인처럼 갈아끼운다(replace).”
이 약속이 없으면, 네이티브 쉘은 길을 잃는다.
8주차는 그 약속을 코드로 박아 넣은 주였다.
1) PR #42 — “모달은 사용자가 닫는 게 아니라, 서버가 닫는다”
우리는 기존에 흩어진 모달 처리 방식을 표준 패턴으로 묶었다.
핵심은 이거다.
- 성공하면: 서버가 모달을 닫아준다
- 실패하면: 422로 모달을 유지하고 에러를 보여준다
- 성공 피드백은: flash 프레임 업데이트로 통일한다
이를 위해 실제로 끝낸 것들:
- turbo-frame id=”modal” 추가(새 표준)
- 기존 report_modal은 호환 레이어로 유지
- flash를 turbo-frame으로 감싸서 stream update 가능하게 변경
- _close_modal.turbo_stream.erb 추가(표준 닫기 스트림)
- Reports / Reviews 컨트롤러를 server-dismissed 패턴으로 정리
- 링크와 폼의 data-turbo-frame 타겟을 modal로 통일
- 인라인 <script> 제거
- backdrop 클릭 닫기용 Stimulus 컨트롤러(modal_backdrop_controller.js) 추가
결론은 간단하다.
이제 조비엣의 모달은 “대충 닫히는 UI”가 아니라
“규칙으로 닫히는 네비게이션”이 됐다.
2) PR #43 — “/me: 흔들리지 않는 프로필 주소”
Turbo Native에서 가장 곤란한 건 “내 프로필”이다.
유저 id가 URL에 끼어 있으면 딥링크/캐시/탭 구성이 복잡해진다.
그래서 우리는 /me로 고정했다.
이번 PR에서 완료한 것:
- /me 라우트 추가
- UsersController#me 액션 추가
- 프로필 관련 링크를 /me로 통일
- 프로필 업데이트 후 redirect도 /me로 변경
- 로그인 후 기본 랜딩을 /posts로 변경(홈 탭 안정화)
- PathConfiguration v2 JSON 파일 추가
- 기존 테스트에서 /users/:id 기대하던 부분을 /me로 수정
프로필은 변해도 주소는 고정.
이게 “앱 같은 안정감”의 시작이다.
3) PR #44 — “모달로 떠야 하는 URL을 PathConfiguration에 명시”
이제 규칙을 코드로만 말하지 않는다.
PathConfiguration JSON에 적어 둔다.
완료한 것:
- 신고/리뷰 작성 화면을 modal context로 규정
- /messages/:id/reports/new
- /conversation_messages/:id/reports/new
- /posts/:id/reports/new
- /posts/:post_id/chat_rooms/:id/reviews/new
- 인증 계열 화면은 replace로 규정
- /users/sign_in, /users/sign_up, /users/password/*
- 참고용으로 regex 버전 / glob 버전 JSON도 함께 추가
이걸 해두면 Turbo Native 붙일 때 “느낌으로”가 아니라
규칙대로 화면이 열린다.
4) 덤으로, 이번 주에 드러난 교훈: 문법도 “규칙”이다 (PR #45 준비)
PathConfiguration은 사소한 JSON 같지만,
문법이 틀리면 네이티브에서 조용히 무시된다.
그래서 “presentation: modal” 같은 혼종을 정리하고
정식 문법인 context: modal로 바로잡는 PR(#45)을 준비했다.
(현재는 체크 통과 상태, 머지는 다음 단계에서 진행)
결론: 이번 주는 기능이 아니라 “길”을 만들었다
모달이 닫히는 방식,
프로필의 고정 주소,
로그인 후 랜딩,
화면을 탭으로 볼지 모달로 볼지의 규칙.
이건 전부 “기능”이 아니라 “길”이다.
조비엣은 이제
“앱처럼 보이는 웹”에서
“앱처럼 움직이는 웹”로 넘어왔다.
