Fix tombstone bug in stats and add cost statistics to forms
All checks were successful
Deploy / deploy (push) Successful in 1m38s
All checks were successful
Deploy / deploy (push) Successful in 1m38s
Bug fix: Stats queries (eggs/day, feed/bird/day, etc.) were not excluding tombstoned (deleted) events. Updated EventStore.list_events() to exclude tombstoned events by default via LEFT JOIN, and updated direct SQL queries in stats.py with the same tombstone exclusion. New stats added: - Harvest form: cost/egg (global, 30-day avg) - Sell form: avg price/egg (30-day) - Give feed form: cost/bird/day (global, 30-day avg) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -359,3 +359,66 @@ class TestTombstoneChecking:
|
||||
)
|
||||
|
||||
assert event_store.is_tombstoned(event.id) is True
|
||||
|
||||
def test_list_events_excludes_tombstoned_by_default(self, migrated_db, event_store, now_utc):
|
||||
"""list_events excludes tombstoned events by default."""
|
||||
event1 = event_store.append_event(
|
||||
event_type=PRODUCT_COLLECTED,
|
||||
ts_utc=now_utc,
|
||||
actor="ppetru",
|
||||
entity_refs={},
|
||||
payload={"order": 1},
|
||||
)
|
||||
event2 = event_store.append_event(
|
||||
event_type=PRODUCT_COLLECTED,
|
||||
ts_utc=now_utc + 1000,
|
||||
actor="ppetru",
|
||||
entity_refs={},
|
||||
payload={"order": 2},
|
||||
)
|
||||
|
||||
# Tombstone event1
|
||||
tombstone_id = generate_id()
|
||||
migrated_db.execute(
|
||||
"""INSERT INTO event_tombstones (id, ts_utc, actor, target_event_id, reason)
|
||||
VALUES (?, ?, ?, ?, ?)""",
|
||||
(tombstone_id, now_utc + 2000, "admin", event1.id, "Test deletion"),
|
||||
)
|
||||
|
||||
events = event_store.list_events()
|
||||
|
||||
assert len(events) == 1
|
||||
assert events[0].id == event2.id
|
||||
|
||||
def test_list_events_includes_tombstoned_when_requested(
|
||||
self, migrated_db, event_store, now_utc
|
||||
):
|
||||
"""list_events includes tombstoned events when include_tombstoned=True."""
|
||||
event1 = event_store.append_event(
|
||||
event_type=PRODUCT_COLLECTED,
|
||||
ts_utc=now_utc,
|
||||
actor="ppetru",
|
||||
entity_refs={},
|
||||
payload={"order": 1},
|
||||
)
|
||||
event2 = event_store.append_event(
|
||||
event_type=PRODUCT_COLLECTED,
|
||||
ts_utc=now_utc + 1000,
|
||||
actor="ppetru",
|
||||
entity_refs={},
|
||||
payload={"order": 2},
|
||||
)
|
||||
|
||||
# Tombstone event1
|
||||
tombstone_id = generate_id()
|
||||
migrated_db.execute(
|
||||
"""INSERT INTO event_tombstones (id, ts_utc, actor, target_event_id, reason)
|
||||
VALUES (?, ?, ?, ?, ?)""",
|
||||
(tombstone_id, now_utc + 2000, "admin", event1.id, "Test deletion"),
|
||||
)
|
||||
|
||||
events = event_store.list_events(include_tombstoned=True)
|
||||
|
||||
assert len(events) == 2
|
||||
assert events[0].id == event1.id
|
||||
assert events[1].id == event2.id
|
||||
|
||||
Reference in New Issue
Block a user