- Add date_engine utility for parsing exact, range, circa, before, after, and #context dates
- Introduce YearValue and NarratorDate models to index and translate narrator dates
- Add description field to OpinionStatus and TransmitterReliability models
- Register DovodiYearValueViewSet and DovodiBookAuthorRutbaViewSet admin endpoints
- Add parse-preview action for validating and translating date inputs
- Add migration 0055 to populate YearValue and NarratorDate from existing transmitters
- Introduce BookAuthorRutba model with title, slug, color, and description
- Link BookAuthor to BookAuthorRutba via rutba_status foreign key
- Update reference admin to manage BookAuthorRutba and assign rutba status
- Include rutba_detail in BookAuthorDetailSerializer and BookAuthorSyncSerializer
- Add migration 0054 to seed rutba records from existing authors
- Create ScholarlyOpinion model for standalone reusable scholarly opinions with status and multilingual text
- Add foreign key link from TransmitterOpinion to ScholarlyOpinion with automatic backward sync
- Create data migration 0053 to populate ScholarlyOpinion records from existing transmitter opinions
- Expose DovodiScholarlyOpinionViewSet and register route /dovodi-opinions/ in admin router
- Update TransmitterOpinion serializers and views to prioritize linked ScholarlyOpinion data
- Update annotate_and_prune_empty_categories helper to count active content from both category and categories relations in subtree
- Check both category and categories in category serializers (get_has_hadis, get_hadis_count, get_children_count)
- Support categories M2M relation in HadisSyncView and HadisMainListView filters
- Remove aggressive cached_view decorator from category tree and listing routes to ensure real-time consistency
- Add GenderChoices (male/female) field to Transmitters model with migration 0052
- Include gender across public and admin transmitter serializers
- Expose gender in TransmittersAdmin filter and list display
- Propagate transmitter gender in HadisCategoryXMindView flowchart payload
- Add split_transmitters_gender management command
- Add is_topic boolean field to HadisCategory model with indexing
- Enforce validation rules in clean():
* Topics cannot have children and must define a source_type
* Structural categories cannot contain hadiths and have source_type=None
* Parents cannot be topics
* Hadiths can only be attached to topics (is_topic=True)
- Update admin serializers and views to support is_topic filtering and mapping
- Expose is_topic in public category serializers (SimpleCategory, HadisCategorySelectSerializer, CategorySerializer)
- Include migration 0051_add_category_is_topic
- Add narrator and transmitter filtering support to HadisMainListView and HadisListView by slug or ID
- Include available narrators list with localized names in HadisFiltersView endpoint
- Document narrator query parameter in Swagger schema
- Add cleanup_non_hadith_narrators.py script to remove orphan/erroneous narrator chains and layers from non-hadith arguments
- Add utils/search_parser.py providing query parsing and Django Q construction for exact phrases, mandatory inclusions (+), excluded negations (-), and grouped OR conditions (()).
- Add auto-balancing and sanitization for unclosed quotes and parentheses.
- Seamlessly integrate all operator terms with Arabic and Persian search normalization.
- Update search querysets across Hadis, Transmitters, Book References, and Categories views.
- Add utils/text_normalizer.py providing robust Arabic and Persian orthographic normalization (diacritics/tashkeel removal, unification of Alef variants, Yeh/Alef Maksura, Kaf, Teh Marbuta, Waw Hamza, Tatweel, and digit normalization).
- Implement recursive text extraction from multilingual JSON structures and models.
- Add normalized_text shadow column across Hadis, HadisCorrection, HadisInterpretation, Transmitters, BookReference, and HadisCategory models with automated save-time synchronization.
- Apply database migrations (0048 and 0049).
- Add populate_normalized_search management command for backfilling existing records.
- Update search querysets in hadis, transmitter, book reference, and category views to filter using normalized text queries.
- Add comprehensive documentation in docs/ARABIC_SEARCH_NORMALIZATION_GUIDE.md.
- Optimize HadisSyncSerializer: remove unused number, address_details, and book descriptions
- Separate sync serializers for corrections and interpretations (omitting redundant hadis_info and category_info)
- Add HadisDatabaseVersion model and migration for tracking offline SQLite DB
- Add export_hadis_sqlite management command with gzip compression and single-file overwrite
- Add GET /api/hadis/sync/database/ endpoint and enhance version serializers
- Automatically trigger background SQLite database export on version increment in admin
- Add request-level user bookmark memoization in BookmarkStatusSerializer to eliminate redundant queries across all lists
- Optimize BookReferenceSyncView and BookReference.authors caching (reduced queries from 185 to 10)
- Add multi-level prefetch_related for references and images in HadisMainListView (reduced queries from 109 to 6)
- Add incremental sync support (updated_after/since) in HadisSyncView
- Add select_related for language in BookListView (reduced queries from 35 to 18)
- Annotate episode count and cache effective_thumbnail in podcast and video playlist views (reduced queries from 22/17 to 4)
- Prefetch categories with annotated article counts in ArticleListAPIView (reduced queries from 41 to 3)
- Scale Gunicorn workers/threads to 4w/4t (16 concurrency) with gthread in docker-compose.prod.yml
- Sort narrator chains in reverse order so each branch leads from first narrator to primary narrator/hadith
- Add support for uncertain transmitters with candidate details in xmind tree
- Localize reliability titles using get_localized_text
- Disable caching on category xmind endpoint and add no-cache response headers
- Eliminate N+1 queries in hadis serializers by using in-memory prefetch cache instead of .first() and .order_by()
- Add select_related for hadis and category in HadisSyncView prefetches
- Apply cached_view (Redis 2h + Accept-Language) to HadisSyncView and public hadis endpoints
- Enable GZipMiddleware in Django settings to compress large API responses
- Add is_root query param filter defaulting to true (parent__isnull=True) in CategoriesBySectView
- Ensure pagination count returns total count of root categories for the sect
Replace direct calls to `request.build_absolute_uri` with a centralized
`absolute_https_url` utility across account and hadis modules. This
ensures consistent enforcement of HTTPS for all absolute media URLs
(avatars, thumbnails, and images) in serializers and views.rl