- Add Country model for transmitters and reference publishers
- Add Publisher model linked to Country and City
- Add migration 0065 for Country and Publisher models
- Expose AdminCountrySerializer, AdminPublisherSerializer, and respective viewsets in admin URLs
- Add RelationType and TransmitterProfession models with two-way sync
- Add migrations 0063 and 0064 for relation types and professions seeding and data migration
- Register RelationType admin serializer, viewset and URL routes
- Update relational migration roadmap documentation
- Introduce Madhhab model with multilingual title, description, and slug
- Link madhhabs relation (ManyToMany) to Transmitters
- Add migration 0062 to create table and populate from existing madhab JSON data
- Register DovodiMadhhabViewSet and admin routes in urls.py
- Update RELATIONAL_MIGRATION_ROADMAP.md for madhhab migration
- Add SahabiStatus model with multilingual title, description, and slug
- Add ForeignKey sahabi_status to Transmitters model
- Create migration 0061 to create SahabiStatus and populate from existing companion_type
- Register DovodiSahabiStatusViewSet and admin routes in urls.py
- Update RELATIONAL_MIGRATION_ROADMAP.md for sahabi_status migration
- Introduce TransmitterFeature model with title, slug, and timestamps
- Link features relation to Transmitters and BookAuthors
- Add DovodiTransmitterFeatureViewSet and register routes in admin router
- Add migration 0060 to create table and populate from existing features data
- Update RELATIONAL_MIGRATION_ROADMAP.md with completed features migration
- Add City model and connect origin_city, lived_in_city, and died_in_city to Transmitters and BookAuthors
- Connect city_of_publication_city to BookEdition
- Add Kunya model and connect many-to-many kunyas relation to Transmitters
- Implement DovodiCityViewSet and DovodiKunyaViewSet and register routes in admin router
- Add migrations 0057, 0058, and 0059 to create tables and migrate existing string/JSON data
- Convert birth_year_hijri and death_year_hijri to CharField and add age_at_death
- Introduce BookAuthorDate model linking BookAuthor with parsed YearValue records
- Add sync_author_dates and date formatting methods to BookAuthor
- Support century filtering via YearValue min/max ranges and prefetch author dates
- Expose live preview fields and canonical date validation in AdminBookAuthorSerializer
- Add migration 0056 to convert fields and populate BookAuthorDate records
- 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
- 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
- Add bulk-assign-topics endpoint to AdminHadisViewSet supporting add/replace modes
- Validate leaf topic constraints and handle both M2M categories and primary category_id
- Invalidate hadis cache on bulk updates and return updated count with category details
- Expand AdminHadisBriefSerializer with slug, title_narrator, and status fields
- 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
- Allow 'cache-control' and 'pragma' headers in CORS_ALLOW_HEADERS to prevent CORS preflight errors on transmitter and hadith requests
- Support both 'hadis' and 'hadis_id' query parameters in AdminHadisCorrectionViewSet
- Support both 'category' and 'category_id' query parameters in AdminHadisInterpretationViewSet
- Support both 'hadis'/'hadis_id' and 'reference'/'reference_id' in AdminHadisReferenceImageViewSet upload handler
- Refactor QuranSecondaryTranslation to store language_code, translation_text and translator per record
- Add migrations 0042 and 0043 to migrate existing secondary translations
- Update AdminCategoryQuranVerseSerializer and AdminHadisCategorySerializer with proper secondary translations handling
- Support category filtering by source_type, has_quran_verse and exclude_verse_id in admin category viewset
- 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
- Return raw, unlocalized translation list in HadisSyncSerializer for Flutter offline multi-language support
- Enable hadis signals in HadisConfig.ready() to load cache invalidation listeners
- Add ContentRelease to TARGET_MODELS and implement invalidate_hadis_cache helper
- Trigger explicit cache invalidation in AdminContentReleaseViewSet upon version increment and CRUD
- Update HadisSyncView swagger documentation example