82 lines
2.8 KiB
Python
82 lines
2.8 KiB
Python
"""Data-access helpers for signal source repair service."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from .shared import Optional, SignalSourceRegistry, User, and_, select
|
|
|
|
|
|
class SignalSourceRepairDataAccessMixin:
|
|
"""Database read helpers for repair workflow."""
|
|
|
|
async def _load_registry(
|
|
self,
|
|
*,
|
|
tenant_id: int,
|
|
project_id: int,
|
|
registry_id: int,
|
|
) -> Optional[SignalSourceRegistry]:
|
|
return (
|
|
await self.db.execute(
|
|
select(SignalSourceRegistry)
|
|
.where(
|
|
and_(
|
|
SignalSourceRegistry.tenant_id == int(tenant_id),
|
|
SignalSourceRegistry.project_id == int(project_id),
|
|
SignalSourceRegistry.id == int(registry_id),
|
|
)
|
|
)
|
|
.limit(1)
|
|
)
|
|
).scalar_one_or_none()
|
|
|
|
async def _find_reusable_signal_id(
|
|
self,
|
|
*,
|
|
tenant_id: int,
|
|
project_id: int,
|
|
row: SignalSourceRegistry,
|
|
) -> Optional[int]:
|
|
target_key = self._normalize_identifier_key(row.source_identifier)
|
|
if not target_key:
|
|
return None
|
|
candidates = (
|
|
await self.db.execute(
|
|
select(SignalSourceRegistry)
|
|
.where(
|
|
and_(
|
|
SignalSourceRegistry.tenant_id == int(tenant_id),
|
|
SignalSourceRegistry.project_id == int(project_id),
|
|
SignalSourceRegistry.id != int(row.id),
|
|
SignalSourceRegistry.signal_id.is_not(None),
|
|
)
|
|
)
|
|
.order_by(SignalSourceRegistry.created_at.desc(), SignalSourceRegistry.id.desc())
|
|
.limit(50)
|
|
)
|
|
).scalars().all()
|
|
for candidate in candidates:
|
|
current_key = self._normalize_identifier_key(candidate.source_identifier)
|
|
if current_key and current_key == target_key:
|
|
return self._safe_int(candidate.signal_id)
|
|
for candidate in candidates:
|
|
current_key = self._normalize_identifier_key(candidate.source_identifier)
|
|
if current_key and (
|
|
current_key.endswith(target_key)
|
|
or target_key.endswith(current_key)
|
|
):
|
|
return self._safe_int(candidate.signal_id)
|
|
return None
|
|
|
|
async def _active_user_ids(self, *, tenant_id: int) -> list[int]:
|
|
rows = (
|
|
await self.db.execute(
|
|
select(User.id).where(
|
|
and_(
|
|
User.tenant_id == int(tenant_id),
|
|
User.is_active.is_(True),
|
|
)
|
|
)
|
|
)
|
|
).scalars().all()
|
|
return [int(item) for item in rows if item is not None]
|