إنتقل إلى المحتوى الرئيسي

سياسة معمارية منصّة RaR-IT لأنظمة SaaS

المعايير الإلزامية للبنية والتقنيات لجميع المحركات المشتركة والقطاعات المنتجة

:::danger الحالة: مُقترَحة — قيد المراجعة والاعتماد والنشر الإصدار 1.0 · 25 أغسطس 2026. هذه الوثيقة ليست إلزامية بعد — راجع القسم 10. :::

1- الغرض والنطاق​

تُحدّد هذه السياسة البنية المعمارية والحزمة التقنية الإلزامية لكل نظام SaaS يُبنى أو يُصان ضمن برنامج RaR-IT متعدد القطاعات لمنصات SaaS — بما يشمل النواة المنصّية المشتركة (@rarit-kernel) وجميع القطاعات المنتجة (حالياً: عَمَار، Clinivio، EduSuite، الشحن والنقل، والسياحة، بالإضافة إلى أي قطاع مستقبلي يُضاف للبرنامج). تحكم هذه السياسة خدمات الخلفية والمحركات المشتركة ونقاط تكاملها المباشرة. قد تحكم سياسات منفصلة خيارات تقنية الواجهة الأمامية/الجوال بتفصيل أكبر، لكن هذه السياسة تُحدّد الحد الأدنى الإلزامي لها (القسم 5).

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

2- سريان السياسة وإلزاميتها​

بعد النشر، تكون هذه السياسة إلزامية لجميع موظفي RaR-IT والمتعاقدين وأي طرف ثالث ينفّذ عملاً هندسياً على أي نظام SaaS تابع لـRaR-IT، دون استثناءات إلا عبر إجراء الانحراف الرسمي في القسم 8.

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

العمل غير المتوافق الذي يُدمَج دون استثناء معتمَد بموجب القسم 8 يكون عرضةً للتراجع عنه أو لخطة ترحيل على حساب الفريق المسؤول، بحسب تقدير لجنة مراجعة المعمارية (القسم 9).

3- بنية المنصّة — النواة المشتركة والقطاعات​

3-1 النواة المشتركة (@rarit-kernel)​

توفّر النواة المشتركة للمنصّة خمسة محركات، تُنشَر كل منها كحزمة npm ضمن النطاق @rarit-kernel، تُستهلَك — لا يُعاد بناؤها — من قِبل كل قطاع:

  • @rarit-kernel/entitlements — خطط المستأجرين، بيانات باقات الميزات، تقييد الوحدات لكل مستأجر.
  • @rarit-kernel/iam — المصادقة، إدارة الجلسات، التحكم بالوصول القائم على الأدوار (RBAC)، وهوية المستأجر (جدول tenants موجود هنا؛ وكل محرك آخر يُشير إليه).
  • @rarit-kernel/payment — الفوترة، إصدار الفواتير، التسوية، وآليات الاسترداد والسداد.
  • @rarit-kernel/notifications — الإرسال داخل التطبيق والبريد الإلكتروني والرسائل النصية عبر جميع أحداث دورة الحياة.
  • @rarit-kernel/audit — سجل تدقيق واحد مشترك غير قابل للحذف عبر كل القطاعات.

3-2 القطاعات المنتجة​

كل قطاع بيئة تشغيل وقاعدة بيانات معزولة، متعددة المستأجرين داخلياً عبر Row-Level Security في PostgreSQL، ومُلزَم بنيوياً باستهلاك المحركات المشتركة الخمسة كافة بدلاً من إعادة بناء أي جزء من وظيفتها:

  • عَمَار (AMAAR) — العقارات والمقاولات
  • Clinivio — الطبي/الرعاية الصحية
  • EduSuite — التعليم
  • الشحن والنقل (Shipping & Transport)
  • السياحة (Tourism)

أي قطاع يُضاف للبرنامج مستقبلاً يدخل تلقائياً ضمن نطاق هذه السياسة منذ أول التزام (commit) له.

4- المبادئ المعمارية الأساسية​

ما يلي إلزامي وغير قابل للتفاوض دون استثناء بموجب القسم 8:

  • المحركات إضافات مُدمَجة (plugins)، لا خدمات مصغّرة مستقلة — المحركات الخمسة هي إضافات Fastify مُدمَجة مباشرة داخل عملية الخلفية الخاصة بكل قطاع؛ ولا تُنشَر أبداً كخدمات منفصلة على الشبكة إلا بعد مراجعة رسمية لمتطلبات القياس (Scale) لمحرك معيّن ومنح استثناء.
  • تغليف Fastify للإضافات هو حد تركيب (Composition)، لا حد تفويض (Authorization) — تغليف محرك كإضافة Fastify يتحكم في كيفية تنظيم الشيفرة وتحميلها؛ ولا يفرض بذاته من يُسمَح له باستدعائه. التفويض دائماً مسؤولية محركَي Entitlements وIAM، ويُتحقَّق منه صراحةً، ولا يُفترَض أبداً من بنية الإضافة.
  • تفويض IAM وتقييد خطة Entitlements فحصان مختلفان، لا فحص واحد — شمول خطة المستأجر لميزة ما (Entitlements) لا يعني أن المستخدم المحدد صاحب الطلب يملك صلاحية استخدامها (نظام الأدوار RBAC الخاص بـIAM). يُفترَض أن يمرّ كل مسار معالجة طلب عبر الفحصين معاً، بالترتيب، لا أن يُغني أحدهما عن الآخر. التسلسل الكامل، الذي يربط هذا بضمانات طبقة قاعدة البيانات في الملحق A.10: المصادقة (IAM) ← تحديد المستأجر ← التفويض/RBAC (IAM) ← التحقق من الاستحقاقات (Entitlements) ← أمان مستوى الصف (PostgreSQL) ← منطق الأعمال. تُظهر كل الأمثلة في الملحق A خطوة التحقق من الاستحقاقات صراحة (requireEntitlement())؛ أما خطوتا مصادقة IAM وRBAC فتحدثان مبكراً في خط معالجة الطلب (التحقق من الجلسة/الرمز قبل تشغيل معالج المسار) ولا تُعرَضان مجدداً في كل مثال توخّياً للاختصار — غيابهما من عيّنة شيفرة معيّنة ليس ترخيصاً بتخطّيهما.
  • هوية المستأجر مملوكة لمحرك IAM، لا لأي محرك آخر — جدول tenants موجود داخل @rarit-kernel/iam؛ وكل محرك آخر (Entitlements، Payment، Notifications، Audit) يُشير إلى هوية المستأجر كمفتاح خارجي منطقي عابر للمحركات، ولا يُكرّرها أو يُعيد تعريفها أبداً.
  • محركات قائمة على البيانات الوصفية (Manifest) مقابل محركات ذات عقد ثابت — Entitlements وIAM وNotifications قائمة على بيانات وصفية (سلوكها قابل للتخصيص وقت التشغيل لكل مستأجر)؛ أما Payment وAudit فذات عقد ثابت (سلوكها بنيوياً واحد لكل المستأجرين). يجب تصنيف أي قدرة جديدة لمحرك كأحد النوعين قبل بنائها.
  • نماذج تحصيل الإيرادات الخاصة بقطاع معيّن (كمنطق العمولة/التسوية، أو مستويات VIP/الفاخرة) هي إعداد (Configuration) فوق Payment وEntitlements، لا محركات جديدة.
  • المراقبة والقابلية للرصد (Observability) هي أدوات قياس على مستوى البنية التحتية (تسجيل مُهيكَل + أداة APM مُستضافة)، لا محرك سادس ذو حالة.
  • يجب أن تكون تبعيات المحركات فيما بينها غير دائرية (Acyclic) — لا يجوز لأي محركين مشتركين استيراد حزمة أحدهما من الآخر مباشرة، في أي من الاتجاهين. حيثما توجد علاقة حقيقية ثنائية الاتجاه بين محركين (على سبيل المثال: يحتاج IAM لتفعيل Notifications لإرسال رمز OTP، بينما يحتاج Notifications لاستيعاب بيانات تواصل المستأجر من IAM)، يجب إعادة هيكلة العلاقة بحيث لا يكون أكثر من اتجاه واحد استيراداً مباشراً؛ ويُعبَّر عن الاتجاه الآخر عبر حدث مُصدَر (Published Event)، لا عبر استيراد عكسي. راجع الملحق A لمثال عملي.
  • ينطبق هذا الحكم بالمثل على القطاعات المنتجة: يجب ألا يستورد أي محرك مشترك حزمة قطاع، ويجب ألا يستورد أي قطاع حزمة قطاع آخر مباشرة. أما الوظائف التي يحتاجها قطاعان معاً فيجب ترقيتها إلى حزمة مشتركة قابلة للاستهلاك عبر النواة، بدلاً من إنشاء تبعية مباشرة بين قطاع وآخر. راجع الملحق A لمثال عملي.

5- حزمة التقنيات الإلزامية​

الطبقةالتقنيةالحالةالمبرر
اللغة وبيئة التشغيلNode.js + TypeScriptإلزاميةلغة واحدة عبر الخلفية والأدوات وجزء كبير من سلسلة بناء الواجهة الأمامية. التصنيف الساكن لـTypeScript ضروري في هذا المقياس — خمسة محركات وأكثر من خمسة قطاعات تتشارك عقوداً لا يمكن صيانتها بأمان بلغة JavaScript غير مُصنَّفة.
إطار الخلفيةFastifyإلزامينموذج التغليف/الإضافات فيه يُطابِق مباشرة معمارية "المحركات كإضافات مُدمَجة" في القسم 4 — المحرك هو إضافة Fastify، بلا أي طبقة ترجمة بين وحدة النمطية الخاصة بالإطار وحد الوحدة الخاص بالمنصّة. التحقق القائم على المخطط أولاً (JSON Schema + Zod) يمنح المحركات القائمة على البيانات الوصفية طبقة تحقق طبيعية. النفقات الحسابية الأقل مقارنة بالأطر الأثقل مهمة عند مقياس تشارك عمليات الخلفية بين مستأجرين كثيرين.
قاعدة البياناتPostgreSQLإلزاميةيُعدّ Row-Level Security (RLS) الآلية الجوهرية لعزل المستأجرين في المنصّة — الآلية التي يعتمد عليها كل قطاع لضمان ألا يرى المستأجر (أ) بيانات المستأجر (ب) على مستوى قاعدة البيانات، لا على مستوى التطبيق فقط. تدعم JSONB إعدادات المحركات القائمة على البيانات الوصفية دون ترحيل مخطط لكل خيار مستأجر. يدعم LISTEN/NOTIFY احتياجات الوقت الحقيقي الخفيفة دون وسيط منفصل.
الواجهة الأمامية (Web)Reactإلزاميةمُعتمَدة عبر تطبيق الويب الخاص بكل قطاع؛ يعتمد اتساق أنماط المكوّنات وإعادة استخدام نظام التصميم بين عَمَار وClinivio وEduSuite والنقل والسياحة على هذا الاتساق.
الجوالFlutterإلزامياختير مرة واحدة للمنصّة بأكملها بدلاً من اختيار لكل قطاع، لكي تكون الأنماط المُثبَتة في تطبيق جوال لقطاع قابلة لإعادة الاستخدام مباشرة في قطاع آخر.
تطبيق قاعدة منع التبعيات الدائريةقاعدة no-cycle من eslint-plugin-import، مُطبَّقة عبر CI على كامل مساحة عمل npmإلزامييُحوّل قاعدة القسم 4 من مبدأ مكتوب إلى فشل بناء (Build) فعلي. يستطيع npm تقنياً تثبيت تبعية دائرية بين الحزم، ويستطيع Node تقنياً تنفيذها بإرجاع وحدة غير مكتملة التهيئة — لكن لا شيء من ذلك يضمن سلوكاً صحيحاً وقت التشغيل. أي طلب سحب يُدخل حلقة استيراد بين أي حزمتين ضمن مساحة العمل يفشل تلقائياً في CI، تماماً كما يفشل أي انحراف غير مراجَع عن القسمين 5/6. راجع الملحق A لمعرفة ما تحمي منه هذه القاعدة وكيفية تطبيقها.
الوصول لقاعدة البيانات محدود النطاق حسب المستأجرgetDb() + withTenantScope()، مُصدَّرتان من @rarit-kernel/platform-core (نطاق تنفيذ قائم على AsyncLocalStorage)إلزاميمُعتمَد بتاريخ 2026-08-26 (db-access-pattern-decision.md). هذا ما يجعل إلزام Row-Level Security في PostgreSQL أعلاه يعمل فعلياً وقت التشغيل — مقبض مستودع لا يضبط app.tenant_id أبداً يترك RLS بلا شيء يُصفّي وفقه، وهذا يفشل بصمت لا بخطأ. كما يُبقي الكتابة وسطر التدقيق الخاص بها في معاملة واحدة، فتتراجع الكتابة إذا فشلت كتابة التدقيق بدلاً من أن تبقى بلا سجل. لا تتغيّر تواقيع دوال المستودع أبداً لتبنّي هذا النمط — يتغيّر الجسم فقط. راجع الملحق A.10 للنمط الكامل وبدائله المرفوضة.

6- البدائل المُقيَّمة والمرفوضة (لتأليف المحركات المشتركة)​

جرى تقييم التقنيات التالية رسمياً لاستخدامها في تأليف المحركات المشتركة (القسم 3-1) ورُفضت صراحةً في هذا الدور. يجب ألا تُدخَل في أي عمل جديد على محركات النواة دون قرار جديد من لجنة مراجعة المعمارية يُلغي هذا القسم. يتناول القسم 6-1 أدناه سؤالاً مختلفاً — استخدام Nest في منطق أعمال القطاع الخاص — وهو أمرٌ تُرِك مفتوحاً، لا مرفوضاً.

التقنيةالحالةسبب الرفض
NestJSمرفوض لتأليف المحركات المشتركةالقيمة الأساسية لـNestJS — نظام وحدات مبني على حقن التبعيات (DI) يفرض فصل الاهتمامات — يُكرّر ما يوفّره تغليف إضافات Fastify فعلاً لنموذج "المحركات كإضافات مُدمَجة". تغليف المحركات بـNest سيفرض على كل قطاع أن يكون تطبيق Nest كامل فقط لاستهلاك محرك مشترك، ويعني أن مسارات المحرك لن تمرّ أبداً عبر خط معالجة الطلبات الخاص بـFastify. حكم على مدى الملاءمة لهذه المعمارية للمحركات بالتحديد، لا حكم عام على NestJS.
Expressمرفوض لصالح Fastifyاستُبدِل بتحقق Fastify القائم على المخطط أولاً وأداء أعلى بشكل ملموس عند حجوم الاتصالات التي تحتاج المحركات متعددة المستأجرين والمشتركة في العملية لدعمها.
MongoDB / أي مخزن NoSQL كمخزن أساسي للمستأجرينمرفوض لبيانات المستأجرين الجوهريةRLS آلية علائقية خاصة بـPostgreSQL يُبنى عليها نموذج عزل المستأجرين بأكمله؛ وأي بديل قائم على قواعد بيانات المستندات سيتطلب إعادة بناء ذلك الضمان على مستوى التطبيق، وهو ما يمنعه القسم 4 صراحةً.
fastify.decorate('db', ...) للوصول لقاعدة البيانات من المستودعاتمرفوض لكل المحركات والقطاعاتاعتُمد جنباً إلى جنب مع النمط الإلزامي أعلاه، ضمن القرار المعماري نفسه. المقبض المُزوَّد تجمّع (Pool) لا معاملة، فلا يمكن للكتابة وكتابة التدقيق الخاصة بها الالتزام ذرّياً. لا يحمل app.tenant_id، فيتوقف RLS في PostgreSQL بصمت عن التصفية بدلاً من إظهار خطأ — يستمر النظام بالعمل بطبقة حماية واحدة أقل دون أي خطأ يُنبّه لذلك. ويتطلب من المستودع استيراد نسخة Fastify أو استلامها، ما يتعارض مع قاعدة القسم 4 القائمة بالفعل بأن الخدمات لا تستورد Fastify أبداً. كانت شيفرة أحد المحركات تحمل هذا النمط قبل القرار المعماري؛ ويجري إزالته الآن، لا توسيعه (راجع الملحق A.10).
معامل معاملة صريح (getPlan(tx, id)) للوصول لقاعدة البيانات من المستودعاتمرفوض لكل المحركات والقطاعاتأكثر تقليدية من نمط AsyncLocalStorage المعتمَد، لكنه سيُغيّر توقيع كل دالة مستودع عبر المحركات الخمسة، ويتطلب استلام كتابة محرك Audit لكائن معاملة Drizzle عبر حدود الحزمة — ما يجعل نوع معاملة Drizzle نفسه جزءاً من واجهة برمجة كل محرك العامة، فتصبح ترقية Drizzle تغييراً كاسراً في كل مكان دفعة واحدة.

6-1 السماح المحدود النطاق: NestJS لمنطق أعمال القطاع الخاص​

بخلاف القسم 6 أعلاه، لا تُعتبَر NestJS مرفوضة كأداة عامة الاستخدام. يجوز لأي قطاع استخدام Nest لتنظيم منطق أعماله الخاص بتطبيقه (شيفرة ليست أحد المحركات المشتركة الخمسة) عندما تستفيد تعقيدات ذلك القطاع فعلياً من بنية الوحدات/حقن التبعيات في Nest. هذا قرار محلي خاص بكل قطاع — لا يتطلب بذاته اعتماد لجنة مراجعة المعمارية، لكنه مقيَّد بشرطين:

"تستفيد فعلياً من بنية الوحدات/حقن التبعيات في Nest" ليست متروكة عمداً لتقدير فردي وحده — تعني تحقّق واحد على الأقل مما يلي، مُرتكِزاً على أمثلة حقيقية في الملحق A:

  • مزوّدات متعددة مترابطة تتشارك حالة أو تتعاون فيما بينها، لا صنف واحد بلا تبعيات داخلية (تعتمد TemplateRegistryService وَBodyDiagramWidgetService وَClinicalValidationService في الملحق A.4 على بعضها فعلياً؛ لا يستوفي هذا الشرط معالج CRUD واحد بلا متعاونين، وفق A.1 أو A.3).
  • نمط استراتيجية أو سجل قابل للتبديل، حيث تُختار مجموعة التطبيقات وقت التشغيل لا ثابتة في الشيفرة (استراتيجيات التنبؤ القابلة للتبديل في الملحق A.5 عبر رمز حقن).
  • مزوّدات مُدارة دورة حياة تحتاج إعداداً وقت الإنشاء مختلفاً عن المعالجة لكل طلب.

صنف واحد بلا تبعيات في المُنشئ (Constructor)، أو منطق هو فعلياً "بضع خطوات متتالية مع استدعاء واحد لقاعدة البيانات"، لا يستوفي هذا الشرط — تلك منطقة A.1/A.3، Fastify صرفاً، بلا حاوية حقن تبعيات. إذا كان غير واضح أي جانب من الخط تقع فيه وحدة ما، اختر Fastify افتراضياً؛ تبنّي Nest لاحقاً لوحدة تبيّن أنها تحتاجه تغيير صغير ومُحتوى، بينما إزالة Nest من وحدة لم تحتجه أصلاً تغيير أكبر.

  1. نمط التكامل: يجب استخدام Nest كسياق تطبيق لحقن التبعيات فقط (عبر NestFactory.createApplicationContext)، مع بقاء ملكية كل مسار HTTP وبيان ميزات الوحدة وخطّاف التحقق من الاستحقاقات بيد Fastify. تُستدعى الخدمات المُحلَّلة عبر Nest من داخل معالجات مسارات Fastify العادية؛ ولا تُشغِّل Nest أبداً خط معالجة HTTP خاصاً بها لحركة مرور المستأجرين ضمن هذا النمط الافتراضي.
  2. الالتزام بالبيان (Manifest): بغضّ النظر عن كون داخل الوحدة Fastify صِرفاً أو مُنظَّماً عبر Nest، يجب أن تُصدِّر نفس بيان الميزات المستقل عن الإطار (المفتاح، الاسم المعروض ثنائي اللغة، الخطة المطلوبة، المسارات) الذي تقرؤه آلية اكتشاف Entitlements فعلاً لكل وحدة أخرى. يجب ألا تحتاج Entitlements أبداً لمنطق حالة خاصة لاكتشاف وحدة مُنظَّمة عبر Nest.

يوجد نمط ثانٍ — تشغيل Nest نسخة HTTP خاصة بها عبر مُوائم Fastify، مُركَّبة أو مُمرَّرة (Proxy) داخل العملية الأصلية — وهو ممكن تقنياً لكنه ليس الافتراضي، لأنه ينقل تطبيق التحقق من الاستحقاقات إلى خارج خط معالجة الطلبات الخاص بـFastify. يتطلب هذا النمط الثاني اعتماد لجنة مراجعة المعمارية قبل استخدامه. راجع الملحق A لأمثلة برمجية عملية لكلا النمطين، المسموح والمقيَّد.

إذا انقسمت المحركات المشتركة مستقبلاً إلى خدمات مصغّرة مستقلة النشر (إمكانية مفتوحة صراحةً، لا خطة حالية)، فإن هذا الحساب يتغيّر — هذا مُحرِّك مستقبلي لإعادة النظر في هذا القسم، لا سنداً لتبنّيه اليوم.

7- المكوّنات المُوصى بها القابلة للاستبدال​

بخلاف القسمين 5 و6، فإن ما يلي هي الخيارات الافتراضية الحالية للمنصّة، ويجوز لأي فريق استبدالها لسبب تقني جيّد دون استثناء كامل من لجنة مراجعة المعمارية — يكفي إشعار أخفّ لمالك معمارية المنصّة (القسم 9).

المكوّنالافتراضي الحالييمكن استبداله بـ
طبقة ORM/الاستعلامDrizzle ORMأي طبقة استعلام TypeScript آمنة الأنواع وقائمة على SQL أولاً (مثل Kysely). تُثنى عن استخدام أطر ORM كاملة تُخفي SQL الخام حتى تحجب الاستعلامات ذات الصلة بـRLS، لا تُمنَع كلياً، وتحتاج مراجعة القسم 8.
طابور المهام الخلفيةpg-boss (على PostgreSQL) أو BullMQ (على Redis)كلاهما مقبول افتراضياً؛ يُختار بحسب الحاجة المسبقة لـRedis لسبب آخر.
التحقق من المخططZodأي مُدقِّق مخطط قائم على TypeScript أولاً ومتوافق مع خطاطف تحقق Fastify.
توثيق APIOpenAPI/Swagger مُولَّد من مخططات Fastifyيجب أن يُولَّد من نفس المخططات المستخدَمة في التحقق وقت التشغيل، لا أن يُصان يدوياً بشكل منفصل.

8- إجراء الاستثناء والانحراف​

أي انحراف عن القسم 5 (الإلزامي) أو القسم 6 (المرفوض) يتطلب:

  1. مقترحاً مكتوباً يُبيّن القيد التقني المحدد الذي لا يستطيع الخيار الإلزامي/المرفوض تلبيته — لا تبريراً قائماً على التفضيل.
  2. مراجعة واعتماد لجنة مراجعة المعمارية (القسم 9).
  3. توثيق الاستثناء المعتمَد في سجل تغييرات هذه السياسة نفسها، بما يشمل النطاق (أي خدمة/قطاع، لا إعادة فتح على مستوى المنصّة كاملة) وتاريخ انتهاء/مراجعة.

تُمنَح الاستثناءات لكل خدمة على حدة، لا على مستوى المنصّة، ولا تُشكّل سابقة لخدمات أخرى دون مراجعتها الخاصة.

9- الحوكمة والملكية​

تخضع ملكية هذه السياسة لـالمدير التقني (CTO). تتكوّن لجنة مراجعة المعمارية من المدير التقني بالإضافة إلى مهندس أول واحد لكل قطاع نشط. تُراجَع هذه السياسة كل ربعين على الأقل، أو فوراً عند منح أي استثناء بموجب القسم 8، لتحديد إن كان ينبغي تحويل ذلك الاستثناء إلى تحديث في السياسة نفسها بدلاً من ذلك.

بند عمل مفتوح، مُتتبَّع كـالإجراء ACT-002: مصفوفة ملكية بيانات — أي كيان يملك أي بيانات، ومن يملك صلاحية قراءة/كتابة مباشرة لكل جدول، لكل محرك وكل قطاع — لا وجود لها بعد كوثيقة معتمَدة. تنصّ هذه السياسة بالفعل على المبدأ (كل محرك يملك جداوله الخاصة؛ لا يستعلم أي قطاع أبداً عن جداول محرك أو قطاع آخر مباشرة)، لكن لا توجد وثيقة واحدة تُعدِّدها جدولاً بجدول. غيابها فجوة حقيقية: بدونها، يُجاب على سؤال "أي محرك يملك هذه البيانات" بالاتفاقية ومراجعة الشيفرة لا بوثيقة يمكن لأي أحد التحقق منها، والخطر هو نفس انزلاق قاعدة البيانات المشتركة الذي تحرص عليه أقسام أخرى من هذه السياسة بوسائل مختلفة (قاعدة عدم الدورانية في القسم 4، إلزام getDb()/withTenantScope() في القسم 5). إنتاج هذه المصفوفة مُسنَد للجنة مراجعة المعمارية كبند عمل قائم، لا مؤجَّل إلى أجل غير مسمّى.

10- اعتماد السياسة​

بالتوقيع أدناه، يقرّ الأطراف المعنيون باعتماد هذه السياسة كمعيار إلزامي، سارٍ من تاريخ النشر الرسمي.

الدورالاسمالتوقيعالتاريخ
المدير التقني
قائد قطاع عَمَار (AMAAR)
قائد قطاع Clinivio
قائد قطاع EduSuite
قائد قطاع النقل (Transport)
قائد قطاع السياحة (Tourism)

:::info السجل المُعتمَد بعد التوقيع، يُودَع ملف PDF/DOCX المعتمَد لهذا الإصدار تحت signed-records/saas-architecture/ في هذا المستودع كنسخة معتمدة غير قابلة للتعديل. يستمر هذا المصدر بصيغة Markdown في التطوّر نحو الإصدار التالي. :::