diff --git a/docs/batches/bat-025_20260715_portfolio-ledger-alembic-migration/design.md b/docs/batches/bat-025_20260715_portfolio-ledger-alembic-migration/design.md new file mode 100644 index 0000000..659587c --- /dev/null +++ b/docs/batches/bat-025_20260715_portfolio-ledger-alembic-migration/design.md @@ -0,0 +1,40 @@ +# BAT-025 Design + +## D-1. Revision graph and parent + +구현 시작 직전 `uv run alembic heads` 및 `uv run alembic history`로 유효 head를 재확인한다. 신규 revision은 그 실제 head 하나를 `down_revision`으로 사용하며, 문서/코드에 20260628_0027을 선결 가정으로 고정하지 않는다. + +## D-2. Migration idempotency + +신규 revision은 inspector/information_schema 기반으로 table/column 존재를 확인한다. + +- `portfolio_ledger`가 정상적으로 존재하는 일반 경로에서는 네 컬럼을 추가한다. +- runtime `ensure_schema()`가 이미 컬럼을 생성한 경로에서는 컬럼 재생성 없이 nullable/default를 검증·보정한다. +- `source`는 upgrade 전에 NULL을 `'broker'`로 backfill하고 이후 `NOT NULL DEFAULT 'broker'`를 보장한다. +- 기존 행은 삭제·재작성하지 않으며 upgrade 전후 row count와 business field를 비교한다. +- down migration은 운영 forward-only 정책과 충돌하지 않도록 구현 범위를 명시하고, 운영 runbook은 column deletion을 rollback으로 제시하지 않는다. + +## D-3. Runtime boundary + +`app/repositories/postgres.py:ensure_schema()`는 bootstrap safety 경로로 유지한다. Alembic revision은 persistent schema history의 source of truth로 둔다. migration 성공만으로 version table을 임의 stamp하지 않으며, schema와 Alembic current가 함께 일치하는지 검증한다. + +## D-4. Test matrix + +| 시작 상태 | 검증 | +| --- | --- | +| fresh Alembic schema | upgrade, 네 컬럼 타입/nullable/default, current/head | +| 기존 ledger rows | row count/business data 보존, source broker backfill | +| runtime-precreated columns | 중복 DDL 부재, constraints/default 정합, current/head | +| broker write | 기존 `/ledger/trades` 회귀 없음 | +| manual API | source/manual metadata 및 REQ-056 핵심 regression | +| runbook | preflight 조건, 실패 중단, forward-only recovery 문서 정합 | + +## D-5. Operational gate + +이번 batch는 local/non-production verification만 수행한다. 운영 DB backup/upgrade, service restart, 신규 API activation, deploy/push/merge는 M5 Release의 별도 결재 없이는 실행하지 않는다. runbook은 실행 가능한 명령 템플릿과 중단 조건을 제공하되 실제 운영 결과를 가장하지 않는다. + +## Design decisions / open findings + +- 실제 revision ID는 구현 preflight 결과로 결정한다. +- 실제 DB driver availability에 따라 migration integration test harness는 repository 표준 fixture 또는 isolated PostgreSQL 경로를 사용하되, 사용하지 못한 환경은 QC evidence에 명시한다. +- stamp 필요성은 schema inspection과 version table evidence 이후에만 판단하며 자동 조치하지 않는다. diff --git a/docs/batches/bat-025_20260715_portfolio-ledger-alembic-migration/index.md b/docs/batches/bat-025_20260715_portfolio-ledger-alembic-migration/index.md new file mode 100644 index 0000000..f64b717 --- /dev/null +++ b/docs/batches/bat-025_20260715_portfolio-ledger-alembic-migration/index.md @@ -0,0 +1,51 @@ +# BAT-025 — portfolio_ledger 명시 Alembic migration + +- Batch ID: BAT-025 +- Profile: standard +- Status: confirmed +- Discovery: dcy-012_20260714_manual-ledger-write-api-owner-scoped (REQ-057 follow-on) +- Included REQ: REQ-057 +- Folder: docs/batches/bat-025_20260715_portfolio-ledger-alembic-migration/ +- Created: 2026-07-15 + +## Summary + +REQ-056/BAT-024가 사용한 `portfolio_ledger` additive metadata 네 컬럼을 runtime `ensure_schema()` 자동 DDL에만 의존하지 않고 명시 Alembic revision으로 추적·검증한다. 기존 broker/manual 데이터 보존, runtime-precreated schema 호환성, 운영 migration runbook 및 독립 QC를 delivery 범위로 둔다. + +## Scope + +- `source TEXT NOT NULL DEFAULT 'broker'` +- `target_ledger_entry_id BIGINT NULL` +- `confirmation_evidence TEXT NULL` +- `actor_user_id TEXT NULL` +- fresh/기존/runtime-precreated schema migration compatibility +- broker ledger regression 및 manual ledger regression +- backup/preflight/current/schema/lock/smoke/forward-only recovery runbook + +## DoR + +- [x] REQ-057 Approved (Justin Ko) +- [x] REQ-056 Implemented 및 BAT-024 release-candidate 유지 확인 +- [x] implementation 시점 `alembic heads`/graph 재확인 요구사항 확인 +- [x] 운영 DB upgrade·service activation은 별도 M5 Release gate로 분리 + +## DoD + +- [ ] confirmed planning/design 문서 local main commit +- [ ] dev-impl의 migration/code/test/runbook commit +- [ ] dev-qc 독립 diff review 및 test rerun PASS +- [ ] lead verification confirmation evidence 기록 +- [ ] M5 Release 미착수 + +## Gate / Constraints + +- 운영 DB, deploy, service activation, push/merge, credential/account disclosure 금지. +- down migration/column deletion은 운영 rollback 경로로 사용하지 않는다. 복구는 호환 코드 rollback + additive schema 유지의 forward-only 정책이다. +- migration 구현 전 실제 단일 head와 graph를 재확인하고, 결과를 implementation/verification evidence에 기록한다. + +## Documents + +- Planning: [planning.md](./planning.md) +- Design: [design.md](./design.md) +- Implementation: [implementation.md](./implementation.md) (dev-impl 산출) +- Verification: [verification.md](./verification.md) (dev-qc/lead 산출) diff --git a/docs/batches/bat-025_20260715_portfolio-ledger-alembic-migration/planning.md b/docs/batches/bat-025_20260715_portfolio-ledger-alembic-migration/planning.md new file mode 100644 index 0000000..d517c67 --- /dev/null +++ b/docs/batches/bat-025_20260715_portfolio-ledger-alembic-migration/planning.md @@ -0,0 +1,49 @@ +# BAT-025 Planning + +## Objective + +REQ-057의 명시 Alembic migration과 운영 runbook을 구현·검증한다. BAT-024의 API 계약과 Implemented 상태는 변경하지 않는다. + +## Delivery sequence + +1. **Preflight** — `uv run alembic heads`, `uv run alembic history`, revision graph 및 `ensure_schema()` DDL 소유 경계를 확인하고 실제 head를 evidence로 고정한다. +2. **Migration** — 실제 head를 parent로 하는 신규 revision을 작성한다. fresh/기존/runtime-precreated schema에서 중복 DDL 없이 네 컬럼, source backfill, NOT NULL/default를 보장한다. +3. **Runtime compatibility** — `ensure_schema()` 선행 생성 경로와 Alembic version tracking의 상호작용을 테스트한다. 임의 stamp는 schema/version evidence와 승인된 절차 없이 사용하지 않는다. +4. **Regression tests** — 기존 broker ledger write, manual ledger API, row/data preservation, schema metadata/current 정합을 검증한다. +5. **Runbook** — backup, current, schema/row count, active query/lock, upgrade, post-check, smoke, 실패 대응 및 forward-only recovery를 문서화하고 dry-run 검토한다. +6. **Independent QC** — dev-qc가 committed diff를 직접 검토하고 표준 테스트 및 migration-focused 테스트를 재실행한다. + +## Work packets + +### WP-1: Batch artifacts (lead) + +- 이 문서와 `design.md`, `index.md`를 confirmed 상태로 작성한다. +- `docs/batches/index.md`에 BAT-025를 `confirmed`로 등록한다. +- local main에 docs-only commit을 남긴다. + +### WP-2: Implementation (dev-impl) + +- 신규 Alembic revision, 필요한 runtime compatibility 수정, tests, `docs/runbooks/` runbook을 작성한다. +- implementation log와 실행 명령/결과를 기록하고 implementation commit을 반환한다. +- 운영 DB나 서비스 activation은 실행하지 않는다. + +### WP-3: QC (dev-qc) + +- dev-impl committed diff와 문서/REQ 정합성을 독립 검토한다. +- `uv run pytest` 및 가능한 migration-focused checks를 재실행한다. +- blocker가 있으면 PASS가 아닌 명시적 finding으로 반환한다. + +## Acceptance evidence targets + +- AC-1: head/graph preflight 출력 +- AC-2~5: fresh/legacy/runtime-precreated schema upgrade와 source backfill/중복 오류 부재 +- AC-6: `alembic current`, information_schema, row count 결과 +- AC-7~9: runbook preflight/실패 대응/forward-only recovery 검토 evidence +- AC-10: 운영 실행을 하지 않았다는 scope evidence 및 release gate 기록 +- AC-11: implementation + tests + QC committed evidence + +## Risks / blockers + +- local repository의 schema graph와 runtime-created schema가 서로 다른 시작 상태를 가질 수 있다. +- `ensure_schema()`와 Alembic 양쪽 소유 경계 변경은 기존 broker flow 회귀 위험이 있다. +- 실제 PostgreSQL 운영 DB evidence는 이번 batch 밖이며 M5 Release 승인 없이는 확보하지 않는다. diff --git a/docs/batches/index.md b/docs/batches/index.md index 770263d..eaedc12 100644 --- a/docs/batches/index.md +++ b/docs/batches/index.md @@ -32,3 +32,4 @@ | BAT-022 | standard | release-candidate | REQ-052, REQ-053, REQ-054 | dcy-011 | [bat-022](./bat-022_20260628_daemon-crud-self-service-credential-api/) | | BAT-023 | batch-lite | in-progress | REQ-055 | trex-tvr-v1 dcy-001 | [bat-023](./bat-023_20260704_portfolios-strategy-market-meta/) | | BAT-024 | standard | release-candidate | REQ-056 | dcy-012 | [bat-024](./bat-024_20260714_manual-ledger-api/) | +| BAT-025 | standard | confirmed | REQ-057 | dcy-012 follow-on | [bat-025](./bat-025_20260715_portfolio-ledger-alembic-migration/) |