from __future__ import annotations from dataclasses import dataclass from datetime import UTC, datetime from typing import Any from govoplan_reporting.backend.db.models import ReportingDefinitionRevision @dataclass(frozen=True, slots=True) class ReportingDefinitionRecord: tenant_id: str definition_kind: str definition_id: str definition_key: str revision: int name: str description: str | None status: str visibility: str content_hash: str recorded_at: datetime change_reason: str payload: dict[str, Any] parent_kind: str | None = None parent_id: str | None = None parent_revision: int | None = None def to_dict(self) -> dict[str, Any]: return { "tenant_id": self.tenant_id, "definition_kind": self.definition_kind, "definition_id": self.definition_id, "definition_key": self.definition_key, "revision": self.revision, "name": self.name, "description": self.description, "status": self.status, "visibility": self.visibility, "content_hash": self.content_hash, "parent_kind": self.parent_kind, "parent_id": self.parent_id, "parent_revision": self.parent_revision, "recorded_at": _datetime_text(self.recorded_at), "change_reason": self.change_reason, "payload": dict(self.payload), } def definition_from_row( row: ReportingDefinitionRevision, ) -> ReportingDefinitionRecord: return ReportingDefinitionRecord( tenant_id=row.tenant_id, definition_kind=row.definition_kind, definition_id=row.definition_id, definition_key=row.definition_key, revision=row.revision, name=row.name, description=row.description, status=row.status, visibility=row.visibility, content_hash=row.content_hash, parent_kind=row.parent_kind, parent_id=row.parent_id, parent_revision=row.parent_revision, recorded_at=row.recorded_at, change_reason=row.change_reason, payload=dict(row.payload or {}), ) def _datetime_text(value: datetime) -> str: if value.tzinfo is None: value = value.replace(tzinfo=UTC) return value.isoformat() __all__ = ["ReportingDefinitionRecord", "definition_from_row"]