fix: harden unmanaged position lifecycle writes
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
co-authored by
genichin
parent
5a13c0494b
commit
be2e73a2d6
@@ -741,6 +741,53 @@ def test_unmanaged_record_text_output(monkeypatch, capsys):
|
||||
assert "evidence_ref=kis-balance:2026-09-11" in out
|
||||
|
||||
|
||||
def test_unmanaged_record_main_dispatch(monkeypatch, capsys):
|
||||
class _Store:
|
||||
def __init__(self, *_args, **_kwargs):
|
||||
pass
|
||||
|
||||
def record_operator_action(self, **kwargs):
|
||||
return {
|
||||
"instance_key": "default",
|
||||
"symbol": kwargs["symbol"],
|
||||
"quantity": 3,
|
||||
"lifecycle_state": "active",
|
||||
"first_seen_at": "2026-09-07T00:00:00+00:00",
|
||||
"last_seen_at": "2026-09-11T00:00:00+00:00",
|
||||
"quantity_changed_at": "2026-09-07T00:00:00+00:00",
|
||||
"resolved_at": None,
|
||||
"operator_action": kwargs["action"],
|
||||
"evidence_ref": kwargs["evidence_ref"],
|
||||
"operator_note": kwargs["note"],
|
||||
"operator_actor": kwargs["actor"],
|
||||
"operator_updated_at": "2026-09-11T00:00:00+00:00",
|
||||
"created_at": "2026-09-07T00:00:00+00:00",
|
||||
"updated_at": "2026-09-11T00:00:00+00:00",
|
||||
}
|
||||
|
||||
monkeypatch.setattr(
|
||||
"trex_core.adapters.portfolio.unmanaged_position_store.PostgreSQLUnmanagedPositionStore",
|
||||
_Store,
|
||||
)
|
||||
|
||||
rc = cli.main(
|
||||
[
|
||||
"unmanaged",
|
||||
"record",
|
||||
"008110",
|
||||
"investigating",
|
||||
"--evidence-ref",
|
||||
"kis-balance:2026-09-11",
|
||||
"--json",
|
||||
]
|
||||
)
|
||||
|
||||
assert rc == 0
|
||||
out = json.loads(capsys.readouterr().out)
|
||||
assert out["result"] == "recorded"
|
||||
assert out["state"]["symbol"] == "008110"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# REL-010 regression: _cmd_verify broker import must not raise ImportError
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -31,6 +31,8 @@ class PostgreSQLUnmanagedPositionStore:
|
||||
actor: str = "reconcile",
|
||||
) -> dict:
|
||||
now = observed_at or datetime.now(tz=UTC)
|
||||
for _attempt in range(2):
|
||||
try:
|
||||
with self._psycopg.connect(self._dsn, autocommit=False) as conn, conn.cursor() as cur:
|
||||
cur.execute(
|
||||
f"SELECT {_STATE_COLUMNS} FROM unmanaged_position_state "
|
||||
@@ -107,6 +109,11 @@ class PostgreSQLUnmanagedPositionStore:
|
||||
"previous_quantity": previous_quantity,
|
||||
"state": state,
|
||||
}
|
||||
except self._psycopg.errors.UniqueViolation:
|
||||
continue
|
||||
raise RuntimeError(
|
||||
"failed to persist unmanaged_position_state due to repeated concurrent insert race"
|
||||
)
|
||||
|
||||
def resolve_absent(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user