استلام مشروع Flutter من مطور آخر: ما يُفحص في الأسبوع الأول
ستستلم تطبيق Flutter بناه فريق آخر، ومعك مستودع وبعض كلمات المرور وضغط لإضافة مزايا. هذه قائمة تحقق خاصة بـ Flutter لمدير التقنية والمطور المستلم: ما يُفحص في الأسبوع الأول، وبأي ترتيب، وكيف تتحول النتائج إلى قرار.
في الأسبوع الأول من استلام مشروع Flutter لا تكتب ميزة واحدة. اجعل هدفه إثبات خمسة أشياء: أن المشروع يُبنى على جهاز نظيف بإصدار Flutter وDart المعروف للمنصتين، وحالة المكتبات (القديمة والمهجورة والمنسوخة من مستودعات خاصة)، وتماسك البنية ونمط إدارة الحالة، وما عُدّل في مجلدي android وios من كود أصلي، وأن إعدادات البناء والتوقيع لكل متجر في يد منشأتك مع مفاتيح الخدمات. تنتهي هذه المرحلة برفع نسخة تجريبية من حسابك إلى TestFlight ومسار الاختبار الداخلي في Google Play، وتقرير قصير بالمخاطر مرتبة بخطورتها، يُبنى عليه قرار الاستمرار.
استلمت تطبيق Flutter بناه فريق آخر، ومعه مستودع وبعض كلمات المرور ووعد بأن «كل شيء موثق». أمامك ضغط لإصلاح أعطال أو إضافة ميزة، وإغراء بأن تبدأ فورًا. لكن مشروع Flutter له طبقات لا تظهر في قوائم الاستلام العامة: إصدار الإطار نفسه، وإضافاته، ومشروعان أصليان كاملان لـ Android وiOS يعيشان داخل المستودع. هذه قائمة تحقق خاصة بـ Flutter لمدير التقنية أو المطور المستلم. أما القائمة العامة للحسابات والاستضافة والتوثيق، فتجدها في مقالة قائمة استلام تطبيق من شركة البرمجة.
ما الذي يجعل استلام مشروع Flutter مختلفًا؟
تطبيق Flutter ليس كود Dart فقط. هو ثلاث طبقات مترابطة، وأي خلل في إحداها يوقف البناء كله:
- كود Dart: الواجهات ومنطق الشاشات وطبقة البيانات. هنا تُقرأ البنية وإدارة الحالة.
- الإطار وإضافاته: إصدار Flutter وDart، والحزم من pub.dev، والإضافات التي تربط Dart بخصائص الجهاز. هنا تكمن أغلب مخاطر الترقية.
- المشروعان الأصليان: مجلد android بإعدادات Gradle وملف الـ Manifest، ومجلد ios بمشروع Xcode وملف Info.plist. كثير من الفرق تعدّل فيهما يدويًا ولا توثق ذلك.
وهذه الطبقات تتحرك بسرعة. بحسب سجل إصدارات Flutter، أحدث إصدار مستقر عند كتابة هذه المقالة هو 3.47. ومنذ الإصدار 3.44 يستخدم Flutter مدير حزم Swift افتراضيًا لاعتماديات iOS، ويُبقي CocoaPods في وضع الصيانة، وتذكر وثيقة Flutter عن مدير حزم Swift أن سجل CocoaPods يصبح للقراءة فقط نهائيًا في 2 ديسمبر 2026. مشروع مستلم مبني على إصدار قديم يعتمد على CocoaPods بتعديلات يدوية في Podfile هو إذن مشروع ينتظره عمل ترقية، وهذا يجب أن تعرفه في الأسبوع الأول لا عند أول تحديث عاجل.
خطة الأسبوع الأول يومًا بيوم
الترتيب مقصود: لا فائدة من قراءة البنية قبل أن تعرف أن المشروع يُبنى، ولا من رفع نسخة قبل أن تعرف أين مفاتيح التوقيع.
| اليوم | التركيز | المخرج |
|---|---|---|
| الأول | الوصول والجرد: المستودع بتاريخه، والفروع، ووسوم الإصدارات، وحسابات Firebase والمتجرين، وملفات الإعدادات المستثناة من المستودع | قائمة بما لديك وما ينقص |
| الثاني | البناء من الصفر للمنصتين على جهاز نظيف بإصدار Flutter المحدد | دليل بناء مكتوب، أو قائمة بما منع البناء |
| الثالث | تدقيق المكتبات: القديمة، والمهجورة، والمنسوخة، والمتجاوزة | جدول المكتبات بحالة كل منها |
| الرابع | قراءة البنية وإدارة الحالة، ومراجعة الكود الأصلي في android وios | ملاحظات البنية وخريطة الكود الأصلي |
| الخامس | الاختبارات والتحليل، ومفاتيح الخدمات، ورفع نسخة تجريبية من حسابك | نسخة على TestFlight والاختبار الداخلي، وتقرير المخاطر |
في المشاريع الكبيرة قد يمتد بعض هذه الأيام، لكن الترتيب يبقى. وإن لم يُبنَ المشروع في اليوم الثاني، فكل ما بعده ينتظر؛ مقالة استلام الكود المصدري من المطور تشرح كيف تثبت اكتمال الكود بالبناء من الصفر.
الإصدار والمكتبات: قائمة التحقق
أول سؤال: بأي إصدار من Flutter بُني التطبيق المنشور؟ الجواب لا يكون في ذاكرة المطور، بل في ملفات المشروع أو في إعدادات خط البناء.
- إصدار Flutter محدد في المشروع (ملف إعداد أداة إدارة الإصدارات إن استُخدمت، أو إعداد خط البناء)، وقيود إصدار Dart وFlutter في ملف pubspec.yaml.
- ملف pubspec.lock موجود في المستودع، حتى تُبنى النسخة بالإصدارات نفسها لا بأحدث ما يسمح به pubspec.
- الأمر flutter pub get ينجح من نسخة نظيفة دون وصول خاص لم يُسلَّم إليك.
- نتيجة flutter pub outdated محفوظة: كم حزمة متأخرة بإصدار رئيسي أو أكثر.
- الحزم الموسومة «متوقفة» (discontinued) في pub.dev، أو التي لم يُنشر لها إصدار منذ مدة طويلة.
- اعتماديات من مستودعات git أو مسارات محلية: نسخ معدّلة من حزم عامة، وهل تملك الوصول إلى مستودعاتها؟
- قسم dependency_overrides: كل تجاوز فيه يخفي تعارضًا لم يُحل، واسأل عن سببه.
- الأمان من القيم الفارغة: Dart يفرض الأمان الصارم من القيم الفارغة منذ الإصدار 3 بحسب وثائق Dart، فالمشروع الذي لم يُرحَّل إليه لا يُبنى بأي إصدار حديث.
الحزمة المتأخرة ليست مشكلة بذاتها. المشكلة حين تكون مهجورة وتلمس مسارًا حرجًا كالدفع أو الدخول أو الإشعارات؛ هذه تُرفع في التقرير إلى أعلى القائمة، لأن أول ترقية إجبارية للإطار ستكسرها.
البنية وإدارة الحالة: قائمة التحقق
في Flutter أكثر من طريقة مقبولة لإدارة الحالة، ولا توجد إجابة واحدة صحيحة. الخطر ليس في الطريقة المختارة، بل في غياب طريقة واحدة، أو في منطق العمل المكتوب داخل الواجهات.
- نمط إدارة الحالة المستخدم، وهل هو واحد في كل المشروع، أم خليط من أكثر من نمط بحسب من كتب كل شاشة.
- مكان منطق العمل: في طبقة مستقلة، أم داخل الواجهات (Widgets) مع استدعاءات الشبكة مباشرة.
- طبقة الوصول إلى البيانات: هل كل استدعاءات الخادم تمر من مكان واحد يعالج الأخطاء وانتهاء الجلسة؟
- الكود المولَّد آليًا (مثل نماذج البيانات وتحويلها من JSON): هل خطوة توليده موثقة، وهل ملفاته في المستودع أم تُولَّد عند البناء؟
- تنظيم المجلدات: حسب المزايا أم حسب نوع الملف، ومدى سهولة العثور على كل ما يخص ميزة واحدة.
- التنقل بين الشاشات والروابط العميقة: طريقة واحدة موحدة، وهل تعمل الروابط من الإشعارات؟
- العربية واتجاه الكتابة: ملفات الترجمة، والنصوص المكتوبة مباشرة في الكود، وسلوك الحقول مع الأرقام والنصوص المختلطة.
- نتيجة flutter analyze وملف قواعد التحليل: عدد التحذيرات مؤشر على الانضباط، لا حكم نهائي.
إن كان التطبيق كبيرًا وتنوي أن يستمر فريقك فيه سنوات، فمقالة معمارية تطبيق Flutter كبير تشرح ما يجب أن تكون عليه البنية، لتقيس ما استلمته عليها.
الكود الأصلي في مجلدي android وios
هذا الجزء يتجاهله كثير من المستلمين لأن «التطبيق مبني بـ Flutter». لكن كل إضافة تصل إلى الكاميرا أو الدفع أو الإشعارات لها جزء أصلي، وبعض الفرق تضيف كودًا أصليًا خاصًا بها عبر قنوات المنصة (Platform Channels).
- كود أصلي مكتوب يدويًا بـ Kotlin أو Swift: أين هو، وما القنوات التي يستقبل عبرها الاستدعاءات من Dart، ومن يعرف صيانته؟
- حزم أصلية أُضيفت مباشرة إلى المشروعين (مثل حزمة بوابة دفع) خارج نظام إضافات Flutter.
- تعديلات على ملفات بدء التطبيق في المنصتين، فهي تتعارض عادة مع قوالب Flutter عند الترقية.
- الأذونات ونصوص طلبها في Info.plist وAndroidManifest، ومطابقتها لما يستخدمه التطبيق فعلًا.
- أدنى إصدار مدعوم في المنصتين، والإصدار المستهدف في Android: بحسب متطلبات Google Play، يجب أن تستهدف التطبيقات الجديدة والتحديثات مستوى API 36 منذ 31 أغسطس 2026، مع إمكانية طلب تمديد حتى 1 نوفمبر 2026.
- إصدارات Gradle وملحق Android وKotlin، وتوافقها مع إصدار Flutter المستخدم.
- في iOS: هل يعتمد المشروع على CocoaPods بتعديلات يدوية في Podfile، أم انتقل إلى مدير حزم Swift؟
إعدادات البناء والتوقيع لكل متجر
هنا يقع الخطر الذي لا يُعوَّض: مفتاح توقيع ضائع، أو إعداد بيئة موجود على جهاز المطور وحده. اختبار هذا القسم عملي لا نظري: ارفع نسخة من حسابك.
- البيئات (تطوير واختبار وإنتاج): كيف تُفصل؟ بنكهات البناء (Flavors)، أو بقيم تُمرر عند البناء، أو بملفات بيئة؟ وأين ملفات البيئة غير الموجودة في المستودع؟
- ملفات إعداد Firebase لكل بيئة ولكل منصة، وأي مشروع Firebase تشير إليه، وباسم من هذا المشروع.
- معرّف التطبيق في المنصتين، ورقم الإصدار والبناء في pubspec.yaml، وأنه أعلى من آخر رقم بناء مرفوع في المتجرين.
- مفتاح رفع Android وملف كلمات مروره خارج المستودع، ومعرفة هل التطبيق مسجل في توقيع Google Play.
- توقيع iOS: الفريق، والشهادات، وملفات التوزيع، والإمكانات المفعلة (الإشعارات، وتسجيل الدخول بحساب Apple، والروابط العامة).
- إخفاء الكود (Obfuscation): إن كان مفعلًا فأين ملفات الرموز لكل إصدار؟ بحسب وثائق Flutter، تحتاج هذه الملفات لقراءة تقارير الانهيار من النسخة المخفية، وبدونها تبقى التقارير غير مقروءة.
- خط البناء الآلي إن وجد: أين يعمل، وباسم من الحساب، وما الأسرار المخزنة فيه.
- الاختبار النهائي: بناء نسخة إصدار ورفعها إلى TestFlight ومسار الاختبار الداخلي في Google Play من حسابات منشأتك، دون مساعدة من المطور السابق.
الاختبارات ومفاتيح الخدمات
الاختبارات تخبرك بما يمكنك تغييره بأمان، والمفاتيح تخبرك بما قد يكون مكشوفًا الآن.
- تشغيل flutter test أمامك: كم اختبارًا، وكم ينجح، وهل تغطي المسارات الحرجة أم الشاشات السهلة فقط؟
- اختبارات التكامل على جهاز أو محاكٍ، إن وجدت، وهل تعمل في خط البناء؟
- المفاتيح المكتوبة في كود Dart أو في ملفات الأصول: كل ما يُضمَّن في التطبيق يمكن استخراجه منه، وتنبه وثائق Flutter إلى أن تخزين الأسرار في التطبيق ممارسة أمنية سيئة وأن إخفاء الكود لا يحميها.
- مفاتيح Google Maps وغيرها: هل هي مقيدة بمعرّف التطبيق وبصمة توقيعه، أم مفتوحة لأي استخدام؟
- مفاتيح بوابة الدفع: السرية منها يجب ألا تكون في التطبيق إطلاقًا، بل في الخادم.
- أدوات مراقبة الأعطال والتحليلات: باسم من الحسابات، ومن يستقبل تنبيهاتها الآن؟
كل مفتاح كان في يد الفريق السابق يُدوَّر بعد الاستلام بترتيب لا يوقف التطبيق، كما تشرح مقالة تدوير مفاتيح API والأسرار بعد تغيير المطور.
- الجردالمستودع والحسابات وملفات الإعدادالمستلم والمنشأة
- البناء من الصفرالمنصتان على جهاز نظيفبوابة: لا تقدم دونها
- المكتبات والبنيةالحالة والمخاطر والكود الأصليالمستلم
- رفع نسخة من حسابكTestFlight والاختبار الداخليبوابة: ملكية التوقيع
- تقرير وقرارمخاطر مرتبة وتوصيةصاحب القرار
كيف تقرأ النتائج وتحولها إلى قرار؟
لن يكون أي مشروع مستلم نظيفًا تمامًا. المهم أن تفرز الملاحظات بحسب أثرها على قدرتك على الإصدار والتطوير:
| ما وجدته | الخطورة | ما تفعله |
|---|---|---|
| المشروع لا يُبنى، أو مفتاح التوقيع غير متاح، أو اعتمادية من مستودع خاص لا تصل إليه | حرجة | توقف أي تطوير، وعالج الوصول أو الاستعادة أولًا |
| سر حساس في كود التطبيق، أو مفاتيح غير مقيدة | حرجة | نقل السر إلى الخادم وتدويره في أول إصدار |
| إصدار Flutter قديم بعدة إصدارات رئيسية، أو مكتبة مهجورة في مسار حرج | عالية | خطة ترقية مستقلة قبل المزايا الكبيرة |
| خليط من أنماط إدارة الحالة، ومنطق عمل داخل الواجهات | متوسطة | اعتماد نمط واحد للكود الجديد، وإعادة هيكلة تدريجية لما يُلمس |
| تحذيرات تحليل كثيرة، واختبارات قليلة | متوسطة | اختبارات للمسارات الحرجة قبل تعديلها |
| تنظيم مجلدات غير مثالي، أو تسميات غير متسقة | منخفضة | تُعالج أثناء العمل دون مشروع مستقل |
إن ظهرت ملاحظات حرجة أو عالية كثيرة، أو احتجت رأيًا مستقلًا قبل قرار كبير، فخدمة مراجعة الكود وتدقيق المعمارية تسلّم تقريرًا بالملاحظات مرتبة بحسب الخطورة مع نتائج الفحص الآلي للجودة والمكتبات والأسرار. وإن كان إصدار Flutter متأخرًا كثيرًا، فمقالة تحديث تطبيق Flutter قديم تشرح الترقية عبر الإصدارات الكبرى.
أخطاء شائعة في استلام مشروع Flutter
- ترقية Flutter في اليوم الأول: تبني على أحدث إصدار قبل أن تبني على الإصدار الأصلي، فلا تعرف إن كانت الأعطال من المشروع أو من الترقية. ابنِ أولًا كما هو، ثم رقِّ في فرع مستقل.
- الحكم على الكود من الواجهات: التطبيق الجميل قد يخفي منطق عمل مكررًا في عشرين شاشة.
- تجاهل مجلدي android وios: ثم يكتشف الفريق عند أول ترقية أن ملفات البدء معدّلة يدويًا بلا توثيق.
- قبول «المفتاح عندي وسأرسله»: مفتاح رفع Android وملفات الرموز والشهادات تُستلم وتُجرب بالرفع الفعلي، لا بالوعد.
- البدء بمزايا جديدة لإرضاء صاحب المشروع: كل ميزة تُبنى قبل فهم البنية تضيف إلى ما سيُعاد لاحقًا.
- إعادة كتابة كل شيء بنمطك المفضل: نمط إدارة حالة مختلف عما تفضله ليس سببًا لإعادة الكتابة. الاتساق أهم من النمط.
ما تطلبه من المطور السابق، وما تجهزه قبل الاستلام
إن كان المطور السابق متاحًا، فجلسة تسليم منظمة معه توفر أيامًا من القراءة. اطلب منه كتابيًا:
- إصدار Flutter وDart الذي بُني به آخر إصدار منشور، وأمر البناء المستخدم فعلًا لكل منصة.
- ملفات البيئة والإعدادات المستثناة من المستودع، ووصول إلى أي مستودع خاص لحزم معدّلة.
- مفتاح رفع Android وكلمات مروره، وملفات الرموز لكل إصدار منشور إن كان الإخفاء مفعلًا.
- قائمة بالكود الأصلي المكتوب يدويًا وسبب كل جزء منه.
- أي حزمة مهجورة أو متجاوزة يعرف بها، ولماذا لم تُستبدل.
- المشكلات المعروفة والحلول المؤقتة في الكود.
وجهّز من جانب منشأتك قبل بدء الأسبوع:
- صلاحيات المستودع وحسابات المتجرين وFirebase باسم المنشأة، مع دعوة للفريق المستلم.
- جهاز Mac بإصدار Xcode الذي تشترطه Apple حاليًا للبناء والرفع، إن كان الفريق المستلم داخليًا.
- قائمة بالأعطال الحالية وشكاوى المستخدمين، وما هو عاجل منها فعلًا.
- قرار مكتوب: هل الأسبوع الأول للفحص وحده، أم مطلوب إصلاح عاجل بالتوازي؟
الخلاصة: ابنِ، ثم افهم، ثم قرر
استلام مشروع Flutter ينجح حين يكون الأسبوع الأول للإثبات لا للإنتاج. أثبت أن المشروع يُبنى بإصداره الأصلي على جهاز نظيف، واعرف حالة مكتباته وكوده الأصلي، واقرأ بنيته ونمط إدارة الحالة فيه، ثم ارفع نسخة من حسابات منشأتك. بعدها يصبح التقرير أساسًا لقرار واضح: تطوير مباشر، أو تثبيت وترقية أولًا، أو مراجعة أعمق لجزء محدد.
Flutter خيارنا الأول لأغلب تطبيقات الأعمال كما توضح صفحة تطوير تطبيقات Flutter، ونستلم مشاريع بناها غيرنا بعد تقييم لحالتها كما في صفحة استلام مشروع متعثر. إن كان لديك مشروع Flutter تستعد لاستلامه، أرسل ما لديك عنه عبر طلب تقييم مشروعك الحالي، ونقترح نطاق الفحص الأول.
أسئلة شائعة
غالبًا نعم إن كان المشروع يُبنى ومفاتيحه متاحة، لكن سرعة البداية تعتمد على اتساق البنية ونمط إدارة الحالة وحجم الكود الأصلي المعدّل يدويًا. أسبوع فحص منظم يكشف ذلك قبل الالتزام بمواعيد مزايا جديدة.
لا تبدأ بالترقية. ابنِ المشروع أولًا بإصداره الأصلي لتتأكد أنه يطابق المنشور، ثم نفذ الترقية في فرع مستقل مع اختبار المسارات الحرجة. الترقية في اليوم الأول تخلط أعطال المشروع بأعطال الترقية.
ليس بالضرورة. الاتساق أهم من النمط نفسه. إن كان النمط موحدًا في المشروع فتعلمه أرخص من إعادة الكتابة. أما إن كان خليطًا من أنماط، فاعتمد نمطًا واحدًا للكود الجديد وأعد هيكلة ما تلمسه تدريجيًا.
إن كان التطبيق مسجلًا في توقيع Google Play فيمكن لصاحب الحساب طلب إعادة تعيين مفتاح الرفع، وإلا فالحلول محدودة جدًا. لذلك تحقق من المفتاح في اليوم الأول بالرفع الفعلي إلى مسار الاختبار الداخلي، لا بالوعد بإرساله.
لا. التشغيل على المحاكي في وضع التطوير لا يثبت أن نسخة الإصدار تُبنى وتُوقّع وتُرفع. الإثبات أن تُبنى نسخة إصدار للمنصتين على جهاز نظيف وتُرفع إلى TestFlight والاختبار الداخلي من حسابات منشأتك.
خدمات وصفحات مرتبطة
اقرأ أيضًا
تستلم تطبيق Flutter؟ ابدأ بفحص يثبت ما لديك
أرسل ما لديك عن مشروع Flutter من مستودع وحسابات وأعطال معروفة، ونقترح نطاق الفحص الأول وما يلزم قبل أي تطوير.