7년 된 주문 관리 서비스에서 CSV 날짜가 하루씩 어긋나는 상황을 사례로 삼겠습니다. 관련 함수는 짧지만 같은 날짜 변환기가 정산, 알림과 관리자 화면에서도 쓰입니다. 첫 검색 결과만 보고 공용 함수를 고치면 버그 하나를 없애고 세 기능을 망가뜨릴 수 있습니다.

핵심 레거시 프로젝트의 첫날에는 코드를 많이 이해하려 하지 않습니다. 실행 방법과 현재 실패를 재현하고, 변경이 번질 경로와 되돌릴 지점을 확인한 뒤 작은 패치 하나로 저장소의 실제 규칙을 배웁니다.

첫날의 목표는 전체 이해가 아닙니다

오래된 저장소를 한 번에 요약하라고 하면 디렉터리 설명은 얻을 수 있어도 중요한 암묵 규칙은 놓치기 쉽습니다. 먼저 사용자에게 보이는 증상 하나를 고르고 그 요청이 들어와 응답으로 나가는 경로만 추적합니다.

README와 프로젝트 지침, 패키지 실행 파일, CI 설정, 최근 관련 커밋을 읽습니다. 문서와 코드가 충돌하면 실행되는 코드와 테스트 결과를 관찰 사실로 두고, 문서 차이는 별도 미확인 항목으로 남깁니다.

수정 권한 없이 저장소 지도를 만듭니다

다음 요청은 CSV 오류의 경로만 조사합니다. 전체 아키텍처 문서를 새로 쓰거나 코드를 정리하는 일은 범위 밖입니다.

레거시 저장소 첫 조사 요청
claude --permission-mode plan

프로젝트 지침과 실행·테스트 명령을 먼저 찾으세요.
CSV 내려받기의 날짜가 하루 빠른 증상만 조사하고 아직 수정하지 마세요.
반환:
- 요청 진입점부터 날짜 직렬화까지의 호출 경로
- 공용 모듈과 다른 호출자
- 관련 테스트와 CI 명령
- 문서와 실제 코드의 불일치
- 재현에 필요한 최소 데이터
중단: 운영 DB, 고객 파일, 비밀값이 필요할 때

깨끗한 기준선을 먼저 기록합니다

작업 전 `git status`와 기준 브랜치의 테스트 결과를 남깁니다. 전체 테스트가 이미 실패한다면 실패 이름과 수를 기록하고 이번 증상에 직접 관련된 테스트를 따로 만듭니다. 기존 빨간 테스트를 모두 고치려 들면 첫 패치의 원인을 설명할 수 없게 됩니다.

서비스를 로컬에서 열 수 없다면 필요한 런타임, 데이터와 외부 서비스가 무엇인지 적습니다. 운영 자격증명을 가져오는 대신 작은 고정 입력이나 테스트 더블로 재현할 수 있는지 먼저 확인합니다.

날짜 함수보다 데이터 계약을 확인합니다

예시에서 `formatDate()`는 UTC 시각을 지역 날짜로 바꿉니다. CSV는 사용자의 지역 날짜를 기대하지만 정산 파일은 UTC 날짜를 계약으로 삼습니다. 함수 이름만 보면 같은 변환처럼 보이지만 호출자의 계약은 다릅니다.

공용 함수를 바꾸기 전에 입력의 시간대, 저장 형식, 화면 표시 규칙과 다른 호출자를 표로 적습니다. 한 호출자만 다른 계약을 가졌다면 CSV 경계에서 변환하는 편이 공용 동작을 바꾸는 것보다 작고 검증하기 쉽습니다.

패치 전에 실패하는 예제를 고정합니다

테스트 이름은 구현이 아니라 사용자가 기대하는 동작을 말해야 합니다. 수정 전에는 첫 항목이 실패하고 기존 UTC 계약 두 개는 통과해야 합니다.

날짜 경계를 구분하는 회귀 사례
CSV: Asia/Seoul 사용자의 2026-08-26 00:30은 2026-08-26으로 출력
정산: 같은 순간은 UTC 계약에 따라 2026-08-25로 유지
빈 값: 빈 칸으로 출력하고 현재 오류 정책을 바꾸지 않음

예상: 수정 전 CSV 사례만 실패, 수정 후 세 사례 모두 통과

첫 패치는 가까운 경계에서 작게 끝냅니다

사람이 조사 결과를 확인한 뒤 CSV 직렬화 지점과 해당 테스트만 수정하도록 범위를 엽니다. 겸사겸사 공용 날짜 라이브러리를 교체하거나 이름을 정리하지 않습니다. 그런 개선은 첫 패치에서 얻은 규칙을 바탕으로 별도 작업에서 판단할 일입니다.

패치 뒤에는 새 회귀 테스트, 관련 모듈 테스트, 저장소가 요구하는 정적 검사와 타입 검사를 실행합니다. `git diff --stat`, 전체 변경 차이와 `git diff --check`에서 생성물, 잠금 파일과 범위 밖 포맷 변경이 없는지 봅니다.

모르는 부분은 문서화하되 사실처럼 채우지 않습니다

담당자를 찾지 못한 배치, 실행할 수 없는 통합 테스트와 시간대 계약의 근거는 `unverified`로 남깁니다. Claude Code의 설명이 그럴듯해도 호출 기록이나 테스트로 확인하지 못했다면 저장소 규칙으로 확정하지 않습니다.

첫 패치에서 확인한 실행 명령과 계약이 앞으로도 유효하다면 프로젝트 문서에 짧게 반영할 수 있습니다. 다만 문서 변경도 패치 범위에 포함됐는지 검토하고, 오래된 설명을 통째로 자동 교체하지 않습니다.

첫날 결과는 코드보다 재현 가능한 기록입니다

좋은 첫날 결과에는 재현 명령, 기준선 실패, 호출 경로, 최소 변경, 통과한 검증과 확인하지 못한 영역이 남습니다. 다음 사람이 대화 기록 없이 같은 테스트를 실행하고 패치의 범위를 설명할 수 있어야 합니다.

공용 계약이 불명확하거나 운영 데이터 없이는 실패를 재현할 수 없거나 변경이 결제·정산처럼 되돌리기 어려운 경로로 번지면 첫 패치를 멈춥니다. 조사만 끝낸 것도 올바른 결과입니다.

읽고 나서 확인하기

답을 떠올린 뒤 본문의 판단 기준과 비교해 보세요.

  • 전체 저장소 요약보다 한 사용자 증상의 실행 경로와 데이터 계약을 먼저 추적할 수 있습니다.
  • 기존 실패와 이번 변경이 만든 실패를 기준선 기록으로 구분할 수 있습니다.
  • 공용 함수를 고치기 전에 다른 호출자의 계약과 작은 경계 수정 가능성을 확인합니다.

공식 출처