- Added hierarchical comments pagination:
- Created new GraphQL query
load_comments_branch
for efficient loading of hierarchical comments - Ability to load root comments with their first N replies
- Added pagination for both root and child comments
- Using existing
commented
field inStat
type to display number of replies - Added special
first_replies
field to store first replies to a comment - Optimized SQL queries for efficient loading of comment hierarchies
- Implemented flexible comment sorting system (by time, rating)
- Created new GraphQL query
- Upgraded caching system described
docs/caching.md
- Module
cache/memorycache.py
removed - Enhanced caching system with backward compatibility:
- Unified cache key generation with support for existing naming patterns
- Improved Redis operation function with better error handling
- Updated precache module to use consistent Redis interface
- Integrated revalidator with the invalidation system for better performance
- Added comprehensive documentation for the caching system
- Enhanced cached_query to support template-based cache keys
- Standardized error handling across all cache operations
- Optimized cache invalidation system:
- Added targeted invalidation for individual entities (authors, topics)
- Improved revalidation manager with individual object processing
- Implemented batched processing for high-volume invalidations
- Reduced Redis operations by using precise key invalidation instead of prefix-based wipes
- Added special handling for slug changes in topics
- Unified caching system for all models:
- Implemented abstract functions
cache_data
,get_cached_data
andinvalidate_cache_by_prefix
- Added
cached_query
function for unified approach to query caching - Updated resolvers
author.py
andtopic.py
to use the new caching API - Improved logging for cache operations to simplify debugging
- Optimized Redis memory usage through key format unification
- Implemented abstract functions
- Improved caching and sorting in Topic and Author modules:
- Added support for dictionary sorting parameters in
by
for both modules - Optimized cache key generation for stable behavior with various parameters
- Enhanced sorting logic with direction support and arbitrary fields
- Added
by
parameter support in the API for getting topics by community
- Added support for dictionary sorting parameters in
- Performance optimizations for author-related queries:
- Added SQLAlchemy-managed indexes to
Author
,AuthorFollower
,AuthorRating
andAuthorBookmark
models - Implemented persistent Redis caching for author queries without TTL (invalidated only on changes)
- Optimized author retrieval with separate endpoints:
get_authors_all
- returns all non-deleted authors without statisticsload_authors_by
- optimized to use caching and efficient sorting and pagination
- Improved SQL queries with optimized JOIN conditions and efficient filtering
- Added pre-aggregation of statistics (shouts count, followers count) in single efficient queries
- Implemented robust cache invalidation on author updates
- Created necessary indexes for author lookups by user ID, slug, and timestamps
- Added SQLAlchemy-managed indexes to
- Significant performance improvements for topic queries:
- Added database indexes to optimize JOIN operations
- Implemented persistent Redis caching for topic queries (no TTL, invalidated only on changes)
- Optimized topic retrieval with separate endpoints for different use cases:
get_topics_all
- returns all topics without statistics for lightweight listingget_topics_by_community
- adds pagination and optimized filtering by community
- Added SQLAlchemy-managed indexes directly in ORM models for automatic schema maintenance
- Created
sync_indexes()
function for automatic index synchronization during app startup - Reduced database load by pre-aggregating statistics in optimized SQL queries
- Added robust cache invalidation on topic create/update/delete operations
- Improved query optimization with proper JOIN conditions and specific partial indexes
- Fixed Topic objects serialization error in cache/memorycache.py
- Improved CustomJSONEncoder to support SQLAlchemy models with dict() method
- Enhanced error handling in cache_on_arguments decorator
- Modified
load_reactions_by
to include deleted reactions wheninclude_deleted=true
for proper comment tree building - Fixed featured/unfeatured logic in reaction processing:
- Dislike reactions now properly take precedence over likes
- Featured status now requires more than 4 likes from users with featured articles
- Removed unnecessary filters for deleted reactions since rating reactions are physically deleted
- Author's featured status now based on having non-deleted articles with featured_at
delete_reaction
detects comments and usesdeleted_at
updatecheck_to_unfeature
etc. update- dogpile dep in
services/memorycache.py
optimized
create_draft
resolver requires draft_id fixedcreate_draft
resolver defaults body and title fields to empty string
Shout.draft
field addedDraft
entity addedcreate_draft
,update_draft
,delete_draft
mutations and resolvers addedcreate_shout
,update_shout
,delete_shout
mutations removed from GraphQL APIload_drafts
resolver implementedpublish_
andunpublish_
mutations and resolvers addedcreate_
,update_
,delete_
mutations and resolvers added forDraft
entity- tests with pytest for original auth, shouts, drafts
Dockerfile
andpyproject.toml
removed for the simplicity:Procfile
andrequirements.txt
Reaction.deleted_at
filter onupdate_reaction
resolver addedtriggers
module updated withafter_shout_handler
,after_reaction_handler
for cache revalidationafter_shout_handler
,after_reaction_handler
now also handledeleted_at
fieldget_cached_topic_followers
fixedget_my_rates_comments
fixed
get_my_rates_shouts
resolver added with:shout_id
andmy_rate
fields in response- filters by
Reaction.deleted_at.is_(None)
- filters by
Reaction.kind.in_([ReactionKind.LIKE.value, ReactionKind.DISLIKE.value])
- filters by
Reaction.reply_to.is_(None)
- uses
local_session()
context manager - returns empty list on errors
- SQLAlchemy syntax updated:
select()
statement fixed for newer versionsReaction
model direct selection instead of labeled columns- proper row access with
row[0].shout
androw[0].kind
- GraphQL resolver fixes:
- added root parameter
_
to match schema - proper async/await handling with
@login_required
- error logging added via
logger.error()
- added root parameter
- login_accepted decorator added
docs
added- optimized and unified
load_shouts_*
resolvers withLoadShoutsOptions
load_shouts_bookmarked
resolver fixed- resolvers updates:
- new resolvers group
feed
load_shouts_authored_by
resolver addedload_shouts_with_topic
resolver addedload_shouts_followed
removedload_shouts_random_topic
removedget_topics_random
removed
- new resolvers group
- model updates:
ShoutsOrderBy
enum addedShout.main_topic
fromShoutTopic.main
asTopic
type outputShout.created_by
asAuthor
type output
bookmark_shout
mutation resolver addedload_shouts_bookmarked
resolver addedget_communities_by_author
resolver addedget_communities_all
resolver fixedCommunity
stats in ormCommunity
CUDL resolvers addedReaction
filter byReaction.kind
sReactionSort
enum addedCommunityFollowerRole
enum addedInviteStatus
enum addedTopic.parents
ids addedget_shout
resolver accepts slug or shout_id
followers_stat
removed for shout- sqlite3 support added
rating_stat
andcommented_stat
fixes
- cache reimplemented
- load shouts queries unified
followers_stat
removed from shout
- reactions load resolvers separated for ratings (no stats) and comments
- reactions stats improved
load_comment_ratings
separate resolver
- follow/unfollow logic updated and unified with cache
- chore: version migrator synced
- feat: precache_data on start
- fix: store id list for following cache data
- fix: shouts stat filter out deleted
- cache isolated to services
- topics followers and authors cached
- redis stores lists of ids
load_authors_by
from cache
- feat: sentry integration enabled with glitchtip
- fix: reindex on update shout
- packages upgrade, isort
- separated stats queries for author and topic
- fix: feed featured filter
- fts search removed
- redis cache for what author follows
- redis cache for followers
- graphql add query: get topic followers
- enabling sentry
- long query log report added
- editor fixes
- authors links cannot be updated by
update_shout
anymore
Shout.featured_at
timestamp of the frontpage featuring event- added proposal accepting logics
- schema modulized
- Shout.visibility removed
- added precommit hook
- fmt
- granian asgi
- fix: rating logix
- fix:
load_top_random_shouts
- resolvers:
add_stat_*
refactored - services: use google analytics
- services: minor fixes search
- services: ackee removed
- services: following manager fixed
- services: import views.json
- fix: adding
author
role - fix: stripping
user_id
in auth connector
- schema: added
Shout.seo
string field - resolvers: added
/new-author
webhook resolver - resolvers: added reader.load_shouts_top_random
- resolvers: added reader.load_shouts_unrated
- resolvers: community follower id property name is
.author
- resolvers:
get_authors_all
andload_authors_by
- services: auth connector upgraded
- schema: enum types workaround,
ReactionKind
,InviteStatus
,ShoutVisibility
- schema:
Shout.created_by
,Shout.updated_by
- schema:
Shout.authors
can be empty - resolvers: optimized
reacted_shouts_updates
query
- resolvers: collab inviting logics
- resolvers: queries and mutations revision and renaming
- resolvers:
delete_topic(slug)
implemented - resolvers: added
get_shout_followers
- resolvers:
load_shouts_by
filters implemented - orm: invite entity
- schema:
Reaction.range
->Reaction.quote
- filters:
time_ago
->after
- httpx -> aiohttp
- schema:
Shout.created_by
removed - schema:
Shout.mainTopic
removed - services: cached elasticsearch connector
- services: auth is using
user_id
from authorizer - resolvers:
notify_*
usage fixes - resolvers:
getAuthor
now accepts slug,user_id
orauthor_id
- resolvers: login_required usage fixes
- schema: some fixes from migrator
- schema:
.days
->.time_ago
- schema:
excludeLayout
+layout
in filters ->layouts
- services: db access simpler, no contextmanager
- services: removed Base.create() method
- services: rediscache updated
- resolvers: get_reacted_shouts_updates as followedReactions query
- services: db context manager
- services:
ViewedStorage
fixes - services: views are not stored in core db anymore
- schema: snake case in model fields names
- schema: no DateTime scalar
- resolvers:
get_my_feed
comments filter reactions body.is_not('') - resolvers:
get_my_feed
query fix - resolvers:
LoadReactionsBy.days
->LoadReactionsBy.time_ago
- resolvers:
LoadShoutsBy.days
->LoadShoutsBy.time_ago
Author.userpic
->Author.pic
CommunityFollower.role
is string nowAuthor.user
is string now
- redis interface updated
viewed
interface updatedpresence
interface updated- notify on create, update, delete for reaction and shout
- notify on follow / unfollow author
- use pyproject
- devmode fixed
- community resolvers connected
- starlette is back, aiohttp removed
- aioredis replaced with aredis
- refactored
loadFollowedReactions
now with `