make refactor (easy, simpler, DRY, KISS, reduce dublications) for this code: backend/app/base/repo/base_repo.py:

from app.base.model.base_model import BaseModel as BaseAlchemyModel
from app.base.utils import get_current_datetime

T = TypeVar("T", bound=BaseAlchemyModel)


class BaseRepo(Generic[T,]):
    def __init__(self, model: Type[T]):
        self.model = model

    async def _commit_and_refresh(self, db: AsyncSession, instance: T):
        try:
            await db.commit()
            await db.refresh(instance)
        except Exception as e:
            await db.rollback()
            logger.error(f"Transaction rolled back. Error: {e}", exc_info=True)
            raise

    async def _get_by_field(
        self,
        db: AsyncSession,
        field: str,
        value: Any,
        get_deleted: bool = False,
    ) -> T | None:
        filters = [getattr(self.model, field) == value]
        if not get_deleted:
            filters.append(self.model.enabled.is_(True))
        stmt = select(self.model).where(*filters)
        result = await db.execute(stmt)
        return result.scalars().first()

    async def create(self, db: AsyncSession, data: dict) -> T:
        new_item = self.model(**data)
        db.add(new_item)
        await self._commit_and_refresh(db, new_item)
        return new_item

    async def get_by_id(
        self,
        db: AsyncSession,
        id: int,
        get_deleted: bool = False,
    ) -> T | None:
        return await self._get_by_field(db, "id", id, get_deleted)

    async def get_by_uuid(
        self,
        db: AsyncSession,
        uuid: UUID,
        include_relations: bool = False,
        relation_model: Type[BaseAlchemyModel] | None = None,
    ) -> T | None:
        stmt = select(self.model).where(
            self.model.uuid == uuid,
            self.model.enabled.is_(True),
        )
        if include_relations and relation_model:
            relationships = [
                attr
                for attr in dir(self.model)
                if isinstance(
                    getattr(self.model, attr).property,
                    RelationshipProperty,
                )
                and getattr(self.model, attr).property.mapper.class_
                == relation_model
            ]
            for rel in relationships:
                stmt = stmt.options(selectinload(getattr(self.model, rel)))
        result = await db.execute(stmt)
        return result.scalars().first()

    async def get_id_by_uuid(
        self,
        db: AsyncSession,
        uuid: UUID,
        get_deleted: bool = False,
    ) -> int | None:
        return await self._get_by_field(db, "uuid", uuid, get_deleted)

    async def get_uuid_by_id(
        self,
        db: AsyncSession,
        id: int,
        get_deleted: bool = False,
    ) -> UUID | None:
        return await self._get_by_field(db, "id", id, get_deleted)

    async def get_by_name(self, db: AsyncSession, name: str) -> T | None:
        return await self._get_by_field(db, "name", name)

    async def update(
        self,
        db: AsyncSession,
        id: int,
        data: dict,
    ) -> T | None:
        data["updated_at"] = get_current_datetime()
        stmt = (
            update(self.model)
            .where(
                self.model.id == id,
            )
            .values(**data)
            .returning(self.model)
        )
        result = await db.execute(stmt)
        instance = result.scalars().first()
        if instance:
            await self._commit_and_refresh(db, instance)
        return instance

    async def soft_delete(self, db: AsyncSession, id: int) -> T | None:
        stmt = (
            update(self.model)
            .where(self.model.id == id, self.model.enabled.is_(True))
            .values(deleted_at=get_current_datetime(), enabled=False)
            .returning(self.model)
        )
        result = await db.execute(stmt)
        instance = result.scalars().first()
        if instance:
            await self._commit_and_refresh(db, instance)
        return instance

    async def hard_delete(self, db: AsyncSession, id: int) -> bool:
        stmt = delete(self.model).where(self.model.id == id)
        result = await db.execute(stmt)
        await db.commit()
        return result.rowcount > 0

    async def get_multi(
        self,
        db: AsyncSession,
        *,
        skip: int = 0,
        limit: int = 100,
        filter_by: dict[str, Any] | None = None,
        order_by: list[str] | None = None,
    ) -> Sequence[T]:
        stmt = select(self.model).where(self.model.enabled.is_(True))
        if filter_by:
            stmt = stmt.filter(self._build_filters(filter_by))
        if order_by:
            stmt = stmt.order_by(
                *[
                    getattr(self.model, field[1:]).desc()
                    if field.startswith("-")
                    else getattr(self.model, field).asc()
                    for field in order_by
                ],
            )
        stmt = stmt.offset(skip).limit(limit)
        result = await db.execute(stmt)
        return result.scalars().all()

    async def count(
        self,
        db: AsyncSession,
        filter_by: dict[str, Any] | None = None,
    ) -> int:
        stmt = (
            select(func.count())
            .select_from(self.model)
            .where(self.model.enabled.is_(True))
        )
        if filter_by:
            stmt = stmt.filter(self._build_filters(filter_by))
        result = await db.execute(stmt)
        return result.scalar_one()

    async def exists(self, db: AsyncSession, id: int) -> bool:
        return await self._get_by_field(db, "id", id) is not None

    async def get_or_create(
        self,
        db: AsyncSession,
        defaults: dict[str, Any] | None = None,
        **kwargs,
    ) -> Tuple[T, bool]:
        instance = await self.get_by_filters(db, **kwargs)
        if instance:
            return instance, False
        if defaults:
            kwargs.update(defaults)
        new_instance = await self.create(db, kwargs)
        return new_instance, True

    async def update_or_create(
        self,
        db: AsyncSession,
        defaults: dict[str, Any] | None = None,
        **kwargs,
    ) -> Tuple[T, bool]:
        # Use only the unique criteria for filtering in get_by_filters
        unique_criteria = {
            k: v
            for k, v in kwargs.items()
            if k in self.model.__table__.primary_key.columns
        }
        instance = await self.get_by_filters(db, **unique_criteria)
        if instance:
            update_data = {**defaults, **kwargs} if defaults else kwargs
            for key, value in update_data.items():
                if hasattr(instance, key):
                    setattr(instance, key, value)
            await self._commit_and_refresh(db, instance)
            return instance, False
        new_instance = await self.create(
            db,
            {**defaults, **kwargs} if defaults else kwargs,
        )
        return new_instance, True

    async def get_by_filters(self, db: AsyncSession, **kwargs) -> T | None:
        stmt = select(self.model).where(self.model.enabled.is_(True))
        for key, value in kwargs.items():
            stmt = stmt.filter(
                getattr(self.model, key)
                == (value.value if isinstance(value, Enum) else value),
            )
        result = await db.execute(stmt)
        instance = result.scalars().first()
        logger.debug(
            f"{'Found' if instance else 'No'} instance found matching filters: {kwargs}",
        )
        return instance

    def _build_filters(self, filter_by: dict) -> BinaryExpression:
        if "or_" in filter_by:
            return or_(*[self._build_filters(f) for f in filter_by["or_"]])
        if "and_" in filter_by:
            return and_(*[self._build_filters(f) for f in filter_by["and_"]])
        return and_(
            *[
                self._build_filter(key, value)
                for key, value in filter_by.items()
            ],
        )

    def _build_filter(self, key: str, value: Any) -> BinaryExpression:
        if isinstance(value, dict):
            op = list(value.keys())[0]
            if op == "like":
                return getattr(self.model, key).like(value[op])
            elif op == "lt":
                return (
                    func.date(getattr(self.model, key))
                    < func.date(bindparam(key, value[op]))
                    if isinstance(getattr(self.model, key).type, Date)
                    else getattr(self.model, key) < bindparam(key, value[op])
                )
            # Add more operators as needed
        return getattr(self.model, key) == value