From a3f1953839acb7821b0118ffd8e9d883bd82b0db Mon Sep 17 00:00:00 2001 From: rifcrat Date: Sun, 19 Apr 2026 17:42:09 +0300 Subject: [PATCH 1/7] fix documentation --- rating_api/routes/comment.py | 29 ++++++++++++----------------- rating_api/routes/lecturer.py | 4 ++++ 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/rating_api/routes/comment.py b/rating_api/routes/comment.py index fc01f0c..34b539e 100644 --- a/rating_api/routes/comment.py +++ b/rating_api/routes/comment.py @@ -39,8 +39,9 @@ @comment.post("", response_model=CommentGet) async def create_comment(lecturer_id: int, comment_info: CommentPost, user=Depends(UnionAuth())) -> CommentGet: """ + Scopes: `["rating.comment.create"]` + Создает комментарий к преподавателю в базе данных RatingAPI - Для создания комментария нужно быть авторизованным """ # Проверяем, что лектор с заданным id существует Lecturer.get(session=db.session, id=lecturer_id) @@ -148,6 +149,7 @@ async def import_comments( ) -> CommentGetAll: """ Scopes: `["rating.comment.import"]` + Создает комментарии в базе данных RatingAPI """ number_of_comments = len(comments_info.comments) @@ -165,6 +167,8 @@ async def import_comments( @comment.get("/{uuid}", response_model=CommentGet) async def get_comment(uuid: UUID, user=Depends(UnionAuth(auto_error=False, allow_none=False))) -> CommentGet: """ + Scopes: `["rating.comment.read"]` + Возвращает комментарий по его UUID в базе данных RatingAPI """ comment: Comment = Comment.query(session=db.session).filter(Comment.uuid == uuid).one_or_none() @@ -301,7 +305,11 @@ async def review_comment( @comment.patch("/{uuid}", response_model=CommentGet) async def update_comment(uuid: UUID, comment_update: CommentUpdate, user=Depends(UnionAuth())) -> CommentGet: - """Позволяет изменить свой неанонимный комментарий""" + """ + Scopes: `["rating.comment.update"]` + + Позволяет изменить свой неанонимный комментарий + """ comment: Comment = Comment.get(session=db.session, id=uuid) # Ошибка, если не найден if comment.user_id != user.get("id") or comment.user_id is None: @@ -358,22 +366,9 @@ async def like_comment( user=Depends(UnionAuth()), ) -> CommentGet: """ - Handles like/dislike reactions for a comment. - - This endpoint allows authenticated users to react to a comment (like/dislike) or change their existing reaction. - If the user has no existing reaction, a new one is created. If the user changes their reaction, it gets updated. - If the user clicks the same reaction again, the reaction is removed. - - Args: - uuid (UUID): The UUID of the comment to react to. - reaction (Reaction): The reaction type (like/dislike). - user (dict): Authenticated user data from UnionAuth dependency. - - Returns: - CommentGet: The updated comment with reactions in CommentGet format. + Scopes: `["rating.comment.write"]` - Raises: - ObjectNotFound: If the comment with given UUID doesn't exist. + Ставит лайк или дизлайк на комментарий по его uuid """ comment = Comment.get(session=db.session, id=uuid) if not comment: diff --git a/rating_api/routes/lecturer.py b/rating_api/routes/lecturer.py index 1a51028..7c9e730 100644 --- a/rating_api/routes/lecturer.py +++ b/rating_api/routes/lecturer.py @@ -212,6 +212,8 @@ async def update_lecturer( ) -> LecturerGet: """ Scopes: `["rating.lecturer.update"]` + + Обновляет данные о преподавателе по его id """ lecturer = Lecturer.get(id, session=db.session) if lecturer is None: @@ -238,6 +240,8 @@ async def delete_lecturer( ): """ Scopes: `["rating.lecturer.delete"]` + + Удаляет из базы данных преподавателя по его id """ check_lecturer = Lecturer.get(session=db.session, id=id) if check_lecturer is None: From 9055a634569280c9fbe1f673e37fd31c04eb18d0 Mon Sep 17 00:00:00 2001 From: rifcrat Date: Mon, 20 Apr 2026 23:33:49 +0300 Subject: [PATCH 2/7] fix documentation --- rating_api/routes/lecturer.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/rating_api/routes/lecturer.py b/rating_api/routes/lecturer.py index 7c9e730..f2d598d 100644 --- a/rating_api/routes/lecturer.py +++ b/rating_api/routes/lecturer.py @@ -35,6 +35,8 @@ async def create_lecturer( Scopes: `["rating.lecturer.create"]` Создает преподавателя в базе данных RatingAPI + + Исключение **AlreadyExists**, если преподаватель с введеным `timetable_id` уже существует """ get_lecturer: Lecturer = ( Lecturer.query(session=db.session).filter(Lecturer.timetable_id == lecturer_info.timetable_id).one_or_none() @@ -95,6 +97,8 @@ async def update_lecturer_rating( async def get_lecturer_by_timetable_id(timetable_id: int) -> LecturerGet: """ Возвращает преподавателя по его timetable_id + + Исключение **ObjectNotFound**, если `timetable_id` не найден """ lecturer: Lecturer = Lecturer.query(session=db.session).filter(Lecturer.timetable_id == timetable_id).one_or_none() if lecturer is None: @@ -112,6 +116,8 @@ async def get_lecturer(id: int, info: list[Literal["comments"]] = Query(default= *QUERY* `info: string` - возможные значения `'comments'`. Если передано `'comments'`, то возвращаются одобренные комментарии к преподавателю. Subject лектора возвращшается либо из базы данных, либо из любого аппрувнутого комментария + + Исключение **ObjectNotFound**, если `id` не найден """ lecturer: Lecturer = Lecturer.query(session=db.session).filter(Lecturer.id == id).one_or_none() if lecturer is None: @@ -168,6 +174,8 @@ async def get_lecturers( `mark` Поле для оценки. Если передано, то возвращает только тех преподавателей, для которых средняя общая оценка ('general_mark') больше, чем переданный 'mark'. + + Исключение **ObjectNotFound**, если преподаватель с введенными параметрами не найден """ lecturers_query = lecturer_filter.filter( Lecturer.query(session=db.session).outerjoin(Lecturer.comments).group_by(Lecturer.id) @@ -214,6 +222,8 @@ async def update_lecturer( Scopes: `["rating.lecturer.update"]` Обновляет данные о преподавателе по его id + + Исключение **ObjectNotFound**, если `id` не найден """ lecturer = Lecturer.get(id, session=db.session) if lecturer is None: @@ -240,8 +250,10 @@ async def delete_lecturer( ): """ Scopes: `["rating.lecturer.delete"]` - + Удаляет из базы данных преподавателя по его id + + Исключение **ObjectNotFound**, если `id` не найден """ check_lecturer = Lecturer.get(session=db.session, id=id) if check_lecturer is None: From 643b72210137688b818a39e9b6878ee33adc4180 Mon Sep 17 00:00:00 2001 From: rifcrat Date: Tue, 21 Apr 2026 00:42:30 +0300 Subject: [PATCH 3/7] fix documentation --- rating_api/routes/comment.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/rating_api/routes/comment.py b/rating_api/routes/comment.py index 34b539e..2a71d0f 100644 --- a/rating_api/routes/comment.py +++ b/rating_api/routes/comment.py @@ -42,6 +42,12 @@ async def create_comment(lecturer_id: int, comment_info: CommentPost, user=Depen Scopes: `["rating.comment.create"]` Создает комментарий к преподавателю в базе данных RatingAPI + + Исключение **TooManyCommentsToLecturer**, если число комментариев превысило лимит + + Исключение **CommentTooLong**, если комментарий слишком длинный + + Исключение **ForbiddenSymbol**, если в комментарии использованы запрещенные символы """ # Проверяем, что лектор с заданным id существует Lecturer.get(session=db.session, id=lecturer_id) @@ -170,6 +176,8 @@ async def get_comment(uuid: UUID, user=Depends(UnionAuth(auto_error=False, allow Scopes: `["rating.comment.read"]` Возвращает комментарий по его UUID в базе данных RatingAPI + + Исключение **ObjectNotFound**, если `uuid` не найден """ comment: Comment = Comment.query(session=db.session).filter(Comment.uuid == uuid).one_or_none() if comment is None: @@ -217,6 +225,10 @@ async def get_comments( `unreviewed` - вернет все непроверенные комментарии, если True. По дефолту False. `asc_order` -Если передано true, сортировать в порядке возрастания. Иначе - в порядке убывания + + Исключение **ObjectNotFound**, если комментарий с введенными параметрами не найден + + Исключение **ForbiddenAction**, если пользователь пытается получить непроверенный комментарий """ comments_query = ( Comment.query(session=db.session) @@ -292,6 +304,8 @@ async def review_comment( `review_status` - возможные значения `approved` - комментарий одобрен и возвращается при запросе лектора `dismissed` - комментарий отклонен, не отображается в запросе лектора + + Исключение **ObjectNotFound**, если `uuid` не найден """ check_comment: Comment = Comment.query(session=db.session).filter(Comment.uuid == uuid).one_or_none() @@ -309,6 +323,10 @@ async def update_comment(uuid: UUID, comment_update: CommentUpdate, user=Depends Scopes: `["rating.comment.update"]` Позволяет изменить свой неанонимный комментарий + + Исключение **ForbiddenAction** при попытке отредактировать чужой комментарий + + Исключение **ForbiddenAction** при попытке отредактировать анонимный комментарий """ comment: Comment = Comment.get(session=db.session, id=uuid) # Ошибка, если не найден @@ -342,6 +360,10 @@ async def delete_comment( Scopes: `["rating.comment.delete"]` Удаляет комментарий по его UUID в базе данных RatingAPI + + Исключение **ObjectNotFound**, если `uuid` не найден + + Исключение **ForbiddenAction** при попытке удалить комментарий пользователем без прав """ comment = Comment.get(uuid, session=db.session) if comment is None: @@ -369,6 +391,8 @@ async def like_comment( Scopes: `["rating.comment.write"]` Ставит лайк или дизлайк на комментарий по его uuid + + Исключение **ObjectNotFound**, если `uuid` не найден """ comment = Comment.get(session=db.session, id=uuid) if not comment: From f6bd430e3469f3638fa0b1f44547f67e46e37e59 Mon Sep 17 00:00:00 2001 From: rifcrat Date: Tue, 21 Apr 2026 00:51:27 +0300 Subject: [PATCH 4/7] fix documentation --- rating_api/routes/comment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rating_api/routes/comment.py b/rating_api/routes/comment.py index 2a71d0f..0301ea6 100644 --- a/rating_api/routes/comment.py +++ b/rating_api/routes/comment.py @@ -226,7 +226,7 @@ async def get_comments( `asc_order` -Если передано true, сортировать в порядке возрастания. Иначе - в порядке убывания - Исключение **ObjectNotFound**, если комментарий с введенными параметрами не найден + Исключение **ObjectNotFound**, если комментарий с введенными параметрами не найден Исключение **ForbiddenAction**, если пользователь пытается получить непроверенный комментарий """ From a214da282af42dc9059bd714595a5cc6aea7c832 Mon Sep 17 00:00:00 2001 From: rifcrat Date: Tue, 21 Apr 2026 00:57:35 +0300 Subject: [PATCH 5/7] fix documentation --- rating_api/routes/lecturer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rating_api/routes/lecturer.py b/rating_api/routes/lecturer.py index f2d598d..c8b108d 100644 --- a/rating_api/routes/lecturer.py +++ b/rating_api/routes/lecturer.py @@ -36,7 +36,7 @@ async def create_lecturer( Создает преподавателя в базе данных RatingAPI - Исключение **AlreadyExists**, если преподаватель с введеным `timetable_id` уже существует + Исключение **AlreadyExists**, если преподаватель с введеным `timetable_id` уже существует """ get_lecturer: Lecturer = ( Lecturer.query(session=db.session).filter(Lecturer.timetable_id == lecturer_info.timetable_id).one_or_none() From c91f6448dccea0388836f993c8c85c10ed58d21e Mon Sep 17 00:00:00 2001 From: rifcrat Date: Wed, 22 Apr 2026 11:40:03 +0300 Subject: [PATCH 6/7] fix documentation --- rating_api/routes/lecturer.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rating_api/routes/lecturer.py b/rating_api/routes/lecturer.py index c8b108d..8200b6d 100644 --- a/rating_api/routes/lecturer.py +++ b/rating_api/routes/lecturer.py @@ -34,7 +34,7 @@ async def create_lecturer( """ Scopes: `["rating.lecturer.create"]` - Создает преподавателя в базе данных RatingAPI + Создает преподавателя в базе данных Исключение **AlreadyExists**, если преподаватель с введеным `timetable_id` уже существует """ @@ -56,7 +56,7 @@ async def update_lecturer_rating( """ Scopes: `["rating.lecturer.update_rating"]` - Обновляет рейтинг преподавателя в базе данных RatingAPI + Обновляет рейтинг преподавателя в базе данных """ updated_lecturers = [] response = { @@ -111,11 +111,11 @@ async def get_lecturer(id: int, info: list[Literal["comments"]] = Query(default= """ Scopes: `["rating.lecturer.read"]` - Возвращает преподавателя по его ID в базе данных RatingAPI + Возвращает преподавателя по его ID в базе данных *QUERY* `info: string` - возможные значения `'comments'`. Если передано `'comments'`, то возвращаются одобренные комментарии к преподавателю. - Subject лектора возвращшается либо из базы данных, либо из любого аппрувнутого комментария + Subject лектора возвращается либо из базы данных, либо из любого аппрувнутого комментария Исключение **ObjectNotFound**, если `id` не найден """ From 9abeab036a634a64944c7a8dff509070d9541c2c Mon Sep 17 00:00:00 2001 From: rifcrat Date: Wed, 22 Apr 2026 12:25:44 +0300 Subject: [PATCH 7/7] fix documentation --- rating_api/routes/comment.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/rating_api/routes/comment.py b/rating_api/routes/comment.py index 0301ea6..dc1021b 100644 --- a/rating_api/routes/comment.py +++ b/rating_api/routes/comment.py @@ -43,7 +43,11 @@ async def create_comment(lecturer_id: int, comment_info: CommentPost, user=Depen Создает комментарий к преподавателю в базе данных RatingAPI - Исключение **TooManyCommentsToLecturer**, если число комментариев превысило лимит + Комментарий создается со статусом PENDING (на модерации) + + Исключение **TooManyCommentRequests**, если число комментариев превысило общий лимит + + Исключение **TooManyCommentsToLecturer**, если число комментариев превысило лимит для лектора Исключение **CommentTooLong**, если комментарий слишком длинный @@ -157,6 +161,8 @@ async def import_comments( Scopes: `["rating.comment.import"]` Создает комментарии в базе данных RatingAPI + + Не выбрасывает исключения """ number_of_comments = len(comments_info.comments) result = CommentGetAll(limit=number_of_comments, offset=number_of_comments, total=number_of_comments) @@ -177,6 +183,8 @@ async def get_comment(uuid: UUID, user=Depends(UnionAuth(auto_error=False, allow Возвращает комментарий по его UUID в базе данных RatingAPI + Если пользователь авторизован, добавляются флаги is_liked/is_disliked (реакция пользователя на комментарий) + Исключение **ObjectNotFound**, если `uuid` не найден """ comment: Comment = Comment.query(session=db.session).filter(Comment.uuid == uuid).one_or_none() @@ -226,6 +234,11 @@ async def get_comments( `asc_order` -Если передано true, сортировать в порядке возрастания. Иначе - в порядке убывания + Разные модели ответа в зависимости от прав пользователя: + CommentGetAllWithAllInfo: для модераторов (со статусом комментария); + CommentGetAllWithStatus: для авторов комментариев (со статусом); + CommentGetAll: для всех остальных (только одобренные комментарии) + Исключение **ObjectNotFound**, если комментарий с введенными параметрами не найден Исключение **ForbiddenAction**, если пользователь пытается получить непроверенный комментарий @@ -305,6 +318,10 @@ async def review_comment( `approved` - комментарий одобрен и возвращается при запросе лектора `dismissed` - комментарий отклонен, не отображается в запросе лектора + Комментарий может быть либо одобрен, либо отклонен + + Отклоненные комментарии не отображаются в обычных GET-запросах(можно посмотреть только через `uuid`) + Исключение **ObjectNotFound**, если `uuid` не найден """ check_comment: Comment = Comment.query(session=db.session).filter(Comment.uuid == uuid).one_or_none() @@ -324,6 +341,8 @@ async def update_comment(uuid: UUID, comment_update: CommentUpdate, user=Depends Позволяет изменить свой неанонимный комментарий + После редактирования комментарий снова отправляется на модерацию + Исключение **ForbiddenAction** при попытке отредактировать чужой комментарий Исключение **ForbiddenAction** при попытке отредактировать анонимный комментарий @@ -361,6 +380,12 @@ async def delete_comment( Удаляет комментарий по его UUID в базе данных RatingAPI + Модератор может удалить любой комментарий + + Обычный пользователь может удалить только свой неанонимный комментарий + + Анонимные комментарии может удалить только модератор + Исключение **ObjectNotFound**, если `uuid` не найден Исключение **ForbiddenAction** при попытке удалить комментарий пользователем без прав @@ -392,6 +417,13 @@ async def like_comment( Ставит лайк или дизлайк на комментарий по его uuid + Дизлайка и лайка не может быть одновременно + + Если реакции от пользователя на этот комментарий не было — создается новая; + Если была противоположная реакция — она заменяется на новую; + Если была такая же реакция — она удаляется; + После операции поля is_liked/is_disliked в ответе отражают итоговое состояние + Исключение **ObjectNotFound**, если `uuid` не найден """ comment = Comment.get(session=db.session, id=uuid)