-- ============================================================================
--  2026_sprint30m_phase4_runtime_pass4.sql — فاز ۴ / پاسِ چهارمِ رفعِ runtime
--  ADDITIVE فقط / idempotent / بدونِ DELIMITER / بدونِ stored procedure /
--  سازگار با cPanel و MariaDB/MySQL / غیرِمخرب.
--  پیش‌نیاز: پس از ...30i → 30j → 30k → 30l اجرا شود. اجرای چندباره بی‌خطر است.
--
--  اصلِ حاکم بر این مهاجرت: **هیچ بازتفسیرِ خودکارِ داده‌های عمدی انجام نمی‌شود.**
--  هرجا ابهام وجود دارد، گزارشِ تشخیصی می‌دهد و تصمیم را به مدیر واگذار می‌کند.
-- ============================================================================
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ─────────────── (۱) مراقبت: همبستگیِ دقیقِ claim/تلاش ───────────────
-- بدونِ اینها، بازیابیِ stale نمی‌تواند ثابت کند نتیجهٔ ارائه‌دهنده مالِ **همان** Worker و همان تلاش بوده.
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_aftercare_deliveries' AND COLUMN_NAME='attempt_token');
SET @s:=IF(@c=0,"ALTER TABLE `cw_aftercare_deliveries` ADD COLUMN `attempt_token` VARCHAR(40) DEFAULT NULL",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_aftercare_history' AND COLUMN_NAME='claim_token');
SET @s:=IF(@c=0,"ALTER TABLE `cw_aftercare_history` ADD COLUMN `claim_token` VARCHAR(32) DEFAULT NULL",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_aftercare_history' AND COLUMN_NAME='attempt_token');
SET @s:=IF(@c=0,"ALTER TABLE `cw_aftercare_history` ADD COLUMN `attempt_token` VARCHAR(40) DEFAULT NULL",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

SET @c:=(SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_aftercare_history' AND INDEX_NAME='idx_hist_attempt');
SET @s:=IF(@c=0,"ALTER TABLE `cw_aftercare_history` ADD INDEX `idx_hist_attempt` (`delivery_id`,`attempt_no`,`status`)",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

-- ─────────────── (۲) رضایت: provenanceِ دقیقِ تأییدِ همان نسخه + نوعِ شواهد ───────────────
-- منبعِ حقیقت: cw_consent_template_history (append-only، action='approve').
-- این ستون‌ها همان رویداد را روی خودِ رضایت **snapshot** می‌کنند تا تغییرناپذیر بماند.
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_consents' AND COLUMN_NAME='template_approved_by');
SET @s:=IF(@c=0,"ALTER TABLE `cw_consents` ADD COLUMN `template_approved_by` INT UNSIGNED DEFAULT NULL",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_consents' AND COLUMN_NAME='template_approved_at');
SET @s:=IF(@c=0,"ALTER TABLE `cw_consents` ADD COLUMN `template_approved_at` DATETIME DEFAULT NULL",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_consents' AND COLUMN_NAME='template_approval_history_id');
SET @s:=IF(@c=0,"ALTER TABLE `cw_consents` ADD COLUMN `template_approval_history_id` BIGINT UNSIGNED DEFAULT NULL",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_consents' AND COLUMN_NAME='evidence_type');
SET @s:=IF(@c=0,"ALTER TABLE `cw_consents` ADD COLUMN `evidence_type` VARCHAR(20) DEFAULT NULL",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

-- backfillِ محافظه‌کارانهٔ provenance: **فقط** رضایت‌های امضاشده‌ای که نسخهٔ آن‌ها در تاریخچه
-- رویدادِ approve دارد. هیچ رکوردی ساخته/بازتفسیر نمی‌شود و مقادیرِ موجود بازنویسی نمی‌شوند.
SET @h:=(SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_consent_template_history');
SET @s:=IF(@h=1,
 "UPDATE `cw_consents` c
     JOIN ( SELECT template_key, version, MAX(id) AS hid FROM `cw_consent_template_history`
             WHERE action='approve' GROUP BY template_key, version ) a
       ON a.template_key = c.template_key AND a.version = c.template_version
     JOIN `cw_consent_template_history` h ON h.id = a.hid
      SET c.template_approval_history_id = h.id,
          c.template_approved_by         = h.by_user,
          c.template_approved_at         = h.created_at
    WHERE c.status='signed' AND c.template_approval_history_id IS NULL",
 'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

-- backfillِ نوعِ شواهد برای رکوردهای موجود: فقط تشخیصِ قطعیِ data-URLِ تصویری.
-- بقیه NULL می‌مانند تا دستی بازبینی شوند (به‌عنوان امضای ترسیمی جا زده نمی‌شوند).
UPDATE `cw_consents`
   SET `evidence_type`='canvas_image'
 WHERE `evidence_type` IS NULL AND `signature_data` LIKE 'data:image/%;base64,%';

-- ─────────────── (۳) ادغام: مقادیرِ تغییرناپذیرِ پیش/پس از ادغام ───────────────
-- (نقشهٔ کاملِ before/after/moved_ids داخلِ ستونِ JSONِ `remap` ذخیره می‌شود؛
--  این ستون فقط نسخهٔ ساختارِ snapshot را نگه می‌دارد تا خواندنِ آینده ایمن باشد.)
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_patient_merges' AND COLUMN_NAME='snapshot_version');
SET @s:=IF(@c=0,"ALTER TABLE `cw_patient_merges` ADD COLUMN `snapshot_version` SMALLINT UNSIGNED NOT NULL DEFAULT 1",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

-- ─────────────── (۴) نشانگرِ امنِ طبقه‌بندیِ کارکنانِ لیزر ───────────────
-- به‌جای استنتاجِ خطرناک («هیچ‌کس 1 نیست ⇒ همهٔ صفرها از DEFAULT آمده‌اند»)،
-- تأییدِ صریحِ مدیر ثبت می‌شود. تا ثبت‌نشدنِ آن، laser_strict_staff نباید 1 شود.
SET @t:=(SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_settings');
SET @s:=IF(@t=1,
 "INSERT INTO `cw_settings` (`k`,`v`,`updated_at`) SELECT 'laser_staff_classified','0',NOW()
    WHERE NOT EXISTS (SELECT 1 FROM `cw_settings` WHERE `k`='laser_staff_classified')",
 'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

-- ─────────────── گزارش‌های تشخیصی/remediation ───────────────

-- (الف) طبقه‌بندیِ لیزر: ابهامِ «همه 0 و هیچ 1» — تصمیم با مدیر، نه با مهاجرت.
-- (جدولِ nurses جزوِ مهاجرت‌ها نیست؛ اجرای این گزارش به وجودِ جدول و ستون مشروط است.)
SET @n:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='nurses' AND COLUMN_NAME='is_laser');
SET @s:=IF(@n=1,
 "SELECT 'nurses_laser_classification' AS report,
         COUNT(*) AS active_nurses,
         SUM(CASE WHEN is_laser IS NULL THEN 1 ELSE 0 END) AS unclassified_null,
         SUM(CASE WHEN is_laser=0 THEN 1 ELSE 0 END)       AS prohibited_zero,
         SUM(CASE WHEN is_laser=1 THEN 1 ELSE 0 END)       AS authorized_one,
         CASE WHEN SUM(CASE WHEN is_laser=1 THEN 1 ELSE 0 END)=0
                   AND SUM(CASE WHEN is_laser=0 THEN 1 ELSE 0 END)>0
              THEN 'AMBIGUOUS: همه 0 و هیچ 1 - amdi ya baqimandeye DEFAULT? dasti taeen konid'
              ELSE 'OK' END AS note
    FROM nurses WHERE is_active=1",
 "SELECT 'nurses_laser_classification' AS report, 'SKIPPED: nurses.is_laser not installed' AS note");
PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

-- (ب) رضایت‌های امضاشده‌ای که نسخهٔ آن‌ها **هرگز تأیید نشده** → با ناوردایِ پاس ۴ گیت را باز نمی‌کنند
SELECT 'consent_version_never_approved' AS report, c.id, c.patient_id, c.template_key, c.template_version
  FROM cw_consents c
 WHERE c.status='signed' AND c.template_key IS NOT NULL AND c.template_key<>''
   AND NOT EXISTS (SELECT 1 FROM cw_consent_template_history h
                    WHERE h.template_key=c.template_key AND h.version=c.template_version AND h.action='approve');

-- (ج) شواهدِ امضایی که نوعشان قابلِ تشخیصِ خودکار نبود → بازبینیِ دستی
SELECT 'consent_evidence_untyped' AS report, id, patient_id, template_key, LEFT(COALESCE(signature_data,''),24) AS sample
  FROM cw_consents
 WHERE status='signed' AND evidence_type IS NULL;

-- (د) تحویل‌های مراقبتِ گیرکرده بدونِ هویتِ دقیقِ تلاش (پیش از 30m ثبت شده‌اند)
SELECT 'aftercare_missing_attempt_identity' AS report, id, performed_service_id, stage, status, retry_count, updated_at
  FROM cw_aftercare_deliveries
 WHERE status='queued' AND attempt_token IS NULL;

SET FOREIGN_KEY_CHECKS = 1;
-- پایانِ مهاجرتِ 30m
