Source code for app.domain.users.filters

from __future__ import annotations

from typing import (
    TYPE_CHECKING,
    Annotated,
    Any,
    ClassVar,
    Literal,
)

from advanced_alchemy.extensions.fastapi import filters as aa_filters
from pydantic import AwareDatetime, Field

from app.lib.filters import CommonFilters

if TYPE_CHECKING:
    from advanced_alchemy.filters import StatementFilter


[docs] class UserFilters(CommonFilters): """Specific filters for User domain.""" search_fields: ClassVar[set[str]] = {"name", "email"} order_by: Annotated[ Literal["name", "email", "createdAt"], Field(description="Field to order by."), ] = "name" is_active: Annotated[ bool | None, Field(description="Filter by active or inactive status."), ] = None created_before: Annotated[ AwareDatetime | None, Field(description="Filter by created date before this timestamp (ISO 8601 UTC). Example: 2026-03-10T14:00:00Z"), ] = None created_after: Annotated[ AwareDatetime | None, Field(description="Filter by created date after this timestamp (ISO 8601 UTC). Example: 2026-03-10T14:00:00Z"), ] = None @property def aa_technical_filters(self) -> list[StatementFilter]: """Extend base filters with user-specific criteria.""" filters = super().aa_technical_filters if self.created_after or self.created_before: filters.append( aa_filters.OnBeforeAfter( field_name="created_at", on_or_before=self.created_before, on_or_after=self.created_after, ) ) if self.is_active is not None: filters.append(aa_filters.CollectionFilter(field_name="is_active", values=[self.is_active])) return filters def model_post_init(self, context: Any) -> None: """Extend the base cache key with user-specific filter parameters.""" super().model_post_init(context) parts = [] if self.is_active is not None: parts.append(f":{self.is_active}") if self.created_before: parts.append(f":{self.created_before}") if self.created_after: parts.append(f":{self.created_after}") self._cache_key += "".join(parts)