diff --git a/.gitignore b/.gitignore index ca647527..91500ad2 100644 --- a/.gitignore +++ b/.gitignore @@ -182,4 +182,6 @@ docs/progress/* panel/graphql/generated -test_e2e.db* \ No newline at end of file +test_e2e.db* + +uv.lock \ No newline at end of file diff --git a/resolvers/author.py b/resolvers/author.py index 062abf56..a03f3c47 100644 --- a/resolvers/author.py +++ b/resolvers/author.py @@ -18,7 +18,7 @@ from cache.cache import ( from orm.author import Author, AuthorFollower from orm.community import Community, CommunityAuthor, CommunityFollower from orm.reaction import Reaction -from orm.shout import Shout, ShoutAuthor, ShoutTopic +from orm.shout import Shout, ShoutAuthor, ShoutReactionsFollower, ShoutTopic from orm.topic import Topic from resolvers.stat import get_with_stat from services.auth import login_required @@ -974,12 +974,23 @@ async def get_author_follows( has_access = is_admin or (viewer_id is not None and str(viewer_id) == str(temp_author.id)) followed_authors.append(temp_author.dict(has_access)) + # Получаем подписанные шауты + followed_shouts = [] + with local_session() as session: + shout_followers = ( + session.query(ShoutReactionsFollower).filter(ShoutReactionsFollower.follower == author_id).all() + ) + for sf in shout_followers: + shout = session.query(Shout).filter(Shout.id == sf.shout).first() + if shout: + followed_shouts.append(shout.dict()) + followed_communities = DEFAULT_COMMUNITIES # TODO: get followed communities return { "authors": followed_authors, "topics": followed_topics, "communities": followed_communities, - "shouts": [], + "shouts": followed_shouts, "error": None, } diff --git a/resolvers/notifier.py b/resolvers/notifier.py index ad67e01e..e8d85fbf 100644 --- a/resolvers/notifier.py +++ b/resolvers/notifier.py @@ -16,7 +16,7 @@ from orm.notification import ( NotificationEntity, NotificationSeen, ) -from orm.shout import Shout +from orm.shout import Shout, ShoutReactionsFollower from services.auth import login_required from storage.db import local_session from storage.schema import mutation, query @@ -57,6 +57,37 @@ def query_notifications(author_id: int, after: int = 0) -> tuple[int, int, list[ return total, unread, notifications +def check_subscription(shout_id: int, current_author_id: int) -> bool: + """ + Проверяет подписку пользователя на уведомления о шауте. + + Проверяет наличие записи в ShoutReactionsFollower: + - Запись есть → подписан + - Записи нет → не подписан (отписался или никогда не подписывался) + + Автоматическая подписка (auto=True) создается при: + - Создании поста + - Первом комментарии/реакции + + Отписка = удаление записи из таблицы + + Returns: + bool: True если подписан на уведомления + """ + with local_session() as session: + # Проверяем наличие записи в ShoutReactionsFollower + follow = ( + session.query(ShoutReactionsFollower) + .filter( + ShoutReactionsFollower.follower == current_author_id, + ShoutReactionsFollower.shout == shout_id, + ) + .first() + ) + + return follow is not None + + def group_notification( thread: str, authors: list[Any] | None = None, @@ -118,15 +149,20 @@ def get_notifications_grouped(author_id: int, after: int = 0, limit: int = 10, o if str(notification.entity) == NotificationEntity.SHOUT.value: shout = payload shout_id = shout.get("id") - author_id = shout.get("created_by") + shout_author_id = shout.get("created_by") thread_id = f"shout-{shout_id}" with local_session() as session: - author = session.query(Author).where(Author.id == author_id).first() + author = session.query(Author).where(Author.id == shout_author_id).first() shout = session.query(Shout).where(Shout.id == shout_id).first() if author and shout: + # Проверяем подписку - если не подписан, пропускаем это уведомление + if not check_subscription(shout_id, author_id): + continue + author_dict = author.dict() shout_dict = shout.dict() + group = group_notification( thread_id, shout=shout_dict, @@ -164,6 +200,10 @@ def get_notifications_grouped(author_id: int, after: int = 0, limit: int = 10, o existing_group["reactions"].append(reaction) groups_by_thread[thread_id] = existing_group else: + # Проверяем подписку - если не подписан, пропускаем это уведомление + if not check_subscription(shout_id, author_id): + continue + group = group_notification( thread_id, authors=[author_dict], diff --git a/schema/type.graphql b/schema/type.graphql index 8097a0b9..165e5fd5 100644 --- a/schema/type.graphql +++ b/schema/type.graphql @@ -245,6 +245,7 @@ type AuthorFollowsResult { topics: [Topic] authors: [Author] communities: [Community] + shouts: [Shout] error: String } diff --git a/uv.lock b/uv.lock index d9621001..d93db8ff 100644 --- a/uv.lock +++ b/uv.lock @@ -425,7 +425,7 @@ wheels = [ [[package]] name = "discours-core" -version = "0.9.28" +version = "0.9.32" source = { editable = "." } dependencies = [ { name = "ariadne" },