refactor(topology): introduce TopologyRepository protocol with DTO return types
Replace repo: BaseRepository with a structural TopologyRepository protocol in persistence.py and allocator.py. All read methods now return typed DTOs (TopologySummary, LANRow, DeckyRow, EdgeRow) instead of raw dicts, eliminating silent field-shape regressions across the topology subsystem. TopologySummary gains email_personas and language_default so api_personas.py can continue reading those fields via attribute access. hydrate() converts DTOs to dicts before passing to _backfill_decky_configs, keeping the mutable working-state function dict-based at its boundary. All production callers (router handlers, mutator, CLI, heartbeat) migrated from dict/get access to attribute access. 134 tests pass.
This commit is contained in:
@@ -8,6 +8,7 @@ from typing import Any, Optional
|
||||
from sqlalchemy import asc, select, text, update
|
||||
|
||||
from decnet.web.db.models import TopologyDecky
|
||||
from decnet.web.db.models.topology import DeckyRow
|
||||
from decnet.web.db.sqlmodel_repo._helpers import (
|
||||
_deserialize_json_fields,
|
||||
_serialize_json_fields,
|
||||
@@ -110,7 +111,7 @@ class TopologyDeckiesMixin:
|
||||
|
||||
async def list_topology_deckies(
|
||||
self, topology_id: str
|
||||
) -> list[dict[str, Any]]:
|
||||
) -> list[DeckyRow]:
|
||||
async with self._session() as session:
|
||||
result = await session.execute(
|
||||
select(TopologyDecky)
|
||||
@@ -118,8 +119,10 @@ class TopologyDeckiesMixin:
|
||||
.order_by(asc(TopologyDecky.name))
|
||||
)
|
||||
return [
|
||||
_deserialize_json_fields(
|
||||
r.model_dump(mode="json"), ("services", "decky_config")
|
||||
DeckyRow.model_validate(
|
||||
_deserialize_json_fields(
|
||||
r.model_dump(mode="json"), ("services", "decky_config")
|
||||
)
|
||||
)
|
||||
for r in result.scalars().all()
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user