fix: harden valuation concurrency and currency scope

This commit is contained in:
2026-10-06 09:22:19 +00:00
parent a4cad342a6
commit 6455c70413
3 changed files with 98 additions and 7 deletions
@@ -174,6 +174,7 @@ def register_account_valuation(
ts = now_iso()
values = (amount_int, currency_norm, (valuation_kind or "balance").strip().lower(), source_norm, source_ref or "", status, memo or "", as_of_at, timezone, optional_ints["cost_basis"], optional_ints["net_contributed"], reported_principal_kind, reported_principal_label, optional_ints["profit"], return_rate, return_basis, optional_ints["principal"], optional_ints["interest"], optional_ints["fee"], definition)
with db(db_path) as conn:
conn.execute("BEGIN IMMEDIATE")
account = conn.execute("SELECT * FROM accounts WHERE id=?", (account_id,)).fetchone()
if account is None:
return fail("not_found", "account not found")
@@ -196,10 +197,10 @@ def register_account_valuation(
conn.execute("""INSERT INTO account_valuations
(id,account_id,basis_date,amount,currency,valuation_kind,source_type,source_ref,verification_status,recorded_at,memo,idempotency_key,supersedes_id,correction_reason,as_of_at,timezone,cost_basis,net_contributed,reported_principal_kind,reported_principal_label,profit,return_rate,return_basis,principal,interest,fee,representative_liability_definition)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", (valuation_id, account_id, basis, *values[:6], ts, values[6], idempotency_key or "", supersedes_id, correction_reason, *values[7:]))
except sqlite3.IntegrityError as exc:
except sqlite3.IntegrityError:
if supersedes_id:
return fail("correction_conflict", "valuation already has a correction")
return fail("idempotency_conflict", str(exc))
return fail("idempotency_conflict", "idempotency_key already has a different payload")
except Exception as exc:
return fail("validation_error", str(exc))
row = conn.execute("SELECT * FROM account_valuations WHERE id=?", (valuation_id,)).fetchone()
@@ -237,7 +238,7 @@ def select_account_valuation(account_id: str, basis_date: str, as_of: bool = Fal
latest_verified_date = max((x["basis_date"] for x in verified), default="")
candidate = [
r for r in leaves
if r["verification_status"] != "verified"
if r["verification_status"] == "unverified"
and r["basis_date"] <= basis
and (r["basis_date"] == basis if not as_of else (not latest_verified_date or r["basis_date"] > latest_verified_date))
]