This commit is contained in:
2024-11-20 23:59:11 +03:00
parent a9d181db8f
commit 79f7c914d7
6 changed files with 342 additions and 29 deletions

94
docs/follower.md Normal file
View File

@@ -0,0 +1,94 @@
# Following System
## Overview
System supports following different entity types:
- Authors
- Topics
- Communities
- Shouts (Posts)
## GraphQL API
### Mutations
#### follow
Follow an entity (author/topic/community/shout).
**Parameters:**
- `what: String!` - Entity type (`AUTHOR`, `TOPIC`, `COMMUNITY`, `SHOUT`)
- `slug: String` - Entity slug
- `entity_id: Int` - Optional entity ID
**Returns:**
```typescript
{
authors?: Author[] // For AUTHOR type
topics?: Topic[] // For TOPIC type
communities?: Community[] // For COMMUNITY type
shouts?: Shout[] // For SHOUT type
error?: String // Error message if any
}
```
#### unfollow
Unfollow an entity.
**Parameters:** Same as `follow`
**Returns:** Same as `follow`
### Queries
#### get_shout_followers
Get list of users who reacted to a shout.
**Parameters:**
- `slug: String` - Shout slug
- `shout_id: Int` - Optional shout ID
**Returns:**
```typescript
Author[] // List of authors who reacted
```
## Caching System
### Supported Entity Types
- Authors: `cache_author`, `get_cached_follower_authors`
- Topics: `cache_topic`, `get_cached_follower_topics`
- Communities: No cache
- Shouts: No cache
### Cache Flow
1. On follow/unfollow:
- Update entity in cache
- Update follower's following list
2. Cache is updated before notifications
## Notifications
- Sent when author is followed/unfollowed
- Contains:
- Follower info
- Author ID
- Action type ("follow"/"unfollow")
## Error Handling
- Unauthorized access check
- Entity existence validation
- Duplicate follow prevention
- Full error logging
- Transaction safety with `local_session()`
## Database Schema
### Follower Tables
- `AuthorFollower`
- `TopicFollower`
- `CommunityFollower`
- `ShoutReactionsFollower`
Each table contains:
- `follower` - ID of following user
- `{entity_type}` - ID of followed entity

View File

@@ -1,23 +1,80 @@
## Reader resolvers
# Система загрузки публикаций
### load_shouts_by
## Особенности реализации
Если graphql запрос содержит ожидаемые поля `stat`, `authors` или `topics`, то будут выполнены дополнительные подзапросы.
### Базовый запрос
- Автоматически подгружает основного автора
- Добавляет основную тему публикации
- Поддерживает гибкую систему фильтрации
- Оптимизирует запросы на основе запрошенных полей
#### Параметры
### Статистика
- Подсчёт лайков/дислайков
- Количество комментариев
- Дата последней реакции
- Статистика подгружается только при запросе поля `stat`
- `filters` - словарь с фильтрами
- `featured` - фильтрует публикации, одобренные для показа на главной, по умолчанию не применяется
- `topics` - список идентификаторов тем, по умолчанию не применяется
- `authors` - список идентификаторов авторов, по умолчанию не применяется
- `after` - unixtime после которого будут выбраны публикации, по умолчанию не применяется
- `layouts` - список идентификаторов форматов, по умолчанию не применяется
- `order_by` может быть `rating`, `comments_count`, `last_reacted_at`. По умолчанию применяется сортировка по `published_at`
- `order_by_desc` определяет порядок сортировки, по умолчанию применяется `desc`
- `offset` и `limit` определяют смещение и ограничение, по умолчанию `0` и `10`
### Оптимизация производительности
- Ленивая загрузка связанных данных
- Кэширование результатов на 5 минут
- Пакетная загрузка авторов и тем
- Использование подзапросов для сложных выборок
### load_shouts_feed, load_shouts_followed, load_shouts_followed_by, load_shouts_discussed, load_shouts_reacted
## Типы лент
Параметры аналогичны `load_shouts_by`, но применяются дополнительные фильтры:
### Случайные топовые посты (load_shouts_random_top)
**Преимущества:**
- Разнообразный контент
- Быстрая выборка из кэша топовых постов
- Настраиваемый размер пула для выборки
- `reacted` - фильтр наличия реакции пользователя
**Ограничения:**
- Обновление раз в 5 минут
- Максимальный размер пула: 100 постов
- Учитываются только лайки/дислайки (без комментариев)
### Неоцененные посты (load_shouts_unrated)
**Преимущества:**
- Помогает найти новый контент
- Равномерное распределение оценок
- Случайный порядок выдачи
**Ограничения:**
- Только посты с менее чем 3 реакциями
- Не учитываются комментарии
- Без сортировки по рейтингу
### Закладки (load_shouts_bookmarked)
**Преимущества:**
- Персонализированная выборка
- Быстрый доступ к сохраненному
- Поддержка всех фильтров
**Ограничения:**
- Требует авторизации
- Ограничение на количество закладок
- Кэширование отключено
## Важные моменты
### Пагинация
- Стандартный размер страницы: 10
- Максимальный размер: 100
- Поддержка курсор-пагинации
### Кэширование
- TTL: 5 минут
- Инвалидация при изменении поста
- Отдельный кэш для каждого типа сортировки
### Сортировка
- По рейтингу (лайки минус дислайки)
- По количеству комментариев
- По дате последней реакции
- По дате публикации (по умолчанию)
### Безопасность
- Проверка прав доступа
- Фильтрация удаленного контента
- Защита от SQL-инъекций
- Валидация входных данных

82
docs/rating.md Normal file
View File

@@ -0,0 +1,82 @@
# Rating System
## GraphQL Resolvers
### Queries
#### get_my_rates_shouts
Get user's reactions (LIKE/DISLIKE) for specified posts.
**Parameters:**
- `shouts: [Int!]!` - array of shout IDs
**Returns:**
```typescript
[{
shout_id: Int
my_rate: ReactionKind // LIKE or DISLIKE
}]
```
#### get_my_rates_comments
Get user's reactions (LIKE/DISLIKE) for specified comments.
**Parameters:**
- `comments: [Int!]!` - array of comment IDs
**Returns:**
```typescript
[{
comment_id: Int
my_rate: ReactionKind // LIKE or DISLIKE
}]
```
### Mutations
#### rate_author
Rate another author (karma system).
**Parameters:**
- `rated_slug: String!` - author's slug
- `value: Int!` - rating value (positive/negative)
## Rating Calculation
### Author Rating Components
#### Shouts Rating
- Calculated from LIKE/DISLIKE reactions on author's posts
- Each LIKE: +1
- Each DISLIKE: -1
- Excludes deleted reactions
- Excludes comment reactions
#### Comments Rating
- Calculated from LIKE/DISLIKE reactions on author's comments
- Each LIKE: +1
- Each DISLIKE: -1
- Only counts reactions to COMMENT type reactions
- Excludes deleted reactions
#### Legacy Karma
- Based on direct author ratings via `rate_author` mutation
- Stored in `AuthorRating` table
- Each positive rating: +1
- Each negative rating: -1
### Helper Functions
- `count_author_comments_rating()` - Calculate comment rating
- `count_author_shouts_rating()` - Calculate posts rating
- `get_author_rating_old()` - Get legacy karma rating
- `get_author_rating_shouts()` - Get posts rating (optimized)
- `get_author_rating_comments()` - Get comments rating (optimized)
- `add_author_rating_columns()` - Add rating columns to author query
## Notes
- All ratings exclude deleted content
- Reactions are unique per user/content
- Rating calculations are optimized with SQLAlchemy
- System supports both direct author rating and content-based rating