refactor: mixins for services

This commit is contained in:
2025-09-08 10:59:06 +04:00
parent 67634836dc
commit d73748deab
16 changed files with 207 additions and 205 deletions

84
services/mixins.py Normal file
View File

@ -0,0 +1,84 @@
from typing import Generic
from fastapi import HTTPException
from repositories.mixins import *
from schemas.base_crud import *
RepositoryMixin = TypeVar("RepositoryMixin")
EntityType = TypeVar("EntityType")
SchemaType = TypeVar("SchemaType", bound=BaseSchema)
UpdateRequestType = TypeVar("UpdateRequestType", bound=BaseSchema)
CreateRequestType = TypeVar("CreateRequestType", bound=BaseSchema)
class ServiceBaseMixin(Generic[RepositoryMixin]):
repository: RepositoryMixin
class ServiceCreateMixin(
Generic[EntityType, CreateRequestType, SchemaType],
ServiceBaseMixin[RepCreateMixin | RepGetByIdMixin],
):
entity_created_msg = "Entity created"
schema_class: type[SchemaType]
async def create(self, request: CreateRequestType) -> BaseCreateResponse:
entity_id = await self.repository.create(request.entity)
entity = await self.repository.get_by_id(entity_id)
return BaseCreateResponse(
entity=self.schema_class.model_validate(entity),
message=self.entity_created_msg,
)
class ServiceGetAllMixin(
ServiceBaseMixin[RepGetAllMixin],
Generic[EntityType, SchemaType],
):
schema_class: type[SchemaType]
async def get_all(self, *args) -> BaseGetAllResponse[SchemaType]:
entities = await self.repository.get_all(*args)
return BaseGetAllResponse[SchemaType](
items=[self.schema_class.model_validate(entity) for entity in entities]
)
class ServiceUpdateMixin(
ServiceBaseMixin[RepUpdateMixin | RepGetByIdMixin],
Generic[EntityType, UpdateRequestType],
):
entity_not_found_msg = "Entity not found"
entity_updated_msg = "Entity updated"
async def update(
self, entity_id: int, request: UpdateRequestType
) -> BaseUpdateResponse:
entity = await self.repository.get_by_id(entity_id)
if not entity:
raise HTTPException(status_code=404, detail=self.entity_not_found_msg)
await self.repository.update(entity, request.entity)
return BaseUpdateResponse(message=self.entity_updated_msg)
class ServiceDeleteMixin(
ServiceBaseMixin[RepDeleteMixin | RepGetByIdMixin],
Generic[EntityType],
):
entity_not_found_msg = "Entity not found"
entity_deleted_msg = "Entity deleted"
async def is_soft_delete(self, entity: EntityType) -> bool:
return hasattr(entity, "is_deleted")
async def delete(self, entity_id: int) -> BaseDeleteResponse:
entity = await self.repository.get_by_id(entity_id)
if not entity:
raise HTTPException(status_code=404, detail=self.entity_not_found_msg)
is_soft = await self.is_soft_delete(entity)
await self.repository.delete(entity, is_soft)
return BaseDeleteResponse(message=self.entity_deleted_msg)