“لو صار إشي لـ “أبو أحمد”، المشروع كله بروح فيها!”
بتذكرها زي كأنها مبارح. كنا شغالين على مشروع ضخم، نظام تحليل بيانات معقد بيستخدم تقنيات الذكاء الاصطناعي. قائد الفريق التقني، خلينا نسميه “أبو أحمد”، كان ما شاء الله عليه، عبقري بمعنى الكلمة. كل الخيوط بإيده، هو اللي اختار لغات البرمجة، وهو اللي صمم قاعدة البيانات، وهو اللي قرر نستخدم خدمة سحابية معينة بدل غيرها. كان هو “قوقل” تبعنا، أي سؤال فني، الجواب عنده.
الأمور كانت ماشية زي الحلاوة، لحد ما بيوم من الأيام، اضطر أبو أحمد ياخذ إجازة طارئة طويلة شوي لأسباب عائلية. وهون بلّش الجحيم. فجأة، وقفنا كلنا مش عارفين نتحرك. ظهرت مشكلة في الأداء، وما حدا عارف ليش النظام مصمم بهالطريقة الغريبة اللي بتسببها. حاولنا نضيف ميزة جديدة، بس اكتشفنا إنها بتتعارض مع قرار قديم اتخذه أبو أحمد، وما حدا فينا بيعرف “ليش” اتخذه أصلاً.
صرنا زي اللي ماشي في غرفة معتمة، كل خطوة ممكن تكون كارثة. أسئلة مثل “ليش استخدمنا MongoDB هون مش PostgreSQL؟” أو “شو الحكمة من تصميم الـ microservice هاي بهالشكل؟” كانت تتردد في كل اجتماع، والجواب الوحيد كان الصمت… أو محاولة يائسة للاتصال بأبو أحمد اللي كان مشغول في همه. وقتها، همس واحد من الزملاء وقال الجملة اللي لخصت مأساتنا: “يا جماعة، لو صار إشي لأبو أحمد، المشروع كله بروح فيها!”. كانت جملة قاسية، لكنها حقيقية 100%. معرفتنا كانت محبوسة في عقل شخص واحد، وكنا على وشك ندفع الثمن غالي.
هذه التجربة المريرة كانت نقطة التحول. تعلمنا الدرس بالطريقة الصعبة: الاعتماد على الأبطال الخارقين في البرمجة هو وصفة أكيدة للكارثة. كان لازم نلاقي طريقة نحرر فيها المعرفة من سجن العقول، ونحولها لذاكرة جماعية للفريق كله. وهون تعرفنا على المنقذ: سجلات قرارات الهندسة المعمارية (Architecture Decision Records – ADRs).
ما هي سجلات قرارات الهندسة (ADRs)؟ وليش هي مهمة؟
بكل بساطة، الـ ADR هو وثيقة نصية قصيرة ومحددة بتسجل قرارًا معماريًا مهمًا واحدًا فقط. الفكرة مش إنك توثّق “شو” عملت، لأنه الكود نفسه بيحكي شو اللي انعمل. الفكرة هي إنك توثّق “ليش” عملته. الـ ADR بيركز على السياق اللي تم فيه اتخاذ القرار، الخيارات اللي كانت مطروحة، والأهم من كل هاد، العواقب والتبعات المترتبة على القرار اللي أخذته.
تخيلها كأنها “محضر اجتماع” تقني دائم. بدل ما تضيع القرارات المهمة في نقاشات شفهية أو في سلاسل رسائل لا نهائية على Slack، إنت بتحفظها في مكان مركزي وواضح ومتاح للجميع، اليوم وبكرا وبعد عشر سنين.
الفوائد اللي غيرت طريقة عملنا
- كسر احتكار المعرفة: أكبر فائدة. المعرفة بتبطل حكر على المبرمجين القدامى أو قائد الفريق. أي عضو جديد في الفريق بيقدر يقرأ الـ ADRs ويفهم تاريخ المشروع والقرارات المصيرية اللي شكلته.
- تسريع انضمام الموظفين الجدد (Onboarding): بدل ما الموظف الجديد يقضي أسابيع يسأل “ليش هيك؟”، بيقدر يفتح مجلد الـ ADRs ويحصل على إجابات وافية خلال ساعات.
- تجنب “فقدان الذاكرة” في القرارات: كم مرة رجعتوا تناقشوا قرار أخذتوه قبل 6 شهور ونسيتوا ليش أخذتوه أصلاً؟ الـ ADRs بتحل هالمشكلة تماماً، وبتمنع إعادة فتح نقاشات حُسمت من قبل.
- تحسين جودة اتخاذ القرار: عملية كتابة ADR بتجبرك تفكر بعمق في القرار. لما تكون عارف إنك لازم تكتب “السياق” و”العواقب”، بتبدأ تحلل الأمور من كل الزوايا، وهذا بحد ذاته بيؤدي لقرارات أفضل وأكثر نضجًا.
كيف تكتب ADR فعال؟ الهيكل والأمثلة
الجميل في الـ ADRs إنها بسيطة وما فيها تعقيدات. عادةً بتكون ملفات Markdown بسيطة بتنحفظ مع الكود في مستودع الـ Git. هاي هي البنية اللي اعتمدناها وبنصح فيها بشدة:
هيكل ملف الـ ADR
العنوان: [رقم السجل] – [عنوان وصفي للقرار]
التاريخ: [تاريخ كتابة السجل]
الحالة: [مقترح / مقبول / مرفوض / تم استبداله بـ ADR-XXX]
السياق (Context):
هاي أهم فقرة. هون بتشرح المشكلة اللي بتحاول تحلها. شو هي الظروف المحيطة؟ شو هي المتطلبات التقنية أو متطلبات العمل (Business) اللي دفعتنا للتفكير في هذا القرار؟القرار (Decision):
هون بتكتب بوضوح وبشكل مباشر شو هو الحل اللي اخترته. “سنقوم باستخدام قاعدة بيانات PostgreSQL لتخزين بيانات المستخدمين.”العواقب (Consequences):
هون السحر الحقيقي. لازم تكون صادق وتذكر كل التبعات، الإيجابية والسلبية.
- إيجابيات: شو بنكسب من ورا هالقرار؟ (مثلاً: دعم ممتاز للـ JSON، استقرار عالي، مجتمع قوي).
- سلبيات: شو بنخسر أو شو هي التحديات الجديدة؟ (مثلاً: أصعب في التوسع الأفقي مقارنة بـ NoSQL، بحاجة لخبرة في إدارة قواعد البيانات العلائقية).
مثال عملي: قرار استخدام Message Queue
لنفترض أننا نريد تحسين عملية إرسال الإشعارات للمستخدمين بعد قيامهم بإجراء معين في التطبيق. الطريقة الحالية هي استدعاء خدمة الإشعارات مباشرة (Synchronous API call)، وهذا يسبب بطئًا في الاستجابة للمستخدم.
# ADR-004: استخدام RabbitMQ لمعالجة الإشعارات بشكل غير متزامن
**التاريخ:** 2023-10-26
**الحالة:** مقبول
## السياق (Context)
عندما يقوم المستخدم بإجراء مهم (مثل إتمام عملية شراء)، يقوم نظامنا حاليًا باستدعاء خدمة الإشعارات (Notifications Service) بشكل مباشر ومتزامن. هذا يؤدي إلى انتظار المستخدم حتى يتم إرسال الإشعارات (بريد إلكتروني، رسالة نصية، ...إلخ)، مما يزيد من زمن الاستجابة (API response time) ويؤثر سلبًا على تجربة المستخدم. إذا فشلت خدمة الإشعارات لأي سبب، قد تفشل العملية بأكملها. نحن بحاجة إلى فصل عملية الإجراء الأساسية عن عملية إرسال الإشعارات لضمان سرعة الاستجابة وموثوقية النظام.
## القرار (Decision)
سنقوم بدمج نظام طوابير الرسائل (Message Queue) وهو RabbitMQ. بدلاً من استدعاء خدمة الإشعارات مباشرة، سيقوم النظام الأساسي بوضع رسالة تحتوي على تفاصيل الإشعار في طابور RabbitMQ. ستقوم خدمة الإشعارات بالاستماع إلى هذا الطابور وسحب الرسائل منه لمعالجتها بشكل غير متزامن (Asynchronously) وفي الخلفية.
## العواقب (Consequences)
### الإيجابيات:
* **تحسين تجربة المستخدم:** سيحصل المستخدم على استجابة فورية من الـ API دون الحاجة للانتظار.
* **زيادة الموثوقية (Reliability):** إذا كانت خدمة الإشعارات معطلة مؤقتًا، ستبقى الرسائل في الطابور وسيتم معالجتها عند عودة الخدمة للعمل، مما يمنع فقدان أي إشعار.
* **قابلية التوسع (Scalability):** يمكننا زيادة عدد الـ "consumers" (الخدمات التي تقرأ من الطابور) بسهولة للتعامل مع الأحمال العالية دون التأثير على النظام الأساسي.
* **فصل الخدمات (Decoupling):** يصبح النظام الأساسي غير معتمد بشكل مباشر على خدمة الإشعارات.
### السلبيات:
* **زيادة التعقيد:** إضافة مكون جديد (RabbitMQ) إلى البنية التحتية يعني وجود جزء إضافي يحتاج إلى المراقبة والصيانة والإدارة.
* **الحاجة لخبرة جديدة:** يحتاج الفريق إلى اكتساب معرفة في كيفية التعامل مع RabbitMQ وإدارته.
* **صعوبة التتبع (Eventual Consistency):** الإشعار لن يصل فورًا، بل بعد فترة قصيرة. هذا يعني أن النظام سيصل إلى حالة الاتساق في النهاية، وهو أمر يجب أن نكون على دراية به.
نصائح من خبرة أبو عمر
بعد استخدامنا للـ ADRs لفترة، تعلمنا كم شغلة بالطريق حابب أشاركها معكم:
- ابدأ ببساطة، يا جماعة: لا تعقّد الأمور. مجلد اسمه `docs/adrs` داخل مشروعك على Git هو كل ما تحتاجه. لا تبحث عن أدوات خرافية في البداية. المهم هو المبدأ وليس الأداة.
- متى أكتب ADR؟ مش لكل صغيرة وكبيرة. اكتب ADR للقرارات اللي إلها تأثير كبير، صعب التراجع عنها، أو بتأثر على أكتر من جزء في النظام. قاعدة بسيطة: “إذا كان القرار سيثير نقاشًا لمدة 5 دقائق في المستقبل، فهو يستحق ADR”.
- الـ “ليش” أهم من الـ “شو”: ركز 80% من مجهودك في كتابة فقرتي “السياق” و “العواقب”. هاي هي القيمة الحقيقية. الـ “شو” (القرار نفسه) غالبًا ما يكون واضحًا من الكود، لكن الـ “ليش” هو الكنز المفقود.
- وثيقة حية: الـ ADRs مش قرآن. ممكن قرار قديم يصبح غير مناسب. في هاي الحالة، لا تعدّل السجل القديم. اكتب ADR جديد يشرح ليش القرار الجديد أفضل، وفي السجل القديم اكتب “تم استبداله بـ ADR-XXX”، وفي الجديد اكتب “يستبدل ADR-YYY”. هيك بتحافظ على التاريخ كامل.
- اجعلها جزءًا من ثقافة الفريق: شجع النقاش حول القرارات في الـ Pull Requests. عندما يتم الاتفاق على قرار، يجب أن يكون الناتج النهائي هو دمج (merge) لـ ADR جديد يوثق هذا القرار.
الخلاصة: حرّر معرفتك 🙏
الاعتماد على بطل واحد في الفريق هو دين تقني (Technical Debt) على شكل بشري، وفائدته بتزيد مع كل يوم بمر. سجلات قرارات الهندسة (ADRs) ما كانت مجرد أداة توثيق بالنسبة لفريقنا، بل كانت ثورة ثقافية. حولتنا من مجموعة أفراد كل واحد فيهم عنده قطعة من الصورة، إلى فريق يمتلك ذاكرة جماعية قوية وواضحة.
هي مش مجرد أوراق وبيروقراطية. هي وسيلة لتمكين كل فرد في الفريق، لتقليل المخاطر، ولبناء أنظمة برمجية تدوم وتتطور بثقة. نصيحتي الأخيرة: لا تنتظر حتى تقع في “جحيم” فقدان المعرفة مثلما حدث معنا. ابدأ اليوم. اختر قرارًا واحدًا مهمًا اتخذتموه مؤخرًا، واكتب أول ADR لفريقك. مستقبلك، ومستقبل فريقك، سيشكرك على هذه الخطوة. ✅