Files
portfolio-hub/docs/batches/index.md
T
genichinandClaude Opus 4.8 2a19b7f058 fix: ledger write idempotency for TimescaleDB hypertable (BAT-016 rework)
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>
2026-06-05 22:11:17 +09:00

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