fix: preserve unmanaged first-seen timestamps
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
co-authored by
genichin
parent
be2e73a2d6
commit
f9284d1de8
@@ -99,3 +99,30 @@ class TestCRUDRoundTrip:
|
||||
rows_b = pg_unmanaged_store.list_states(instance_key="inst-B", lifecycle_state="all")
|
||||
assert len(rows_a) == 1 and rows_a[0]["lifecycle_state"] == "resolved"
|
||||
assert len(rows_b) == 1 and rows_b[0]["quantity"] == 7
|
||||
|
||||
def test_reactivated_state_preserves_original_first_seen(self, pg_unmanaged_store):
|
||||
t1 = datetime(2026, 9, 7, 0, 0, tzinfo=UTC)
|
||||
t2 = t1 + timedelta(minutes=1)
|
||||
t3 = t2 + timedelta(minutes=1)
|
||||
|
||||
pg_unmanaged_store.observe(
|
||||
instance_key="inst-A",
|
||||
symbol="008110",
|
||||
quantity=3,
|
||||
observed_at=t1,
|
||||
)
|
||||
pg_unmanaged_store.resolve_absent(
|
||||
instance_key="inst-A",
|
||||
observed_symbols=set(),
|
||||
observed_at=t2,
|
||||
)
|
||||
reopened = pg_unmanaged_store.observe(
|
||||
instance_key="inst-A",
|
||||
symbol="008110",
|
||||
quantity=5,
|
||||
observed_at=t3,
|
||||
)
|
||||
|
||||
assert reopened["transition"] == "detected"
|
||||
assert reopened["state"]["first_seen_at"] == t1
|
||||
assert reopened["state"]["last_seen_at"] == t3
|
||||
|
||||
@@ -109,6 +109,22 @@ def test_in_memory_store_isolates_same_symbol_by_instance():
|
||||
assert state_b["quantity"] == 7
|
||||
|
||||
|
||||
def test_in_memory_store_preserves_first_seen_when_resolved_symbol_reappears():
|
||||
store = InMemoryUnmanagedPositionStore()
|
||||
t1 = datetime(2026, 9, 7, 0, 0, tzinfo=UTC)
|
||||
t2 = t1 + timedelta(minutes=1)
|
||||
t3 = t2 + timedelta(minutes=1)
|
||||
|
||||
store.observe(instance_key=INSTANCE, symbol="008110", quantity=3, observed_at=t1)
|
||||
store.resolve_absent(instance_key=INSTANCE, observed_symbols=set(), observed_at=t2)
|
||||
reopened = store.observe(instance_key=INSTANCE, symbol="008110", quantity=5, observed_at=t3)
|
||||
|
||||
assert reopened["transition"] == "detected"
|
||||
assert reopened["state"]["first_seen_at"] == t1
|
||||
assert reopened["state"]["last_seen_at"] == t3
|
||||
assert reopened["state"]["quantity_changed_at"] == t3
|
||||
|
||||
|
||||
def test_reconcile_core_holdings_suppresses_repeated_unmanaged_alarm_spam():
|
||||
repo, svc = _wire()
|
||||
emitter, transport = _make_emitter()
|
||||
|
||||
@@ -58,11 +58,11 @@ class PostgreSQLUnmanagedPositionStore:
|
||||
cur.execute(
|
||||
"UPDATE unmanaged_position_state "
|
||||
"SET quantity = %s, lifecycle_state = 'active', "
|
||||
" first_seen_at = %s, last_seen_at = %s, quantity_changed_at = %s, "
|
||||
" resolved_at = NULL, updated_at = %s "
|
||||
" last_seen_at = %s, quantity_changed_at = %s, resolved_at = NULL, "
|
||||
" updated_at = %s "
|
||||
"WHERE instance_key = %s AND symbol = %s "
|
||||
f"RETURNING {_STATE_COLUMNS}",
|
||||
(quantity, now, now, now, now, instance_key, symbol),
|
||||
(quantity, now, now, now, instance_key, symbol),
|
||||
)
|
||||
elif int(previous["quantity"]) != int(quantity):
|
||||
transition = "quantity_changed"
|
||||
|
||||
@@ -629,7 +629,9 @@ class InMemoryUnmanagedPositionStore:
|
||||
"symbol": symbol,
|
||||
"quantity": quantity,
|
||||
"lifecycle_state": "active",
|
||||
"first_seen_at": now,
|
||||
"first_seen_at": (
|
||||
existing.get("first_seen_at", now) if existing is not None else now
|
||||
),
|
||||
"last_seen_at": now,
|
||||
"quantity_changed_at": now,
|
||||
"resolved_at": None,
|
||||
|
||||
Reference in New Issue
Block a user