※ 이 글은 MyStock 초기 개발 과정에서 유실된 ChatGPT 대화 내용을 당시 Codex devlog와 Git 이력, 남아 있는 자료를 바탕으로 기억을 더해 재구성한 글이다.
Cash Flow가 실제 KIS 조회 결과를 JSON Snapshot으로 보존하기 시작하자, 이제 cash_flow.json 자체가 중요한 데이터가 됐다. 단순히 한 컴퓨터에만 두는 것보다 Google Drive에 안전하게 보관하고 여러 환경에서 사용할 수 있는 구조가 필요해졌다. 처음부터 실제 투자 데이터를 올리지는 않았다. OAuth와 Drive API 연결이 정상인지 독립 테스트 JSON으로 먼저 검증하고, 왕복이 확인된 뒤 실제 동기화를 붙이는 순서로 진행했다.
Google OAuth부터 실제 파일 왕복까지
권한은 전체 Drive가 아니라 drive.file scope를 사용했다. MyStock이 생성하거나 사용자가 허용한 파일만 다루는 최소 권한 원칙이었다.
첫 실행에서는 OAuth 환경변수가 없어 인증 전에 안전하게 중단됐고, 설정 후에는 Google OAuth 앱이 Testing 상태인데 로그인 계정이 테스트 사용자로 등록되지 않아 access_denied가 발생했다. Google Cloud Console에서 테스트 사용자를 등록한 뒤 다시 실행하자 OAuth 인증, MyStock 폴더 생성, 테스트 JSON 업로드, 재다운로드, 내용 비교까지 모두 성공했다.
단순 업로드로는 부족했다
연결이 된 뒤 실제 cash_flow.json을 동기화하려고 보니 더 큰 문제가 생겼다. Local과 Cloud 양쪽에서 데이터가 달라질 수 있기 때문에 단순히 최신 파일 하나로 덮어쓰면 Snapshot이나 투자계획을 잃을 수 있었다. 그래서 Snapshot은 snapshot_date 기준으로 합치고, 같은 날짜에서는 최신 updated_at을 선택했다. 날짜와 시각이 같은데 내용이 다르면 자동으로 한쪽을 고르지 않고 SYNC_CONFLICT로 처리했다. 투자계획 역시 어느 쪽이 최신인지 판단할 근거가 없으면 충돌로 남겼다.
편리한 자동 병합보다 잘못된 최신 판정으로 데이터를 잃지 않는 것을 우선한 정책이었다.
실패해도 Local은 살아 있어야 했다
Local 저장은 검증, fsync, 임시 파일, os.replace 순서로 강화했다. last_sync는 Cloud upload가 성공하고 Local commit까지 가능한 경우에만 기록했다. 다운로드, 병합, 업로드 중 어느 단계든 실패하면 기존 Local 바이트와 기존 last_sync를 유지했다.
충돌이 발생하면 Local과 Cloud 전체 문서를 별도 conflict 폴더에 보존했고, Cloud update 전에는 날짜별 백업을 만들었다. GUI에서는 별도 QThread에서 Sync를 실행하고, Sync 중 KIS 저장이 겹치지 않게 했다. Sync가 실패하더라도 Dashboard는 Local 데이터로 계속 실행하도록 했다.
이때 가장 놀랐던 것은 Google Drive API 연결 자체보다 동기화 로직이었다. Local과 Cloud 중 어느 쪽이 최신인지 판단하고, 충돌하면 임의로 덮어쓰지 않고, 실패하면 기존 데이터를 보존하는 정책까지 요구사항만 정리해서 전달했는데 생각보다 너무 쉽게 구현됐다. ‘파일 동기화 알고리즘을 이렇게 쉽게 만들어도 되는 건가? 이게 진짜 가능한 건가?’ 싶을 정도로 AI의 코딩 능력에 꽤 감탄하고 있었다. 이때까지만 해도 말이다...
Drive 작업이 Python 버전 문제를 드러냈다
Google 라이브러리를 붙이는 과정에서 Python 3.9 EOL 경고와 macOS LibreSSL 관련 경고가 계속 보였다. Drive 기능 자체는 정상 동작했지만, 장기적으로 라이브러리 지원 문제가 남는다는 신호였다. 그래서 다음 작업으로 Python 3.9.6 환경을 바로 폐기하지 않고 .venv_py39에 롤백용으로 보존한 뒤, Python 3.14.6을 기본 .venv로 전환했다. 버전이 크게 올라갔지만 소스와 requirements.txt를 먼저 수정하지 않고 실제 문제가 확인되는 부분만 고치기로 했다.
테스트만 통과했다고 끝내지 않았다
Python 3.9.6과 3.14.6에서 모두 39개 테스트가 통과했고, pip check와 compile 검사도 통과했다. 하지만 마이그레이션 성공 여부를 테스트 결과만으로 판단하지 않았다. PySide6 GUI 생성과 clean exit, 실제 KIS 5계좌 조회, 기존 Google OAuth token 사용, 실제 Drive Sync, Local/Cloud 재다운로드 비교까지 확인했다. Snapshot은 2개에서 2개, 투자계획은 3개에서 3개로 유지됐고, device_id도 보존됐다.
결과적으로 Google Drive 동기화는 단순한 백업 기능을 넘어 MyStock의 데이터 보존 원칙을 구체화했고, 그 과정에서 실행환경까지 최신 Python으로 정비하게 됐다.