BAT-016's initial implementation passed only against mocked repositories and broke on a real database. Two defects fixed: 1. insert_ledger_trade used `ON CONFLICT (portfolio_id, order_id, execution_id) WHERE order_id IS NOT NULL` but portfolio_ledger is a TimescaleDB hypertable, which cannot have that partial unique index (must include the partitioning column recorded_at). The statement errored against Postgres. Replaced with application-level idempotency: SELECT-before-insert inside the existing `SELECT ... FOR UPDATE` portfolio row lock, which serializes concurrent same-portfolio writes (race-safe). Duplicate returns current authoritative portfolio state (dcy-006 OQ-4 b). 2. `with self._connect() as conn:` closes the shared psycopg3 connection on exit, leaving the reused repository connection unusable. Switched to `with conn.transaction():` (commits without closing). Added tests/test_ledger_consolidation_integration.py — real-Postgres integration tests (new / duplicate / negative-balance) that close the mock-only verification gap. Full suite: 376 passed. SDLC: REQ-036/037 CHG-20260605-03 reconcile OQ-7 (ii) (DB partial unique → application-level idempotency) since the hypertable makes the DB constraint infeasible. REQ-036/037/038 → Implemented; BAT-016 → release-candidate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2.5 KiB
2.5 KiB
Batch Index
목적
- 이 문서는 batch delivery 단위의 전역 인덱스다.
- 각 batch는
docs/batches/<BAT_ID>/아래에서 profile(standard|batch-lite)에 맞는 산출물을 관리한다.
Batch Register
| BAT ID | Profile | Status | Included REQ | Discovery | Folder |
|---|---|---|---|---|---|
| BAT-001 | standard | verified | REQ-009, REQ-011, REQ-014 | dcy-001 | bat-001 |
| BAT-002 | standard | release-candidate | REQ-010, REQ-012, REQ-013, REQ-015 | dcy-001 | bat-002 |
| BAT-003 | standard | release-candidate | REQ-001, REQ-002, REQ-003, REQ-006 | dcy-002 | bat-003 |
| BAT-004 | standard | release-candidate | REQ-004, REQ-005 | dcy-002 | bat-004 |
| BAT-005 | standard | release-candidate | REQ-007, REQ-008 | dcy-002 | bat-005 |
| BAT-006 | standard | release-candidate | REQ-016, REQ-017, REQ-018 | dcy-004 | bat-006 |
| BAT-007 | standard | release-candidate | REQ-022, REQ-023 | dcy-004 | bat-007 |
| BAT-008 | standard | release-candidate | REQ-019, REQ-020, REQ-021, REQ-024 | dcy-004 | bat-008 |
| BAT-009 | standard | release-candidate | REQ-025, REQ-026, REQ-027, REQ-028 | dcy-003 | bat-009 |
| BAT-010 | standard | release-candidate | REQ-030, REQ-031, REQ-032 | dcy-003 | bat-010 |
| BAT-011 | standard | release-candidate | REQ-029 | dcy-003 | bat-011 |
| BAT-012 | standard | release-candidate | REQ-002, REQ-010 | dcy-001, dcy-002, dcy-003 | bat-012 |
| BAT-013 | batch-lite | release-candidate | REQ-005 | dcy-002 | bat-013 |
| BAT-014 | batch-lite | release-candidate | REQ-025, REQ-026, REQ-027, REQ-028, REQ-032 | dcy-003 | bat-014 |
| BAT-015 | standard | release-candidate | REQ-033, REQ-034, REQ-035 | dcy-005 | bat-015 |
| BAT-016 | standard | release-candidate | REQ-036, REQ-037, REQ-038 | dcy-006 | bat-016 |