🔬 تدقيق شامل — منظومة الأجهزة والميدل وير في الـLIS

دراسة متعمّقة للوضع الحالي + المشاكل + اقتراحات التظبيط + البيانات الناقصة + الإعدادات الجديدة المقترحة

Moon ERP · وحدة LIS · على نطاق: الميدل وير (Python) + شاشة الأجهزة + الكاتلوج + إعداد الجهاز

📅 13 يونيو 2026 🔄 محدّث بعد جلسة الإصلاحات ✅ 8 إصلاحات منشورة 📡 Query شغّال — راك كامل 🌿 lis/lab-updates + Modules/LIS
8
إصلاحات اتعملت ونُشرت في جلسة 13 يونيو ✅
استعلام الـMaglumi (Query) شغّال — راك كامل بيتقرا 100%
3
محاور لسه مفتوحة (أكواد دقيقة · تحاليل مكرّرة · موثوقية)
30+
تحسينات/إعدادات مقترحة باقية للمدى المتوسط

الخلاصة التنفيذية

المنظومة مبنية بالكامل ومتكاملة من حيث الهيكل — الميدل وير بيستقبل من الأجهزة وبيرفع للكلاود، الكلاود مصدر الحقيقة للأجهزة، والكاتلوج + شاشة الربط موجودين. لكن فيه فجوات جوهرية بتمنع التشغيل الإنتاجي الموثوق، وأهمها متكررة عبر أكتر من طبقة:

🟢 تحديث 13 يونيو — اتجاه الاستعلام (Query) بقى شغّال إنتاجياً: بعد سلسلة إصلاحات، الـMaglumi دلوقتي بيعمل query لراك كامل (5+ عينات) وكل العينات بتتقرا 100% وبيرجعلها التحاليل الصح. الباقي = ضبط بيانات (أكواد دقيقة + تحاليل مكرّرة) مش أعطال كود.
🔴 المحاور اللي لسه مفتوحة:
  • الأكواد لازم تطابق اسم الـassay على الجهاز بالحرف — الجهاز بيتجاهل أي كود مش متعرّف عنده (مثلاً قبل TSH II ✅ بس FT4 III ❌). الحل: نلتقط الأكواد الحقيقية من نتايج الجهاز أو من شاشة الـassays.
  • تحاليل مكرّرة بأسماء/أرقام مختلفة — نفس التحليل متعمل مرتين (مثال Vitamin D رقم 151 و 2567)، فالطلب بيستخدم نسخة والربط على نسخة تانية → التحليل ميرجعش. يتحل بـmulti-mapping أو دمج المكرّرات.
  • الموثوقية + مطابقة رقم العينة + الباقات — الميدل وير لسه مفيش له Windows Service/watchdog؛ ورقم العينة الداخلي مقابل الباركود؛ وتوسيع الباقات — كلها باقية للمدى المتوسط.

التقرير بيقسّم المشاكل حسب الخطورة: CRITICAL HIGH MEDIUM LOW · RESOLVED — وبيدّي لكل بيان ناقص طريقة عملية للإضافة.

ما تم إصلاحه ونُشر — جلسة 13 يونيو 2026

كل ده اتعمل واتنشر (الميدل وير على الويندوز + الكلاود لايف + الـFE على /app/).

#المشكلةالإصلاحالمكان
1صف الجهاز يظهر «متوقف» رغم إنه شغّالمفتاح portlisten_port في الـstats عشان يطابق مفتاح شاشة الـadminastm_tcp_server.py
2الميدل وير بيسمح بإضافة/تعديل أجهزة يدوي (يخالف الكلاود)شاشة admin بقت قراءة فقط — الأجهزة من الكلاود بس + توجل تشغيل لكل محطةadmin.py
3الاستعلام يرجّع تحليل واحد بس (شكل الرد)كل التحاليل كـrepeats في O record واحد + كل record في فريم STX..ETX منفصلastm_base.py · astm_tcp_server.py
4راك متعدد العينات: عينات بالتبادل بتضيعحلقة الاستقبال بقت تتجاهل بايتات ACK/NAK اللي كانت بتتزرع جوّه الرسالة وتبوّظ الباركود (زي maglumi.py)astm_tcp_server.py
5الاستعلام يرجّع أكواد قديمة/محذوفة (FERR/FT4/FT3)إضافة whereNull('deleted_at') + unique() — الـraw query كان بيتجاهل الـsoft-deleteLabMachineController::orders()
6إنشاء mapping يفشل بـduplicate (صف محذوف ماخد المكان)الحفظ بقى يرجّع الصف المحذوف ويحدّثه بدل insert جديدLabMachineTestMappingController::store()
7شاشة machine-setup فيها 3 أماكن مكرّرة للربطدمج في جدول واحد (كاتلوج + يدوي) + صف إضافة واحد — اتشال الجدول المكرّرmachine-setup (FE)
8بحث التحاليل بيحمّل الآلاف client-sideserver-side search (debounce + 50 نتيجة) مع تثبيت المربوطmachine-setup (FE)
+ أداة تشخيص: الميدل وير دلوقتي بيأرشِف الرد الصادر (direction=outgoing) في الكلاود — فنقدر نشوف بالظبط اترسل إيه للجهاز من غير الوصول للويندوز.

🔬 دروس تكامل Maglumi (مثبتة بالبيانات)

الخطوة العملية الجاية: تشغيل كل assay مرة واحدة على الجهاز → نلتقط الأكواد الحقيقية من machine-results → نظبط كل الـmappings بالحرف. وبعدها multi-mapping للتحاليل المكرّرة.

المعمارية والوضع الحالي

أجهزة المعمل الميدل وير (Python, on-prem) Moon ERP Cloud (Laravel) ┌──────────────┐ TCP/Serial ┌────────────────────────────┐ HTTPS ┌─────────────────────────┐ │ Maglumi 800 │ ─ ASTM/TCP ──▶ │ astm_tcp_server (متسامح) │ ────────▶ │ POST /lis/machine-results│ │ Dymind DH36 │ ─ HL7/MLLP ──▶ │ server (HL7) │ │ POST .../heartbeat │ │ (Serial ASTM)│ ─ RS232 ─────▶ │ serial_server (صارم) │ ◀──────── │ GET .../orders?barcode= │ └──────────────┘ │ outbox (SQLite) → uploader │ query │ GET /lis/machines │ │ admin UI :8765 (قراءة فقط) │ │ device-models (كاتلوج) │ └────────────────────────────┘ │ machine-test-mappings │ └─────────────────────────┘ اتجاهان: (1) نتيجة: باركود+قيم ──▶ تتسجّل | (2) استعلام: باركود ──▶ يرجّع أكواد التحاليل المطلوبة
الطبقةالمكوّنالحالة
الميدل ويرlis-middleware/ (app, cloud, buffer, drivers, *_server, admin)يعمل بنقاط ضعف في الموثوقية والأمان
شاشة الأجهزةfeatures/lis/machines + LabMachineControllerيعمل · orders() اتصلّح (soft-delete) · كود ميت + بيانات وهمية باقية
الكاتلوجdevice-catalog + LabDeviceModelمبني لكن فارغ (مفيش seeder)
إعداد الجهازmachine-setup + machine-test-mappingsاتحسّن · جدول موحّد + server search + إصلاح الـduplicate · باقي: multi-mapping

١ الميدل وير (Python on-prem)

كيف يعمل الآن

المشاكل والفجوات

الخطورةالمشكلةالتفصيل والإصلاح المقترح
CRITICALلا توجد مراقبة للعملية (process supervision)مفيش Windows Service / watchdog / auto-restart / تشغيل عند الإقلاع. لو العملية ماتت، النتايج بتقف بصمت. الحل: سكربت تثبيت NSSM أو Task Scheduler مع «إعادة تشغيل عند الفشل + تشغيل عند الإقلاع» داخل الريبو.
CRITICALعدم مطابقة رقم العينة ↔ الباركودالجهاز يبعت رقمه الداخلي مش باركود النظام. الحل: endpoint بحث عكسي في الكلاود GET /lis/machines/{id}/resolve-sample?analyzer_no= + استراتيجية محلية sample_number_map في connection_settings.
CRITICALالأسرار في config.json بنص واضحالتوكن/الإيميل/الباسوورد غير مشفّرين، وGET /api/config بيرجّعهم حرفياً. الحل: إخفاء الأسرار في الردود (****) + تفضيل توكن خدمة على تخزين باسوورد + DPAPI على ويندوز.
HIGHشاشة admin بدون مصادقة افتراضياًadmin_password فاضي = مفتوح للكل. خطير لو الـhost اتغيّر لـ0.0.0.0. الحل: إلزام باسوورد لما الـhost ≠ 127.0.0.1.
HIGHصفوف الرفع 4xx لا تُحل أبداً (poison rows)422/404 بتفضل pending وتتعاد كل 20 ثانية للأبد وتضخّم عدّاد الانتظار. الحل: تصنيف الأخطاء — 401/403→re-auth، 422/404→dead-letter يظهر للمشغّل، 5xx/شبكة→إعادة.
HIGHفشل الـheartbeat غير مرئيlog.debug فقط — الجهاز بيقع offline في الكلاود من غير أي إشارة. الحل: log.warning + تتبّع last_heartbeat_at/last_heartbeat_error في status().
HIGHالتوكن لا يُحفظ ويُعاد تسجيل الدخول عند كل reloadكل save/sync بيعمل CloudClient جديد ويرمي التوكن → login متكرر. الحل: تمرير التوكن عبر reload.
HIGHإطار ASTM (framing) فضفاض وغير متطابق بين النقلينالـTCP يتجاهل FN/checksum (يصلح لـMaglumi بس)، والـSerial صارم — سلوك مختلف لنفس الدرايفر. الحل: flag لكل جهاز astm_strict_framing.
MEDIUMوقت/توقيت ساذج + إهمال توقيت الجهازالـoutbox يختم بالتوقيت المحلي بدون tz، وطابع وقت نتيجة الجهاز (ASTM R-13) يُحلّل ثم يُرمى. الحل: تمرير result_at + ختم UTC ISO-8601.
MEDIUMاستعلام أوفلاين يرجّع «لا طلبات»لو الكلاود بطيء/مقطوع، الاستعلام يردّ «مفيش تحاليل» — أسوأ من الفشل (الأنبوبة ممكن تتخطّى). الحل: إعداد order_offline_behavior.
MEDIUMاتصال SQLite واحد + DELETE عند الإرسالمفيش أرشيف محلي دائم لما اترفع. الحل: جدول sent أو status='sent' مع تقليم دوري.
LOWتسريب PHI في اللوج / كود ميتmllp.feed يسجّل كل chunk خام (HL7 مريض) على INFO؛ KNOWN_DRIVERS قديمة؛ work_orders() dead code؛ سطور replace("\r","\r") وغيره.
↑ أعلى

٢ شاشة الأجهزة (Machines list — FE + BE)

كيف تعمل الآن

المشاكل والفجوات

الخطورةالمشكلةالتفصيل
CRITICALtotal_results_today بيانات ميتةموجود في الموديل/الـResource/الـstatus لكن لا يُزاد ولا يُصفّر أبداً — دايماً 0. إمّا نوصّله (زيادة عند الـstore + reset يومي) أو نشيله.
CRITICALتضارب 5 دقايق مقابل 30 دقيقةis_online = 5 دقايق، بينما status() يثبّت Offline بعد 30 دقيقة. وبما إن الـFE لا يستدعي /status أصلاً، فإن connection_status المخزّن «يُكتب Online فقط» ولا يرجع Offline أبداً.
CRITICALconnection_status = Error لا يُضبط أبداًالقيمة موجودة في الـEnum لكن مفيش endpoint بيضبطها. جهاز في حالة خطأ فعلي بيفضل أخضر/Online طول ما الـheartbeat واصل.
HIGHتبويبة النتايج تعرض قيم فاضيةالـHTML يربط raw_value/processed_value بينما الـResource يرجّع raw_result/parsed_result → كل خلية تعرض «-».
HIGHلا يوجد إظهار للأخطاء/الصحة في القائمةعمود الاتصال ثنائي بس (online/offline). مفيش «آخر خطأ» ولا عدّاد أخطاء ولا badge.
HIGHلا يوجد «اختبار اتصال» من الكلاودمفيش endpoint/زر يفحص الجهاز فعلياً — المشغّل بس بيستنى heartbeat.
HIGHلا يوجد scoping للفروعindex مفلتر بالشركة فقط بدون branch_id — مستخدم الـspoke بيشوف أجهزة كل الفروع.
HIGHendpoints الإدخال بدون صلاحياتheartbeat, storeCommunicationLog, orders, agentConfig, work-orders, وmachine-results store بدون permission middleware — أي توكن يقدر يضخ نتايج/heartbeat.
MEDIUMنموذجان متنافسان (~500 سطر ميت)النموذج اليدوي القديم (Basic/Connection/Dates/Cost) غير قابل للوصول لكنه باقٍ — خطر صيانة + يكتب مفاتيح connection_settings مختلفة.
MEDIUMالربط (mappings) لا يُدار من هناالشاشة لا تستورد LisMachineTestMappingService إطلاقاً؛ لو مفيش mapping كل النتايج تفضل pending للأبد — ومفيش UI هنا لإنشائها.
MEDIUMstatus() يعدّل داخل GETside-effect على قراءة + N استعلامات بدل bulk update.
MEDIUMتضارب enum للتكلفةالـFE: per_test/hourly/depreciation بينما الـBE: per_test/time_based — كسر عقد كامن.
↑ أعلى

٣ كاتلوج الأجهزة (Device Catalog)

كيف يعمل الآن

المشاكل والفجوات

الخطورةالمشكلةالتفصيل
CRITICALلا يوجد كاتلوج مزروع (seeder)مفيش أي seeder بيملأ lab_device_models — كل معمل بيبدأ بكاتلوج فاضي ولازم يدخّل كل جهاز/كود/وحدة/رينج بإيده. ده بيلغي فكرة «اضبط مرة واحدة».
CRITICALقائمة الدرايفرات hardcoded في الـFEالدرايفرات الصالحة في component واحد (4 عناصر)، والاشتقاق driverFromProtocol هش (name.includes('mispa')?...:maglumi_astm). إضافة جهاز خامس بيشتق غلط بصمت. الـBE: عمود driver نص حر بدون enum/registry.
HIGHprotocols/transports مش data-driven بشكل نظيفالـtransport مدسوس جوّه نفس مصفوفة protocols (مثال ["astm","serial","tcp"]) ويُفصل بـstring-filter في 3 أماكن. مفيش عمود transports.
HIGHخريطة code→investigation ليست على مستوى الكاتلوجالربط الفعلي يُنشأ لكل جهاز بمطابقة fuzzy وقت الإنشاء — كل نسخة جهاز تطابق بشكل مستقل وهش، وبدون LOINC.
HIGHازدواج بين الكاتلوج وconnection_settingsbarcode_fields/driver منسوخين snapshot — تعديل الكاتلوج لا ينتشر للأجهزة الموجودة. value_types/send_ack غير موجودين في الكاتلوج أصلاً.
HIGHالـranges تُنسخ snapshot بدون حمايةcopyRanges يـinsert بدون dedup — إنشاء جهازين من نفس الموديل يكرّر الـranges على نفس الـinvestigation.
MEDIUMتغطية الأجهزة الحقيقية ≈ صفر3 درايفرات بس متصوّرة (Dymind/Maglumi/Mispa) + JSON. مفيش Sysmex/Mindray/Cobas/Architect/Beckman/Erba/Horiba.
MEDIUMنقص LOINC/الوحدات/الدقة على صفوف الكاتلوجlab_device_model_tests مفيهاش loinc_code/decimal_places/result_type — الكاتلوج متأخّر عن باقي الـLIS.
↑ أعلى

٤ إعداد الجهاز / الربط (Machine-Test Mapping)

كيف يعمل الآن

المشاكل والفجوات

الخطورةالمشكلةالتفصيل
CRITICALالباقات (Panels) لا تتوسّعالربط صارم investigation_id → كود واحد. باقة CBC = investigation واحد = كود واحد، فالـ13 محلّل الباقيين ملهمش هدف ربط ونتايجهم تتجاهل بصمت. أكبر فجوة وظيفية.
CRITICALالكود غير المعروف = إسقاط صامتلو مفيش mapping، الصف يتسجّل Pending ومفيش أي حاجة تانية — لا خطأ ولا تنبيه ولا تمييز عن «مستني مطابقة يدوية». كود مكتوب غلط بيختفي.
CRITICALعدم معالجة رقم العينة مقابل الباركودالمطابقة متربطة بـbarcode فقط؛ كتير من الأجهزة بترجّع رقم العينة/الـaccession. لو اختلفوا → إسقاط صامت. مفيش fallback ولا إعداد لاختيار حقل الهوية.
HIGHلا يوجد تحويل وحداتيخزّن وحدة الجهاز كما هي. لو الجهاز mg/dL والرينج mmol/L → flags خاطئة سريرياً. عمود unit وصفي بس.
HIGHلا توجد معالجة لنوع القيمةكل حاجة تُخزّن string ويتفرّع بس على is_numeric. النتايج المرمّزة (POS، <0.01، تيتر 1:160) والنصية تُخزّن حرفياً بدون تطبيع، وresult_type للـinvestigation لا يُستشار.
HIGHflags الجهاز تُهملflag الجهاز (HL7 OBX-8) لا يُلتقط؛ النظام يعيد الحساب بنفسه — مفيش سجل لاختلاف الجهاز/النظام (إشارة QC مفيدة).
HIGHازدواج الربط لكل جهازالربط UNIQUE(machine_id, investigation_id) — معمل بـ3 أجهزة Maglumi لازم يربط نفس الأكواد 3 مرات. مفيش «طبّق ربط الكاتلوج على كل النسخ».
HIGHمحرّر الـranges يعدّل رينج الـinvestigation المشترك«ranges الجهاز» فعلياً بتعدّل الرينج العام لكل الأجهزة. NormalRange.machine_id + حقول valid/reportable موجودة لكن مسار الحفظ يتجاهلها.
MEDIUMلا يوجد استيراد جماعي / re-map = delete+create / لا toggle لـis_activeالأكواد تُضاف صف-صف؛ إعادة الربط حذف+إنشاء غير ذرّي؛ ومفيش طريقة تعطيل mapping بدون حذفه.
↑ أعلى

🗑 بيانات غير مهمة (للتنظيف)

الطبقةالعنصرالسبب
الميدل ويرتسجيل MLLP لكل chunk على INFOتشخيصي + يسرّب PHI + ضوضاء — يتشال أو يتنقل لـDEBUG.
الميدل ويرسجلّات comm_log لكل رسالةمفيدة وقت أول تكامل بس بتضاعف الترافيك والتخزين بعدين — تبقى opt-in لكل جهاز (archive_raw:false).
الميدل ويرKNOWN_DRIVERS، work_orders()، سطور serial cs/port، replace("\r","\r")، relay/forwardكود ميت/قديم أو ميزة relay غير مستخدمة بتكلّف تعقيد في معالج HL7.
الميدل ويرparsed_result يكرّر raw_resultزائد لحد ما يبقى فيه تحويل فعلي.
شاشة الأجهزةtotal_results_today (دايماً 0) + calculated_hourly_cost + نموذج التكلفة الكامل (7 حقول)تُرسَل في كل صف بدون UI يستهلكها (النموذج اليدوي ميت).
شاشة الأجهزةأعمدة model/manufacturer/serialتُعرض لكن المسار الفعّال لا يسمح بضبطها — أغلب الصفوف «-».
شاشة الأجهزةمفاتيح connection_settings القديمة (timeout_seconds، hl7_version، encoding، folder_path...) + raw_value/processed_valueلا يُنتجها المسار الفعّال؛ raw_value/processed_value هي سبب باگ الأعمدة الفاضية.
الكاتلوجdriverInfo reference card + عمود model + ازدواج host/listen_host + port/listen_port + category نص حروصف عربي ضخم hardcoded + حقول مكرّرة/قليلة القيمة.
الربطmachine_test_name + sort_order (مخزّن وغير مستخدم)تجميلي/معطّل — يُشتق عند القراءة.
↑ أعلى

بيانات ناقصة + طريقة عملية للإضافة

المبدأ: ما يخصّ الجهاز → يعيش في الكلاود (catalog أو machine connection_settings) عشان يتبع الجهاز. ما يخصّ المحطة (workstation) → محلي. ما هو سياسة معمل → إعداد LIS عام.

أعلى قيمة (تفتح الإنتاج الفعلي)

الناقصليه مهمطريقة الإضافة العملية
توسيع الباقات (Panel members)الباقات بتسقط نتايجهاعمود panel_member_investigation_id (nullable) على الـmapping — كل كود محلّل يربط بعضو الباقة. orders()/workOrders() يوسّعوا الباقة لأكواد أعضائها، وstore() يحلّ كود العضو لنتيجة العضو.
ترجمة رقم الجهاز ↔ باركود النظامكل النتايج pendingendpoint كلاود resolve-sample?analyzer_no= (الكلاود عنده الرقمين وقت إرسال الـworklist) + عمود match_identifier (barcode/sample_number/accession) لكل جهاز.
عامل تحويل + وحدة الجهازflags خاطئة سريرياًأعمدة analyzer_unit + conversion_factor (default 1) + conversion_offset (default 0) على الـmapping. عند الإدخال: system_value = raw*factor+offset قبل حساب الـflag.
نوع القيمة + خريطة الترميزالنتايج المرمّزة/النصيةvalue_type (NM/ST/SN/CE) + coded_map JSON لكل mapping؛ واستشارة investigation.result_type في store().
سلوك الكود غير المربوطإسقاط صامتunmapped_action (queue/drop/alert) لكل جهاز + عمود match_failure_reason على نتايج الجهاز للتمييز (no-sample / no-mapping / ambiguous).

الكاتلوج (seeder + migration + وراثة في instantiate)

الناقصالمكانالإضافة
بورت TCP افتراضيlab_device_models.default_portmigration + seeder + استخدامه كـlisten_port افتراضي في instantiate.
إعدادات serial افتراضيةserial_defaults JSONmigration + seeder + spread في بلوك السيريال بدل 9600/8/1/none الـhardcoded.
أعلام الإطار (framing)framing JSON (send_ack، checksum، mllp)migration + seeder + نسخ لـconnection_settings.
regex لرقم العينة/الباركودsample_number_regexmigration + seeder + سطح في connection_settings للتطبيع/التحقق.
أنواع القيم المدعومةvalue_types JSONmigration + seeder + نسخ في instantiate (حالياً fallback في agent-config بس).
LOINC + دقة + نوع نتيجة لكل تحليلlab_device_model_tests.loinc_code/decimal_places/result_type/coded_mapmigration + seeder + استخدام LOINC كمفتاح مطابقة أساسي في instantiate (LOINC ثم code ثم name).
endpoint إعادة المزامنةPOST device-models/{id}/resync-machinesيدفع تعديلات الكاتلوج لـconnection_settings للأجهزة الموجودة (يقفل فجوة الـsnapshot drift).

شاشة الأجهزة / الموثوقية

الناقصالمكانالإضافة
last_error / last_error_atأعمدة على lab_machinesتُضبط في heartbeat/storeCommunicationLog لما status==='error' — تظهر الخطأ في القائمة من غير فتح لوج.
expected_workstationعمودمقارنة بالـworkstation الحيّة لتنبيه «يعمل على محطة غير متوقعة».
إصلاح total_results_todayمنطقزيادة في store() + أمر مجدول يومي للتصفير.
ranges خاصة بالجهازNormalRange.machine_id + valid/reportable (موجودة)توصيل machine_id في محرّر الـranges + تفضيل الرينج الخاص بالجهاز في حساب الـflag.
UI لإدارة الربط داخل الشاشةFE (الخدمة موجودة)تبويبة/dialog «Test mapping» تستخدم LisMachineTestMappingService — بدون schema جديد.
↑ أعلى

إعدادات جديدة مقترحة

أ) لكل جهاز — في LIS → Machines.connection_settings

تخصّ الجهاز نفسه فتتبعه لو اتنقل لمحطة تانية.

المفتاحالنوعافتراضييتحكّم في
match_identifierenum: barcode/sample_number/accessionbarcodeأي هوية عينة يرجّعها الجهاز (يحل مشكلة عدم المطابقة).
sample_number_mapenum: none/lis_barcode/strip_leading_zeros/regexnoneاستراتيجية ترجمة رقم الجهاز للباركود.
sample_number_regexstring""عند regex — مجموعة الالتقاط → الباركود.
unmapped_actionenum: queue/drop/alertqueueالتصرّف مع كود بدون mapping.
expand_panelsbooltrueتوسيع الباقات لأكواد أعضائها في الاستعلام.
astm_strict_framingboolfalse (TCP) / true (Serial)إطار ASTM صارم مقابل المتسامح.
auto_verify / auto_applyboolوراثة العامتجاوز لكل جهاز — جهاز موثوق يتحقّق آلياً، وجهاز مشكوك لأ.
trust_analyzer_flagboolfalseاستخدام flag الجهاز (OBX-8) لما النظام مفيهوش رينج.
archive_rawboolfalseإرسال سجلّات الرسائل الخام (تحكّم في الضوضاء).
host_query_enabledbooltrueهل يردّ على استعلامات الطلب.
ack_timeout_secondsnumber5مهلة انتظار ACK في ASTM.
decimal_placesintnullتقريب قيمة الجهاز لـN منازل.
poll_interval / heartbeat_grace_minutesint (sec/min)60 / 5تردّد الـpolling + عتبة اعتبار الجهاز offline.

ب) إعدادات LIS عامة (key-value، تبويبة «Lab Settings → الأجهزة»)

سياسات على مستوى المعمل كله.

المفتاحالنوعافتراضييتحكّم في
lis.auto_apply_machine_resultsboolfalseموجود في الكود بس مش مزروع ولا في أي UI — كتابة قيم الجهاز المطابقة على LabResult آلياً.
lis.auto_verify_machine_resultsboolfalseموجود في الكود بس مش مزروع/UI — ترقية القيم الناجحة لـvalidated آلياً.
lis.machine_offline_threshold_minutesint5مصدر وحيد لعتبة online/offline (يقتل تضارب 5 مقابل 30).
lis.machine_unmapped_default_actionstringqueuefallback لـunmapped_action لما الجهاز مالوش.
lis.machine_match_identifier_defaultstringbarcodefallback لاستراتيجية الهوية.
lis.machine_alert_on_unmappedbooltrueتنبيه لما نتيجة متقدرش تتربط (يقفل ثقب الإسقاط الصامت).
lis.machine_require_full_mappingboolfalseمنع تفعيل جهاز أكواده مش كلها مربوطة.
lis.machine_critical_block_autoverifybooltrueعدم التحقّق الآلي أبداً لقيمة حرجة حتى لو نجحت القواعد.
lis.machine_heartbeat_alertboolfalseإشعار لما جهاز نشط يقع offline (حالياً مفيش تنبيه).
lis.middleware_upload_max_attemptsint50عتبة dead-letter لصفوف الرفع السامة.
lis.middleware_log_redact_phibooltrueإخفاء بيانات المريض الخام من اللوج.
lis.middleware_require_admin_passwordbooltrueإلزام مصادقة شاشة الـadmin عند الربط لغير localhost.
lis.middleware_order_offline_behaviorenum: no_order/reject/cache_lastrejectالرد على استعلام جهاز لما الكلاود مقطوع (عشان الأنبوبة متتخطّاش).

ج) سجل درايفرات موثوق (يستبدل الـhardcoded)

جدول مرجعي lab_device_drivers أو map في config('lis.drivers') بشكل {code, label, protocol, default_transport, parser} — يقراه كلٌّ من تحقّق الكاتلوج والـFE dropdown، فالدرايفرات تبقى قابلة للتوسّع بدون تعديل كود، ويموت heuristic الـname.includes('mispa').

↑ أعلى

🗺 خطة الأولويات المقترحة

الخطوة الجاية مباشرة (تخص Maglumi دلوقتي):
  • التقاط الأكواد الحقيقية: شغّل كل assay على الجهاز مرة → نقرا الكود الفعلي من machine-results → نظبط كل الـmappings بالحرف (يحل رفض الجهاز لأكواد زي FT4 III).
  • multi-mapping: كود واحد لأكتر من تحليل + اختيار التحليل الصح حسب الطلب وقت النتيجة (يحل التحاليل المكرّرة زي Vitamin D 151/2567). مؤجّل بطلب المستخدم
  • قايمة التحاليل المكرّرة عشان قرار الدمج لاحقاً.
1
المرحلة 0 — إصلاحات سريعة (أيام):
  • إصلاح أعمدة تبويبة النتايج الفاضية (raw_value→raw_result).
  • توحيد عتبة online/offline خلف إعداد واحد + تثبيت Offline/Error فعلياً.
  • توصيل أو حذف total_results_today.
  • إضافة permission middleware للـendpoints المكشوفة.
  • حذف النموذج اليدوي الميت (~500 سطر) + المفاتيح القديمة.
2
المرحلة 1 — فتح الإنتاج الفعلي (الأهم):
  • ترجمة رقم العينة ↔ الباركود (endpoint resolve-sample + match_identifier).
  • توسيع الباقات (Panels) في الربط/الاستعلام/الإدخال.
  • سلوك الكود غير المربوط + تنبيه (يقفل الإسقاط الصامت).
3
المرحلة 2 — موثوقية وأمان:
  • إشراف على عملية الميدل وير (NSSM/Task Scheduler + restart + boot) مسكربت في الريبو.
  • إخفاء الأسرار + مصادقة شاشة الـadmin.
  • dead-letter للصفوف السامة + حفظ التوكن عبر reload.
  • رصد heartbeat + cloud-reachability + last_error في القائمة.
4
المرحلة 3 — جودة البيانات السريرية:
  • تحويل الوحدات + الدقة + نوع القيمة + الترميز.
  • ranges خاصة بالجهاز + flags الجهاز.
  • التحقّق الآلي / التطبيق الآلي لكل جهاز.
5
المرحلة 4 — الكاتلوج الموثوق:
  • Seeder لـ15-20 جهاز شائع (Sysmex/Mindray/Maglumi/Cobas/Architect/Beckman/Erba/Horiba) بدرايفراتهم وبورتاتهم وإطاراتهم وأكوادهم وLOINC والـranges.
  • سجل درايفرات موثوق + عمود transports منفصل.
  • خريطة الربط على مستوى الكاتلوج + endpoint re-sync.
ملاحظة: المراحل 0 و1 لوحدهم بيحوّلوا المنظومة من «proof-of-concept شغّال» لـ«قابل للإنتاج في معمل حقيقي». باقي المراحل بتكبّر التغطية والجودة والأمان.
↑ أعلى