일단 EC2 한 대에 올려보기로 했어요
배포 비용을 보다가 RDS를 빼기로 했어요. 서버리스도 알아봤지만, 일단 EC2 small 한 대에 웹과 API, PostgreSQL을 같이 올려보기로 했어요. 그 과정에서 스토리지와 백업, S3 권한도 하나씩 고쳤어요.
개발하면서 해결한 문제
배포 비용을 보다가 RDS를 빼기로 했어요. 서버리스도 알아봤지만, 일단 EC2 small 한 대에 웹과 API, PostgreSQL을 같이 올려보기로 했어요. 그 과정에서 스토리지와 백업, S3 권한도 하나씩 고쳤어요.
사진 서비스에는 GraphQL과 Apollo를, Game Mate에는 REST와 TanStack Query를 썼어요. 두 서비스를 만들면서 API 계약과 DB 정합성, 테스트를 정하고 ESLint로 코드의 경계를 검사한 과정을 적어 봤어요.
기능과 아키텍처만 정해 주고 AI 에이전트에게 구현을 최대한 자율적으로 맡겨 봤어요. 나온 서비스를 직접 써 보고 코드를 읽으면서 화면 구성, 익명 기록, 그룹 권한과 채팅 재전송처럼 부족하거나 빠진 부분을 채워 나갔어요.
전화로 문의하던 건강검진을 복지몰에서 고르고 결제할 수 있게 만들었어요. 기존 프로그램에 검진을 더하면서 등록 권한과 검사 선택, 결제 후 돌아올 화면을 따로 풀어야 했어요.
시트를 끌다 놓으면 화면이 멈추는 오류가 있었어요. 라이브러리를 올려 문제의 코드를 없앴지만, 제목까지 스크롤되는 문제는 그때도 놓쳤어요.
타입 단언을 정리하면서 API 응답과 URL, 폼의 실패 처리를 구분했어요. 타입을 좁히는 일과 실제 값이 안전한지 확인하는 일의 차이를 정리했어요.
에이전트가 성공했다고 한 테스트에도 화면에 없는 문구를 기다리는 코드가 있었어요. 구현을 맡기면서도 plan과 diff를 직접 읽고, 반복된 지적은 다음 작업에 쓸 규칙으로 남기게 됐어요.
복지몰의 브라우저와 서버 오류를 Sentry로 모았어요. 전송 정책과 에러 레벨을 정하고, Web Vitals와 MCP, 릴리스 연결을 확인했어요.
목록 조회가 실패했는데 메뉴와 헤더까지 사라졌어요. 실패한 표나 필터만 다시 시도할 수 있도록 조회 위치와 Error Boundary를 함께 바꿨어요.
검색을 눌러도 주소가 그대로였고, 배포 뒤에는 열어 둔 탭의 공지가 닫히지 않았어요. 라우팅과 쿠키, 폼 초기화를 따라가며 서버가 다시 처리해야 할 일을 구분했어요.
화면을 보려는데 조회 순서와 계산부터 읽게 되는 코드가 불편했어요. 리뷰 상세와 검색 필터, 쿠폰 계산을 고치며 화면 구성과 세부 동작을 나눈 방법이에요.
프로토타입을 서비스로 옮기는 동안 비슷한 구현을 여러 번 맡겼어요. 그때마다 고치던 내용을 skills에 적었지만, 짧고 강한 규칙이 오히려 잘못된 코드를 만들기도 했어요.
쿠폰 결제를 넣으니 결제수단만으로는 화면을 고를 수 없었어요. 저장 전에는 금액을 고치고 쿠폰을 풀어야 했고, 저장 뒤에는 현장 결제와 함께 보여줘야 했어요.
폴더는 FSD대로 나눴는데 새 파일을 어디에 둘지는 매번 달랐어요. 실제로 옮겨 보면서 도메인 코드와 화면 조합을 다시 나눴고, URL을 그대로 폴더로 쓰던 규칙도 바꿨어요.
AI 답변과 상담사 메시지가 서로 다른 서비스에서 왔어요. 두 SSE를 한 대화창에 이어 붙이며, 메시지를 보내는 곳과 보여 주는 곳을 따로 정했어요.
사이트맵 캐시 안에서 인증 쿠키를 읽는 공용 interceptor가 문제가 됐어요. 공개 조회와 회원별 조회를 나누고 캐시할 범위를 정했어요.
같은 로그인으로 다른 호스트의 정산 화면을 열어야 했어요. 토큰을 URL에서 POST 본문으로 옮겼지만, 두 호스트에 복제된 인증 상태까지 해결된 것은 아니었어요.
두 관리자 앱에서 프로그램 입력을 공유하면서 필드 타입과 API 변환을 나눴어요. 공용으로 둘 부분과 앱마다 남길 부분을 정리했어요.
리뷰 폼을 RHF와 Zod로 옮기면서 시술 선택 UI도 다시 붙였어요. 시트를 닫으면 선택을 취소하고, 확인할 때만 폼에 넣도록 바꾼 과정이에요.
예약 상세는 브라우저에서 멀쩡했지만 처음 받은 HTML에는 병원 정보가 없었어요. prefetch를 시작한 것과 서버가 데이터를 넘길 준비가 된 것은 달랐어요.
예약할 가족을 추가했는데 날짜 선택은 이전 인원수대로 움직였어요. 서버의 가족 목록과 사용자가 고른 일시를 구분하고, 작성 중인 값은 React Hook Form에서 바꾸도록 고쳤어요.
서버에서 미리 조회한 데이터를 브라우저에서도 이어서 쓰려고 했어요. QueryClient는 두 환경에서 다르게 만들고, 조회 옵션은 함께 쓰도록 연결했어요.
값의 추론을 유지하는 satisfies, optional property, 제네릭과 배타적인 props를 실무에서 어떻게 쓰는지 정리했어요.
후보자 메모를 고치고도 어떤 캐시를 갱신할지 찾으려면 문자열부터 검색해야 했어요. query key와 조회 함수를 함께 정의하고, mutation 옆에서 무효화할 범위를 고르게 바꿨어요.
채용 플랫폼을 추가할 때마다 수집 흐름도 복사하고 있었어요. NestJS를 넣었다가 걷어냈지만, 요청을 받는 코드와 수집 순서, 사이트별 처리는 나눠 남겼어요.
Electron 수집 앱에서 요청 헤더와 파일 정보를 함께 기다려야 했어요. 값을 모으는 일은 closure에, 기다림을 끝내고 리스너를 정리하는 일은 Promise에 맡겼어요.