Implement task 006 site config versioning and audit events
This commit is contained in:
@@ -37,6 +37,7 @@ class BackendRepository:
|
||||
self.target_sites = TargetSitesRepository(self)
|
||||
self.articles = ArticlesRepository(self)
|
||||
self.script_config_versions = ScriptConfigVersionsRepository(self)
|
||||
self.script_config_version_events = ScriptConfigVersionAuditEventsRepository(self)
|
||||
self.schema = SchemaRepository(self)
|
||||
|
||||
def setup(self) -> None:
|
||||
@@ -719,6 +720,7 @@ class ScriptConfigVersionsRepository:
|
||||
target_site_id: UUID,
|
||||
version_id: UUID,
|
||||
activated_at: datetime,
|
||||
rollback_target_version_id: UUID | None = None,
|
||||
) -> dict[str, Any]:
|
||||
placeholder = self._repository.placeholder()
|
||||
with self._repository.connection() as connection:
|
||||
@@ -756,13 +758,15 @@ class ScriptConfigVersionsRepository:
|
||||
SET
|
||||
status = {placeholder},
|
||||
activated_at = {placeholder},
|
||||
updated_at = {placeholder}
|
||||
updated_at = {placeholder},
|
||||
rollback_target_version_id = COALESCE({placeholder}, rollback_target_version_id)
|
||||
WHERE id = {placeholder}
|
||||
""",
|
||||
(
|
||||
ScriptConfigVersionStatus.ACTIVE.value,
|
||||
_datetime_value(activated_at),
|
||||
_datetime_value(activated_at),
|
||||
_uuid_value(rollback_target_version_id),
|
||||
str(version_id),
|
||||
),
|
||||
)
|
||||
@@ -795,6 +799,97 @@ class ScriptConfigVersionsRepository:
|
||||
return [_plain_row(row) for row in rows]
|
||||
|
||||
|
||||
class ScriptConfigVersionAuditEventsRepository:
|
||||
def __init__(self, repository: BackendRepository) -> None:
|
||||
self._repository = repository
|
||||
|
||||
def create(
|
||||
self,
|
||||
*,
|
||||
target_site_id: UUID,
|
||||
version_id: UUID,
|
||||
event_type: str,
|
||||
actor_user_id: UUID | None,
|
||||
payload: JsonObject,
|
||||
created_at: datetime,
|
||||
) -> dict[str, Any]:
|
||||
placeholder = self._repository.placeholder()
|
||||
sql = f"""
|
||||
INSERT INTO script_config_version_events (
|
||||
id,
|
||||
target_site_id,
|
||||
version_id,
|
||||
event_type,
|
||||
actor_user_id,
|
||||
payload,
|
||||
created_at
|
||||
)
|
||||
VALUES (
|
||||
{placeholder},
|
||||
{placeholder},
|
||||
{placeholder},
|
||||
{placeholder},
|
||||
{placeholder},
|
||||
{placeholder},
|
||||
{placeholder}
|
||||
)
|
||||
"""
|
||||
params = (
|
||||
str(uuid4()),
|
||||
str(target_site_id),
|
||||
str(version_id),
|
||||
event_type,
|
||||
_uuid_value(actor_user_id),
|
||||
_json_value(payload),
|
||||
_datetime_value(created_at),
|
||||
)
|
||||
with self._repository.connection() as connection:
|
||||
connection.execute(sql, params)
|
||||
|
||||
return self.get(event_type=event_type, target_site_id=target_site_id, version_id=version_id)
|
||||
|
||||
def list_for_site(self, target_site_id: UUID) -> list[dict[str, Any]]:
|
||||
placeholder = self._repository.placeholder()
|
||||
with self._repository.connection() as connection:
|
||||
rows = connection.execute(
|
||||
f"""
|
||||
SELECT id, target_site_id, version_id, event_type, actor_user_id, payload, created_at
|
||||
FROM script_config_version_events
|
||||
WHERE target_site_id = {placeholder}
|
||||
ORDER BY created_at
|
||||
""",
|
||||
(str(target_site_id),),
|
||||
).fetchall()
|
||||
|
||||
return [_script_config_version_event_from_row(row) for row in rows]
|
||||
|
||||
def get(
|
||||
self,
|
||||
*,
|
||||
target_site_id: UUID,
|
||||
version_id: UUID,
|
||||
event_type: str,
|
||||
) -> dict[str, Any]:
|
||||
placeholder = self._repository.placeholder()
|
||||
with self._repository.connection() as connection:
|
||||
row = connection.execute(
|
||||
f"""
|
||||
SELECT id, target_site_id, version_id, event_type, actor_user_id, payload, created_at
|
||||
FROM script_config_version_events
|
||||
WHERE target_site_id = {placeholder}
|
||||
AND version_id = {placeholder}
|
||||
AND event_type = {placeholder}
|
||||
""",
|
||||
(str(target_site_id), str(version_id), event_type),
|
||||
).fetchone()
|
||||
|
||||
if row is None:
|
||||
raise LookupError(
|
||||
f"Script config version event not found: {target_site_id} {version_id} {event_type}"
|
||||
)
|
||||
return _script_config_version_event_from_row(row)
|
||||
|
||||
|
||||
class SchemaRepository:
|
||||
def __init__(self, repository: BackendRepository) -> None:
|
||||
self._repository = repository
|
||||
@@ -920,6 +1015,18 @@ def _workflow_event_from_row(row: Any) -> WorkflowEventSummary:
|
||||
)
|
||||
|
||||
|
||||
def _script_config_version_event_from_row(row: Any) -> dict[str, Any]:
|
||||
return {
|
||||
"id": _row_value(row, "id"),
|
||||
"target_site_id": _row_value(row, "target_site_id"),
|
||||
"version_id": _row_value(row, "version_id"),
|
||||
"event_type": _row_value(row, "event_type"),
|
||||
"actor_user_id": _row_value(row, "actor_user_id"),
|
||||
"payload": _json_from_row(row, "payload"),
|
||||
"created_at": _row_value(row, "created_at"),
|
||||
}
|
||||
|
||||
|
||||
def _plain_row(row: Any) -> dict[str, Any]:
|
||||
if isinstance(row, sqlite3.Row):
|
||||
result = dict(row)
|
||||
|
||||
Reference in New Issue
Block a user