Source code for trader.persistence.deployed_versions

"""Repository for `deployed_versions` (issue #30).

A sparse deploy-event log, not a per-invocation timestamp — see
`DeployedVersion`'s docstring for why. `record_if_changed` is the only write;
`latest`/`version_at` are the two reads a future consumer (`tools/
roi_investigation.py`, `trader/replay/`) would use to attribute a historical
row to the code that produced it.
"""

from datetime import datetime

from sqlalchemy import select
from sqlalchemy.orm import Session, sessionmaker

from trader.persistence.models import DeployedVersion

__all__ = ["DeployedVersionRepository"]


[docs] class DeployedVersionRepository: """Writes and reads `deployed_versions`.""" def __init__(self, session_factory: sessionmaker[Session]) -> None: self._session_factory = session_factory
[docs] def latest(self) -> DeployedVersion | None: """The most recently detected version, or `None` if never recorded.""" statement = ( select(DeployedVersion) .order_by(DeployedVersion.detected_at.desc(), DeployedVersion.id.desc()) .limit(1) ) with self._session_factory() as session: return session.scalars(statement).first()
[docs] def record_if_changed( self, git_sha: str, git_ref: str | None, *, now: datetime ) -> bool: """Insert a new row iff `git_sha` differs from the most recent one. Returns whether it inserted. A process running unchanged code across many cycles or invocations must not grow this table on every one of them — only an actual version change is an event worth recording. """ current = self.latest() if current is not None and current.git_sha == git_sha: return False row = DeployedVersion(git_sha=git_sha, git_ref=git_ref, detected_at=now) with self._session_factory() as session: session.add(row) session.commit() return True
[docs] def version_at(self, instant: datetime) -> DeployedVersion | None: """The version in effect at `instant`, or `None` if unrecorded. The row with the greatest `detected_at <= instant` — `None` when `instant` predates every recorded version, which must read as unknown rather than defaulting to the earliest row on file. """ statement = ( select(DeployedVersion) .where(DeployedVersion.detected_at <= instant) .order_by(DeployedVersion.detected_at.desc(), DeployedVersion.id.desc()) .limit(1) ) with self._session_factory() as session: return session.scalars(statement).first()