fix: align portfolio-hub ledger write adapter to live API contract

REQ-017 CHG-20260606-01. Live portfolio-hub returned 404 for the
trex-orbit-assumed POST /v1/assets/{asset_id}/ledger/trades. Correct to
POST /v1/portfolios/{portfolio_id}/ledger/trades with body keys
quantity/fee_amount/tax_amount (was qty/fee/tax), success 201. Reverified
with live e2e (201 Created, outbox COMPLETED) + durability drain of the
prior 404'd item. Resolves the REL-001 ledger-write release blocker.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-06 11:27:30 +09:00
co-authored by Claude Opus 4.7
parent e24de29335
commit 9e64a24441
6 changed files with 81 additions and 19 deletions
@@ -1,6 +1,7 @@
"""portfolio-hub HTTP ledger adapter tests (REQ-017 AC-2/3)."""
from __future__ import annotations
import json
from datetime import datetime, timezone
import httpx
@@ -26,7 +27,7 @@ def _client(handler):
return httpx.Client(transport=httpx.MockTransport(handler))
def test_post_contract_includes_execution_id_and_path_uses_asset_id():
def test_post_contract_includes_execution_id_and_path_uses_portfolio_id():
captured = {}
def handler(request: httpx.Request) -> httpx.Response:
@@ -38,9 +39,15 @@ def test_post_contract_includes_execution_id_and_path_uses_asset_id():
adapter = PortfolioHubLedger("https://portfolio-hub.test", token="tok",
client=_client(handler))
adapter.record_trade(_trade(asset="PF-77"))
assert captured["url"] == "https://portfolio-hub.test/v1/assets/PF-77/ledger/trades"
assert "execution_id" in captured["body"]
assert "\"side\":\"buy\"" in captured["body"]
assert captured["url"] == "https://portfolio-hub.test/v1/portfolios/PF-77/ledger/trades"
body = json.loads(captured["body"])
# Live contract field names (REQ-017 CHG-04): quantity / fee_amount / tax_amount.
assert body["execution_id"] == "paper:PAPER-000001:10"
assert body["side"] == "buy"
assert body["quantity"] == 10
assert body["fee_amount"] == 1.5
assert body["tax_amount"] == 0.0
assert "qty" not in body and "fee" not in body and "tax" not in body
assert captured["auth"] == "Bearer tok"