32feb1b6db
Fixes: - F821: install.py site_url 未定义(NameError)、sync_v2.py os 未导入、script_jobs.py LOG f-string - F401: 移除 22 个未使用导入(models/__init__.py、install.py、auth.py 等) - B904: 20 个 except 块 raise 添加 from e/from None - S110: 20 个有意的 try-except-pass 添加 noqa 注释(SSH清理/DDL幂等/WS断连) - B007: 3 个未使用循环变量重命名(dirs→_dirs、server_id→_server_id) - F541: 3 个无占位符 f-string 修正 - F841: auth.py 未使用 ip_address 变量移除 - S105: auth_service.py Redis key prefix 误报 noqa - B023: script_execution_flush.py 循环变量绑定修复 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
125 lines
5.0 KiB
Python
125 lines
5.0 KiB
Python
"""Nexus — Repository Abstract Interfaces
|
|
Protocol-based interfaces for dependency inversion.
|
|
Concrete implementations in infrastructure/database/.
|
|
"""
|
|
|
|
from typing import Protocol, Optional, List
|
|
from server.domain.models import (
|
|
Server, SyncLog, Script, ScriptExecution, DbCredential,
|
|
Admin, LoginAttempt, Setting, PasswordPreset,
|
|
PushSchedule, PushRetryJob, AuditLog,
|
|
)
|
|
|
|
|
|
class ServerRepository(Protocol):
|
|
"""Server data access abstract interface"""
|
|
|
|
async def get_by_id(self, id: int) -> Optional[Server]: ...
|
|
async def get_by_ids(self, ids: List[int]) -> List[Server]: ...
|
|
async def get_all(self) -> List[Server]: ...
|
|
async def get_by_category(self, category: str) -> List[Server]: ...
|
|
async def get_online(self) -> List[Server]: ...
|
|
async def create(self, server: Server) -> Server: ...
|
|
async def update(self, server: Server) -> Server: ...
|
|
async def delete(self, id: int) -> bool: ...
|
|
async def update_heartbeat(self, id: int, is_online: bool, system_info: str, agent_version: str) -> None: ...
|
|
|
|
|
|
class SyncLogRepository(Protocol):
|
|
"""Sync log data access abstract interface"""
|
|
|
|
async def get_by_server_id(self, server_id: int, limit: int = 50) -> List[SyncLog]: ...
|
|
async def create(self, log: SyncLog) -> SyncLog: ...
|
|
async def update_status(self, id: int, status: str, **kwargs) -> SyncLog: ...
|
|
|
|
|
|
class AdminRepository(Protocol):
|
|
"""Admin user data access abstract interface"""
|
|
|
|
async def get_by_id(self, id: int) -> Optional[Admin]: ...
|
|
async def get_by_username(self, username: str) -> Optional[Admin]: ...
|
|
async def get_by_refresh_token(self, refresh_token: str) -> Optional[Admin]: ...
|
|
async def create(self, admin: Admin) -> Admin: ...
|
|
async def update(self, admin: Admin) -> Admin: ...
|
|
|
|
|
|
class LoginAttemptRepository(Protocol):
|
|
"""Login attempt data access abstract interface"""
|
|
|
|
async def create(self, attempt: LoginAttempt) -> LoginAttempt: ...
|
|
async def count_recent_failures(self, username: str, ip_address: str, minutes: int = 15) -> int: ...
|
|
|
|
|
|
class SettingRepository(Protocol):
|
|
"""System setting data access abstract interface"""
|
|
|
|
async def get(self, key: str) -> Optional[str]: ...
|
|
async def set(self, key: str, value: str) -> Setting: ...
|
|
async def get_all(self) -> List[Setting]: ...
|
|
|
|
|
|
class PasswordPresetRepository(Protocol):
|
|
"""Password preset data access abstract interface"""
|
|
|
|
async def get_by_id(self, id: int) -> Optional[PasswordPreset]: ...
|
|
async def get_all(self) -> List[PasswordPreset]: ...
|
|
async def create(self, preset: PasswordPreset) -> PasswordPreset: ...
|
|
async def delete(self, id: int) -> bool: ...
|
|
|
|
|
|
class PushScheduleRepository(Protocol):
|
|
"""Push schedule data access abstract interface"""
|
|
|
|
async def get_by_id(self, id: int) -> Optional[PushSchedule]: ...
|
|
async def get_all(self) -> List[PushSchedule]: ...
|
|
async def get_enabled(self) -> List[PushSchedule]: ...
|
|
async def create(self, schedule: PushSchedule) -> PushSchedule: ...
|
|
async def update(self, schedule: PushSchedule) -> PushSchedule: ...
|
|
async def delete(self, id: int) -> bool: ...
|
|
|
|
|
|
class PushRetryJobRepository(Protocol):
|
|
"""Push retry job data access abstract interface"""
|
|
|
|
async def get_pending(self, limit: int = 100) -> List[PushRetryJob]: ...
|
|
async def create(self, job: PushRetryJob) -> PushRetryJob: ...
|
|
async def update_status(self, id: int, status: str, **kwargs) -> PushRetryJob: ...
|
|
|
|
|
|
class AuditLogRepository(Protocol):
|
|
"""Audit log data access abstract interface"""
|
|
|
|
async def create(self, log: AuditLog) -> AuditLog: ...
|
|
async def get_recent(self, limit: int = 200) -> List[AuditLog]: ...
|
|
async def get_by_action(self, action: str, limit: int = 50) -> List[AuditLog]: ...
|
|
|
|
|
|
class ScriptRepository(Protocol):
|
|
"""Script library data access abstract interface"""
|
|
|
|
async def get_by_id(self, id: int) -> Optional[Script]: ...
|
|
async def get_all(self) -> List[Script]: ...
|
|
async def get_by_category(self, category: str) -> List[Script]: ...
|
|
async def create(self, script: Script) -> Script: ...
|
|
async def update(self, script: Script) -> Script: ...
|
|
async def delete(self, id: int) -> bool: ...
|
|
|
|
|
|
class ScriptExecutionRepository(Protocol):
|
|
"""Script execution data access abstract interface"""
|
|
|
|
async def get_by_id(self, id: int) -> Optional[ScriptExecution]: ...
|
|
async def create(self, execution: ScriptExecution) -> ScriptExecution: ...
|
|
async def update_status(self, id: int, status: str, results: str) -> Optional[ScriptExecution]: ...
|
|
async def list_recent(
|
|
self, limit: int = 50, offset: int = 0, status: Optional[str] = None,
|
|
) -> tuple[List[ScriptExecution], int]: ...
|
|
|
|
|
|
class DbCredentialRepository(Protocol):
|
|
"""Database credential data access abstract interface"""
|
|
|
|
async def get_by_id(self, id: int) -> Optional[DbCredential]: ...
|
|
async def get_all(self) -> List[DbCredential]: ...
|
|
async def create(self, credential: DbCredential) -> DbCredential: ...
|
|
async def delete(self, id: int) -> bool: ... |