دراسة domain-model مرجعية
دراسة موديل نظام معلومات المستشفيات (HIS) لتصميم ERP النساء والتوليد
تحليل تنظيم موديل GNU Health مفتوح المصدر، وربطه بنظامك الحالي لاستخلاص أنماط تصميم مُجرّبة — مرجع مرافق لـ obgy-erp-analysis.md.
2026-06-15 · المرجع: GNU Health 5.0.5 (Tryton) · إعادة بناء مفاهيم، لا نسخ كود
55+موديول إكلينيكي في GNU Health
3 → 1توحيد stacks الـ antenatal
8أنماط تصميم تحل ديونك التقنية
0سطر كود منسوخ (آمن قانونياً)
| النشاط | الحالة |
| دراسة تنظيم الـ entities والعلاقات والـ workflows في GNU Health | ✅ مسموح — الأفكار والـ data models مش محمية بحقوق نشر |
| إعادة بناء المفاهيم من الصفر في الستاك بتاعك (PHP/Laravel) | ✅ سليم — إعادة تنفيذ مستقلة |
| نسخ كود GNU Health (Python/XML) داخل مشروعك | ❌ مخالف — ترخيص GPL/AGPL copyleft |
حقيقتان بتأمّنا الموضوع: (١) GNU Health مكتوب بـ Tryton/Python ونظامك PHP — مفيش أصلاً كود ممكن يتنسخ، بس مفاهيم. (٢) إحنا بنقرأ مشروع GPL مفتوح المصدر، فحتى قراءة الكود واضحة. كل اللي تحت "إيه اللي نبنيه" معبّر عنه كـ schema هدف — مفيش منه كود من GNU Health.
ملاحظة: الـ OCA vertical-medical ميت على Odoo 18 (ريبو فاضي، مفيش موديولات). المرجع الجاد الوحيد هو GNU Health (على منصة Tryton) — وهو المستخدم هنا.
| المشكلة عندك | نمط GNU Health | اللي تبنيه في الـ ERP |
الزوجين في صف واحد (wifename+husdandname) | فصل Party / Role | جدول party = أي شخص. جداول دور رفيعة: patient, health_professional كلها → party_id. الزوج = علاقة، مش عمود. |
| مفيش FKs (٣٠٠+ علاقة ضمنية) | كل علاقة Many2One مُعلنة | قيود FOREIGN KEY حقيقية + ON DELETE. التكامل في الـ DB، مش في PHP. |
| ٣ stacks متوازية للـ antenatal | aggregate حمل واحد (pregnancy) | master pregnancy واحد + صفوف prenatal_visit. احذف الـ stacks التانية. |
GPA متخزّن ومتضارب (pno/ab/ectopic) | GPA محسوب من قائمة الحمل | ماتخزنش Gravida/Para. احسبهم من COUNT(pregnancy) + عدّ النتايج. |
| ١٩٠ جدول dropdown (٦١٪ من الجداول) | Selection enums + كتالوجات قليلة | جدول واحد lookups(type,code,label) يستبدل ~١٥٠ جدول صغير. |
فصل الزيارة عن الإكلينيكي (مفيش visit_id) | Encounter هو جذر كل سجل إكلينيكي | كل sheet → encounter_id. الـ encounter يربط المريض + الطبيب + الحجز + التشخيص. |
| EAV + جداول semen/hormon متوازية | بنية lab عامة: كتالوج→طلب→نتيجة→سطر | lab_test_type واحد + lab_request + lab_result + lab_result_line. السائل المنوي والهرمونات = أنواع تحاليل، مش جداول. |
الدفع inline على visits (cash/visa/debt) | Service → Invoice؛ كل مفوتر = product | مستند service منفصل + invoice. الرسوم والتحاليل والأدوية كلها تشاور product. |
party (شخص أو منشأة؛ أعلام دور: is_patient, is_healthprof, is_institution, is_pharmacy)
├─ ref (PUID — معرّف شخص فريد)
├─ dob, gender, marital_status ← الديموغرافيا هنا، مرة واحدة
├─ person_name[] , alternative_ids[] (تاريخ الأسماء، الباسبور/الرقم القومي)
└─ du (وحدة سكنية / أسرة)
▲
┌───┴────────────┬─────────────────┐
patient health_professional institution
(سمات إكلينيكية) (رخصة، تخصص) (نوع، أسرّة، أجنحة)
ليه ده مهم ليك: مشكلة الزوج/الزوجة بتختفي. الاتنين صفوف party؛ المريضة غلاف patient؛ الزوج party مربوط بصف علاقة (family_member دوره "husband"). والشخص اللي هو مريض وموظف في نفس الوقت = سجل واحد.
| الغرض | كيان GNU Health | عمود visits عندك دلوقتي |
| الحجز / الطابور | appointment free→confirmed→checked_in→done→no_show | visitdate, visitorder, visit_period |
| الكشف الإكلينيكي | patient.evaluation in_progress→done→signed | (مفقود — الداتا الإكلينيكية سايبة) |
| الفلوس | health_service → invoice | detectionvalue_cash/_visa/... |
الـ Encounter هو المحور: يربط المريض + الحجز + الطبيب + الشكوى + العلامات الحيوية + التشخيص + صفوف فرعية (أعراض/إجراءات)، وعند التوقيع (sign) يتقفل للقراءة فقط — نمط تدقيق (audit) ناقص عندك حالياً.
patient (الأم، biological_sex='f')
│
├─ menstrual_history[] (LMP، طول الدورة، منتظمة؟، عسر طمث، تكرار/كمية)
├─ pap_history[] (نتيجة Bethesda: NILM/ASC-US/LSIL/HSIL/AIS…)
├─ mammography_history[] (طبيعي/غير طبيعي + آخر تاريخ)
├─ colposcopy_history[]
│
└─ pregnancy[] ◄── master واحد لكل حمل (توحيد ancsheet/mainantenental/followup)
├─ gravida (رقم # فريد لكل مريضة)
├─ current_pregnancy (bool — واحد بس مسموح، مُتحقَّق منه)
├─ lmp → pdd (EDD = LMP + 280 يوم)
├─ fetuses, monozygotic (دعم الحمل المتعدد)
├─ pregnancy_end_result (live_birth/abortion/stillbirth) + end_date
│
├─ prenatal_evaluation[] ← زيارات المتابعة (antenatal)
│ gestational_weeks = (visit_date − lmp)/7 [محسوب، مش متخزّن]
│ fundal_height, fetus_heart_rate, EFW, BPD/AC/HC/FL,
│ hypertension, preeclampsia, diabetes, placenta_previa, IUGR…
│
├─ perinatal[] ← حدث الولادة
│ admission_date, delivery_mode (SVD/vacuum/forceps/CS),
│ presentation, episiotomy, laceration, مضاعفات المشيمة
│ └─ monitoring[] ← صفوف partograph أثناء المخاض (ضغط، اتساع، نبض جنين)
│
├─ puerperium_monitor[] ← صفوف النفاس (lochia كمية/لون/رائحة، ارتجاع الرحم)
│
└─ pregnancy_result[] ← نتيجة لكل جنين
└─ newborn → party (المولود شخص حقيقي)
└─ سجل المولود (APGAR ١/٥، وزن/طول/HC، فحوصات، ردود أفعال)
اختيارات تصميم توليدية تستحق النقل (كمفاهيم)
| الاختيار | الفايدة عندك |
| EDD = LMP + 280 يوم، وعمر الحمل يُعاد حسابه عند الطلب — مايتخزّنش أبداً | يحل منطق الـ EDD المكرر، ومفيش داتا قديمة بايتة |
| GPA مُشتق: Gravida = عدد الحمول؛ الإجهاض/الإملاص/المبتسر = عدّ حسب النتيجة | يقتل أعمدة pno/ab/ectopic المبعثرة في كل sheet |
| إدخال أمامي vs "عكسي": حمل حالي (LMP) أو حمل سابق (تاريخ نهاية + أسابيع، ويُحسب LMP عكسياً) | يطابق بالظبط فصلك بين "تاريخ" و"حمل نشط" — كيان واحد بعلم reverse |
| حمل نشط واحد ثابت كقاعدة (invariant) | يمنع تكرار/تضارب سجلات الحمل |
| صف نتيجة لكل جنين → يربط المولود كـ شخص حقيقي | كده registeration/حجز الولادة بيدخّل المولود في سجل المرضى |
التحاليل (Investigations) — بديل الـ EAV وجداول semen/hormon
lab_test_type (كتالوج) مثال: "Semen Analysis"، "Hormonal Profile"، "CBC"
├─ code, category, specimen_type
├─ product_id → يخليه مفوتر
└─ analyte_template[] (سطور النتيجة المتوقعة: count, motility, morphology / FSH, LH, E2…)
lab_request (الطبيب يطلب test_type لمريض؛ state draft→ordered→tested)
lab_result (مستند النتيجة؛ state draft→done→validated؛ validated_by + وقت)
└─ analyte_line[] name, result(float) | result_text, units, lower/upper limit, WARNING لو بره المدى
ضربة مباشرة لديونك: semen/semen2/semeninfertility وhormon/hormonalprofile/hormonalprofile2 مش جداول جديدة — دول صفّين lab_test_type بقوالب analytes مختلفة. والـ otherinvestigations EAV بيبقى analyte_lines منظّمة بوحدات ومديات مرجعية وتنبيه آلي بره المدى.
الأدوية والصيدلية
medicament (كتالوج: يغلّف product؛ active_component, strength+unit, route, form,
pregnancy_category A–X, pregnancy_warning) ← أمان مهم لتخصصك
prescription_order (header: patient, prescriber, pharmacy؛ بوابة ACK لتحذير حساسية/حمل؛ state)
└─ prescription_line[] medicament, dose+unit, frequency, indication→pathology, refills
└─ stock_move (الصرف بيخصم من مخزون الصيدلية)
الخدمات والفوترة
health_service (header: patient, date) ← كل المفوتر بيتجمّع هنا
└─ service_line[] product, qty, to_invoice → invoice
المطابقة: drugs/recepittmp/receiptdrugs + currentbalance → كتالوج medicament + prescription_order/line + stock move (بدل تعديل عمود رصيد). وdetections + مدفوعات visits → product + health_service + invoice.
| القديم (نظامك) | الكيان الهدف | ملاحظات |
patients (زوجين) | party (×٢) + patient + family_member | افصل الزوج المدمج |
awusers (كأطباء) | party + health_professional | الرخصة/التخصص على الغلاف |
visits | appointment + encounter + service | افصل التلات أغراض |
detections | product | كتالوج الرسوم |
ancsheet/mainantenental/followup | pregnancy (واحد) | توحيد ٣ → ١ |
ancnewvisit/antenalvisit/followupvisit | prenatal_visit | جدول أبناء واحد |
*us/ultrasoundobst | حقول biometry في prenatal_visit (+ imaging_study) | بيومتري منظّم |
الولادات/operativedetails | perinatal (+ perinatal_monitor) | حدث الولادة + partograph |
| داتا النفاس | puerperium_monitor | lochia/ارتجاع |
registeration/المولود | pregnancy_result → party → newborn | المولود يبقى مريض حقيقي |
phmenstrual | menstrual_history | اربطه بالـ encounter |
phobstetric/wifep/awifep | مُشتق من pregnancy[] | احسب GPA، ماتخزنش |
infertility*/ivfsheet/mointoringsheet | موديول ART مخصّص (قسم ٧) | اعمله aggregate زي pregnancy |
semen*/hormon* | lab_test_type + lab_result + analyte_line | نوعين تحاليل، مش ٦ جداول |
invests/otherinvestigations (EAV) | lab_test_type/analyte_line | منظّم بمديات |
drugs/recepittmp/pharmacystore | medicament/prescription_*/stock_move | المخزون عبر moves |
totalbalance/التقارير المالية | health_service → invoice + مدفوعات | حسابات مدينة سليمة |
~١٩٠ جدول id/title/del | lookups(type,…) أو enums | تجميع |
مفيش في GNU Health موديل عميق لدورات IVF/ICSI/IUI، ولا folliculometry، ولا تقييم أجنّة، ولا بروتوكولات تنشيط. جداولك ivfsheet/mointoringsheet/folliculom وأبناء التنشيط والأجنّة دي قيمتك الحقيقية. التوصية: خليها موديول ART من الدرجة الأولى، بس ابنيها بنفس نمط الـ aggregate بتاع الحمل:
art_cycle (master: patient, cycle_type ICSI/IVF/IUI, protocol, start_date, outcome)
├─ stimulation_day[] (folliculometry: تاريخ، أحجام جريبات، E2، سُمك البطانة)
├─ procedure (OPU/ET) (بويضات، أجنّة، درجة، تاريخ نقل، عدد المنقول)
└─ outcome → يربط بـ pregnancy[] (β-hCG → حمل سريري → الـ aggregate فوق)
الفايدة الكبيرة: الدورة الناجحة تولّد سجل pregnancy — فيبقى عندك خط متصل: عقم → دورة → حمل → ولادة → مولود، وهو اللي تصميمك الحالي بالجداول المتوازية مش قادر يعبّر عنه.
- العمود الفقري للهوية + الزيارة أولاً:
party / patient / health_professional / appointment / encounter. كل حاجة بتتعلّق بده.
- aggregate الحمل:
pregnancy + prenatal_visit + perinatal + puerperium_monitor + pregnancy_result/newborn. رحّل الـ ٣ stacks لجواه.
- التحاليل + الصيدلية:
lab_* وmedicament/prescription_* العامة. ادمج semen/hormon/EAV هنا.
- الفوترة:
product + health_service + invoice بدل فلوس visits الـ inline.
- موديول ART (قيمتك الخاصة)، مربوط بالحمل.
- جمّع الـ lookups، وضيف قيود FK، وافرض UTF-8 في كل مكان، وparameterize كل الاستعلامات (يقتل فئة الـ SQL injection بالكامل).
| مصدر GNU Health | https://codeberg.org/gnuhealth/his.git (مستقر 5.0.5) |
| الموديولات المحللة | health, health_gyneco, health_pediatrics, health_lab, health_services, health_inpatient, health_stock |
| نظامك | obgy-erp-analysis.md |
| النسخة النصية لهذا التقرير | his-gnuhealth-vs-obgy-analysis.md |