قاعدة البيانات تضم 312 جدولًا بدون أي مفتاح أجنبي مُعلن (Declared Foreign Key) على الإطلاق؛ جميع العلاقات «ضمنية» تُفهم من تسمية الأعمدة (patientid, doctorid, ancsheetid, ...) ومن جمل JOIN داخل الكنترولرات في core/controllers. هذا القسم يرسم الخريطة الكلية: الكيانات المحورية الأربعة (المريضة، الزيارة، المستخدم، الفرع)، والعلاقات الرئيسية بينها وبين الموديولات الإكلينيكية، وأنماط التصميم الثلاثة المتكررة (نمط الشيت الأب وأبنائه، نمط جداول الترميز الصغيرة، نمط EAV للتحاليل الحرة)، ثم قائمة الجداول المكررة والمهجورة المكتشفة في الـ dump.
patients — مركز النظام بأكمله: يرتبط به 73 جدولًا مباشرة عبر العمود patientid (وأحيانًا patient_id): الزيارات، كل الشيتات الإكلينيكية (حمل/نساء/عقم/حقن مجهري/متابعة تنشيط)، كل جداول التاريخ المرضي ph*، الفحوصات والأشعة والمناظير، الأدوية والتحاليل، الأرصدة المالية، الملفات المرفوعة. السجل الواحد يضم الزوجة والزوج معًا.awusers — المستخدمون والأطباء: يرتبط به 59 جدولًا عبر أعمدة متعددة الأسماء: doctorid (في ~45 جدولًا إكلينيكيًا)، userid/user_id (إدخال البيانات)، memberid (موديول البورد)، assistantid/anasthetstsid (فريق العمليات)، enddoctorid (إنهاء الزيارة)، sender_id/receiver_id (الرسائل). مفتاحه الأساسي user_id وليس id — استثناء عن بقية الجداول.visits — حركة الاستقبال اليومية: يرتبط صعودًا بـ patients.id وdetections.id (نوع الكشف وسعره) وvisit_periods.id (الفترة) وawusers وbranches. لافت أن الجداول الإكلينيكية لا تشير إلى الزيارة إطلاقًا — لا يوجد عمود visitid إلا في visits نفسه وvisits_updates (سجل التدقيق)؛ فالربط الإكلينيكي كله يتم عبر patientid + التاريخ، وهذه نقطة ضعف بنيوية تمنع ربط أي إجراء بزيارة بعينها.branches — الفروع: كيان حديث الإضافة؛ لا يرتبط به سوى جدولين: awusers.branch_id وvisits.branch_id — أي أن تعدد الفروع مطبق على مستوى الاستقبال والمستخدمين فقط، وكل البيانات الإكلينيكية مشتركة بين الفروع.infertilitysheet يرتبط به 17 جدولًا عبر infertilitysheetid (أكبر شيت في النظام)، ancsheet يرتبط به 6 جداول عبر ancsheetid، mointoringsheet له 3 جداول أبناء عبر mointoringsheetid و9 جداول ترميز خاصة به، وivfsheet جدولان (eprep, ovst).| من (الجدول الابن) | إلى (الجدول الأب) | عمود الربط | النوع |
|---|---|---|---|
visits, old_visits, endvisitreports, lastvisit | patients | patientid → patients.id | 1:N |
الشيتات الأم: ancsheet, gynasheet, infertilitysheet, ivfsheet, mointoringsheet, followupcard, mainantenental, maingyna | patients | patientid → patients.id | 1:N (عمليًا 1:1 في gynasheet/infertilitysheet) |
التاريخ المرضي: phobstetric, phmenstrual, phfamily, phcontraception, phpastmedical, phpastsurgical, phpastgynecological, phpastart, phpasticsi, previous_marriage, hus_previous_marriage | patients | patientid → patients.id | 1:N |
الأشعة والمناظير: ultrasound, ultrasoundgyna, ultrasoundobst, gynaus, ustv, sonar, gtimage, hsg, hysteroscopy, laparoscopy, mrict, pathology, semen, hormon | patients | patientid → patients.id | 1:N |
visits | detections / visit_periods / branches / awusers | detectionid → detections.id، visit_period → visit_periods.id، branch_id → branches.id، user_id / enddoctorid → awusers.user_id | N:1 |
visits_updates, patients_updates | visits, patients | visitid → visits.id، patientid → patients.id (+ userid_edit) | 1:N (سجل تدقيق) |
ancsheetdrugs, ancsheetinvest, ancnewvisit, investigations, registeration, op_4d_list | ancsheet | ancsheetid → ancsheet.id | 1:N |
17 جدولًا منها: newvisit, tvs, dtvs, sis, folliculom, hormonalprofile, hormonalprofile2, semen2, semeninfertility, hsginfertility, hysteroscopyinfertility, laparoscopyinfertility, icsi, operations, wifep, awifep, wifeepc | infertilitysheet | infertilitysheetid → infertilitysheet.id | 1:N |
newvisitg | gynasheet | gynasheetid → gynasheet.id | 1:N |
gynasheetdrugs, gynasheetinvest, infertilitysheetdrugs, infertilitysheetinvest | gynasheet / infertilitysheet (عبر المريضة) | patientid فقط — لا يوجد عمود sheetid (شيت واحد لكل مريضة) | 1:N غير مباشر |
mointoringsheetdrugs, mointoringsheetinvestigation, mointoringsheetvisits | mointoringsheet | mointoringsheetid → mointoringsheet.id | 1:N |
mointoringsheet | 9 جداول ترميز: mointoringsheetprocedure/protocol/ejac/pesa/tese/sryo/hmg/agonist/hcg | procedure/protocol/... → {lookup}.id (مؤكدة بـ LEFT JOIN في الكنترولر) | N:1 |
eprep, ovst | ivfsheet | ivfsheetid → ivfsheet.id | 1:N |
followupcarddrugs | followupcard | cardid → followupcard.id | 1:N |
followupvisit, followupinvest, followupexam, followupdiagnosis | followup | followid → followup.id | 1:N |
13 جدول *drugs + pharmacystore + receiptdrugs + importdetails | drugs | drugid / drug_id / drugs_id → drugs.id | N:1 |
6 جداول *invest / *investigation | invests → investcats | investid → invests.id، invests.investcatid → investcats.id | N:1 |
*drugs ↔ recepittmp | recepittmp ← patients/awusers | recepittmpid → recepittmp.id؛ recepittmp.patient_id/doctor_id | N:1 |
otherinvestigationsvalues | otherinvestigationsrows + otherinvestigations | investrowid → rows.id، investid → otherinvestigations.id | N:M (نمط EAV) |
operativedetails, operativedetailsdrugs, operationids | operations / awusers | operationid → operations.id؛ doctorid/assistantid/anasthetstsid → awusers.user_id | 1:N + N:M (فريق العملية) |
gynausficils | gynaus | gynausid → gynaus.id (مؤكدة بـ JOIN) | 1:N |
presenthistoryanswers | presenthistoryquestions | catid/answerid في جداول الشكوى (مؤكدة بـ JOIN) | N:1 |
awusers | awrole / branches | role_id → awrole.id، branch_id → branches.id | N:1 |
awrolemenu, awrolecontrollprop, awrolebtn | awrole ↔ awmenu / awcontrollprop | role_id + menu_id / ... | N:M (صلاحيات) |
bsession, bsessionmembers, bcomments, bmemberopenion, brequests | bsession ↔ awusers | sessionid + memberid | N:M (بورد الأطباء) |
totalbalance, totalbalancepaids | patients / awusers | patientid, userid | 1:N (مالية) |
device_tracking | patients / awusers / أي جدول | patient_id, user_id, target_id + target_table (مرجع متعدد الأشكال Polymorphic) | N:1 |
*drugs (روشتة: drugid, drugtype, drugdos, forhusband, recepittmpid) وجدول *invest (تحاليل: investid, investresult, forhusband) وأحيانًا *us (سونار) و*visits (زيارات متابعة). الأمثلة: ancsheet→(ancsheetdrugs, ancsheetinvest, ancnewvisit)، gynasheet→(gynasheetdrugs, gynasheetinvest, newvisitg)، infertilitysheet→(infertilitysheetdrugs, infertilitysheetinvest, newvisit + 14 جدول فحوصات)، mointoringsheet→(drugs, investigation, visits)، mainantenental→(drugs, invest, us)، followupcard→(followupcarddrugs). البنية متطابقة لكنها منسوخة بالكامل لكل تخصص بدل توحيدها في جدول واحد بعمود نوع.id + title/name + del/deleted فقط، يغذي قائمة منسدلة واحدة في الشاشات. وصل الأمر إلى تخصيص جدول مستقل لكل حقل منسدل حتى داخل الموديول الواحد: 9 جداول لشيت التنشيط (mointoringsheet*)، 14 جدولًا لتقرير المنظار الرحمي/البطني (copy*, lapar*)، 7 جداول لنتائج السائل المنوي (semen2result*, semen2place*)، وجداول التاريخ المرضي ph*.otherinvestigations (تعريف التحليل/العمود) ← otherinvestigationsrows (صف لكل مريضة + تاريخ + طبيب) ← otherinvestigationsvalues (القيمة: investrowid + investid + value). يسمح بإضافة أنواع تحاليل جديدة دون تعديل البنية، على حساب صعوبة الاستعلام والتقارير.patients_updates وvisits_updates نسخ كاملة من بنية الجدول الأصلي مضافًا إليها userid_edit/date_edit لحفظ النسخ القديمة قبل التعديل.deleted, del, tempdelete, status — يجب مراعاتها جميعًا عند أي ترحيل.device_tracking.target_id + target_table يشير إلى أي جدول بالاسم، وrecepittmp.drugstablename يحدد جدول الروشتة المصدر نصيًا.| المجموعة | الجداول | الملاحظة |
|---|---|---|
| جداول تجارب مهجورة | table2, table3, tablename, testtbl1, testtbl2, patients_tmp | مخلفات تطوير بلا أي استخدام في الكود — آمنة الحذف بعد التحقق |
| استنساخ رباعي لنفس القائمة | ssemen, sseemen, sseemmen, sseemmeen | 4 جداول ترميز متطابقة البنية، أنشئ واحد لكل عمود من أعمدة السائل المنوي الأربعة في ivfsheet (ssemen/sseemen/sseemmen/sseemmeen) بدل جدول واحد بعمود نوع |
| أزواج شبه مكررة | antype/antypes، place/place2، importdetails/importtdetails، hormonalprofile/hormonalprofile2، semen/semen2، excelinfo/excelinfopatients | أجيال متعاقبة من نفس الوظيفة بقيت جنبًا إلى جنب (الإصدار 2 هو المستخدم غالبًا) |
عائلة copy* | copycavity, copycx, copydil, copyintrod, copylostium, copyrostium, copyplace + نسخ copym* (mcavity, mcx, mlostium, mrostium) | 10 جداول ترميز لتقرير المنظار الرحمي بدأت كنسخ (copy) وأصبحت أصلية، مع نسخة m* ثانية لكل منها تقريبًا |
| بيانات تاريخية | old_visits | أرشيف زيارات بنية قديمة (قبل إضافة الفروع والفترات) — للقراءة فقط |
| موديولات ANC متوازية | ancsheet+ancnewvisit مقابل mainantenental+antenalvisit مقابل followup+followupvisit | ثلاثة أجيال لمتابعة الحمل تعمل بالتوازي في الكود، لكل منها جداول أدوية/تحاليل خاصة |
| جداول معطلة/غير مفعلة | patientfiles, patients_updates (جزئيًا), help, messages | موجودة بالبنية لكن الكود الفعّال لا يكتب فيها أو يتجاوزها (استنتاج من مراجعة الكنترولرات) |