도입
코드를 수정하는 일은 파일을 바꾸는 것으로 끝나지 않는다. 다른 개발자가 문제를 재현하고 변경 범위를 검토하며, 운영에 반영된 버전을 찾고, 문제가 생겼을 때 안전하게 되돌릴 수 있어야 하나의 작업이 완성된다.
이 글은 존재하지 않는 PHP 게시글이 HTTP 200을 반환하는 문제를 예로 들어 이슈 작성, 작은 브랜치, 검증 commit, Pull Request, 배포 기록과 복구 판단을 하나의 흐름으로 연결한다.
문제를 재현 가능한 이슈로 만든다
제목: 존재하지 않는 게시글 요청이 HTTP 200을 반환함
환경:
- PHP 8.1
- 요청: GET /post/999999
현재 결과:
- HTTP 200
- 빈 게시글 화면
기대 결과:
- 존재하지 않는 공개 게시글은 HTTP 404
- 비공개 글의 존재 여부를 응답으로 노출하지 않음
완료 조건:
- 없는 글·비공개 글 테스트 추가
- 기존 공개 글 조회 테스트 유지
- 실제 HTTP 상태 코드 확인
관찰한 결과와 원하는 결과를 분리한다. “404 수정”처럼 결과만 쓰면 비공개 글, 삭제 글과 권한 경계가 빠질 수 있다.
작업을 시작하기 전에 기준 상태를 남긴다
git status --short
git branch --show-current
git log -1 --oneline
git switch main
git pull --ff-only
git switch -c fix/post-not-found-status
기존 작업 파일을 새 변경과 섞거나 지우지 않는다. 기준 브랜치와 시작 commit을 기록하고 하나의 문제만 다루는 브랜치를 만든다.
변경 범위와 제외 범위를 먼저 정한다
- 공개 게시글 조회 조건
- Controller의 HTTP 상태 코드 결정
- 404 화면 렌더링
- 정상·실패·권한 경계 테스트
관리자 미리보기, DB 스키마와 삭제 글의 410 정책은 이번 변경에서 제외한다. 독립적으로 검증하거나 되돌릴 수 없는 변경이 함께 필요하다면 작업을 나눈다.
diff와 테스트를 확인한 뒤 commit한다
git status --short
git diff --stat
git diff -- src/PostController.php tests/PostControllerTest.php
php -l src/PostController.php
vendor/bin/phpunit tests/PostControllerTest.php
git add src/PostController.php tests/PostControllerTest.php
git diff --cached
git commit -m "fix: return 404 for unavailable posts"
git add .로 모든 파일을 올리기 전에 diff를 확인한다. 환경 파일, 로그, 개인 설정과 무관한 포맷 변경이 섞이지 않았는지 본다. 실행하지 않은 검사는 통과했다고 기록하지 않는다.
PR 설명을 diff의 사용 설명서로 작성한다
## 문제
없는 게시글과 비공개 게시글이 HTTP 200을 반환했습니다.
## 변경
- 공개 상태를 포함한 조회 조건을 적용했습니다.
- 결과가 없으면 404 응답으로 전환했습니다.
- 정상·없는 글·비공개 글 테스트를 추가했습니다.
## 변경하지 않은 것
- 관리자 미리보기
- DB 스키마
- 삭제 글의 410 정책
## 검증
- php -l: 통과
- 관련 테스트 3건: 통과
- 로컬 HTTP 응답: 200 / 404 확인
## 위험과 롤백
- 내부 링크가 비공개 글을 가리키면 404가 증가할 수 있습니다.
- 문제 발생 시 해당 commit을 revert합니다.
리뷰는 요구사항과 위험부터 확인한다
- 이슈의 완료 조건을 만족하는가
- 정상·실패·경계 입력을 처리하는가
- 권한과 입력 검증이 서버에서 수행되는가
- 데이터 변경 범위와 트랜잭션이 올바른가
- 배포 호환성과 롤백 경로가 있는가
- 요청과 무관한 변경이 섞이지 않았는가
[blocker] 비공개 게시글의 존재 여부가 응답 차이로 노출됩니다.
[suggestion] 중복 조건을 메서드로 추출하면 다음 수정이 쉬워 보입니다.
[question] 삭제 글은 기존 410 정책을 유지하는 것이 맞나요?
[nit] 변수명을 프로젝트 규칙과 맞추면 좋겠습니다.
리뷰 반영 후에는 “수정했습니다”만 남기지 않는다. 해결한 commit, 재실행한 테스트와 반영하지 않은 제안의 이유를 연결한다.
배포 기록은 commit SHA와 연결한다
배포 시각:
환경: production
commit SHA:
PR / 이슈:
artifact 또는 release ID:
검증 결과:
직전 정상 commit:
롤백 여부:
브랜치 이름은 바뀌거나 삭제될 수 있지만 commit SHA는 배포된 코드를 식별한다. 진단 화면에 release SHA를 노출할 때는 저장소의 민감한 정보를 함께 공개하지 않는다.
되돌리기 전에 코드 밖의 변경을 확인한다
git show --stat <problem-commit>
git revert <problem-commit>
공유된 이력에서는 문제 commit을 없애기보다 반대 변경을 만드는 git revert가 추적하기 쉽다. 다만 DB 마이그레이션, 새 데이터 형식, 캐시, 큐와 외부 설정이 바뀌었다면 코드만 되돌려도 복구되지 않을 수 있다.
병합과 배포 전 확인표
- 이슈의 완료 조건을 충족했다.
- 요청 범위 밖의 변경이 없다.
- 필수 자동 검사와 경계 테스트를 통과했다.
- 차단 리뷰 의견이 해결됐다.
- 배포 commit과 직전 정상 commit을 기록했다.
- DB·설정·캐시를 포함한 복구 방법을 확인했다.
참고 자료
한 줄 요약
안전한 PHP 변경은 재현 가능한 이슈, 작은 diff, 실제 검사 결과, 리뷰, 배포 SHA와 복구 판단이 끊기지 않고 연결된 작업이다.
댓글 0