fix corporate action ledger replay invariants

This commit is contained in:
2026-09-13 14:04:30 +09:00
parent 48735bbb4a
commit 14c118f503
4 changed files with 59 additions and 15 deletions
+8 -4
View File
@@ -290,7 +290,7 @@ def corporate_action_portfolio(
"""Record an auditable stock consolidation without a trade."""
from datetime import date
from decimal import Decimal
from app.domain.corporate_actions import calculate_stock_consolidation
from app.domain.corporate_actions import calculate_stock_consolidation, canonical_payload_hash
from app.domain.models import CorporateAction
if action_type != "stock_consolidation":
ctx.obj.console.print("Error: INVALID_CORPORATE_ACTION_TYPE")
@@ -307,9 +307,13 @@ def corporate_action_portfolio(
def _callback(service, repository, app_context):
portfolio_id = _resolve_portfolio_id(repository, name, user)
portfolio = repository.get(portfolio_id)
calc = calculate_stock_consolidation(Decimal(str(quantity_before)), Decimal(str(quantity_after)), Decimal(str(portfolio.price)))
action = CorporateAction("", portfolio_id, portfolio.asset_id, action_type, day, calc.quantity_before, calc.quantity_after, calc.average_price_before, calc.average_price_after, calc.total_cost_basis, Decimal(str(portfolio.cash_balance)), Decimal(str(portfolio.profit_buffer)), evidence_ref, idempotency_key, "", 0, user)
return repository.record_corporate_action(portfolio_id, action=action, idempotency_key=idempotency_key, payload_hash="")
if not idempotency_key.strip():
raise ValueError("Idempotency-Key must not be empty")
payload = {"action_type": action_type, "effective_date": day.isoformat(), "quantity_before": str(quantity_before), "quantity_after": str(quantity_after), "evidence_ref": evidence_ref, "confirm_daemon_managed": False}
digest = canonical_payload_hash(payload)
calc = calculate_stock_consolidation(Decimal(str(quantity_before)), Decimal(str(quantity_after)), Decimal("0"))
action = CorporateAction("", portfolio_id, portfolio.asset_id, action_type, day, calc.quantity_before, calc.quantity_after, calc.average_price_before, calc.average_price_after, calc.total_cost_basis, Decimal(str(portfolio.cash_balance)), Decimal(str(portfolio.profit_buffer)), evidence_ref, idempotency_key, digest, 0, user)
return repository.record_corporate_action(portfolio_id, action=action, idempotency_key=idempotency_key, payload_hash=digest)
detail = _with_service_and_repo(ctx, _callback)
render_output(ctx.obj.console, ctx.obj.output_format, detail)