الدفعة الأخيرة يجب أن تكون الأسهل: هكذا أدير مشاريع العملاء
كيف أدير مشاريع العملاء ليدفع العميل ويثق ويعود: عرض مكتوب بمراحل، وكل مرحلة تعمل على خادمه، واختبارات يقرؤها بلغته، وحزمة تسليم يشغّل بها النظام من دوني.
كيف أُبقي وحدي نظامًا محاسبيًا من 322 ألف سطر صحيحًا: بوابة حفظ واحدة، وقيود مالية لا تُعدَّل، وسجل تدقيق ببصمات متسلسلة، واختبارات على قواعد حقيقية، وتدقيق كشف ما فاتها.
لماذا تُفسد طابعات ESC/POS الحروف العربية، وكيف تطبعها صورةً أحادية البت بعرض الرأس الحقيقي، وخلل الأبعاد الذي حوّل إيصالًا طوله 12 سم إلى رولٍ كامل ملقى على الأرض.
فوترة محطات الكهرباء دون اتصال: معرّف واحد يرافق الدفعة من الهاتف إلى الإيصال، ولماذا لا تُجمع إجماليات الفواتير، وطابور يعرف ما يعيده، وخطأ 500 صنع حلقة لا تنتهي.
الأسبوع الأخير من مشروع حر. النظام يعمل على جهازك، ولا مكان غيره. العميل لم يره قط على خادمه هو. أكبر دفعة لم تُدفع بعد، وما وُعد به يعيش في محادثة واتساب عمرها شهور. كل عرض تجريبي من الآن مفاوضة.
بعض أصحاب المنشآت الذين يراسلونني عاشوا هذا الأسبوع من الجهة الأخرى. دفعوا ثمن برنامج ولم يستلموه في حال يستطيع موظفوهم العمل عليها.
أدير مشاريعي بحيث لا يأتي هذا الأسبوع أبدًا. وهذه الطريقة، مكتوبة للمطوّرين والمستقلين. حين تنتهي سيكون بين يديك هيكل عرض يحسم أغلب الخلافات قبل أن تبدأ، ودورة مراحل تضع برنامجًا يعمل على خادم العميل منذ المرحلة الأولى، وطريقة تجعل اختباراتك جزءًا مما يشتريه العميل، وحزمة تسليم، والأسئلة التي يطرحها العملاء الجيدون، مجابًا عنها كتابةً قبل أن يسألوها.
وفي ما يلي شيئان يعملان أكثر من غيرهما: قسم في العرض يمنع من الخلافات أكثر من أي قسم آخر، وسطر في الشروط يجعل الدفعة الأخيرة هي الأسهل.
حيث تتعثر المشاريعكيف أديرها
النطاق يعيش في محادثةعرض مكتوب بمراحل وقائمة لما لا يشمله
كشف كبير واحد في النهايةكل مرحلة تعمل على خادم العميل
يعمل على جهاز المطوّرفريق العميل يختبره على خادمه هو
الاختبارات تكلفة مخفية في التقديرالاختبارات بند فيما يشتريه العميل
التسليم ملف مضغوطكود وتوثيق وسكربتات وتقرير قبول
التعديلات متفق عليها في رسالة صوتيةالتعديلات تُقدَّر وتُعتمد كتابيًا
وصف قصير يكفي للبداية: ماذا تعمل المنشأة، ومن سيستخدم النظام، وما الذي لا يعمل اليوم. ونموذج التواصل في موقعي يسأل أيضًا عن نوع المشروع والميزانية التقريبية، و"لم أحدد بعد" واحدة من الإجابات.
بعدها أرسم صورة العمل. ثلاثة أسئلة تحمل معظم الوزن:
من يستخدم النظام؟ الاستقبال، والمحاسبون، ومديرو الفروع، والسائقون، والعملاء.
ما البيانات المهمة؟ الفواتير، والمخزون، وملفات المرضى، والقراءات، والصناديق.
من يحق له فعل ماذا؟ من يلغي الفاتورة، ومن يرى سعر التكلفة، ومن يعتمد الاسترجاع.
السؤال الثالث يحدد من التصميم أكثر مما تحدده أي شاشة. في منصة لإدارة شبكات الإنترنت بنيتها، صارت الإجابة 49 صلاحية منفصلة موزعة على أربعة أدوار. وفي منصة طلبات لتاجر ملابس، كانت القاعدة الأساسية ألا يرى العميل سعر فئة غير فئته، وهذه القاعدة تُفرض داخل قاعدة البيانات نفسها، ولها اختباراتها.
ثم اطلب أن ترى الأدوات التي يعملون بها اليوم: الجدول المشترك، والنموذج الورقي، والبرنامج القديم. هي تُظهر سير العمل الحقيقي أفضل من وصف أي أحد له.
لا يُبنى شيء قبل أن يحمل العميل عرضًا مكتوبًا. وعروضي تسير على هيكل واحد:
القسم
ما الذي يجيب عنه
الوضع الحالي
ما الذي لا يعمل اليوم، بكلمات فريق العميل نفسه
ما سنبنيه
كل جزء من النظام، موصوفًا بما يفعله ولمن
المراحل والجدول
ما الذي يُسلَّم في نهاية كل مرحلة
الاستثمار
تكلفة كل مرحلة وموعد كل دفعة
ما يشمله العرض وما لا يشمله
ما يغطيه السعر، والرسوم الخارجية التي لا يغطيها
الشروط
لمن الكود، وكيف تُعالج التعديلات، وإلى متى يبقى العرض قائمًا
القسم الذي يمنع من الخلافات أكثر من أي قسم آخر هو قائمة "ما لا يشمله العرض". رسوم الخادم والنطاق، وحساب واتساب للأعمال، ورسوم متجري التطبيقات: كلها تُدفع لشركات أخرى. حين تُكتب قبل أن يوقّع العميل، لا يمكن أن يصله أي منها لاحقًا مفاجأةً تحمل اسمك.
وقائمة "ما يشمله" لها وزنها أيضًا. في نموذجي تقول: التصميم، والبرمجة، والاختبارات الآلية، والنشر على خادم العميل، وتدريب فريق الاستقبال، ومدة دعم بعد التسليم الأخير. الاختبارات الآلية بند يقرؤه العميل بعينه، وسيهمّنا هذا لاحقًا.
لكل مرحلة تكلفتها، ونموذجي يربط كل دفعة ببداية مرحلتها. فلا يدفع العميل أبدًا أكثر من مرحلة واحدة قبل برنامج استخدمه بنفسه، ولا تعمل أنت أبدًا أكثر من مرحلة واحدة قبل المال.
يصل العرض إلى العميل صفحةً في موقعي، بالعربية أو الإنجليزية، برقم مرجعي وتاريخ تنتهي عنده صلاحيته. ولا شيء في الموقع يشير إليها. وإن بنيت مثلها، فثلاث قواعد من نظام البناء عندي تستحق النسخ.
اسم الملف هو الرابط، لذلك يرفض البناء أي اسم لا ينتهي بذيل عشوائي من ستة أحرف على الأقل:
والتوليد المسبق (prerender) يتوقف إن لم تكن صفحة العرض noindex. والعروض تبقى خارج الـ sitemap، وملف robots.txt يمنع مساراتها، وقائمة العروض لا تُضمَّن أبدًا في ما يصل إلى المتصفح.
والخادم يُبعد محركات البحث، ويُخفي الرابط من ترويسة المُحيل (referrer) حين ينقر العميل على رابط خارجي:
قبل الكود نتفق على أربعة أشياء: البيانات التي يحفظها النظام، والصلاحيات، والربط مع الأنظمة الأخرى، والشاشات الرئيسية.
هذه أرخص لحظة لأي أحد كي يغيّر رأيه. نقل حقل في رسم أولي يأخذ دقائق. أما تغيير طريقة حفظ البيانات بعد أن يعمل النظام فهندسة حقيقية: حين نقلت FinyxWatt، منصتي لمحطات الكهرباء والمياه، من Firebase إلى PostgreSQL، احتاج ذلك 107 ترحيلات مرتبة ومتحقق منها، والمحطات تعمل طوال الوقت.
يُقسَّم العمل إلى مراحل، وكل مرحلة مفيدة بذاتها. في نموذج العرض الذي أستخدمه، يُقسَّم نظام لمجمع طبي هكذا:
المرحلة
ما يُسلَّم
1. الأساس
المواعيد، وملف المريض، والصلاحيات
2. الفوترة
الفاتورة من الزيارة نفسها، والمدفوعات، والتقارير
3. تطبيق المرضى
الحجز والتذكير على أندرويد وiOS
كل مرحلة تنتهي بنسخة تعمل على خادم العميل، أو على الاستضافة التي يسمّيها العرض، ويختبرها فريقه قبل أن تبدأ المرحلة التالية. وداخل المرحلة أعمل بدورات قصيرة، ببرنامج يعمل، واختبارات، وبيئة تجريبية (staging).
هذا الترتيب يحمي الطرفين. يرى العميل برنامجًا يعمل منذ المرحلة الأولى. ويكتشف موظفوه المشكلات التي تهمهم وإصلاحها ما زال رخيصًا. وإن تغيّرت أولوياته، تغيرت المرحلة التالية معها. وكل دفعة بعد الأولى تأتي بعد برنامج استخدمه العميل بنفسه.
البناءدورات قصيرة، وبيئة تجريبية
الاختبارات الآليةمع كل تغيير
النشرعلى خادم العميل
فريقه يختبروالإصلاحات تعود إلى البناء
داخل كل مرحلة. مشروع من ثلاث مراحل يدور في هذه الحلقة ثلاث مرات.
تسليم كل مرحلة على خادم حقيقي لا ينجح إلا إن كان الإصدار رخيصًا وقابلًا للتراجع. سكربت النشر في منصة إدارة شبكات الإنترنت يأخذ نسخة احتياطية متحققًا منها قبل أن يوقف حاوية واحدة، ويرفض المتابعة إن فشلت، ثم يشغّل الترحيلات وينتظر فحص السلامة. وقلب التراجع في هذا الموقع خمسة أسطر:
bash
CURRENT=$(readlink -f "$ROOT/current")PREVIOUS=$(ls -1dt "$ROOT"/releases/*/ | sed 's:/$::' | grep -vx "$CURRENT" | head -n 1 || true)[ -n "$PREVIOUS" ] || { echo "!! No earlier release to go back to."; exit 1; }ln -sfn "$PREVIOUS" "$ROOT/current.new"mv -Tf "$ROOT/current.new" "$ROOT/current"
يستغرق أقل من ثانية. وحين يكون الرجوع بهذا الثمن، يكفّ وضع مرحلة على خادم العميل عن أن يكون مقامرة.
الاختبار الآلي برنامج صغير يتحقق من قاعدة واحدة من قواعد العمل، في كل مرة يتغير فيها الكود. كتبت منها أكثر من أربعة آلاف عبر عشرين منتجًا.
4,000+
اختبار آلي عبر عشرين منتجًا
1,580+
FinyxWatt: اختبارات التطبيقات والخادم
1,240+
منصة إدارة شبكات الإنترنت: اختبارات الخادم والتطبيق
530+
FinyX-ERP: المحاسبة والصلاحيات والخادم
من السهل أن تُعامَل الاختبارات تكلفةً مخفية داخل التقدير. في نموذجي هي في قائمة "ما يشمله العرض"، حيث يقرؤها العميل. والحيلة أن تصف كل اختبار بلغة العميل.
في FinyX-ERP، نظامي للمحاسبة ونقاط البيع، يستطيع المالك حذف فاتورة مرحَّلة عبر أداة إدارية. ومجموعة من الاختبارات تتحقق من أن الحذف يقع، ومن أن الحمايات التي تمنع أي أحد من تعديل مبلغ مرحَّل تعود للعمل بعده، ومن أنها تعود حتى حين يتعثر الحذف في منتصفه. والتعليق في رأس الملف يشرح ما على المحك: المالك طلب الحذف، فالحذف سليم. الخطر دفتر يبقى بلا حراس، بصمت، حتى يعدّل أحدهم مبلغًا مرحَّلًا.
وأول فحص فيه يستحق أن يُنسخ إلى كل مجموعة اختبارات:
csharp
Require(before > 0, "The database carries no integrity triggers, so the test proves nothing.");
أي: إن لم يكن في القاعدة حرّاس أصلًا، فهذا الاختبار لا يثبت شيئًا. الاختبار الذي لا يستطيع أن يفشل بلا قيمة، لذلك يتأكد هذا أولًا أنه قادر على الفشل، قبل أن يفحص أي شيء آخر. وعبارة "المبلغ المرحَّل لا يُعدَّل أبدًا، حتى بعد حذف إداري" جملة يريد أي مالك أن يقرأها في عرض.
وفي المشاريع الأكبر تعمل الاختبارات قبل خروج أي إصدار. في FinyxWatt تعمل اختبارات التطبيقات مع كل push وكل طلب دمج، ولا يبدأ النشر التلقائي للخادم إلا بعد أن تنجح اختبارات الخادم في الـ CI. وفي متجر بن مسعود يمر كل تغيير في الخلفية عبر فحص جودة الكود، وفحص الأنواع، واختبارات الوحدات مع قياس التغطية، وترحيلات قاعدة البيانات، واختبارات شاملة من طرف إلى طرف.
والآن السطر الذي في الشروط. نموذجي يقول إن الكود المصدري ملك العميل بعد سداد الدفعة الأخيرة. وحين تحين تلك اللحظة، يكون فريقه قد استخدم كل مرحلة على خادمه هو، فالدفعة الأخيرة تنقل ملكية نظام يشغّله بالفعل. هي أسهل دفعة تطلبها، لأنه لا شيء فيها يُؤخذ على الثقة.
وهذا ما يستلمه:
البند
ما يحويه
الكود المصدري
كل المستودعات، وتصير ملك العميل بعد الدفعة الأخيرة
التوثيق
دليل النشر، ودليل التشغيل اليومي، ودليل النسخ الاحتياطي والاستعادة، ومرجع الصلاحيات، ودليل الـ API، والقرارات المعمارية وأسبابها، وملاحظات الأمان، ودليل حل المشكلات، وملاحظات الإصدارات
للذين يستخدمون النظام كل يوم، وهم فريق الاستقبال في نموذج المجمع الطبي
قائمتا التوثيق والسكربتات هما ما يضمه مستودع منصة إدارة شبكات الإنترنت. واختبار الحزمة بسيط: هل يستطيع المطوّر التالي تشغيل النظام دون أن يتصل بك؟ العميل الذي يعرف أنه يستطيع الرحيل هو العميل الذي يملك ترف أن يثق بك.
المشاريع تتغير. والشرط في نموذجي سطر واحد: أي عمل خارج النطاق المتفق عليه يُقدَّر ويُعتمد كتابيًا قبل البدء به. هكذا يبقى للعرض الذي وقّعه العميل معناه، ولا تجد نفسك تعمل مجانًا في صمت.
والمراحل تسهّل الأمر. يمكن تقدير التعديل ووضعه في المرحلة التالية، وحين تتبدل الأولويات تتبدل المرحلة التالية معها. والتعديل المكتوب يحتاج خمسة أشياء: ما الذي يتغير، ولماذا، والتقدير، والمرحلة التي يدخلها، واعتماد العميل.
الاستخدام الحقيقي يكشف دائمًا ما لم تكشفه الاختبارات. النشر والنسخ الاحتياطي والمراقبة وتلك الإصلاحات جزء من العمل، ومدة الدعم بعد التسليم الأخير مكتوبة في العرض. أدير اليوم سبعة أنظمة تعمل: إصداراتها، وخوادمها، وأمانها، والإصلاحات التي تبقيها قائمة.
المحادثة الأولىمن يستخدمه، وما البيانات المهمة، ومن يحق له فعل ماذا
العرض المكتوبالمراحل، وما يشمله وما لا يشمله، والشروط، برابط خاص
التصميمالبيانات والصلاحيات والربط والشاشات الرئيسية، متفق عليها قبل الكود
المراحلكل واحدة تعمل على خادم العميل ويختبرها فريقه
العملاء الجيدون يطرحون هذه الأسئلة قبل التوقيع. ضع كل إجابة في العرض، ولن تضطر إلى قول أي منها في خلاف.
هل سيصلني عرض مكتوب بمراحل، وبقائمة لما لا يشمله؟
أين سيعمل النظام، وباسم من الخادم والنطاق؟
هل سأختبر كل مرحلة على خادمي قبل أن تبدأ التالية؟
لمن الكود المصدري، ومن متى؟
كم عدد الاختبارات الآلية، وهل تعمل قبل كل إصدار؟
كيف تُؤخذ النسخ الاحتياطية، ومتى جُرّبت الاستعادة آخر مرة؟
ما التوثيق الذي سأستلمه عند التسليم؟
كيف تُسعَّر التعديلات خارج النطاق، وكيف تُعتمد؟
إن فشل إصدار، كيف يُتراجع عنه، وكم يستغرق ذلك؟
بعد الإطلاق، من يصلح المشكلات، وإلى متى؟
الدفعة الأخيرة سهلة حين لا يكون فيها شيء جديد. العميل استخدم كل مرحلة على خادمه، وقرأ قائمة ما لا يشمله العرض قبل التوقيع، واعتمد كل تعديل كتابيًا، ويحمل حزمة تتيح له تشغيل النظام من دونك. ولهذا السبب نفسه يعود.
التعليقات
شارك في النقاش
سجّل الدخول بحساب Google لتعجب بالمقالات وتعلّق عليها. ضغطة واحدة تكفي.