diff --git a/RELATIONAL_MIGRATION_ROADMAP.md b/RELATIONAL_MIGRATION_ROADMAP.md new file mode 100644 index 0000000..c26d5e1 --- /dev/null +++ b/RELATIONAL_MIGRATION_ROADMAP.md @@ -0,0 +1,167 @@ +# نقشه راه مهاجرت فیلدهای راویان و مؤلفان به مدل‌های رابطه‌ای +> این سند بر اساس مستند نیازمندی‌های کارفرما در فایل `کالکشن‌های_راویان.md` تهیه شده است و مراحل تبدیل فیلدهای متنی (`JSONField` / `CharField`) به مدل‌های رابطه‌ای مستقل به همراه جزئیات پیاده‌سازی بک‌اند، فرانت‌اند و وضعیت پیشرفت را مشخص می‌کند. + +--- + +## وضعیت کلی مراحل (Overview & Checklist) + +- [x] **فاز ۰: سیستم شهرها و مکان‌ها (`City`)** *(انجام شده)* +- [x] **فاز ۱: کنیه‌ها (`Kunya` / `kunyas`)** — رابطه چندبه‌چند (M2M) *(تکمیل شده)* +- [ ] **فاز ۲: ویژگی‌ها (`TransmitterFeature` / `features`)** — رابطه چندبه‌چند (M2M) +- [ ] **فاز ۳: وضعیت صحابی بودن (`SahabiStatus` / `sahabi_status`)** — رابطه تک‌به‌چند (ForeignKey / M2O) +- [ ] **فاز ۴: تفکیک و اتصال رتبه‌بندی و وثاقت راوی و مؤلف (`NarratorRating` و `reliability_levels`)** — رابطه ForeignKey / M2O +- [ ] **فاز ۵: مذاهب راویان (`Madhhab` / `madhabs`)** — رابطه چندبه‌چند (M2M) +- [ ] **فاز ۶: داینامیک‌سازی انواع نسبت‌های خویشاوندی (`RelationType` / `relatives`)** — رابطه ForeignKey در `TransmitterRelative` +- [ ] **فاز ۷: مکان‌های چندگانه راوی (`narrators_locations`)** — اتصال چندبه‌چند با ترتیب (`sort_order`) و نوع (`residence` / `death`) + +--- + +## جزئیات کامل هر فاز + +--- + +### فاز ۰: سیستم شهرها و مکان‌ها (`City`) ✅ +* **وضعیت:** `تکمیل شده` +* **کارهای انجام‌شده:** + 1. ایجاد مدل `City` در `transmitter.py` با فیلد چندزبانه `title` و `slug`. + 2. اتصال `origin_city`، `lived_in_city` و `died_in_city` در `Transmitters` و `BookAuthor`. + 3. اتصال `city_of_publication_city` در `BookEdition`. + 4. اعمال مایگریشن و استخراج ۲۲ شهر از رکوردهای قبلی. + 5. ساخت سریالایزر و ویوست `AdminCitySerializer` و `DovodiCityViewSet`. + 6. ساخت کامپوننت اختصاصی `CitySelect` با کش ماژولار و جلوگیری از درخواست تکراری در داشبورد. + +--- + +### فاز ۱: کنیه‌ها (`Kunya` / `kunyas`) ✅ +* **وضعیت:** `تکمیل شده` +* **نوع رابطه طبق داکیومنت کارفرما:** **Many-to-Many (M2M)** + > یک راوی ممکن است چند کنیه داشته باشد (مثلاً «أبو سعید»، «أبو خالد») و همچنین یک کنیه می‌تواند متعلق به چندین راوی باشد. +* **مراحل پیاده‌سازی بک‌اند:** + 1. **مدل `Kunya`:** + - فیلد `title`: عنوان چندزبانه (`JSONField` شامل زبان‌های fa, ar, ru, en) + - فیلد `slug`: اسلاگ خودکار با قابلیت حروف عربی/فارسی + - زمان‌های `created_at` و `updated_at` + 2. **اتصال به `Transmitters`:** + - افزودن رابطه `kunyas = models.ManyToManyField('Kunya', blank=True, related_name='transmitters')` + - حفظ فیلد متنی قدیمی `kunya` جهت پشتیبانی از کدهای گذشته (Backward Compatibility) + - همگام‌سازی خودکار در متد `save()` مدل: پر شدن خودکار متن `kunya` از روی کنیه‌های متصل شده. + 3. **دیتامایگریشن (Data Migration):** + - اسکریپت استخراج مقادیر یکتای موجود از فیلدهای `Transmitters.kunya`. + - ایجاد رکوردهای `Kunya` و اتصال M2M آنها به راویان مربوطه بدون از دست رفتن هیچ داده‌ای. + 4. **سریالایزرها و APIها:** + - ساخت `AdminKunyaSerializer` و `DovodiKunyaViewSet` (با اکشن‌های استاندارد `list`, `create`, `update`, `delete` و سرچ متنی). + - ثبت در روت‌های API ادمین (`/api/hadis/admin/kunyas/`). + - بروزرسانی `AdminTransmitterDetailSerializer` و `AdminTransmitterListSerializer` جهت ارسال و دریافت لیست شناسه‌ها و آبجکت‌های کنیه. +* **مراحل پیاده‌سازی داشبورد (فرانت‌اند):** + 1. ساخت کامپوننت `KunyaSelect` (چندانتخابی با تگ / Dropdown Multi-Select + مودال ساخت کنیه جدید با هدر چندزبانه مشابه شهر). + 2. جایگزینی فیلد متنی کنیه در فرم ویرایش/ایجاد راوی با کامپوننت جدید. + +--- + +### فاز ۲: ویژگی‌ها (`TransmitterFeature` / `features`) 🔲 +* **وضعیت:** `در انتظار اجرا` +* **نوع رابطه طبق داکیومنت کارفرما:** **Many-to-Many (M2M)** + > ویژگی‌های جسمی یا توصیفی راویان و مؤلفان (مانند «أعرج»، «أعمى فی عین واحدة»، «صاحب سر النبی» و...). +* **مراحل پیاده‌سازی بک‌اند:** + 1. **مدل `TransmitterFeature`:** + - فیلد `title`: چندزبانه (`JSONField`) + - فیلد `slug`: اسلاگ یکتا + - متدهای کمکی جهت دریافت عنوان به زبان‌های مختلف + 2. **اتصال به راویان و مؤلفان:** + - رابطه M2M در `Transmitters.features_list = models.ManyToManyField('TransmitterFeature', blank=True, related_name='transmitters')` + - رابطه M2M در `BookAuthor.features_list = models.ManyToManyField('TransmitterFeature', blank=True, related_name='authors')` + - همگام‌سازی در متد `save()` با فیلدهای متنی قدیمی `features`. + 3. **دیتامایگریشن:** + - انتقال ویژگی‌های متنی موجود در دیتابیس به رکوردهای یکتای `TransmitterFeature` و اتصال به راویان و مؤلفان. + 4. **سریالایزر و API:** + - ویوست و سریالایزر `AdminTransmitterFeatureViewSet` در اندپوینت `/api/hadis/admin/transmitter-features/`. + - پشتیبانی در سریالایزرهای راوی و مؤلف. +* **مراحل پیاده‌سازی داشبورد:** + 1. کامپوننت `FeatureSelect` چندانتخابی همراه با مودال ساخت سریع ویژگی. + 2. قرارگیری در تب ویژگی‌های راوی و صفحه مؤلف کتاب. + +--- + +### فاز ۳: وضعیت صحابی بودن (`SahabiStatus` / `companion_type`) 🔲 +* **وضعیت:** `در انتظار اجرا` +* **نوع رابطه طبق داکیومنت کارفرما:** **Many-to-One / ForeignKey** + > راوی دارای یک وضعیت مشخص صحابی بودن است. +* **مراحل پیاده‌سازی بک‌اند:** + 1. **مدل `SahabiStatus`:** + - فیلد `code` یا `slug`: کد شناسه (مانند `sahabi`, `saw_prophet`, `contemporary`, `minor_sahabi`, `mukhadram`, `unproven`, `disputed`) + - فیلد `title`: چندزبانه (`JSONField`) به ۴ زبان بر اساس ۷ رکورد استاندارد داکیومنت کارفرما: + 1. صحابی (сподвижник) + 2. رؤیت پیامبر (видел) + 3. درک زمان پیامبر (застал) + 4. صحابی صغیر (малый) + 5. مخضرم (мухадрам) + 6. اثبات‌نشده (недоказано) + 7. اختلافی / محل بحث (спорный) + 2. **اتصال به `Transmitters`:** + - فیلد `sahabi_status = models.ForeignKey(SahabiStatus, null=True, blank=True, on_delete=models.SET_NULL, related_name='transmitters')` + - سینک خودکار با فیلد متنی قدیمی `companion_type`. + 3. **مایگریشن و Seeding:** + - اعمال مایگریشن و ایجاد خودکار ۷ رکورد پیش‌فرض فوق به همراه ترجمه عربی، فارسی، انگلیسی و روسی. + 4. **API و سریالایزر:** + - اندپوینت `/api/hadis/admin/sahabi-statuses/` و پوشش در جزئیات راوی. +* **مراحل پیاده‌سازی داشبورد:** + 1. افزودن دراپ‌داون تک‌انتخابی وضعیت صحابی به فرم راوی با امکان پاک کردن یا تغییر وضعیت. + +--- + +### فاز ۴: تفکیک و اتصال رتبه‌بندی و وثاقت راوی و مؤلف (`NarratorRating` و `reliability_levels`) 🔲 +* **وضعیت:** `در انتظار اجرا` +* **نوع رابطه طبق داکیومنت کارفرما:** **ForeignKey (M2O) برای هر دو فیلد** + > در معماری کارفرما دو مفهوم متمایز وجود دارد: + > ۱. `reliability_levels` (۱۱ سطح کلی اعتبار: ثقه، صدوق، ضعیف، کذاب و...) + > ۲. `narrator_ratings` (عبارت دقیق ارزیابی رجالی: ثقة ثبت، صدوق له أوهام و...) +* **مراحل پیاده‌سازی بک‌اند:** + 1. بررسی و یکپارچه‌سازی مدل `TransmitterReliability` فعلی با ۱۱ سطح استاندارد کارفرما. + 2. استفاده از مدل `BookAuthorRutba` یا ایجاد مدل عمومی `NarratorRating` (با ترجمه چندزبانه) و اتصال آن به عنوان `rating` هم به راوی (`Transmitters.narrator_rating`) و هم به مؤلف (`BookAuthor.rutba_status`). + 3. تبدیل فیلد `BookAuthor.scholarity` به کلید خارجی به `TransmitterReliability`. + 4. سریالایزرها و مایگریشن داده‌ها. +* **مراحل پیاده‌سازی داشبورد:** + 1. نمایش هر دو دراپ‌داون «سطح وثاقت کلی» و «عبارت ارزیابی نهایی» در فرم راوی و مؤلف. + +--- + +### فاز ۵: مذاهب راویان (`Madhhab` / `madhabs`) 🔲 +* **وضعیت:** `در انتظار اجرا` +* **نوع رابطه طبق داکیومنت کارفرما:** **Many-to-Many (M2M)** + > کارفرما مذهب را به عنوان یک کالکشن چندزبانه با رابطه M2M در نظر گرفته است (تا بتوان مذاهب گوناگون، انشعابات، یا نظرات متعدد درباره مذهب راوی را ثبت کرد). +* **مراحل پیاده‌سازی بک‌اند:** + 1. ساخت مدل `Madhhab` با فیلد چندزبانه `name`/`title` و `slug`. + 2. ایجاد رابطه M2M روی `Transmitters.madhhabs = models.ManyToManyField('Madhhab', blank=True, related_name='transmitters')`. + 3. حفظ فیلد `madhhab` قبلی (`shia`/`sunni`) و سینک مقدار پیش‌فرض با آن. + 4. ساخت Seed داده‌های مذاهب و ثبت API ادمین. +* **مراحل پیاده‌سازی داشبورد:** + 1. تبدیل سلکتور دو گزینه‌ای به دراپ‌داون داینامیک چندزبانه. + +--- + +### فاز ۶: داینامیک‌سازی انواع نسبت‌های خویشاوندی (`RelationType` / `relatives`) 🔲 +* **وضعیت:** `در انتظار اجرا` +* **نوع رابطه طبق داکیومنت کارفرما:** **ForeignKey در جدول خویشاوندان راوی** +* **مراحل پیاده‌سازی بک‌اند:** + 1. ساخت مدل `RelationType` شامل فیلد کلیدی و `title` چندزبانه (برای جایگزینی دیکشنری هاردکد شده `RELATION_TYPE_MAP`). + 2. متصل کردن `TransmitterRelative.relation_type_ref = models.ForeignKey(RelationType, ...)` به مدل جدید. + 3. دیتامایگریشن برای انتقال ۲۹ نسبت خویشاوندی موجود به رکوردهای جدول جدید. + 4. اندپوینت‌های مدیریت نسبت‌ها در پنل ادمین. +* **مراحل پیاده‌سازی داشبورد:** + 1. دریافت داینامیک لیست نسبت‌های خویشاوندی از API به جای گزینه‌های استاتیک در فرم خویشاوندان راوی. + +--- + +### فاز ۷: مکان‌های چندگانه راوی (`narrators_locations`) 🔲 +* **وضعیت:** `در انتظار اجرا` +* **نوع رابطه طبق داکیومنت کارفرما:** **رابطه چندبه‌چند با متادیتا (`sort_order`, `type`)** + > برای مواردی که راوی در طول حیات خود در چند شهر مختلف سکونت داشته است. +* **مراحل پیاده‌سازی بک‌اند:** + 1. ایجاد مدل واسط `TransmitterLocationRecord` با فیلدهای `transmitter`, `city`, `type` (`residence` / `death`), `sort_order`. + 2. سینک دوطرفه با فیلدهای `origin_city`, `lived_in_city`, `died_in_city` فعلی. + 3. سریالایزرها و پشتیبانی در داشبورد. + +--- + +## راهنمای بروزرسانی این سند +پس از انجام هر مرحله توسط هوش مصنوعی، تیک چک‌باکس مربوطه در بخش بالا از `[ ]` به `[x]` تبدیل شده و وضعیت آن فاز از `در انتظار اجرا` به `تکمیل شده` تغییر داده خواهد شد. diff --git a/docs/BULK_IMPORT_JSON_GUIDE.md b/docs/BULK_IMPORT_JSON_GUIDE.md new file mode 100644 index 0000000..eb498f4 --- /dev/null +++ b/docs/BULK_IMPORT_JSON_GUIDE.md @@ -0,0 +1,497 @@ +# راهنمای جامع و طرح اولیه ایمپورت دسته‌جمعی داده‌ها (Bulk Import JSON Specification) + +این سند به عنوان **«طرح اولیه» (Initial Blueprint)** برای انتقال و ایمپورت دسته‌جمعی داده‌ها به بخش **Arguments (حدیث، قرآن، تاریخ، فتوا، نقل‌قول، راویان و منابع)** طراحی شده است. + +هدف این ساختار این است که شما بتوانید داده‌های دیتابیس فعلی خود را با **کمترین پیچیدگی** خروجی بگیرید و سیستم ایمپورت بک‌اند به صورت خودکار کارهای فنی (ساخت اسلاگ‌ها، درختواره، نرمال‌سازی متن برای جستجو، فرمت‌بندی تاریخ‌ها و ساخت دیتابیس آفلاین موبایل) را انجام دهد. + +--- + +## ۱. قوانین طلایی و عمومی (که کار شما را راحت می‌کند) + +### الف) شناسه یکتا (`id` / `legacy_id`) برای اتصال بخش‌ها به هم +برای اینکه بتوانیم بخش‌ها را یکی‌یکی ایمپورت کنیم و به هم وصل نماییم، هر رکورد اصلی (راوی، کتاب، دسته‌بندی، حدیث و...) یک فیلد `"id"` (یا `"legacy_id"`) دارد که همان **کد یکتای دیتابیس خودتان** است (مثلاً `"nar_105"`, `"book_12"`, `"hadith_501"` یا عدد `105`). +- مزیت: اگر یک فایل را دو بار ایمپورت کنیم، رکورد تکراری ساخته نمی‌شود بلکه رکورد قبلی **به‌روزرسانی (Update)** می‌شود. + +### ب) فرمت فیلدهای چندزبانه (پشتیبانی از ۳ حالت ساده) +در دیتابیس ما، عناوین و ترجمه‌ها چندزبانه (`ru`, `ar`, `en`, `fa`, `ur`) هستند. برای راحتی شما در ساخت JSON، سیستم ایمپورت ما هر ۳ حالت زیر را قبول می‌کند: +1. **حالت پیشنهادی (آبجکت کلید-مقدار ساده):** + ```json + "title": { "ru": "Книга веры", "ar": "كتاب الإيمان", "en": "Book of Faith" } + ``` +2. **حالت تک‌زبانه (رشته متنی ساده - اگر فقط یک زبان مثل روسی یا عربی دارید):** + ```json + "title": "Книга веры" + ``` +3. **حالت آرایه استاندارد دیتابیس:** + ```json + "title": [ + { "language_code": "ru", "text": "Книга веры" }, + { "language_code": "ar", "text": "كتاب الإيمان" } + ] + ``` + +### ج) فرمت استاندارد سال تولد، وفات و سن (`birth_year_hijri`, `death_year_hijri`, `age_at_death`) +موتور تاریخ سیستم به صورت خودکار فرمت‌های زیر را به ۳ زبان ترجمه و فرمت‌بندی می‌کند: +- عدد دقیق هجری: `"148"` (برای قبل از هجرت منفی بگذارید: `"-15"`) +- بازه زمانی: `"140..150"` +- تقریبی (حدودِ): `"~150"` +- بعد از سال / بیش از: `">150"` +- قبل از سال / کمتر از: `"<150"` +- دو احتمال (یا): `"148;149"` یا `"140..145;148..150"` +- تگ‌های مفهومی خاص: `"#early_islam"`, `"#hijra_habasha"`, `"#umayyad_era"` + +--- + +## ۲. ترتیب و ساختار فایل‌های JSON (۵ فاز) + +### فاز اول: اطلاعات پایه، تگ‌ها و وضعیت‌ها (`01_lookups.json`) +این فایل شامل تعاریف پایه است که در سایر بخش‌ها به آن‌ها ارجاع داده می‌شود. *(نکته: اگر تگ یا وضعیتی را مستقیم داخل فایل احادیث یا راویان هم بنویسید، سیستم خودش آن را می‌سازد، اما داشتن این فایل برای تنظیم رنگ‌ها و توضیحات عالی است).* + +```json +{ + "hadith_statuses": [ + { + "id": "status_sahih", + "title": { "ru": "Достоверный (Сахих)", "ar": "صحيح", "en": "Authentic (Sahih)" }, + "description": { "ru": "Описание достоверного хадиса...", "ar": "..." }, + "color": "green", + "order": 1 + } + ], + "transmitter_reliabilities": [ + { + "id": "rel_thiqa", + "title": { "ru": "Надёжный (Сика)", "ar": "ثقة", "en": "Reliable (Thiqa)" }, + "description": { "ru": "Заслуживающий доверия передатчик" }, + "color": "green" + } + ], + "opinion_statuses": [ + { + "id": "op_confirmed", + "title": { "ru": "Подтверждение (Таусик)", "ar": "توثيق", "en": "Confirmed" }, + "color": "green" + } + ], + "author_rutbas": [ + { + "id": "rutba_hafiz", + "title": { "ru": "Хафиз", "ar": "حافظ", "en": "Hafiz" }, + "color": "blue" + } + ], + "hadith_tags": [ + { "id": "tag_imamat", "title": { "ru": "Имамат", "ar": "الإمامة", "en": "Imamate" } }, + { "id": "tag_fiqh", "title": { "ru": "Фикх", "ar": "الفقه", "en": "Fiqh" } } + ], + "book_subject_areas": [ + { "id": "subj_hadith", "title": { "ru": "Книги хадисов", "ar": "كتب الحديث" } } + ], + "book_types": [ + { "id": "type_shia_primary", "sect": "shia", "title": { "ru": "Первоисточник (Шииты)", "ar": "مصدر أصلي" } }, + { "id": "type_sunni_primary", "sect": "sunni", "title": { "ru": "Первоисточник (Сунниты)", "ar": "مصدر سني" } } + ] +} +``` +> **رنگ‌های مجاز (`color`):** `"green"`, `"blue"`, `"yellow"`, `"orange"`, `"red"`, `"purple"`, `"gray"` + +--- + +### فاز دوم: راویان، علما و اقوال رجالی (`02_narrators_and_scholars.json`) +در این فایل، لیست تمام راویان (`transmitters`) و مولفان/علمای رجال (`scholars_and_authors`) قرار می‌گیرد. + +```json +{ + "scholars_and_authors": [ + { + "id": "author_najashi", + "name": { "ru": "Ан-Наджаши", "ar": "النجاشي", "en": "Al-Najashi" }, + "known_as": { "ru": "Абу аль-Аббас", "ar": "أبو العباس" }, + "scholarity": { "ru": "Ученый в области риджал", "ar": "عالم بالرجال" }, + "tabaqa": { "ru": "5-й век хиджры", "ar": "القرن الخامس" }, + "rutba_id": "rutba_hafiz", + "birth_year_hijri": "372", + "death_year_hijri": "450", + "age_at_death": "78", + "birth_year_miladi": 982, + "death_year_miladi": 1058, + "image_path": "authors/najashi.jpg" + } + ], + "transmitters": [ + { + "id": "nar_101", + "narrator_number": 101, + "gender": "male", + "madhhab": "shia", + "reliability_id": "rel_thiqa", + "generation": 5, + "full_name": { "ru": "Зурара ибн Айян", "ar": "زرارة بن أعين الشيباني", "en": "Zurara ibn A'yan" }, + "known_as": { "ru": "Зурара", "ar": "زرارة" }, + "kunya": { "ru": "Абу аль-Хасан", "ar": "أبو الحسن" }, + "nickname": { "ru": "Аш-Шайбани", "ar": "الشيباني" }, + "origin": { "ru": "Куфа", "ar": "الكوفة" }, + "lived_in": { "ru": "Куфа", "ar": "الكوفة" }, + "died_in": { "ru": "Куфа", "ar": "الكوفة" }, + "birth_year_hijri": "~80", + "death_year_hijri": "150", + "age_at_death": "~70", + "freed_slave_of": { "ru": "Бану Шайбан", "ar": "بني شيبان" }, + "occupation": { "ru": "Факих, мухаддис", "ar": "فقيه ومحدث" }, + "features": { "ru": "Сподвижник Имама Бакира и Имама Садика", "ar": "من أصحاب الباقر والصادق" }, + "companion_type": { "ru": "Сподвижник Имама Садика (а)", "ar": "أصحاب الإمام الصادق" }, + "tadlis": false, + "ikhtilat": false, + "in_sahih_bukhari": false, + "in_sahih_muslim": false, + "tags": ["Куфа", "Сподвижники"], + "description": { "ru": "Подробная биография передатчика...", "ar": "..." }, + "relatives": { + "father_id": null, + "mother_id": null, + "sibling_ids": ["nar_102"] + }, + "opinions": [ + { + "scholar_id": "author_najashi", + "scholar_name": { "ru": "Ан-Наджаши", "ar": "النجاشي" }, + "status_id": "op_confirmed", + "opinion_text": { + "ar": "شيخ أصحابنا في زمانه ومتقدمهم، وكان قارئاً فقيهاً متكلماً", + "ru": "Шейх наших соратников в свое время и их лидер, был чтецом, факихом, мутакаллимом" + }, + "order": 1 + } + ], + "original_texts": [ + { + "title": { "ru": "Риджал ан-Наджаши о Зураре", "ar": "ترجمة زرارة في رجال النجاشي" }, + "text": "زرارة بن أعين بن سنسن مولى بني شيبان...", + "translation": { "ru": "Зурара ибн Айян ибн Сансан, вольноотпущенник Бану Шайбан..." }, + "order": 1, + "references": [ + { + "book_id": "book_rijal_najashi", + "edition_id": "ed_najashi_1", + "volume": "1", + "pages": "175", + "hadith_number": "463", + "address": "Риджал ан-Наджаши, том 1, стр. 175", + "url": "https://example.com/book/175", + "screenshots_folder": "screens_trx/nar_101/ex_1" + } + ] + } + ] + } + ] +} +``` + +--- + +### فاز سوم: منابع، کتاب‌ها، چاپ‌ها و جلدها (`03_sources.json`) +در ساختار جدید، هر کتاب (`BookReference`) می‌تواند چندین چاپ (`editions`) و چندین جلد (`volumes`) به همراه فایل PDF و تصاویر جلد داشته باشد. + +```json +{ + "books": [ + { + "id": "book_kafi", + "title": { "ru": "Аль-Кафи", "ar": "الكافي", "en": "Al-Kafi" }, + "description": { "ru": "Важнейший сборник шиитских хадисов...", "ar": "..." }, + "language": { "ru": "Арабский", "ar": "العربية", "en": "Arabic" }, + "author_id": "author_kulayni", + "type_id": "type_shia_primary", + "subject_area_ids": ["subj_hadith"], + "rate": 5.0, + "order": 1, + "has_editions": true, + "attributes": [ + { + "title": { "ru": "Век написания", "ar": "قرن التأليف" }, + "value": { "ru": "4-й век хиджры", "ar": "القرن الرابع الهجري" } + } + ], + "editions": [ + { + "id": "ed_kafi_dar_islamiya", + "edition_number": "4", + "year_of_publication": "1407 هـ / 1986 م", + "number_of_volumes": 8, + "publisher": { "ru": "Дар аль-Кутуб аль-Исламия", "ar": "دار الكتب الإسلامية" }, + "city_of_publication": { "ru": "Тегеран", "ar": "طهران" }, + "country_of_publication": { "ru": "Иран", "ar": "إيران" }, + "isbn": "978-964-440-001-1", + "source_url": "https://lib.eshia.ir/11005", + "researcher_ids": ["author_ghaffari"], + "editor_ids": [], + "notes": { "ru": "С исследованием Али Акбара Гаффари" }, + "volumes": [ + { + "id": "vol_kafi_1", + "title": "1", + "cover_image_path": "books/book_kafi/ed_1/vol_1_cover.jpg", + "pdf_file_path": "books/book_kafi/ed_1/01.pdf" + }, + { + "id": "vol_kafi_2", + "title": "2", + "cover_image_path": "books/book_kafi/ed_1/vol_2_cover.jpg", + "pdf_file_path": "books/book_kafi/ed_1/02.pdf" + } + ] + } + ] + } + ] +} +``` + +--- + +### فاز چهارم: دسته‌بندی‌ها، تاپیک‌ها و آیات قرآن (`04_categories_and_quran.json`) + +**نکته بسیار مهم درباره دسته‌بندی‌ها در سیستم:** +دسته‌بندی‌ها در سیستم ما به دو نوع تقسیم می‌شوند: +1. **پوشه/شاخه ساختاری (`"is_topic": false`):** فقط زیرمجموعه دارد و مستقیماً حدیثی داخل آن قرار نمی‌گیرد (`source_type` ندارد). +2. **تاپیک نهایی (`"is_topic": true`):** آخرین برگ درخت است که احادیث، تفاسیر یا آیات داخل آن قرار می‌گیرند. برای تاپیک حتماً باید `"source_type"` مشخص شود: + - مقادیر مجاز `source_type`: `"quran"` (قرآن)، `"hadith"` (حدیث)، `"history"` (تاریخ)، `"fatwa"` (فتوا)، `"quote"` (نقل‌قول). + +```json +{ + "categories": [ + { + "id": "cat_imamat_root", + "parent_id": null, + "sect": "sunni", + "is_topic": false, + "source_type": null, + "order": 1, + "title": { "ru": "Имамат и Халифат", "ar": "الإمامة والخلافة", "en": "Imamate and Caliphate" }, + "description": { "ru": "Раздел, посвященный вопросам руководства после Пророка (с)" }, + "xmind_file_path": null + }, + { + "id": "topic_ayah_tathir", + "parent_id": "cat_imamat_root", + "sect": "sunni", + "is_topic": true, + "source_type": "quran", + "order": 1, + "title": { "ru": "Аят ат-Татхир (Очищение)", "ar": "آية التطهير", "en": "Verse of Purification" }, + "description": { "ru": "Кто входит в Ахль аль-Бейт согласно суннитским источникам" }, + "xmind_file_path": "xmind/tathir.xmind", + "quran_verse": { + "surah_name": { "ru": "Аль-Ахзаб (Союзники)", "ar": "الأحزاب", "en": "Al-Ahzab" }, + "ayah_number": "33", + "arabic_text": "إِنَّمَا يُرِيدُ اللَّهُ لِيُذْهِبَ عَنكُمُ الرِّجْسَ أَهْلَ الْبَيْتِ وَيُطَهِّرَكُمْ تَطْهِيرًا", + "primary_translation": { + "ru": "О обитатели дома! Аллах желает лишь избавить вас от скверны и очистить вас полностью.", + "en": "Allah intends only to remove from you the impurity, O People of the [Prophet's] household..." + }, + "primary_translator": { + "ru": "Э. Кулиев", + "en": "Sahih International" + }, + "secondary_translations": [ + { + "language_code": "ru", + "translator": "И. Ю. Крачковский", + "translation_text": "Аллах хочет только удалить от вас скверну, о люди дома, и очистить вас очищением." + }, + { + "language_code": "ru", + "translator": "М.-Н. О. Османов", + "translation_text": "Воистину, Аллах хочет отвратить от вас скверну, о члены дома [Пророка]..." + } + ] + } + }, + { + "id": "topic_hadith_thaqalayn", + "parent_id": "cat_imamat_root", + "sect": "sunni", + "is_topic": true, + "source_type": "hadith", + "order": 2, + "title": { "ru": "Хадис ас-Сакалайн (Две драгоценности)", "ar": "حديث الثقلين" }, + "description": { "ru": "Хадисы об оставлении Корана и Ахль аль-Бейт" } + } + ] +} +``` + +--- + +### فاز پنجم: احادیث (آرگومنت‌ها)، سلسله روات، تصحیحات و تفاسیر (`05_arguments_hadiths.json`) + +این فایل قلب اصلی محتواست و شامل ۳ بخش است: +1. **`hadiths` (یا آرگومنت‌ها):** شامل متن اصلی، ترجمه، منابع، و **سلسله روات (`chains`)**. +2. **`corrections` (تصحیحات و بررسی اسناد حدیث):** زیرمجموعه‌های تحلیلی/تصحیحی که به یک حدیث خاص وصل می‌شوند. +3. **`interpretations` (تفاسیر و شروح):** متون تفسیری که به یک تاپیک (`topic_id`) وصل می‌شوند. + +#### چطور سلسله روات (`chains`) را در JSON بنویسیم؟ +ما دو روش در اختیار شما گذاشته‌ایم: +- **روش ساده (فقط لیست کد یا شماره راویان):** اگر سلسله سند ساده است، فقط آرایه‌ای از کد راویان بدهید: + `"chains": [ ["nar_101", "nar_102", "nar_105"] ]` +- **روش پیشرفته (پشتیبانی از انقطاع در سند `is_gap`، راوی مردد `is_uncertain` و لایه/طبقه):** اگر در گره‌ای از سند تردید بین دو راوی وجود دارد یا افتادگی سند هست، به جای کد ساده، یک آبجکت بگذارید (در نمونه زیر هر دو حالت نشان داده شده است). + +```json +{ + "hadiths": [ + { + "id": "hadith_1001", + "number": 1, + "primary_topic_id": "topic_ayah_tathir", + "additional_topic_ids": ["topic_hadith_thaqalayn"], + "status_id": "status_sahih", + "hadis_status_text": { "ru": "Достоверный по условиям Муслима", "ar": "صحيح على شرط مسلم" }, + "visibility": true, + "title": { + "ru": "Хадис аль-Киса (Хадис о плаще) от Умм Саламы", + "ar": "حديث الكساء عن أم سلمة" + }, + "title_narrator": { + "ru": "Умм Салама", + "ar": "أم سلمة" + }, + "text": "عَنْ أُمِّ سَلَمَةَ قَالَتْ: فِي بَيْتِي نَزَلَتْ: {إِنَّمَا يُرِيدُ اللَّهُ لِيُذْهِبَ عَنكُمُ الرِّجْسَ أَهْلَ الْبَيْتِ}...", + "translation": { + "ru": "Передается от Умм Саламы, что она сказала: «В моем доме был ниспослан аят: Поистине, Аллах желает избавить вас от скверны, о Ахль аль-Бейт...»", + "en": "Narrated by Umm Salama: In my house the verse was revealed..." + }, + "description": { + "ru": "Краткое примечание к хадису" + }, + "explanations": [ + { + "language_code": "ru", + "items": [ + { + "title": "Разбор лексики (Ахль аль-Бейт)", + "detail": "Подробное объяснение значения выражения Ахль аль-Бейт в контексте данного хадиса..." + }, + { + "title": "Исторический контекст", + "detail": "Обстоятельства ниспослания (Асбаб ан-Нузуль)..." + } + ] + } + ], + "address": { + "ru": ["Сахих Муслим", "Книга достоинств сподвижников", "Глава о достоинствах Ахль аль-Бейт"] + }, + "links": [ + { "title": "Sunnah.com", "link": "https://sunnah.com/muslim:2424" }, + { "title": "Dorar.net", "link": "https://dorar.net/hadith/123" } + ], + "tag_ids": ["tag_imamat"], + "chains": [ + [ + { + "transmitter_id": "nar_101", + "order": 0, + "layer_number": 1, + "layer_name": { "ru": "Сподвижники (Сахаба)", "ar": "الصحابة" }, + "is_gap": false, + "is_uncertain": false + }, + { + "transmitter_id": "nar_102", + "order": 1, + "layer_number": 2, + "is_gap": false, + "is_uncertain": true, + "uncertain_transmitter_ids": ["nar_102", "nar_103"] + } + ] + ], + "references": [ + { + "book_id": "book_kafi", + "edition_id": "ed_kafi_dar_islamiya", + "volume_id": "vol_kafi_1", + "volume": "1", + "pages": "287", + "hadith_number": "3295", + "address": "Сунан ат-Тирмизи, том 5, стр. 351, хадис № 3205", + "url": "https://shamela.ws/book/123/456", + "description": { "ru": "Издание Дар аль-Кутуб" }, + "screenshots_folder": "screens/hadith_1001/ref_1" + } + ], + "corrections": [ + { + "id": "corr_501", + "priority": 1, + "title": { "ru": "Оценка аль-Альбани", "ar": "تحقيق الألباني" }, + "narrator": "Мухаммад Насируддин аль-Альбани", + "text": "قال الألباني في صحيح سنن الترمذي: صحيح", + "translation": { "ru": "Аль-Альбани сказал в «Сахих Сунан ат-Тирмизи»: Достоверно (Сахих)." }, + "links": [ + { "title": "Источник", "link": "https://example.com/albani" } + ], + "references": [ + { + "book_id": "book_sahih_tirmidhi", + "volume": "3", + "pages": "90", + "hadith_number": "3205", + "address": "Сахих Сунан ат-Тирмизи, том 3, стр. 90", + "url": null, + "screenshots_folder": "screens/corr_501/ref_1" + } + ] + } + ] + } + ], + "interpretations": [ + { + "id": "interp_201", + "topic_id": "topic_ayah_tathir", + "priority": 1, + "narrator": "Ибн Касир", + "title": { "ru": "Тафсир Ибн Касира к аяту 33 суры Аль-Ахзаб", "ar": "تفسير ابن كثير لآية التطهير" }, + "text": "

وهذا نص في دخول أزواج النبي صلى الله عليه وسلم في أهل البيت ههنا...

", + "translation": { + "ru": "

Толкование Ибн Касира и приведение хадисов о плаще...

" + }, + "links": [], + "references": [ + { + "book_id": "book_tafsir_ibn_kathir", + "volume": "6", + "pages": "410", + "hadith_number": null, + "address": "Тафсир аль-Куран аль-Азим, том 6, стр. 410", + "url": null, + "screenshots_folder": "screens/interp_201/ref_1" + } + ] + } + ] +} +``` + +--- + +## ۳. ساختار پیشنهادی پوشه ارسالی (Media + JSON) + +اگر همراه با داده‌ها، **تصاویر اسکرین‌شات منابع، عکس جلد کتاب‌ها، فایل‌های PDF یا فایل‌های XMind** دارید، کافی است کل پکیج را در یک فایل فشرده (`ZIP`) با ساختار پوشه‌بندی زیر قرار دهید و مسیر نسبی آن‌ها را در فیلدهای مربوطه بنویسید: + +```text +import_package/ +├── 01_lookups.json +├── 02_narrators_and_scholars.json +├── 03_sources.json +├── 04_categories_and_quran.json +├── 05_arguments_hadiths.json +└── media/ + ├── authors/ # تصاویر مولفین و علما + ├── books/ # عکس جلدها و فایل‌های PDF هر کتاب/چاپ/جلد + ├── xmind/ # فایل‌های XMind دسته‌بندی‌ها + ├── screens/ # اسکرین‌شات‌های منابع احادیث، تصحیحات و تفاسیر + └── screens_trx/ # اسکرین‌شات‌های منابع متون رجالی راویان (Original Texts) +```