54 lines
4.2 KiB
Markdown
54 lines
4.2 KiB
Markdown
# BAT-015 Implementation
|
|
|
|
- Status: completed
|
|
- Batch: BAT-015
|
|
|
|
## Plan Summary
|
|
- 변경 순서: REQ-034 → REQ-035 → REQ-033 (planning 권장 순서대로 진행)
|
|
- 각 REQ 구현 후 부분 회귀 (pytest 전체 + 해당 영역 smoke)
|
|
- 최종 batch 통합 회귀 + 로컬 smoke
|
|
|
|
## Changed Files
|
|
- REQ-034:
|
|
- `app/schemas/auth.py` — `LoginRequest.model_config = ConfigDict(extra="forbid")` 추가
|
|
- `tests/test_auth.py` — `test_login_rejects_no_expiry_extra_field`, `test_login_rejects_arbitrary_extra_field` 신규
|
|
- REQ-035:
|
|
- `app/api/health.py` — `HealthResponse.db_enabled` 필드 추가 + `healthcheck()` 핸들러가 `settings.db_enabled` 노출
|
|
- `tests/test_app.py` — `test_healthcheck`에 db_enabled 확인 추가, `test_health_exposes_db_enabled_true`, `test_health_exposes_db_enabled_false` 신규
|
|
- `docs/runtime-flows.md` — health endpoint 섹션(line 97)에 `db_enabled` 의미 명문화 노트 추가
|
|
- `docs/interface-contract.md` — `/health` payload schema에 `db_enabled` 필드 추가 + 의미 노트
|
|
- REQ-033:
|
|
- `migrations/versions/20260601_0024_ledger_trades_portfolio_id_rename.py` — 신규 alembic revision (ALTER COLUMN RENAME with has_table guard)
|
|
- `app/domain/models.py` — `LedgerTrade.asset_id` → `portfolio_id`
|
|
- `app/repositories/portfolio_repository.py` — `insert_ledger_trade` interface 시그니처 갱신
|
|
- `app/repositories/postgres.py` — `insert_ledger_trade` INSERT/SELECT/RETURNING SQL 컬럼명 + `_row_to_ledger_trade` 매핑
|
|
- `app/schemas/v1.py` — `LedgerTradeResponse.asset_id` → `portfolio_id`
|
|
- `app/api/v1_portfolios.py` — ledger handler에서 `insert_ledger_trade(portfolio_id=...)` + 응답 매핑
|
|
- `tests/test_v1_portfolios_ledger.py` — `LedgerTrade(portfolio_id=...)` + 응답 `body["portfolio_id"]` 검증
|
|
- `tests/test_v1.py` — `_make_ledger_trade` + `body["portfolio_id"]` 검증
|
|
- `tests/test_daemon_assignment.py` — mock `trade.portfolio_id` 갱신
|
|
- `docs/data-model.md` — LedgerTrade entity, Key Fields, Uniqueness Constraints, State Rules의 `asset_id` 표기 모두 `portfolio_id`로 갱신 + revision 20260601_0024 명시
|
|
- `docs/interface-contract.md` — `POST /v1/portfolios/{id}/ledger/trades` 응답 schema에 `portfolio_id` 명시 + REQ-033 cross-reference
|
|
|
|
## Execution Log
|
|
1. REQ-034: `LoginRequest`에 `extra="forbid"` 적용 → `tests/test_auth.py` 16 passed
|
|
2. REQ-035: `HealthResponse` 확장 + 핸들러 → `tests/test_app.py` 9 passed → baseline 갱신
|
|
3. REQ-033: alembic revision 20260601_0024 작성 → `alembic upgrade head` 적용(local DB에 `ledger_trades` 테이블 부재로 `has_table` guard에 의해 안전 skip) → repository/도메인/스키마/라우트 정합 → `tests/test_v1_portfolios_ledger.py` 10 passed
|
|
4. 통합 회귀 1차: 5 failed 발견 (test_v1.py + test_daemon_assignment.py 잔존 `asset_id` mock) → 갱신 → 통합 회귀 2차: **372 passed, 0 failed**
|
|
5. 로컬 smoke:
|
|
- GET /health → HTTP 200 + `db_enabled: true` (REQ-035 AC-1)
|
|
- POST /auth/login + `no_expiry: true` → HTTP 422 + `extra_forbidden` (REQ-034 AC-2)
|
|
- codebase grep `ledger_trades.*asset_id` → 0건 (REQ-033 AC-3)
|
|
- `docs/runtime-flows.md` baseline 노트 grep → 매치 (REQ-035 AC-4)
|
|
- `docs/interface-contract.md` /health payload grep → 매치 (REQ-035 AC-5)
|
|
|
|
## Validation
|
|
- pytest 전체: **372 passed, 0 failed** (BAT-015 base 368 → +4: test_auth 2건 + test_app 2건 신규)
|
|
- 로컬 smoke 5건 모두 통과
|
|
- AC 매핑은 verification.md에서 정리
|
|
- 실 DB AC (REQ-033 AC-1 `\d ledger_trades`, AC-4 staging dry-run lock 측정): 본 워크스페이스 `ledger_trades` 테이블 미생성 상태로 N/A. REL-002 staging 시점에 별도 수집.
|
|
|
|
## Remaining Risks
|
|
- R-실 DB ledger_trades 테이블 미생성: REQ-033 마이그레이션은 `has_table` guard로 안전하지만, 본 워크스페이스에서 ledger_trades 적재 흐름이 활용되지 않는 상태. BAT-011 release-candidate verification은 mock 기반이라 이 gap이 release 단계에서 발견되지 않았음. **본 batch 범위 밖**, 별도 후속 항목으로 등록 후보(REL-002 또는 후속 Discovery).
|
|
- (workspace_purpose 메모리: 본 워크스페이스 개발용 → prod 영향 검증 N/A)
|