diff --git a/CHANGELOG.md b/CHANGELOG.md index 1360017a..8d20ca18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +#### [0.4.8] +- `Reaction.deleted_at` filter on `update_reaction` resolver added +- `triggers` module updated with `after_shout_handler`, `after_reaction_handler` for cache revalidation + #### [0.4.7] - `get_my_rates_shouts` resolver added with: - `shout_id` and `my_rate` fields in response diff --git a/cache/triggers.py b/cache/triggers.py index 937ee82e..e92bb12e 100644 --- a/cache/triggers.py +++ b/cache/triggers.py @@ -2,7 +2,7 @@ from sqlalchemy import event from cache.revalidator import revalidation_manager from orm.author import Author, AuthorFollower -from orm.reaction import Reaction +from orm.reaction import Reaction, ReactionKind from orm.shout import Shout, ShoutAuthor, ShoutReactionsFollower from orm.topic import Topic, TopicFollower from utils.logger import root_logger as logger @@ -43,6 +43,39 @@ def after_follower_handler(mapper, connection, target, is_delete=False): revalidation_manager.mark_for_revalidation(target.follower, "authors") +def after_shout_handler(mapper, connection, target): + """Обработчик изменения статуса публикации""" + if not isinstance(target, Shout): + return + + # Проверяем изменение статуса публикации + was_published = target.published_at is not None and target.deleted_at is None + + if was_published: + # Обновляем счетчики для авторов + for author in target.authors: + revalidation_manager.mark_for_revalidation(author.id, "authors") + + # Обновляем счетчики для тем + for topic in target.topics: + revalidation_manager.mark_for_revalidation(topic.id, "topics") + + +def after_reaction_handler(mapper, connection, target): + """Обработчик для комментариев""" + if not isinstance(target, Reaction) or target.kind != ReactionKind.COMMENT.value: + return + + # Проверяем что комментарий относится к опубликованному посту + shout = target.shout + if shout and shout.published_at and not shout.deleted_at: + # Обновляем счетчики для автора комментария + revalidation_manager.mark_for_revalidation(target.created_by.id, "authors") + + # Обновляем счетчики для поста + revalidation_manager.mark_for_revalidation(shout.id, "shouts") + + def events_register(): """Регистрация обработчиков событий для всех сущностей.""" event.listen(ShoutAuthor, "after_insert", mark_for_revalidation) @@ -64,6 +97,9 @@ def events_register(): event.listen(Reaction, "after_update", mark_for_revalidation) event.listen(Author, "after_update", mark_for_revalidation) event.listen(Topic, "after_update", mark_for_revalidation) - event.listen(Shout, "after_update", mark_for_revalidation) + event.listen(Shout, "after_update", after_shout_handler) + + event.listen(Reaction, "after_insert", after_reaction_handler) + event.listen(Reaction, "after_delete", after_reaction_handler) logger.info("Event handlers registered successfully.") diff --git a/pyproject.toml b/pyproject.toml index 9bd7df02..66d9736f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "core" -version = "0.4.7" +version = "0.4.8" description = "core module for discours.io" authors = ["discoursio devteam"] license = "MIT" diff --git a/resolvers/stat.py b/resolvers/stat.py index 5372732b..d149aef1 100644 --- a/resolvers/stat.py +++ b/resolvers/stat.py @@ -100,10 +100,7 @@ def add_author_stat_columns(q): def get_topic_shouts_stat(topic_id: int) -> int: """ - Получает количество публикаций для указанной темы. - - :param topic_id: Идентификатор темы. - :return: Количество уникальных публикаций для темы. + Получает количество опубликованных постов для темы """ q = ( select(func.count(distinct(ShoutTopic.shout))) @@ -116,7 +113,7 @@ def get_topic_shouts_stat(topic_id: int) -> int: ) ) ) - # Выполнение запроса и получение результата + with local_session() as session: result = session.execute(q).first() return result[0] if result else 0 @@ -198,10 +195,7 @@ def get_topic_comments_stat(topic_id: int) -> int: def get_author_shouts_stat(author_id: int) -> int: """ - Получает количество публикаций для указанного автора. - - :param author_id: Идентификатор автора. - :return: Количество уникальных публикаций автора. + Получает количество опубликованных постов для автора """ aliased_shout_author = aliased(ShoutAuthor) aliased_shout = aliased(Shout) @@ -214,6 +208,7 @@ def get_author_shouts_stat(author_id: int) -> int: and_( aliased_shout_author.author == author_id, aliased_shout.published_at.is_not(None), + aliased_shout.deleted_at.is_(None) # Добавляем проверку на удаление ) ) )