"""Real restored audit pagination must preserve numeric sequence ordering.""" from __future__ import annotations import importlib import os from pathlib import Path from sqlalchemy.orm import Session from modelforge_api.services.audit import AuditWriter from modelforge_api.services.recovery import RecoveryService from modelforge_api.services.recovery_postgres import parse_target from modelforge_api.settings import Settings from tests.test_managed_identities_postgres import ( IdentityDatabase, ManagedPostgresTools, identity_database, ) __all__ = ["identity_database"] def test_restored_audit_numeric_order_crosses_page_boundary( identity_database: IdentityDatabase, tmp_path: Path, ) -> None: database = identity_database importlib.import_module("alembic.command").upgrade(database.migration(), "head") event_count = 512 # Production iteration reads 500 rows per page. with Session(database.runtime) as session: writer = AuditWriter(session, "operator", "audit-pagination-qualification") expected_ids = [] for ordinal in range(1, event_count + 1): event = writer.write( "qualification.audit_pagination", "recovery", None, {"ordinal": ordinal, "source": "isolated regression fixture"}, ) assert event.sequence == ordinal expected_ids.append(str(event.id)) session.commit() archive = tmp_path / "audit-pagination.dump" database.archive(archive) database.archive(archive, restore=True) target = parse_target(database.restored_owner.render_as_string(hide_password=False)) with Session(database.runtime) as session: recovery = RecoveryService(session, Settings(_env_file=None, env="test")) recovery.engine = ManagedPostgresTools( base_environment=dict(os.environ), timeout_seconds=60, ) events = list(recovery._restored_audit_events(target)) assert [event.sequence for event in events] == list(range(1, event_count + 1)) assert [event.id for event in events] == expected_ids assert len({event.id for event in events}) == event_count checkpoint = recovery._verify_restored_audit_chain(target) assert checkpoint.event_count == checkpoint.last_sequence == event_count assert checkpoint.last_event_hash == events[-1].event_hash