🛠️ Structural Fix: Sample ↔ Investigation Linkage

المشكلة في كلمة

دلوقتي مفيش جدول صريح يربط الـ sample بالـ investigations اللي عليها. النظام بيستنتج الرابطة من ٣ آليات مختلفة (section، specimen_type، deferred JSON). ده بيخلي:

الحل: جدول صريح lab_sample_investigations

CREATE TABLE lab_sample_investigations (
  id BIGINT PK,
  lab_sample_id BIGINT FK → lab_samples,
  lab_investigation_id BIGINT FK → lab_investigations,
  lab_request_investigation_id BIGINT FK → lab_request_investigations (NULLABLE),
  status ENUM('pending','collected','rejected','deferred','recollected'),
  deferred_reason TEXT NULL,
  rejection_reason TEXT NULL,
  created_at, updated_at, deleted_at,
  UNIQUE(lab_sample_id, lab_investigation_id, deleted_at)
)
كل sample بقى متضمن قائمة صريحة بالـ tests اللي عليها. صفر inference.

الـ Flow الجديد

الـ Actionقبل (الحالي)بعد (الجديد)
Create initial sample sample بدون investigations؛ يستنتج من section إنشاء sample + إنشاء rows في sample_investigations لكل تحليل تابع له
Aliquot group by section في الـ FE/listener قسم الـ sample_investigations على الـ children
Defer test sample جديد is_deferred=true + JSON sample جديد + نقل الـ row للسامبل الجديد بـ status='deferred'
Recollect sample جديد + overload JSON كـ "scoped" sample جديد + نقل الـ rows بـ status='pending'
Collect sample.status = collected sample.status + كل sample_investigations → 'collected'
Create results (listener) يحسب الـ investigations من section_id/specimen_type قراءة مباشرة من sample.investigations
FE Display tube codes filterBillableTests + panel logic معقد قراءة مباشرة من sample.investigations

الـ Migration Phases (٥ مراحل)

١Backend: Schema + Backfill (لا تأثير على المستخدم)

٢Backend: Writers

٣Backend: Readers + Listener

٤Frontend

٥Cleanup (later)

الـ Risks

الترتيب التنفيذي

  1. Phase 1 (BE schema + backfill) — اختبار على dev
  2. Phase 2 (BE writers) — الـ defer/recollect أولاً، aliquot ثانياً
  3. Phase 3 (BE readers + listener)
  4. Phase 4 (FE) — UI يقرأ من الـ relation الجديد
  5. Final test: defer TG من Lipid Panel، recollect، verify TG يظهر لوحده
  6. Phase 5 (Cleanup) — بعد ما الـ user يأكد إن الكل شغّال