تعلم كيف تحول الشفرة إلى مواصفات ميزات حية: استخرج سلوك التطبيق الفعلي من المسارات والمكوّنات ثم أنشئ مواصفة وقائمة فجوات قابلة للتحديث.

newEmailFlow، فسجّل كلا النسختين وما الذي يختلف بينهما.\n\nاكتب كل تدفق واجهة كمجموعة خطوات قصيرة (ما يفعله المستخدم، ما تفعله الواجهة ردًا) واحتفظ بالشروط والأخطاء بجانب الخطوة التي تؤثر عليها. هذا يحافظ على قابلية قراءة المواصفة ويسهّل اكتشاف الفجوات.\n\n## تحويل الملاحظات إلى مواصفات ميزات قابلة للقراءة\n\nالملاحظات الخام من المسارات والمكوّنات مفيدة، لكن يصعب مناقشتها. أعد صياغة ما لاحظت إلى مواصفة يمكن لمدير المنتج والمصمم والمهندس والاختبار قراءتها والموافقة عليها.\n\nنمط عملي هو قصة مستخدم واحدة لكل مسار أو شاشة. اجعله صغيرًا ومحددًا. مثال: "As a signed-in user, I can reset my password so I can regain access." إذا أظهرت الشفرة سلوكًا مختلفًا حسب الدور (مسؤول مقابل مستخدم)، اقسمها إلى قصص منفصلة بدل إخفائها في الحواشي.\n\nثم اكتب معايير قبول تعكس مسارات الشفرة الحقيقية، لا المنتج المثالي. إذا أرجع المعالج 401 عند غياب الرمز، فهذه معيار. إذا عطّلت الواجهة Submit حتى يصبح الحقل صالحًا، فهذه معيار.\n\nأدرج قواعد البيانات بلغة بسيطة، خاصة التي تسبب مفاجآت: الحدود، الفرز، التفرد، الحقول المطلوبة. "Usernames must be unique (checked on save)" أوضح من "فهرس فريد."\n\nحالات الحافة غالبًا ما تفرق بين وثيقة لطيفة وواحدة مفيدة. اذكر الحالات الفارغة، القيم null، المحاولات المتكررة، المهلات، وماذا يرى المستخدم عندما يفشل استدعاء API.\n\nعند مواجهة المجهولات، علّمها بدل التخمين:\n\n- Unknown: what message should appear when the email isn't found?\n- Unknown: should we allow 0 items, or force at least 1?\n- Unknown: is this error meant to be user-facing or only logged?\n\nتتحوّل هذه العلامات إلى أسئلة سريعة للفريق بدلًا من افتراضات صامتة.\n\n## إنشاء قائمة فجوات دون تحويلها إلى قائمة مهام\n\nقائمة الفجوات ليست Jira ثاني. هي سجل قصير مبني على الأدلة لأين لا تتطابق الشفرة والسلوك المقصود، أو أين لا يستطيع أحد بوضوح تفسير ما هو "صحيح". إذا نُفّذت جيدًا، تصبح أداة للاتفاق لا معركة للتخطيط.\n\nكن صارمًا بشأن ما يُحتسب كفجوة:\n\n- سلوك غير واضح: التطبيق يفعل شيئًا لكن القاعدة غير موثقة.\n- عدم اتساق: مكانان يتصرفان بشكل مختلف لنفس الحالة.\n- قاعدة مفقودة: حالة حافة موجودة لكن لا يوجد قرار في الشفرة أو الوثائق.\n\nعند تسجيل فجوة، أدرج ثلاثة أجزاء لتظل مبنية على أرضية واقعية:\n\n- Type: bug (الشفرة تبدو خاطئة) أو missing decision (النية غير واضحة)\n- Impact: ارتباك المستخدم، خطر أمني، فقدان بيانات، أو بسيط\n- Evidence: أين رأيتها وماذا لاحظت (route/handler/component)\n\nالأدلة هي ما يمنع القائمة من التحول إلى آراء. مثال: "POST /checkout/apply-coupon يقبل القسائم المنتهية، لكن CouponBanner.tsx يمنعها في الواجهة. الأثر: إيرادات وارتباك المستخدم. النوع: bug أو missing decision (تأكيد القاعدة المقصودة)."\n\nاجعلها قصيرة. ضع حدًا صارمًا، مثل 10 عناصر للمرّة الأولى. إذا وجدت 40 مشكلة، جمّعها إلى أنماط (تباينات التحقق، فحوصات الأذونات، حالات فارغة) واحتفظ بأمثلة رئيسية فقط.\n\nتجنّب إضافة تواريخ وجدولة داخل قائمة الفجوات. إذا كنت تحتاج ملكية، اجعلها خفيفة: اذكر من يجب أن يتخذ القرار (المنتج) أو من يمكنه التحقق (الهندسة)، ثم انقل التخطيط الحقيقي إلى قائمة المهام لديك.\n\n## مثال: توثيق ميزة حقيقية من الشفرة\n\nاختر نطاقًا صغيرًا عالي الحركة: الدفع مع رموز الترويج وخيارات الشحن. الهدف ليس إعادة كتابة المنتج، بل التقاط ما يفعله التطبيق اليوم.\n\nابدأ بالمسارات الخلفية. غالبًا ما تظهر القواعد هناك أولًا. قد تجد مسارات مثل POST /checkout/apply-promo, GET /checkout/shipping-options, وPOST /checkout/confirm.\n\nمن تلك المعالجات، اكتب السلوك بكلمات بسيطة:\n\n- تُتحقَّق رموز الترويج في الخادم (منتهية، حد الاستخدام، أهلية العميل).\n- تُعاد حسابات الإجماليات بعد تطبيق الكوبون، لكن فقط بعد إعادة التحقق من المخزون.\n- خيارات الشحن تعتمد على الوجهة، الوزن، وما إذا كان أي عنصر مُعلّم كـ "restricted."\n- تفشل عملية التأكيد إذا تغيّر مخزون بند line item منذ تحميل السلة.\n- تُحسب الضريبة بعد اختيار الشحن (وليس عند تطبيق الكوبون).\n\nثم تفقد مكوّنات الواجهة. قد يظهر PromoCodeInput أن الإجماليات تُحدّث فقط بعد استجابة ناجحة وأن الأخطاء تُعرض تحت الحقل. قد يختار ShippingOptions أرخص خيار تلقائيًا عند التحميل الأول ويطلق تحديث تفصيلي للأسعار عند تغيّر المستخدم للاختيار.\n\nالآن لديك مواصفة قابلة للقراءة وقائمة فجوات صغيرة. مثال: تختلف رسائل الأخطاء بين مسار الترويج والواجهة ("Invalid code" مقابل "Not eligible"), ولا يستطيع أحد تحديد قاعدة تقريب الضريبة (لكل بند أم لإجمالي الطلب).\n\nفي التخطيط، يتفق الفريق على الواقع أولًا ثم يقرر ما الذي سيتغيّر. بدلًا من مناقشة الآراء، تستعرضون السلوك الموثق، تختارون تباينًا واحدًا لإصلاحه، وتتركون الباقي كـ "السلوك الحالي المعروف" حتى يستحق إعادة النظر.\n\n## تحقق من المواصفة مع الفريق وابقها محدثة\n\nالمواصفة تساعد فقط إذا اتفق الفريق أنها تطابق الواقع. قم بقراءة سريعة مع مهندس واحد وشخص من المنتج. اجعلها مركّزة: 20–30 دقيقة عن ما يمكن للمستخدم فعله وماذا يفعل النظام ردًا.\n\nأثناء القراءة، حوّل العبارات إلى أسئلة نعم/لا. "عندما يصل المستخدم إلى هذا المسار، هل نعيد دائمًا 403 بدون جلسة؟" "هل هذه الحالة الفارغة مقصودة؟" هذا يفصل السلوك المقصود عن السلوك العرضي الذي تسلل مع مرور الوقت.\n\nاتفقوا على المصطلحات قبل التحرير. استخدم الكلمات التي يراها المستخدم في الواجهة (تسميات الأزرار، عناوين الصفحات، رسائل). أضف الأسماء الداخلية فقط عندما تساعد المهندسين على العثور على الشفرة (أسماء المسارات، أسماء المكوّنات). هذا يمنع عدم التطابق مثل قول المنتج "Workspace" بينما تقول المواصفة "Org."\n\nللحفاظ عليها محدثة، اجعل الملكية والإيقاع واضحين:\n\n- Spec owner: شخص واحد يدمج تغييرات المواصفة (غالبًا صاحب الميزة أو القائد الفني)\n- Update trigger: عند دمج PR لتغيّر سلوكي، أو عند كل إصدار\n- فحص سريع: أضف خانة "هل تم تحديث المواصفة؟" إلى قالب PR\n- التخزين: احتفظ بها قريبًا من الشفرة حتى تتغير مع الشفرة\n\nإذا كنت تستخدم أداة مثل Koder.ai، تساعد اللقطات والاسترجاع على مقارنة "قبل" و"بعد" السلوك عند تحديث المواصفة، خصوصًا بعد إعادة تهيئة كبيرة.\n\n## الأخطاء والفخاخ الشائعة\n\nأسرع طريق لفقدان الثقة في المواصفة هو وصف المنتج الذي تريده بدل المنتج الذي لديك. ضع قاعدة صارمة: كل عبارة يجب أن تدعمها شيء يمكنك الإشارة إليه في الشفرة أو شاشة حقيقية.\n\nفخ شائع آخر هو نسخ شكل الشفرة داخل الوثيقة. مواصفة تظهر كـ "Controller -> Service -> Repository" ليست مواصفة، بل خريطة مجلدات. اكتب بمصطلحات مرئية للمستخدم: ما الذي يطلق الإجراء، ماذا يرى المستخدم، ماذا يُحفَظ، وماذا تبدو الأخطاء.\n\nغالبًا ما تُتجاهل الأذونات والأدوار حتى النهاية، ثم ينهار كل شيء. أضف قواعد الوصول مبكرًا، حتى لو كانت فوضوية. اذكر أي الأدوار يمكنها العرض، الإنشاء، التعديل، الحذف، التصدير، أو الموافقة، وأين تُنفَّذ القاعدة (واجهة فقط، API فقط، أو كلاهما).\n\nلا تتخطَ المسارات غير السعيدة. السلوك الحقيقي يختبئ في المحاولات المتكررة، الفشل الجزئي، والقواعد القائمة على الزمن مثل الانتهاء، فترات التبريد، أو حدود "مرة واحدة في اليوم". تعامل معها كأفعال أولى.\n\nطريقة سريعة لابراز الفجوات هي البحث عن:\n\n- فشل التحقق ورسائل الخطأ الدقيقة التي يرىها المستخدم\n- معالجة الإرسال المزدوج (قابلية التكرار)\n- العمل الخلفي (الطوابير، cron) وماذا يحدث إذا فشل\n- قضايا التزامن (شخصان يغيران نفس السجل)\n- السلوك القائم على الزمن (مهلات، انتهاء صلاحية، حدود المعدل)\n\nأخيرًا، حرّك قائمة الفجوات. يجب تصنيف كل فجوة كواحدة من: "unknown, needs decision," "bug, fix," أو "missing feature, plan." إذا لم يُصنّف شيء، تتوقف القائمة وتتوقف المواصفة عن كونها "حية."\n\n## قائمة تحقق سريعة قبل المشاركة\n\nمرّر بسرعة للتحقق من الوضوح والتغطية وقابلية التنفيذ. يجب أن يفهم شخص لم يكتبها ما الذي تفعله الميزة اليوم وما الذي لا يزال غير واضح.\n\n### الوضوح والفهم المشترك\n\nاقرأ المواصفة كزميل جديد في اليوم الأول. إذا استطاع تلخيص الميزة في دقيقة، فأنت قريب. إذا ظل يسأل "أين يبدأ هذا؟" أو "ما هو المسار السعيد؟" شدد المقدمة.\n\nتحقق من:\n\n- اختبار الصفحة الواحدة: الافتتاحية تذكر هدف المستخدم، أين يبدأ التدفق، وأين ينتهي.\n- الأدوار والوصول: الأدوار الأساسية وما الذي يستطيع كل منها فعله وعدم فعله.\n- النتائج: ماذا يبدو النجاح وماذا يرى المستخدم عند الفشل (رسائل، إعادة توجيه، محاولات)\n- الحواف والحدود: حدود الحجم، حدود المعدل، المهلات، قواعد التحقق، وماذا يحدث عند غياب البيانات.\n- اللغة: استخدم مصطلحات الواجهة أولًا؛ عرّف المصطلحات الداخلية غير القابلة للتجنّب مرة واحدة.\n\n### فجوات تساعد، لا ضوضاء\n\nيجب أن تكون كل فجوة محددة وقابلة للاختبار. بدلًا من "عدم وضوح معالجة الأخطاء،" اكتب: "إذا أعاد مزود الدفع 402، تعرض الواجهة إشعارًا عامًا؛ أكد الرسالة المرغوبة وسلوك إعادة المحاولة." أضف إجراءً واحدًا لاحقًا (سؤال للمنتج، إضافة اختبار، فحص السجلات) واذكر من يجب أن يجيب.\n\n## الخطوات التالية لبدء هذا الأسبوع\n\nاختر مجال ميزة وحدده بمدة زمنية 60 دقيقة. اختر شيئًا صغيرًا لكن حقيقيًا (تسجيل الدخول، الدفع، البحث، شاشة إدارة). اكتب جملة واحدة للنطاق: ما الذي يتضمنه وما الذي لا يتضمنه.\n\nشَغِّل سير العمل مرة واحدة من البداية للنهاية: تصفّح المسارات/المعالجات الرئيسية، تتبع تدفق الواجهة الرئيسي، واكتب السلوكيات القابلة للملاحظة (المدخلات، المخرجات، التحقق، حالات الخطأ). إذا علِقت، سجّل السؤال كفجوة وواصل.\n\nعند الانتهاء، شارك المواصفة حيث يمكن للفريق التعليق، وضع قاعدة واحدة: يجب تحديث المواصفة مع أي تغيير سلوكي مُشحون في نفس نافذة التسليم، حتى لو كان خمسة أسطر.\n\nاحتفظ بالفجوات منفصلة عن قائمة المهام. جمّعها ضمن "سلوك غير معروف," "سلوك غير متسق," و"اختبارات مفقودة," ثم راجعها سريعًا أسبوعيًا لتقرر ما المهم الآن.\n\nإذا بدا المسودة والتكرار بطيئين، يمكن لأداة محادثة مثل Koder.ai مساعدتك في إخراج نسخة أولية بسرعة. صِف الميزة، ألصق مقتطفات أو أسماء مسارات رئيسية، حسّن الصياغة بالمحادثة، وصدر المصدر عند الحاجة. الفكرة هي السرعة والوضوح المشترك، لا عملية أكبر.ابدأ بقطعة صغيرة مرئية للمستخدم (مثال: “إعادة تعيين كلمة المرور” أو “دعوة زميل”). اقرأ Routes/handlers لالتقاط القواعد والنتائج، ثم اطلع على تدفق الواجهة لالتقط ما يراه المستخدم فعليًا (حالات تعطيل الأزرار، الأخطاء، إعادة التوجيه). اكتب المواصفة باستخدام قالب ثابت وسجل المجهولات في قائمة فجوات منفصلة.
الافتراض الافتراضي: اعتبر سلوك الشفرة الحالي كمصدر الحقيقة وادونه.\n\nإذا بدا السلوك عرضيًا أو غير متسق، لا “تصححه” داخل المواصفة — ضع علامة كـ فجوة مع أدلة (أين رأيتها وماذا تفعل)، ثم حدد قرارًا لتحديث الشفرة أو المواصفة.
اجعله مملًا وقابلًا للتكرار. قالب عملي: \n\n- Purpose\n- Entry points\n- Preconditions (auth/role/data)\n- Main flow (5–10 steps)\n- Data and side effects\n- Errors and edge cases\n- Open questions\n\nهذا يحافظ على قراءة المواصفات بسهولة ويسهل اكتشاف التباينات.
اكتب القواعد كمتطلبات مرئية للمستخدم، لا كملاحظات شفرة.\n\nأمثلة: \n\n- “Email must be valid”\n- “Quantity must be at least 1”\n- “Only admins can cancel any order; regular users can cancel their own within 10 minutes”\n\nالتقط ما الذي يسبب خطأً وماذا يرى المستخدم عند حدوثه.
ركّز على ما يمكن ملاحظته: \n\n- نتيجة النجاح (ماذا يتغير وماذا يرى المستخدم)\n- أنواع الفشل الشائعة (غير مسجل، غير مسموح، غير موجود، خطأ تحقق)\n- الآثار الجانبية (سجلات محدثة، رسائل/إشعارات مرسلة، مهام خلفية مجدولة)\n\nالآثار الجانبية مهمة لأنها تؤثر على ميزات ودعم/تشغيل أخرى.
إذا حظرت الواجهة شيئًا تسمح به الـ API (أو العكس)، سجّله كـ فجوة حتى يُتخذ قرار.\n\nسجل: \n\n- ما تقوله/تفعله الواجهة\n- ما يطبقه الـ backend\n- الأثر (ارتباك، أمان، مشكلات بيانات)\n\nثم اتفق على قاعدة واحدة وحدث الشفرة والمواصفة لتتطابقا.
اجعل قائمة الفجوات صغيرة ومبنية على أدلة. يجب أن يحتوي كل عنصر على: \n\n- Type: bug vs missing decision\n- Impact: minor vs serious (ارتباك المستخدم، مخاطرة أمنية، فقدان بيانات)\n- Evidence: أين رصدته (route/handler/component) والسلوك الدقيق\n\nتجنّب تحويلها إلى جدول زماني أو قائمة مهام منفصلة.
وثّقهم صراحة بدل إخفائهم. \n\nضمن: \n\n- حالات الفارغ (نتائج صفر، لا أذونات)\n- عمليات إعادة المحاولة/المهلات وما يمكن للمستخدم فعله بعد ذلك\n- إرسال مزدوج (نقرة مزدوجة، تحديث الصفحة)\n- التعارضات (شخصان يعدّلان نفس السجل)\n- قواعد زمنية (انتهاء صلاحية، فترات تبريد)\n\nهذه الأماكن غالبًا ما تُنتج المفاجآت والأخطاء.
اجعلها قصيرة: قراءة سريعة 20–30 دقيقة مع مهندس واحد وشخص من المنتج.\n\nحوّل العبارات إلى أسئلة نعم/لا (مثال: “هل نعيد دائمًا 403 عند عدم السماح؟”). ونسق المفردات باستخدام الكلمات التي تظهر في الواجهة (عناوين الأزرار، رسائل)، حتى يتفق الجميع على المعنى.
ضع المواصفة قرب الشفرة واجعل التحديث جزءًا من إطلاق الميزة.\n\nإعدادات عملية افتراضية: \n\n- مالك واحد واضح يدمج تغييرات المواصفة\n- مشغل التحديث: أي تغيير سلوكي يتم دمجه أو كل إصدار\n- بند في قالب PR: “هل تم تحديث المواصفة؟”\n- احتفظ بالفجوات منفصلة وراجعها باختصار حسب وتيرة\n\nالهدف هو تعديلات صغيرة ومتكررة، لا إعادة كتابة ضخمة.