--- name: code-refactorer description: "Restructure existing, WORKING code into a clean layered architecture and accurate SOLID — aggressively improving structure while keeping behavior byte-identical. Use when asked to refactor, clean up, apply SOLID, decouple, split a god class/component, remove duplication, introduce dependency injection, or reorganize into proper layers. For restructuring code that already works — NOT adding features, fixing bugs, or writing test suites. Repo-agnostic. Architectural sibling of ce-simplify-code (that = tidy recent diff; this = system-level restructuring)." ---
Code Refactorer (معيد الهيكلة المعماري)
> المصدر: مقتبَسة ومكيّفة من Kings-Of-The-Web/futrx-skills (code-refactorer، GitHub، 2026-06-23، بلا license — استخدام داخلي خاص مع توثيق المصدر). أُضيفت لترسانتنا 2026-06-29 بموافقة د. وائل، مع طبقة تكامل خاصة بنا (Serena MCP + TestSprite + أعرافنا).
🔧 تكامل الترسانة (طبقتنا — اقرأها أولاً)
هذه المهارة = الاستراتيجية (ماذا يُنقل وأين). نُنفّذها بأدواتنا:
- الآلية الآمنة = Serena MCP ⭐ — لكل «حركة آمنة» في §10 (extract / rename / move / find-references): استخدم أدوات Serena الرمزية (symbol-level rename عبر المشروع كله بنداء واحد، find referencing symbols، symbol overview) بدل التعديل النصي اليدوي. هذا يحوّل «جراحة نص هشّة» إلى نقل رمزي مؤكَّد. القاعدة: أي rename/move عبر ملفات ← Serena أولاً.
- التحقق = §11 + أدواتنا: المترجِم (type-check) أولاً، ثم مجموعة اختبارات المشروع الحالية، ثم TestSprite MCP (لا «تم» قبل pass 100%). characterization test فقط للمنطق الذي لا يحرسه النوع ولا تغطّيه الاختبارات.
- الموديل: قرارات المعمارية الكبرى = Opus 4.8 (الأعمق) · الحركات الكثيفة/التكرارية (bulk moves) = GLM-5.2 (بطل القيمة). للمهام الحرجة: نقد متقاطع عبر
parallel-adversarial-review. - يقترن مع greenfield (S2): كود قديم/مجهول/VB قديم ←
greenfieldيعكس هندسته ويستخرج specs ← ثم هذه المهارة تعيد هيكلته. خط متّصل. - يغذّي حلقة التحسين المستمر (المرحلة 11): كل smell رُصد وتُرك يُسجَّل كـ Linear issue / TODO في backlog الأسبوع التالي (auditing-progress).
- commits: أعراف git عندنا — commit لكل حركة محافِظة على السلوك (restructure ثم verify ثم commit). لا diff عملاق غير مُلتزَم. ممنوع push بدون اختبارات تمرّ.
- التقرير: عربي مختصر بصيغة «smell ← المبدأ ← الإصلاح (file:line)» + «أُثبت السلوك بـ:» + «تُرك عمداً:».
مهمتك. تُعيد هيكلة كود موجود ويعمل أصلاً. شخصٌ كتب مسودة أولى؛ مهمتك إعادة هيكلتها للمعمارية والمعايير أدناه ليجدها الصيانة التالية بديهية. لستَ مطوّر ميزات ولا مصلِح أخطاء ولا كاتب اختبارات — لو رصدت bug دوّنه واتركه؛ ولو نقصت ميزة فهذه ليست المهمة.
كن جريئاً في البنية، صارماً لا يساوم في السلوك. لا يتعارضان، وفصلهما هو ما يجعلك معيد هيكلة لا مطوّراً جباناً ولا مُعيد كتابة متهوّراً:
- جريء على البنية — انقل وحدات كاملة لطبقتها الصحيحة، قسّم god classes، أدخِل الواجهات الناقصة، أعد التسمية بحسم. ترك smell «احتياطاً» = فشل، لا حذر.
- صارم على السلوك — المخرجات، الآثار الجانبية، الأخطاء، التوقيت تخرج متطابقة. أي تغيير للسلوك = إعادة كتابة لا refactor.
commit لكل خطوة. كل حركة محافِظة على السلوك = commit مستقل (restructure ثم verify ثم commit). لا تكدّس عشر حركات في diff عملاق واحد.
السلوك مُجمَّد — الثابت الوحيد
أثبت أن السلوك لم يتغيّر بعد كل خطوة — أساساً عبر المترجِم والاختبارات الموجودة (§11). لو لزم إصلاح صحّة فعلاً، فاجعله commit مستقلاً موسوماً بوضوح؛ لا تهرّب تغيير سلوك داخل refactor.
اعمل بالأسئلة: شخّص مقابل المعايير أدناه، سمِّ كل smell بـ file:line، ثم انقل الكود لموضعه في خطوات صغيرة قابلة للعكس ومُتحقَّق منها.
---
1. الهدف — أين ينتهي الكود
نجمتك القطبية. اربط الكود الحالي بالمجلدات أدناه ثم انقل كل قطعة لموضعها. معظم مشاكل الصيانة هي في الحقيقة مشاكل طبقات: قواعد عمل متشابكة مع SQL، معالج طلب يتخذ قرار دفع، «أين يذهب هذا؟» يُجاب بالملاءمة لا بالدور. أسماء المجلدات أعراف — الحدود واتجاه الاعتماد هما المهم، ويصمدان في أي لغة أو إطار.
جمّع حسب الطبقة (الدور)، لا حسب الميزة. كل الـ controllers معاً، كل الـ services معاً، كل الـ repositories معاً. الخدمات متغايرة وغالباً غير مرتبطة بميزة واحدة (خدمة دفع، خدمة تحليل، خدمة بيانات سوق) فشجرة قائمة على الطبقات تبقيها قابلة للإيجاد. حين تكبر طبقة، قسّمها داخلياً حسب القدرة (services/payment/)، لا بنشر ميزة عبر مجلدات كثيرة.
المجلدات، ومهمة كل واحد
كل مجلد يجيب سؤالاً واحداً. لو أجاب ملف سؤالين، فهذا هو الـ smell — قسّمه.
Backend:
controllers/— التسليم الوارد (الباب الأمامي). العالم الخارجي يناديك. الـ controller يأخذ طلباً وارداً، يستخرج المُدخلات، ينادي خدمة واحدة، يشكّل الرد/الحالة. رفيع — لا منطق عمل، لا SQL.
if يتخذ قرار عمل، أو استعلام قاعدة بيانات.
services/— منطق العمل (النواة؛ الأفعال). ما يفعله التطبيق فعلاً. تنسّق repositories وclients، تملك سير العمل/المعاملة، تبقى حرّة من تفاصيل الـ I/O — تعتمد على واجهات لا على HTTP/SQL مباشرة. قسّمها حسب القدرة.
repositories/— الوصول للبيانات (صادر لقاعدة بياناتك). يقرأ/يكتب خلف واجهة. الكود الوحيد الذي يعرف DB/SQL/ORM.
clients/— محوّلات التكامل (صادر لواجهات الآخرين). أنت تنادي العالم الخارجي (Stripe، بورصة، API طرف ثالث) وتخفيه خلف واجهة. مرآة الـ controller.
models/— أشكال البيانات (مصدر حقيقة واحد). كيانات وقيم، تُعرَّف مرة واحدة كأنواع قابلة للتسلسل. افصل request/response منفصلاً فقط عند حدّ يختلف فيه الشكل المكشوف فعلاً عن الداخلي، أو حين يجب إخفاء حقل (لا تكشف password hash أبداً).transport/— ميكانيكا الشبكة فقط. كيف تعبر البايتات حدّ العملية: البروتوكول (HTTP/WS/RPC/gRPC/SSE)، دورة حياة الاتصال، (de)serialization، retries، reconnects. خلف واجهة transport.
config/— الربط والإعدادات. تحميل env، جذر التركيب DI الذي يربط الـ concretes بالواجهات، الإعدادات، feature flags. مستوى أعلى ومستقل — ليس جزءاً من transport.middleware/— خط أنابيب الطلب العابر. Auth، logging، error mapping تلفّ controllers كثيرة.shared/— أدوات ورقية (leaf). مساعدات عابرة بلا اعتماد: تنسيق، رياضيات، وقت، أنواع نتيجة/خطأ. القاعدة التي تمنع تعفّنها: الكود هنا لا يستورد منservices//controllers//repositories/— إنه ورقة يعتمد عليها الجميع ولا يعتمد على شيء. لحظة احتياج «util» لخدمة، لم يعد shared — صار خدمة.
ui/— مكوّنات/شاشات؛ عرض فقط.state/— stores/hooks/منطق العرض؛ ينادي API client لا داخليات الـ backend.api/— عميل الـ API: نداءات ذات معنى تجاري تُطابق models، بلا تفاصيل بروتوكول.transport/— ميكانيكا HTTP/WebSocket/RPC.shared/— أدوات ورقية (نفس قاعدة الـ leaf).
shared/(بين الـ backend والـ frontend) — عقد الـ API. أنواع request/response التي يستوردها الطرفان. متميّزة عنshared/الداخلي لكل جانب.
domain/ افتراضياً. منطق العمل في services/؛ الأشكال في models/. طبقة domain/ منفصلة من كيانات-وقواعد نقية = تصعيد DDD/Clean — أضِفها فقط حين تتعقّد القواعد فعلاً وتنمذج مع خبراء المجال. لمعظم التطبيقات = طقوس؛ لا تُدخلها استباقياً.قاعدة الاعتماد
النداءات تتدفّق للداخل نحو الخدمات: controller ثم service ثم repository/client. الخدمة هي النواة؛ تعتمد على واجهات، فالـ repositories (قاعدتك) والـ clients (واجهات خارجية) يشيران للخلف نحو عقود الخدمة — لا العكس. config/ يربط الـ concretes في جذر تركيب واحد؛ shared/ ورقة يستخدمها الكل. البنية التحتية لا تتسرّب للأعلى — لا نوع SQL/ORM في توقيع خدمة، لا نوع Stripe يفلت من client، لا تفصيل بروتوكول يظهر فوق transport/.
المحوّلات الحدّية الثلاثة (التماسات التي يجب ضبطها)
controllers/ وrepositories/ وclients/ كلها محوّلات حدّية تبقي تفاصيل العالم الخارجي خارج منطق العمل. نفس المهمة، ثلاثة اتجاهات:
- Controller يخفي كيف تصل الطلبات (HTTP/WS) — يواجه الداخل.
- Repository يخفي أين تعيش البيانات (DB/SQL) — يواجه الخارج.
- Client يخفي أي API خارجي تعتمد عليه — يواجه الخارج.
- تماس الـ API (backend ثم frontend): الـ frontend يكلّم الـ backend فقط عبر العقد المُنمَّط في
shared/الجذر، مُتحقَّقاً عند الحدّ، عبر API client — لا repository/service/DB row. - تماس الـ transport (السلك، تحت controllers وclients): كلاهما على واجهة transport لا بروتوكول concrete. بدّل HTTP لـ WebSocket أو أضِف RPC ← implementation transport جديد وصفر تغيير في controllers/clients/services/models.
أين ينتمي هذا؟ — أسئلة التوجيه
- العالم الخارجي ينادي للداخل (معالج طلب)؟ ←
controllers/رفيع. - منطق/سير عمل («حين X، افعل A ثم B ثم احفظ»)؟ ← قدرة في
services/. - قراءة/كتابة قاعدتنا؟ ←
repositories/خلف واجهة. - نداء API لغيرنا؟ ←
clients/خلف واجهة. - شكل بيانات؟ ←
models/. - السلك نفسه — بروتوكول/sockets/serialization/retries؟ ←
transport/خلف واجهة. - env/ربط/flags؟ ←
config/. - نقي ومُعاد استخدامه؟ ←
shared/ورقة بلا استيراد تطبيق.
البنية (كيّف الأسماء؛ ابقِ الحدود)
قسّم القمة حسب وحدة النشر —backend/ مقابل frontend/، ثم جمّع حسب الطبقة داخل كل جانب، ويلتقيان فقط عبر عقد الـ API في shared/ الجذر.
backend/
controllers/ # تسليم وارد — رفيع: حلّل الطلب ثم نادِ خدمة واحدة ثم شكّل الرد
services/ # منطق العمل (الأفعال)؛ قسّم حسب القدرة: payment/ parsing/ marketData/
repositories/ # وصول بيانات — الكود الوحيد الذي يعرف الـ DB، خلف واجهات
clients/ # محوّلات صادرة — نداء APIs خارجية، خلف واجهات
models/ # أشكال قابلة للتسلسل — مصدر حقيقة واحد
transport/ # ميكانيكا شبكة فقط — HTTP/WS/RPC، serialization، retries
config/ # env، جذر تركيب DI، إعدادات، flags ← قمة، ليس تحت transport
middleware/ # خط أنابيب عابر — auth، logging، error mapping
shared/ # أدوات ورقية — لا تستورد شيئاً من التطبيق
frontend/
ui/ state/ api/ transport/ shared/ # نفس القاعدة: ui ← state ← api ← transport
shared/ # جذر الـ repo: عقد الـ API — أنواع request/response للطرفين
هذا تحقيق واحد لا إلزام. monorepo يجعلها ثلاث حزم؛ تطبيق full-stack يبقيها مجلدات؛ خدمة صغيرة تجمع الثلاثي وتؤجّل clients/. تطبيق متمحور حول الميزات فعلاً قد يجمع حسب الميزة — البديل المشروع، اخترْه فقط حين تخصّ الخدمات ميزة واحدة فعلاً. ما يجب أن يصمد دائماً: قاعدة البيانات خلف واجهات repository، الخدمات تحمل منطق العمل حرّاً من I/O، الـ APIs الخارجية خلف واجهات client، الـ frontend يعتمد فقط على عقد الـ API، وسرد تكراري للمجلدات يكشف الوحدات وطبقاتها قبل أن يفتح أحد ملفاً.
2. افهم ما هنا قبل أن تنقله
- ما طُلب مني إعادة هيكلته فعلاً؟ حدّد النطاق، لا توسّعه.
- أي سلوك يجب أن يبقى متطابقاً؟ سمِّ النتائج المرصودة التي تجمّدها.
- الشكل الحالي مقابل الهدف؟ اربط كل قطعة بـ §1.
- ما الموجود قريباً؟ اقرأ أقرب شقيق كاملاً؛ تحرّك مع النمط المحلي.
- أي عقد/أساس/أنواع تحكم هذا؟ اقرأ الواجهات وتعريفات النوع قبل تغيير ما تصفه.
- أي اختبارات تغطّي هذا؟ اعثر عليها — توثّق السلوك المُجمَّد وهي شبكتك الأولى.
- ما الذي قد يكسره هذا؟ اسرد المنادين والعقود والتدفّقات.
3. الوضوح — هل سيعرف الصيانة التالية أين ينظر؟
- هل الملكية واضحة؟ إن لا، انقل الكود لأوضح موضع مسؤولية.
- هل البنية تشرح النظام؟ كل قطعة حيث دورها بديهي.
- هل يمكن تمثيل حالات غير صالحة؟ إن نعم، ضيّق الأنواع أو قسّم الحالة فيستحيل بناء الحالة السيئة.
- هل السطح العام ضروري؟ عقود صغيرة ومستقرة.
4. التسمية — هل كل اسم يقول الحقيقة؟
اسمٌ يكذب أو يطمس النيّة = عيب؛ إصلاحه هو الـ refactor.- هل الاسم يذكر النيّة لا الميكانيكا/النوع؟
activeUsersلاfilteredArray؛ لا تشفّر النوع (userList). - الطول متناسب مع النطاق؟ فهرس حلقة
i؛ export واسع يجب أن يكون وصفياً. - الدوال أفعال، القيم أسماء؟
parseDateمقابلitemCount. - الـ booleans محمولات موجبة؟
isEnabled/hasErrorsلاflagولاisNotReady. - صادق عن الكلفة والأثر؟
getيصيب الشبكة كاذب — استخدمfetch/load؛ اجعل الأثر مسموعاً (commit/flush). - مصطلح واحد للمفهوم في كل مكان؟ لا تخلط
fetch/get/load. - الأضداد متناظرة؟
open/closeلاopen/dismiss. - حذفت كلمات الضجيج؟
Manager/Helper/Util/-Implغالباً مفهوم مفقود.
5. كود رشيق — هل يستحق مكانه؟
- هل أعيد استخدام/أمدّ نمطاً موجوداً؟ افعل إن صغّر النظام كله.
- أضيف شيئاً للمستقبل؟ لا خيارات/flags/تجريدات تخمينية. YAGNI يهزم SOLID التخميني.
- هل هذا wrapper يعمل فعلاً؟ احذف pass-throughs التي تمرّر فقط.
- هل التكرار بنيوي؟ أسطر مكرّرة قليلة أفضل من تجريد سابق لأوانه؛ ملفات/دورات/فروع مكرّرة = شكل مشترك مفقود فاستخرجه.
- ما الذي أحذفه الآن بعد نجاح التغيير؟ كود ميت، params غير مستخدمة، تعليقات بائدة.
6. الأنواع والتغليف — هل النموذج يطابق الواقع؟
- ما الشكل الدقيق؟ أنواع دقيقة لا
any/stringعامة. - لماذا هذا التأكيد آمن؟ تجنّب
asإلا حين الثابت مضمون — خاصة على بيانات تعبر حدّاً. - هل أُسكت المترجِم؟ لا تكبت خطأً — أصلح النموذج.
- هل هذا السلوك مغلّف في class؟ الافتراض OOP: احتوِ السلوك والحالة/الثوابت التي يحرسها داخل class متماسك يخفي داخلياته خلف واجهة عامة صغيرة. الإشارة الواضحة: لو شاركت دالتان أو أكثر نفس البيانات أو عدّلتاها، فتلك البيانات تريد أن تصير class. فقط التحويل النقي عديم الحالة يبقى دالة.
- هل يجب تصدير/إظهار هذا؟
publicتعني مدعوم؛ علّم الأوّليات منخفضة المستوىprivateفلا يتجاوز المنادون الثوابت.
7. الحدود — هل اتجاه الاعتماد صحيح؟
- هل أتبع اتجاه الاعتماد؟ الكود الأدنى لا يستورد التنسيق الأعلى. لو عكس refactor سهماً، توقّف.
- أين الحواف؟ أبقِ I/O وDOM وشبكة وتخزين ووقت عند حدود النظام؛ اعزل المنطق النقي.
- هل المُدخل موثوق؟ تحقّق من غير الموثوق عند الحدّ.
- من يملك الثوابت؟ أبقِ الانتقالات الحافظة للثابت في المالك الدلالي.
- هل هذا الفرع يدافع عن حالة داخلية مستحيلة؟ احذفه أو أصلح النوع الذي سمح بها.
8. SOLID — تعريفات دقيقة كاختبار ضغط
استخدم التعريفات الحقيقية لا الفولكلور. SOLID تشخيص لا إذن لإضافة تجريد. لو كبّر مبدأٌ الكود بلا توضيح ملكية أو حماية سلوك، اختر الأصغر.- S — مسؤولية واحدة. «سبب واحد للتغيير» = فاعل/صاحب مصلحة واحد يقود تغييراتها. الاختبار: هل طلب من دور مختلف (DB admin مقابل UI مقابل خبير مجال) يجبر تعديل نفس الوحدة؟ الإصلاح: قسّم على محاور التغيير.
- O — مفتوح/مغلق. الاختبار: هل إضافة variant تتطلّب تعديل
if/switchقائم؟ الإصلاح: registry/strategy أو عقد polymorphic — حين يقلّل الـ diff الكلي. - L — استبدال ليسكوف. كل implementation يعمل حيث يُتوقّع عقده. الاختبار: هل يحتاج المنادون
instanceofأو تضيف الأنواع الفرعيةthrow "not supported"؟ الإصلاح: التجريد الأساس خاطئ — ضيّقه أو قسّمه. - I — فصل الواجهات. الاختبار: هل يكتب المنفّذون stubs أو يستخدم المنادون شريحة من واجهة سمينة؟ الإصلاح: واجهات حسب الدور (reader مقابل writer).
- D — عكس الاعتماد. السياسة العليا تعتمد على تجريدات. الاختبار: هل تعمل خدمة
newلـ class concrete أو تصل لـ singleton عام؟ الإصلاح: اعتمد واجهة، احقن الـ concrete، اربط في جذر تركيب واحد.
9. روائح بنيوية للصيد
- آثار جانبية وقت الاستيراد — وحدات تبدأ sockets/intervals على
import. انقلها لـ factory بـstart()/stop(). - god unit — class/component يملك دورة حياة + mapping + عرض + I/O. استخرج المتعاونين.
- منطق مجال مكرّر — نفس parse/aggregate منسوخ. استخرج أداة مشتركة واحدة.
- دورة حياة/تخلّص مفقودة — timers/sockets بلا teardown ← تسريبات. وفّر disposer ونادِه.
- معالجة أخطاء حدّية غير متّسقة — وحّد mapping واحداً عند الحافة.
- فقد بيانات صامت — مُدخل غير صالح يُفلتر بدل رفضه. تحقّق وأظهر.
- إفراط في إبطال الـ effect — افصل «أنشئ مرة» عن «حدّث عند تغيّر البيانات».
- config مثبّت داخل المنطق — ارفعه لوحدات config أو props.
10. حركات آمنة — ميكانيكا كل تغيير
لا تنقل وتدعُ. لكل تغيير تسلسل آمن ميكانيكياً؛ اتبعه وتحقّق بين الخطوات. (عندنا: نفّذ هذه عبر Serena MCP حيثما أمكن.)- استخراج (دالة/class/hook/component): انسخ المنطق لموطنه الجديد ثم اجعل الموقع القديم يفوّض ثم تحقّق ثم احذف الجسم القديم. لا قصّ-ولصق في حركة واحدة.
- تغيير عقد يعتمده المنادون (توسيع/تقليص): أضِف الشكل الجديد بجانب القديم ثم رحّل المنادين commit تلو الآخر ثم احذف القديم. لا تكسر كل المواقع دفعة.
- إدخال seam (DIP): استخرج الواجهة من الاستخدام الحالي ثم اجعل الـ concrete ينفّذها ثم احقنه ثم اربط في جذر واحد.
- استبدال conditional بـ registry/polymorphism (OCP): انصب الـ dispatch بنفس الفروع ثم انقل فرعاً تلو الآخر ثم احذف الـ conditional حين يفرغ.
- refactoring مدفوع بالنوع: غيّر التعريف (rename/narrow/split union) ودع المترجِم يسرد كل موقع متأثّر — عندنا: Serena rename/find-references. أصلح ما احمرّ؛ قائمة فارغة تثبت اكتمال النقل.
- rename: استخدم rename واعياً بالنوع فتتحرّك كل المراجع معاً (Serena).
11. تحقّق من كل خطوة — المترجِم أولاً، الاختبارات مِبضع
- type-check بعد كل حركة. أرخص وأقوى إثبات أن التماس لا يزال متّصلاً؛ قائمة أخطاء فارغة = الحركة وصلت.
- شغّل الموجود. أوامر المشروع نفسه (scripts/Makefile/CI) — lint، build، مجموعة الاختبارات الحالية. عندنا: + TestSprite MCP، لا «تم» قبل 100% pass.
- الاختبارات مِبضع لا شرط مسبق. لا تبنِ تغطية لكود يعمل لتعيد هيكلته — اكتب characterization test فقط حين تعيد هيكلة منطق لا يحرسه النوع ولا تغطّيه الاختبارات (حساب/parser/خوارزمية). ثبّت مخرجاته الحالية (بالأخطاء)، أعد الهيكلة، أكّد التطابق.
- احذر الانجراف الصامت. «يترجم/الاختبارات تمرّ» ليس إثباتاً كاملاً. تغيّر صامت محتمل: ترتيب المخرجات، رسائل/أنواع الأخطاء، أسطر اللوج،
nullمقابلundefined، دقّة الأرقام، توقيت/ترتيب async، خطأ مرمي مقابل معاد. افحصها بالعين. - لو تعذّر فحص، قُلها — أبلغ بالضبط ما فشل أو تُخطّي؛ لا تدّعِ تحقّقاً لم تفعله.
12. النطاق والـ commits — ابقَ في المهمة، commit لكل حركة
- أعد هيكلة ما تتطلّبه المهمة فقط. أبقِ الملفات غير ذات الصلة خارج الـ diff. دوّن الروائح الأخرى للاحقاً.
- حركة واحدة لكل commit. برسالة تقول ماذا تحرّك ولماذا — فتقرأ المراجعة بنظافة ويبقى
git bisectذا معنى. - لا تتنكّر كإعادة كتابة. لو تعذّر بلوغ الهدف بخطوات حافظة للسلوك، توقّف وأبلِغ — إعادة الكتابة قرار منفصل صريح.
- غيّرت عقداً عاماً؟ حدّث كل منادٍ واختبار في نفس التغيير.
13. المراجعة النهائية — اقرأ الـ diff كالصيانة التالية
- هل التغيير أصغر من المسودة الأولى العاملة؟
- هل الأسماء والأنواع وحدود الملكية واضحة بلا جولة؟ هل كل قطعة في طبقتها الصحيحة؟
- هل جعل SOLID التصميم أبسط وأأمن أم أضفت تجريداً لذاته؟
- هل حذفت الكود الميت والسقالات وتجنّبت توسيع APIs بلا حاجة؟
- هل السلوك مُثبَت عدم تغيّره، مع ذكر الفحص؟
التقرير (عربي مختصر)
حين تنتهي، أبلِغ: 1. smell ← المبدأ ← الإصلاح لكل تغيير، معfile:line.
2. السلوك حُفظ بـ: أي فحص/اختبار أثبته (+ نتيجة TestSprite).
3. تُرك عمداً: روائح رأيتها وتركتها، ولماذا (خارج النطاق أو YAGNI) — تُسجَّل في backlog حلقة التحسين.