diff --git a/modal_backend/models/db.py b/modal_backend/models/db.py index d5b36a6..0c8f5d8 100644 --- a/modal_backend/models/db.py +++ b/modal_backend/models/db.py @@ -10,8 +10,11 @@ ForeignKey, Integer, String, + cast, + or_, true, ) +from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.ext.hybrid import hybrid_method from sqlalchemy.orm import Mapped, mapped_column @@ -79,10 +82,32 @@ class Note(BaseDbModel): @hybrid_method def search_by_type_id(self, query: int) -> bool: - if not self.query: + if query is None: return true() return Note.type_id == query + @hybrid_method + def search_by_group_ids(self, query: list[int]) -> bool: + if not query: + return true() + group_ids_jsonb = cast(Note.group_ids, JSONB) + return or_(*(group_ids_jsonb.contains([qid]) for qid in query)) + + @hybrid_method + def search_by_service_ids(self, query: list[int]) -> bool: + if not query: + return true() + service_ids_jsonb = cast(Note.service_ids, JSONB) + return or_(*(service_ids_jsonb.contains([qid]) for qid in query)) + + @hybrid_method + def search_by_status(self, status: Optional[str] = None) -> bool: + if status == "active": + return Note.status == "active" + elif status == "archived": + return Note.status == "archived" + return True + class NoteResponse(BaseDbModel): __tablename__ = "note_response" diff --git a/modal_backend/routes/notes.py b/modal_backend/routes/notes.py index 1fc2b82..dcb559b 100644 --- a/modal_backend/routes/notes.py +++ b/modal_backend/routes/notes.py @@ -30,8 +30,6 @@ @note.get("", response_model=list[NoteGet]) async def get_notes( - limit: int = 10, - offset: int = 0, type_id: int = Query(None), groups_id: list[int] = Query(None), services_id: list[int] = Query(None), @@ -40,15 +38,37 @@ async def get_notes( default=None, ), asc_order: bool = False, + limit: int = 10, + offset: int = 0, user=Depends(UnionAuth()), ) -> list[NoteGet]: """ - Получить список модалок по type_id. + Получить список модалок по фильтрам + + `limit` - максимальное количество возвращаемых модалок + + `offset` - смещение, определяющее, с какой по порядку модалки начинать выборку. + Если без смещения возвращается модалка с условным номером N, + то при значении offset = X будет возвращаться модалка с номером N + X + + `status` - возможные значения `"active", "archived"`. + Если передано `'active'` - возвращается список активных модалок + Если передано `'archived'` - возвращается список архивированных модалок + + `type_id` - вернет все модалки конкретного типа по type_id типа + + `groups_id` - вернет все модалки с конкретным groups_id + + `services_id` - вернет все модалки сервиса по id + + `asc_order` -Если передано true, сортировать в порядке возрастания. Иначе - в порядке убывания В случае несуществующего type_id ошибка ObjectNotFound """ - notes = await NoteService.get_note_by_type_id(db, type_id, limit, offset, groups_id, services_id, status, asc_order) + notes = await NoteService.get_notes_by_filters( + db, limit, offset, asc_order, type_id, groups_id, services_id, status + ) return [NoteGet.model_validate(note) for note in notes] diff --git a/modal_backend/utils/services.py b/modal_backend/utils/services.py index 9c21069..2f84558 100644 --- a/modal_backend/utils/services.py +++ b/modal_backend/utils/services.py @@ -11,19 +11,33 @@ class NoteService: """ @classmethod - async def get_note_by_type_id( + async def get_notes_by_filters( cls, db: Session, - type_id: int, limit: int, offset: int, - groups_id: list[int], - services_id: list[int], - status: str, asc_order: bool, + type_id: int = None, + groups_id: list[int] = None, + services_id: list[int] = None, + status: str = None, ): - # add filter logic - notes = Note.query(session=db.session).filter(Note.search_by_type_id(type_id)).limit(limit).offset(offset).all() + notes_query = ( + Note.query(session=db.session) + .filter(Note.search_by_type_id(type_id)) + .filter(Note.search_by_group_ids(groups_id)) + .filter(Note.search_by_service_ids(services_id)) + .filter(Note.search_by_status(status)) + ) + + order_expr = Note.start_ts.asc() if asc_order else Note.start_ts.desc() + notes_query = notes_query.order_by(order_expr) + + notes = notes_query.limit(limit).offset(offset).all() + + if not notes: + raise ObjectNotFound(Note, 'all') + return notes @staticmethod