fix: 스냅샷 UNIQUE(date) 단독 제약 재구축 + 저장 실패 전파#439
Merged
Conversation
kr_pocket 첫 실사이클이 적발한 결함: account_key 도입 전 스키마의 UNIQUE(date) 단독 제약이 운영 DB에 남아 있어(ALTER ADD COLUMN은 제약을 못 바꿈), 두 번째 바스켓이 같은 날 스냅샷을 쓰는 최초의 순간 IntegrityError로 조용히 유실됐다. 계정이 하나였던 지금까지는 드러날 수 없던 결함이다. 수정 1 — _migrate_snapshot_unique_constraint(init_database에서 호출): SQLite는 인라인 UNIQUE 삭제가 불가하므로 표준 재구축(rename → 신 스키마 create_all → INSERT OR IGNORE 복사 → 행수 검증 → 구 테이블 삭제). 멱등이며 rename 직후 중단돼도 다음 초기화가 legacy 테이블을 감지해 복사부터 재개한다. 검증 실패 시 legacy 보존 + 예외. 수정 2 — 저장 성공 전파: save_portfolio_snapshot이 실패를 삼키고 호출부가 무조건 True를 반환해 관측성이 거짓 SNAPSHOT_SAVED를 기록했다. repo(bool) → portfolio_manager(bool) → save_daily_nav_snapshot 전파로 실패가 SNAPSHOT_SKIPPED(warning)와 결측 경보에 정직하게 잡히게 했다. 운영 적용 완료: 사전 백업 확인 후 재구축(18행 보존, 복합 유니크 확인), kr_pocket 사이클 재실행으로 트랙 개시(스냅샷 7/6, KODEX200 1주). 테스트: legacy DDL 재현 재구축·행 보존·두 계정 같은 날 허용·같은 계정 차단·멱등·중단 재개. 전체 스위트 1631 통과.
easygap
added a commit
that referenced
this pull request
Jul 6, 2026
fix: 스냅샷 UNIQUE(date) 단독 제약 재구축 + 저장 실패 전파
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
무엇
kr_pocket 첫 실사이클이 적발한 구버전 스키마 결함 수정 + 그 결함이 드러낸 거짓 SNAPSHOT_SAVED 수정.
발견 경위 (실측)
kr_pocket 첫 사이클(2026-07-06 12:27)에서 매수는 성공했는데 스냅샷 저장이
UNIQUE constraint failed: portfolio_snapshots.date로 실패. 원인: account_key 도입 전 스키마의UNIQUE (date)단독 제약이 운영 DB에 남아 있었음(ALTER ADD COLUMN마이그레이션은 제약을 못 바꿈). 지금까지 계정이 하나라 드러나지 않다가, 두 번째 바스켓이 같은 날 스냅샷을 쓰는 최초의 순간 충돌 — 이후 매일 조용히 유실될 상태였습니다.부수 발견:
save_portfolio_snapshot이 실패를 삼키고 호출부는 무조건 True를 반환해, 관측성이 거짓 SNAPSHOT_SAVED 이벤트를 기록했습니다(실제 DB엔 행 없음).수정
_migrate_snapshot_unique_constraint(models.py, init_database에서 호출): SQLite는 인라인 UNIQUE 삭제 불가 → 표준 재구축(rename → 신 스키마 create_all →INSERT OR IGNORE복사 → 행수 검증 → 구 테이블 삭제). 멱등이며 중간 중단 시 다음 초기화에서 legacy 테이블을 감지해 복사부터 재개. 검증 실패 시 legacy 보존 + 예외(조용히 안 넘어감).save_portfolio_snapshot → bool→save_daily_snapshot → bool→save_daily_nav_snapshot이 그대로 전파 — 저장 실패가 SNAPSHOT_SKIPPED(warning)로 정직하게 기록되고 커버리지 결측 경보가 잡는다.운영 적용 완료
테스트
tests/test_snapshot_unique_migration.py: legacy DDL 재현 → 재구축 후 행 보존 + 두 계정 같은 날 저장 가능 + 같은 계정 같은 날은 여전히 차단 + 신 스키마 멱등 + rename 직후 중단 재개.