프로그램을 이전 버전으로 돌리면 문제가 사라질까. 자료가 이미 새 구조가 됐다면 옛 코드가 읽지 못하거나 새 필드를 잃게 만들 수도 있다.

이번에는 실제 배포를 되돌리지 않고 코드 릴리스의 읽기·쓰기 스키마 계약과 합성 자료 버전을 비교했다. 되돌릴 수 있다는 말을 코드 파일만의 문제로 쓰지 않기 위해서다.

코드 파일과 자료는 같은 속도로 돌아가지 않는다

예제의 옛 릴리스는 schema 1만 읽고 쓴다. 새 자료가 schema 2라면 옛 코드를 선택해도 readable과 writable은 거짓이다. 결과는 blocked이며 실제 실행은 하지 않는다. 이전 프로그램이 있다는 사실만으로 이전 업무 상태를 다시 만들 수 있는 것은 아니라는 판단을 명시했다.

이 계약은 실제 실행 파일을 분석하지 않는다. 개발자가 선언한 읽기·쓰기 지원 범위가 맞는지는 별도 실행 검사로 증명해야 한다. 이번 코드는 그 선언이 주어졌을 때 자료와 맞는지 계산한다. 거짓 선언을 안전하게 고쳐 주는 도구나 자동 복구 시스템으로 소개하지 않는다.

읽을 수 있어도 쓸 수 없는 경우를 남긴다

bridge 릴리스는 schema 1과 2를 읽지만 schema 2로만 쓴다고 선언할 수 있다. schema 1 자료와 비교하면 read_only가 된다. 읽는 순간 자동 변환해 덮는 동작은 없다. 확인용 열람과 자료를 바꿀 수 있는 권한을 다른 결과로 만드는 이유다. 단순한 호환 여부 한 칸보다 적용할 행동을 구체적으로 말할 수 있다.

읽기 전용 결과 자체가 실제 버튼을 막지는 않는다. 서비스는 쓰기 API와 작업 실행기에서 같은 정책을 적용해야 한다. 브라우저에서 저장 단추만 감추면 충분하지 않다. 이번 모듈에는 그런 API가 없으므로 정책 계산과 실제 강제의 연결을 미완성 책임으로 적어 둔다.

변환 제안이 되돌릴 경로를 바꾼다

자료 변환 미리보기는 원본 schema 1을 보존하고 schema 2 제안을 돌려준다. 회귀 검사에서 그 제안을 옛 코드 계약에 넣으면 차단된다. 미리보기는 적용하지 않았어도 적용 뒤 달라질 복귀 조건을 생각할 수 있다. 자료를 바꾸기 전에 확인해야 할 질문을 먼저 만드는 방식이다.

실제로 적용했다면 이전 원본과 그 뒤의 새 입력을 어떻게 보존할지 정해야 한다. 예전 백업을 무조건 덮으면 새로 처리한 업무가 사라질 수 있다. 이번 예제에는 역변환이나 실제 복구가 없다. 원본 보존과 운영 중 생긴 자료의 관계를 검토할 필요를 설명하되 실행하지 않은 복구 성공을 주장하지 않는다.

계약이 모호하면 멈추는 편을 택했다

릴리스에는 release, reads와 writes만 허용한다. 지원 스키마는 1과 2이며 중복 목록과 읽을 수 없는 쓰기 버전은 거절한다. 자료 버전도 정해진 정수여야 한다. 알 수 없는 입력을 최신으로 간주하거나 호환된다고 추측하지 않는다. 지원 범위 밖이라는 사실을 결과 또는 오류로 드러낸다.

이 단순화는 모든 업그레이드 경로를 표현하지 않는다. 기능별 능력, 다른 저장소와 연결된 작업, 지연된 백그라운드 실행은 포함하지 않았다. 실제 서비스는 영향을 받는 책임을 더 구체적으로 모델링해야 한다. 작은 버전 비교가 전체 배포 위험을 계산했다는 뜻으로 쓰이지 않도록 제한을 함께 설명했다.

돌아갈 수 있는지 실제 연습으로 확인한다

로컬 테스트는 옛 코드와 새 자료의 차단, 양쪽을 읽는 코드의 읽기 전용 결과와 같은 스키마의 쓰기 가능 결과를 확인했다. 공유 기록에서는 실제 실행을 뜻하는 executed가 거짓으로 남는다. 사이트나 ERP를 이전 버전으로 내리거나 운영 데이터를 복구하지 않았다.

실무에서는 정확한 코드 묶음과 자료 백업을 보관하고 별도 환경에서 읽기와 필요한 업무를 실제로 시험해야 한다. 이후 운영 적용은 그 결과와 현재 자료를 다시 확인한 뒤 결정할 일이다. 나는 되돌리기 단추보다 돌아간 코드가 현재 자료를 이해하는지 묻는 기준을 공개했다. 코드와 자료를 한 쌍으로 기록하면 그 질문을 놓치기 어렵다.