diff --git a/modal_backend/models/db.py b/modal_backend/models/db.py index d5b36a6..cb86916 100644 --- a/modal_backend/models/db.py +++ b/modal_backend/models/db.py @@ -10,8 +10,12 @@ ForeignKey, Integer, String, + cast, + desc, + or_, true, ) +from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.ext.hybrid import hybrid_method from sqlalchemy.orm import Mapped, mapped_column @@ -79,10 +83,30 @@ 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 order_by_start_ts( + self, query: str, asc_order: bool + ) -> UnaryExpression[datetime.datetime] | InstrumentedAttribute: + return getattr(Note, query) if asc_order else desc(getattr(Note, query)) + class NoteResponse(BaseDbModel): __tablename__ = "note_response" diff --git a/modal_backend/routes/notes.py b/modal_backend/routes/notes.py index 1fc2b82..547a9b3 100644 --- a/modal_backend/routes/notes.py +++ b/modal_backend/routes/notes.py @@ -43,12 +43,32 @@ async def get_notes( 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, type_id, limit, offset, groups_id, services_id, status, asc_order + ) 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..57362cc 100644 --- a/modal_backend/utils/services.py +++ b/modal_backend/utils/services.py @@ -11,7 +11,7 @@ class NoteService: """ @classmethod - async def get_note_by_type_id( + async def get_notes_by_filters( cls, db: Session, type_id: int, @@ -22,8 +22,24 @@ async def get_note_by_type_id( status: str, asc_order: bool, ): - # 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)) + ) + + if status == 'active': + notes_query = notes_query.filter(Note.status == "active") + if status == 'archived': + notes_query = notes_query.filter(Note.status == "archived") + + notes_query = notes_query.order_by(Note.order_by_start_ts("start_ts", asc_order)) + notes = notes_query.limit(limit).offset(offset).all() + + if not notes: + raise ObjectNotFound(Note, 'all') + return notes @staticmethod