الخلاصة

  • تنتمي ContactCard الحية في RFC 9610 إلى AddressBook واحد على الأقل، ويجوز أن تنتمي إلى عدة دفاتر؛ إزالة عضوية واحدة ليست إتلافاً للبطاقة.
  • تخزن المجموعة معرّفات UID للأعضاء. إذا فُقد الوصول مؤقتاً إلى البطاقة المطابقة اختفى العضو من العرض، لكن UID غير المحلول يبقى محفوظاً وقد يظهر العضو عند عودة الوصول.
  • يحتاج إثبات الحذف إلى الحساب ومعرّف الخادم وUID ومجموعة العضويات السابقة وحجج /set والاستجابة وقراءة لاحقة موثوقة.

اختفى الصف، لا الحقيقة كلها

تنتهي مهمة، فيحذف المشغّل دفتر عناوين المشروع. تعود الواجهة بقائمة فارغة، ويضع تقرير الامتثال عبارة «حُذفت جهات الاتصال». بعد أشهر تظهر إحدى الجهات في دفتر الاستمرارية. قد يبدو الأمر استعادة أو خرقاً، لكن السؤال الأول أدق: هل أثبت الإيصال السابق إتلاف البطاقة أم إزالة علاقتها بمجموعة واحدة؟

يعرّف RFC 9610 دفتر AddressBook بوصفه مجموعة مسماة من ContactCards. ويمكن للبطاقة نفسها أن تنتمي إلى دفاتر المشروع والمناوبة والتجديد معاً. عند إتلاف دفتر المشروع مع onDestroyRemoveContents:true يزيل الخادم ذلك الدفتر من عضويات البطاقات، ولا يتلف البطاقة إلا إذا لم يبق لها أي دفتر آخر.

لذلك يمكن أن تكون العملية ناجحة والقائمة فارغة والبطاقة باقية في الوقت نفسه. العرض يصف سطحاً محدداً؛ ولا يمنحه ذلك سلطة إصدار شهادة محو شاملة.

المجموعة لا تملك محتوياتها ملكية حصرية

يحتوي Account الداعم لنموذج جهات الاتصال على دفاتر، وتحمل كل بطاقة مجموعة addressBookIds التي تنتمي إليها. يجب أن تبقى هذه المجموعة غير فارغة ما دامت البطاقة موجودة. يسمح ذلك لسجل واحد بخدمة أكثر من سياق من دون نسخ متعارضة.

إزالة «التجديد» تغيّر علاقة واحدة ولا تلغي «الطوارئ» أو «المشتريات». هذه قاعدة تشغيل مشتركة ضيقة: يحدد البروتوكول الحالة اللازمة للتزامن، بينما تستطيع المنتجات عرضها كمجلدات أو وسوم. لكن استعارة الواجهة لا توسع أثر العملية.

ينبغي أن تبقى السياسة المحلية، وفترة الاحتفاظ، ونطاق المحو القانوني منفصلة عن قاعدة التشغيل المشتركة، لأن لكل منها صاحب قرار وإيصالاً مختلفاً.

خيار الإزالة المتتابعة مشروط بالحالة السابقة

القيمة الافتراضية لـ onDestroyRemoveContents هي false. إذا احتوى الدفتر على بطاقة، يرفض الخادم الإتلاف بخطأ addressBookHasContents. يثبت الخطأ رفض الطلب بهذه الحجج، ولا يثبت بقاء البطاقة في كل مكان.

عندما تكون القيمة true، يزيل الخادم الدفتر من البطاقات. ولا يتلف سوى البطاقة التي لا تنتمي بعد ذلك إلى أي دفتر آخر. وهكذا قد يتلف طلب واحد الدفتر، ويبقي بطاقات متعددة العضوية، ويتلف بطاقات فقدت آخر عضوية.

تسجيل عبارة «cascade=true» وحدها يمحو الشرط الحاسم. يجب حفظ addressBookIds قبل التغيير وحقول destroyed وnotDestroyed وupdated والأخطاء في الاستجابة. اسم الخيار دليل نية، أما الحالة والاستجابة فهما دليل نتيجة.

معرّف الخادم وUID لا يجيبان عن السؤال نفسه

لـ ContactCard معرّف id ثابت يضعه الخادم، ولها أيضاً uid من JSContact. يسمح RFC 9610 باختلافهما، ويمنع وجود بطاقتين بالـ UID نفسه داخل Account واحد.

يشير معرّف الخادم إلى الكائن الذي تتعامل معه طرق JMAP. ويحفظ UID استمرارية بطاقة الاتصال، وهو القيمة المخزنة في أعضاء المجموعة. إذا احتفظ السجل بالاسم المعروض فقط ضاعت الهويتان. وإذا احتفظ بـ UID وحده لم يحدد أي كائن في أي حساب تغيّر. وإذا احتفظ بمعرّف الخادم وحده فقد استمرارية المجموعة.

ولا يمثل أي منهما الشخص الحقيقي. إتلاف بطاقة في حساب لا يحذف الرسائل أو النسخ المصدرة أو الأجهزة أو أنظمة CRM أو النسخ الاحتياطية أو الشخص الموصوف.

تحتفظ المجموعة بما لا يستطيع المستخدم رؤيته الآن

تحوي ContactCard من نوع المجموعة مجموعة UIDs. يبحث العميل عن بطاقات مطابقة في الحسابات التي يمكنه الوصول إليها. إذا تعذر العثور على UID، ينبغي تجاهله في العرض الحالي مع إبقائه محفوظاً.

يقدم RFC مثالاً صريحاً: يضيف المستخدم جهات من دفتر مشترك إلى مجموعة خاصة، ثم يفقد الوصول إلى الدفتر مؤقتاً. تختفي الجهات لأن UIDs لا تُحل. وعند عودة الإذن تعثر المعرّفات المحفوظة على البطاقات فتظهر الجهات ثانية.

لم يلزم حدوث استعادة. بقيت إشارة الاستمرارية طوال فترة الانقطاع. تثبت لقطة الشاشة آنذاك أن هذا المستخدم لم يستطع الحل في تلك اللحظة؛ ولا تثبت إتلاف البطاقة أو حذف UID أو غيابها عن جميع المستخدمين.

غياب نتيجة البحث يظل حقيقة محدودة النطاق

يرشح inAddressBook البطاقات المنتمية إلى دفتر محدد. عدم ظهور بطاقة يعني أنها لا تطابق ذلك النطاق، لكنها قد تبقى في دفتر آخر أو خارج السطح المتاح للطالب.

تتيح حالات JMAP وطريقة /changes تتبع الانتقال إذا احتفظ العميل بالحالة القديمة وفحص المعرّفات المنشأة والمحدثة والمتلفة، ثم استخدم /get في الحساب الصحيح عند الشك. اختفاء صف ليس بديلاً عن هذه السلسلة.

حتى تأكيد إتلاف ContactCard يظل محدوداً: لم يعد الكائن موجوداً في ذلك Account. لا يثبت شيئاً تلقائياً عن حسابات أخرى أو نسخ أو بريد أو نسخ احتياطية أو أنظمة خارجية.

طلب الدفتر الافتراضي يوضح الفرق بين الطلب والنتيجة

يحاول onSuccessSetIsDefault جعل دفتر ما افتراضياً بعد نجاح التغييرات الأخرى. لكن إذا لم يوجد المعرّف أو منعت سياسة الخادم التغيير، يتجاهله الخادم بلا خطأ ويبقى الدفتر الافتراضي السابق.

إرسال النية ليس ملاحظة للنتيجة. يجب على العميل قراءة الخصائص المعادة أو جلب الحالة الحالية قبل إعلان النجاح. الزر والحمولة يثبتان المحاولة؛ الاستجابة والقراءة تثبتان الأثر.

إيصال الحذف سلسلة قابلة للمراجعة

يبدأ الإيصال بتحديد Account وid وUID. ثم يحفظ جميع addressBookIds السابقة وأي إشارات UID في المجموعات. ويوضح هل استهدف الطلب دفتر العناوين أم البطاقة نفسها، وما القيمة الدقيقة لـ onDestroyRemoveContents.

بعد ذلك يحفظ الاستجابة والحالة الجديدة والقراءة اللاحقة. يجب أن تكون الخلاصة واحدة من عبارات محدودة: أزيل من هذا الدفتر؛ غير قابل للحل حالياً لهذا المستخدم؛ أُتلفت ContactCard في هذا الحساب؛ أو لم تُثبت النتيجة. لا يستطيع RFC 9610 أن يقول إن الشخص مُحي من كل مكان.

الفصل بين العرض والعلاقة والكائن والعالم الخارجي يجعل التدقيق قابلاً للاستخدام. كل طبقة تحمل فقط السلطة التي يسندها إيصالها.

المصادر