From d68030faca6454f62997c2f8d3622d690e617cab Mon Sep 17 00:00:00 2001 From: Untone Date: Sun, 31 Aug 2025 22:42:21 +0300 Subject: [PATCH] author-stats-fix --- resolvers/author.py | 74 ++++++++++++++++++++++++++++++--------------- schema/type.graphql | 3 +- 2 files changed, 52 insertions(+), 25 deletions(-) diff --git a/resolvers/author.py b/resolvers/author.py index 8369913c..7779dfa9 100644 --- a/resolvers/author.py +++ b/resolvers/author.py @@ -151,6 +151,17 @@ async def get_authors_with_stats( # Базовый запрос для получения авторов base_query = select(Author).where(Author.deleted_at.is_(None)) + # Применяем фильтрацию по параметрам из by + if by: + for key, value in by.items(): + if key != "order" and value is not None: # order обрабатывается отдельно + if hasattr(Author, key): + column = getattr(Author, key) + base_query = base_query.where(column == value) + logger.debug(f"Applied filter: {key} = {value}") + else: + logger.warning(f"Unknown filter field: {key}") + # vars for statistics sorting stats_sort_field = None default_sort_applied = False @@ -753,29 +764,33 @@ async def get_author( if "stat" in cached_author: author_dict["stat"] = cached_author["stat"] - if not author_dict or not author_dict.get("stat"): - # update stat from db using new comprehensive stats - try: - # Используем новый резолвер для получения полной статистики - filter_by: AuthorsBy = {} - if slug: - filter_by["slug"] = slug - elif author_id: - filter_by["id"] = author_id # author_id уже int + # ВСЕГДА используем новый резолвер для получения полной статистики + try: + # Используем новый резолвер для получения полной статистики + filter_by: AuthorsBy = {} + if slug: + filter_by["slug"] = slug + elif author_id: + filter_by["id"] = author_id # author_id уже int - authors_with_stats = await get_authors_with_stats(limit=1, offset=0, by=filter_by) - if authors_with_stats and len(authors_with_stats) > 0: - author_dict = authors_with_stats[0] - # Фильтруем данные согласно правам доступа - if not is_admin: - # Убираем защищенные поля для не-админов - protected_fields = ["email", "phone"] - for field in protected_fields: - author_dict.pop(field, None) - # Кэшируем полные данные для админов - _t = asyncio.create_task(cache_author(author_dict)) - except Exception as e: - logger.error(f"Error getting author stats: {e}") + logger.debug(f"Calling get_authors_with_stats with filter: {filter_by}") + authors_with_stats = await get_authors_with_stats(limit=1, offset=0, by=filter_by) + + if authors_with_stats and len(authors_with_stats) > 0: + author_dict = authors_with_stats[0] + logger.debug(f"Got author with stats: shouts={author_dict.get('stat', {}).get('shouts', 'missing')}") + + # Фильтруем данные согласно правам доступа + if not is_admin: + # Убираем защищенные поля для не-админов + protected_fields = ["email", "phone"] + for field in protected_fields: + author_dict.pop(field, None) + + # Кэшируем полные данные для админов + _t = asyncio.create_task(cache_author(author_dict)) + else: + logger.warning(f"No author found with filter: {filter_by}") # Fallback to basic author data without stats with local_session() as session: if slug: @@ -784,6 +799,17 @@ async def get_author( author = session.query(Author).filter_by(id=author_id).first() if author: author_dict = author.dict(is_admin) + logger.debug(f"Using fallback author dict: {author_dict.get('name', 'unknown')}") + except Exception as e: + logger.error(f"Error getting author stats: {e}") + # Fallback to basic author data without stats + with local_session() as session: + if slug: + author = session.query(Author).filter_by(slug=slug).first() + else: + author = session.query(Author).filter_by(id=author_id).first() + if author: + author_dict = author.dict(is_admin) except ValueError: pass except Exception as exc: @@ -906,11 +932,11 @@ 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)) - # TODO: Get followed communities too + followed_communities = DEFAULT_COMMUNITIES # TODO: get followed communities return { "authors": followed_authors, "topics": followed_topics, - "communities": DEFAULT_COMMUNITIES, + "communities": followed_communities, "shouts": [], "error": None, } diff --git a/schema/type.graphql b/schema/type.graphql index 49e4fb0d..8097a0b9 100644 --- a/schema/type.graphql +++ b/schema/type.graphql @@ -8,8 +8,9 @@ type AuthorStat { # Взаимодействие с другими авторами coauthors: Int # Количество уникальных соавторов followers: Int # Количество подписчиков + authors: Int # Количество авторов, на которых подписан данный автор - # Рейтинговая система # Общий рейтинг (rating_shouts + rating_comments) + # Рейтинговая система rating_shouts: Int # Рейтинг публикаций (сумма реакций LIKE/AGREE/ACCEPT/PROOF/CREDIT минус DISLIKE/DISAGREE/REJECT/DISPROOF) rating_comments: Int # Рейтинг комментариев (реакции на комментарии автора)