Preserve ledger venue provenance (#39)

* feat: preserve ledger venue provenance

* fix: satisfy ledger test lint ratchet

* fix: advance image migration inventory
This commit is contained in:
2026-09-19 19:30:32 +09:00
committed by GitHub
parent 567d662913
commit 996127f215
23 changed files with 768 additions and 35 deletions
+16
View File
@@ -0,0 +1,16 @@
---
id: "ac-0040"
status: active
---
# Idempotent venue provenance enrichment
## Criterion
동일 `(portfolio_id, order_id, execution_id)`의 broker ledger duplicate는 기존 portfolio row lock을 유지하면서 기존 ledger row를 `FOR UPDATE`로 선택해야 한다. 같은 transaction에서 기존 economic payload(`side`, `quantity`, `price`, `fee_amount`, `tax_amount`)를 먼저 비교하고 불일치면 metadata 변경 없이 `409`로 중단해야 한다. Economic payload가 같을 때 모든 incoming venue를 검사하여 저장값과 서로 다른 non-null이 하나라도 있으면 어느 field도 갱신하지 않고 `409`로 중단하며, 충돌이 없을 때만 저장값 NULL·incoming non-null인 venue들을 하나의 metadata-only update로 보강해야 한다. Incoming NULL은 기존 non-null을 유지해야 한다. 이 경로는 기존 ledger row를 재생성하거나 portfolio cash·asset quantity·snapshot과 WAC/PnL를 다시 변경하지 않아야 한다.
## Verification
- 성공 조건: execution/order venue 각각과 두 필드 동시 NULL→non-null duplicate가 같은 ledger row를 갱신하고 `200 duplicate` 최종 저장값을 반환하며 ledger row 수·cash·quantity·snapshot이 최초 `201 new` 이후 변하지 않는다. Incoming NULL replay는 기존 값을 보존한다.
- 실패·경계 조건: economic payload 불일치는 venue 검사·update 전에 `409`이고, execution 또는 order venue의 non-null 불일치는 모든 venue 검사를 완료한 뒤 update 전에 `409`이므로 어느 venue도 부분 갱신되지 않으며 회계가 변하지 않는다. 서로 다른 concurrent backfill은 portfolio·ledger row lock 아래 하나만 성공하거나 같은 값으로 수렴하고 상충 값의 last-write-wins를 허용하지 않는다.
- 검사 방법: API/repository idempotency·conflict tests와 실제 PostgreSQL row-lock/concurrency integration에서 final row·row count·portfolio balances·quantity·snapshot을 함께 검사한다.