from __future__ import annotations from typing import TypeVar from sqlalchemy.orm import Session from fastapi import HTTPException, status from app.models.contact import Contact from app.models.customer import Customer from app.models.device import Device from app.models.equipment import Equipment from app.models.location import Location from app.models.validation import Validation from app.repositories.base import Repository from app.repositories.domain import ( ContactRepository, CustomerRepository, DeviceRepository, EquipmentRepository, LocationRepository, ValidationRepository, ) ModelT = TypeVar("ModelT") class CrudService: def __init__(self, repository: Repository[ModelT]) -> None: self.repository = repository def list(self, page: int = 1, page_size: int = 20, search: str | None = None) -> dict: safe_page = max(page, 1) safe_page_size = min(max(page_size, 1), 100) offset = (safe_page - 1) * safe_page_size return { "items": self.repository.list(safe_page_size, offset, search), "total": self.repository.count(search), "page": safe_page, "page_size": safe_page_size, } def create(self, data: dict) -> ModelT: return self.repository.add(self.repository.model(**data)) def update(self, item_id: str, data: dict) -> ModelT: item = self.repository.get(item_id) if item is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Resource not found") for key, value in data.items(): setattr(item, key, value) return item def delete(self, item_id: str) -> None: item = self.repository.get(item_id) if item is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Resource not found") self.repository.delete(item) class DomainServices: def __init__(self, session: Session) -> None: self.customers: CrudService[Customer] = CrudService(CustomerRepository(session)) self.locations: CrudService[Location] = CrudService(LocationRepository(session)) self.contacts: CrudService[Contact] = CrudService(ContactRepository(session)) self.devices: CrudService[Device] = CrudService(DeviceRepository(session)) self.equipment: CrudService[Equipment] = CrudService(EquipmentRepository(session)) self.validations: CrudService[Validation] = CrudService(ValidationRepository(session))