마이그레이션의 신뢰는 "기존 기능이 하나도 사라지지 않았다"에서 시작한다. 새 기술의 장점을 보여주기 전에, 먼저 기존 동작을 증명해야 한다.
시연 첫인상 — 흰 화면이 깜빡인다
Daqda에서 장지(묘지) 위치를 시각화하는 서비스 The Prestige를 담당하고 있었다. 연세 세브란스 같은 대형 고객사 시연을 앞두고, 기존 ASP.NET 서비스의 문제가 선명해졌다. 필터를 하나 바꿀 때마다 페이지 전체가 새로고침되면서 흰 화면이 깜빡였다. step별로 다른 페이지로 이동해야 했고, 뒤로가기를 누르면 사용자가 선택한 필터가 날아갔다.
서버 사이드 렌더링 기반 MPA 구조의 본질적 한계였다. 패치할 수 있는 문제가 아니라, 아키텍처를 바꿔야 하는 문제였다. Next.js 기반 SPA로 전면 재구축하기로 결정했다. 시간은 6주.
페이지 단위 우선순위
8개 페이지를 한꺼번에 옮기면 6주 안에 끝나지 않는다. 페이지별로 우선순위를 매겼다.
- P0 — 시연에 반드시 필요한 페이지: 지도 뷰, 장지 상세, 필터
- P1 — 시연에 보여주면 좋은 페이지: 통계 대시보드, 관리자 설정
- P2 — 시연 이후 마이그레이션: 레거시 보고서, 기타 유틸리티
P0을 먼저 완성하고 시연에서 검증한 뒤, P1과 P2를 순차적으로 진행했다. 이 순서 덕분에 6주 중 4주 시점에 시연이 가능했다.
프론트엔드 주도 API 설계
레거시 ASP.NET의 API 응답은 프론트엔드 요구에 맞지 않았다. 서버 사이드 렌더링을 전제로 설계된 데이터 구조였기 때문이다. 백엔드에 API 응답 형식을 직접 제안하고 협의했다.
// FE가 필요한 데이터 구조를 인터페이스로 정의하고 BE에 전달
interface GraveSiteResponse {
id: number;
name: string;
location: {
lat: number;
lng: number;
address: string;
};
filters: {
type: GraveType;
status: GraveStatus;
capacity: number;
};
// ASP.NET 시절에는 이 데이터가 3개 엔드포인트에 분산되어 있었다
}프론트엔드가 필요한 형태를 인터페이스로 정의해서 백엔드에 전달하니, 불필요한 API 호출이 줄고 데이터 변환 로직도 사라졌다. 프론트엔드 개발자가 API 설계에 참여하는 것은 마이그레이션에서 특히 중요하다.
Kakao Map + Recoil + LocalStorage
지도 기반 서비스의 핵심은 필터 변경 시 지도가 새로고침되지 않는 것이다. Recoil로 필터 상태를 관리하고, Kakao Map API의 마커를 클라이언트 사이드에서 실시간으로 업데이트했다. 기존 ASP.NET에서는 필터를 바꾸면 새 페이지로 이동했는데, SPA에서는 같은 화면에서 마커만 바뀐다.
import { atom } from 'recoil';
import { recoilPersist } from 'recoil-persist';
const { persistAtom } = recoilPersist({
key: 'prestige-filters',
storage: typeof window !== 'undefined' ? localStorage : undefined,
});
export const graveFilterState = atom<GraveFilter>({
key: 'graveFilter',
default: { type: 'all', status: 'available' },
effects_UNSTABLE: [persistAtom],
});recoil-persist로 필터 상태를 localStorage에 저장했다. 이전에는 사용자가 뒤로가기를 누르면 선택한 필터가 날아가서 전화로 CS를 해야 했는데, 이 문제가 완전히 사라졌다.
배포 — 10분에서 2분으로
기존 배포 과정은 이랬다. 로컬에서 빌드 → 빌드 파일을 Windows Server 접근 권한이 있는 사람에게 전달 → 그 사람이 서버에 수동 업로드. 10분이 걸렸고, 접근 권한 문제로 빌드 파일을 넘겨야 하는 비효율적인 중간 단계가 있었다.
Vercel 기반 CI/CD를 구축했다. git push하면 자동으로 빌드, 린팅 검사, 배포가 실행된다. 배포 시간은 2분으로, 80% 단축되었다.
마이그레이션의 사회학
코드 마이그레이션보다 어려운 것은 사람을 설득하는 것이다. CTO와 백엔드 개발자에게 "왜 새로 만들어야 하는가"를 납득시키려면, 기존 시스템의 문제를 감정이 아니라 사실로 보여줘야 한다. 시연 중 흰 화면이 깜빡이는 것을 직접 보여주고, 페이지 로딩 시간을 측정해서 비교한 것이 결정적이었다.
마이그레이션 완료 후 알파 테스터들로부터 "훨씬 좋은 경험"이라는 피드백을 받았다. 가장 큰 차이는 필터를 바꿀 때 흰 화면이 없어진 것이었다.
결과
- 8개 페이지, 설계 포함 6주 완료
- 기능 삭제 0건 — 기존 동작 100% 유지
- 배포 시간 10분 → 2분 (80% 단축)
- 필터 변경 시 전체 새로고침 제거 → SPA 내 실시간 반영
- LocalStorage 기반 상태 유지로 CS 전화 문의 감소
- 알파 테스터 긍정 피드백 확보