refactor(harness): route workflow persistence through repositories

This commit is contained in:
User
2026-07-16 18:01:29 +02:00
parent 259f021313
commit c1cddaa667
30 changed files with 925 additions and 348 deletions
@@ -33,6 +33,8 @@ _ARTIFACT_KEYS = {
"validation_report",
"retrieval_pack",
"cte_tests",
"cte_plan",
"cte_plan_doc",
}
_LOCK_KEY = 8_420_613_069_444_020_731
_RUNTIME_ROLE = "thoth_sessions_runtime"
@@ -278,6 +280,13 @@ class PostgresSessionRepository:
decisions=decisions,
)
def list(self) -> list[SessionSnapshot]:
with self._transaction() as connection:
ids = [row[0] for row in connection.execute(
text("SELECT id FROM thoth_sessions.sessions ORDER BY created_at DESC")
).all()]
return [self.get(session_id) for session_id in ids]
def save_manifest(self, manifest: SessionManifest) -> SessionSnapshot:
self._require_uuid4(manifest.id)
with self._transaction() as connection:
@@ -322,6 +331,17 @@ class PostgresSessionRepository:
{"id": session_id, "key": key, "content": content},
)
def delete_artifact(self, session_id: str, key: str) -> None:
self._require_uuid4(session_id)
self._require_artifact_key(key)
with self._transaction() as connection:
self._lock_session(connection, session_id)
self._require_session(connection, session_id)
connection.execute(
text("DELETE FROM thoth_sessions.session_artifacts WHERE session_id = :id AND artifact_key = :key"),
{"id": session_id, "key": key},
)
def append_decisions(
self, session_id: str, decisions: Sequence[DecisionInput | dict]
) -> list[DecisionRecord]:
@@ -357,6 +377,36 @@ class PostgresSessionRepository:
)
return records
def finalize(self, manifest: SessionManifest, artifacts: dict[str, str]) -> SessionSnapshot:
"""Atomically publish DWH-verified artifacts and the final manifest."""
self._require_uuid4(manifest.id)
for key in artifacts:
self._require_artifact_key(key)
with self._transaction() as connection:
self._lock_session(connection, manifest.id)
self._require_session(connection, manifest.id)
for key, content in artifacts.items():
connection.execute(
text(
"INSERT INTO thoth_sessions.session_artifacts (session_id, artifact_key, content) "
"VALUES (:id, :key, :content) "
"ON CONFLICT (session_id, artifact_key) DO UPDATE "
"SET content = EXCLUDED.content, updated_at = pg_catalog.now()"
),
{"id": manifest.id, "key": key, "content": content},
)
result = connection.execute(
text(
"UPDATE thoth_sessions.sessions "
"SET manifest = CAST(:manifest AS jsonb), updated_at = pg_catalog.now() "
"WHERE id = :id"
),
{"id": manifest.id, "manifest": json.dumps(manifest.model_dump(by_alias=True, mode="json"))},
)
if result.rowcount != 1:
raise SessionError(f"Sessione non trovata: {manifest.id}")
return self.get(manifest.id)
def get_preferences(self) -> dict:
with self._transaction() as connection:
principal_id = self._upsert_principal(connection)