ArchScan - النتائج وتقرير الجودة
يفحص ArchScan قاعدة الكود لديك ويُنتج تقريرًا كامل المطابقة مع درجة جودة واحدة مرجّحة حسب الفئات.
أقسام التقرير
Section titled “أقسام التقرير”- درجة الملخّص - درجة واحدة مرجّحة حسب الفئات + الحالة، قابلة للمقارنة عبر الإصدارات.
- النتائج - مع مقتطف الكود والموقع الدقيق للملف.
- تفصيل SOLID - تُفصَّل الانتهاكات بحسب المبادئ الخمسة.
- الحِزم - التبعيات والإصدارات.
- المشاريع - مقاييس لكل مشروع.
- خريطة التبعيات - عرض رسم بياني تفاعلي.
- التصدير - HTML/PDF قابل للمشاركة؛ تختار لغة التقرير لكل مساحة عمل.
كيف تُحسَب الدرجة؟
Section titled “كيف تُحسَب الدرجة؟”تُختزَل فئات المعمارية وSOLID والتبعيات والمقاييس إلى درجة واحدة وفقًا لأوزانها. ويُجرى الفحص في CI الخاص بك.
لوحة التحليلات
Section titled “لوحة التحليلات”صفحة ArchScan الرئيسية لوحة على مستوى مساحة العمل تحمل بشكل غير متزامن:
- المشاريع المدققة، متوسط الدرجة، النتائج المفتوحة، تدقيقات الشهر - بطاقات الترويسة.
- اتجاه الفحص - التشغيلات ومتوسط الدرجة لآخر 12 أسبوعا.
- حالة الأسطول - حلقة التقديرات (A-E)، وأشرطة التغطية والمحصلة، ومؤشر إيقاع العمل.
- التوزيع حسب اللغة - المشاريع والحصة المفحوصة ومتوسط الدرجة والإخفاقات.
- ما الذي تحرك - المشاريع التي ارتفعت أو هبطت درجتها مؤخرا أكثر من غيرها.
صحة الشيفرة (Code Health)
Section titled “صحة الشيفرة (Code Health)”يجيب ArchScan ← Code Health عن سؤال مختلف عن الدرجة: أين يقبع الدين. يقرأ آخر تشغيل لمشروع - أو، مع كل المشاريع، آخر تشغيل لكل مشروع مفحوص مدمجة معا:
- خريطة مخاطر الملفات - خريطة شجرية: مساحة البلاطة هي الخطر المركز (النتائج موزونة بأسوأ دالة في الملف) ولونها أسوأ شدة داخله. الملفات الصغيرة تطوى في بلاطة «أخرى» - لا شيء يسقط بصمت.
- توزيع التعقيد - الدوال في نطاقات تعقيد دوراني (1-5 / 6-10 / 11-20 / 21+)، مع أسوأ دالة بالاسم.
- دين التصميم حسب المبدأ - النتائج مجمعة بالمبدأ الذي تحرسه قاعدتها (SOLID وDRY وKISS وYAGNI).
- المكونات على التسلسل الرئيسي - كل وحدة بالتجريد × عدم الاستقرار؛ منطقتا الألم وعدم الجدوى معلمتان.
- البؤر الساخنة - الملفات التي تلتقي فيها النتائج مع التعقيد.
المشروع الذي لا يرسل عداؤه مقاييس يبلغ عنه بوصفه غير مقيس - لا صفرا أبدا.
صحة الاعتماديات (Dependency Health)
Section titled “صحة الاعتماديات (Dependency Health)”يقلب ArchScan ← الاعتماديات قوائم الحزم لكل مشروع إلى إجابات على مستوى الأسطول:
- جدول الحزم - بالحزمة لا بالمشروع: أي حزمة تعيق أكثر المشاريع، وكم إصدارا يتخلف أسوأ تثبيت، وأي مشروع على أي إصدار. الحزمة المثبتة على عدة إصدارات توسم منقسمة.
- إصدارات المنصة - SDK/بيئة التشغيل التي يعلنها كل مستودع (
csproj/global.json،pyproject.toml،go.mod،pom.xml،Gemfile،composer.json،package.json) - «من ما زال على .NET 6» بنظرة واحدة. تبلغ عنها لغات العدائين السبع كلها. - صفوف المشاريع - المجاميع ومزيج الحداثة والاستعلامات غير المحلولة (العداء دون شبكة لا يستطيع سؤال السجل - يبلغ عن ذلك غير معروف لا محدث).
SmartScan
Section titled “SmartScan”يتتبّع ArchScan → SmartScan كل نقطة دخول ويب ومهمة Quartz وخدمة خلفية ومستهلك MassTransit في مشروع .NET عبر الخدمات والمعالِجات حتى طبقة ORM (Entity Framework وDapper)، ويُبلغ عن المخاطر التي يراها في هذه السلسلة. إنه وحدة تحذير: لا يخفض الدرجة ولا يُفشل خط التكامل. السلسلة الخالية من المخاطر لا تُرسل شيئًا.
- السجل غير موجود - قد لا يُرجع استعلام (
FirstOrDefaultوFind…) أي شيء ويُستخدم الناتج دون تحقق. يوضّح الأثر ما إذا كان الطلب ينتهي بخطأ 500 أم أن catch عامًا في الأعلى يحوّله إلى رسالة خاطئة. - بيانات مكتوبة جزئيًا - طلب واحد ينفّذ commit أكثر من مرة دون معاملة تحيط بها.
- طول يتجاوز العمود وقيمة إلزامية مفقودة وقيمة مكررة - يصل حقل في الطلب إلى عمود محدود الطول أو
NOT NULLأو فريد دون قاعدة مطابقة في الطريق. - قيمة في الطلب لا يستطيع الكود قراءتها (.NET, Java, Kotlin, Python, Go, Ruby, PHP) - تُقرأ قيمة يرسلها الطلب باستخدام
int.ParseأوGuid.ParseأوConvert.ToInt32وما شابهها دون فحص مسبق، فتنتهي القيمة غير الصحيحة بخطأ 500 بدلًا من 400. وتظهر قراءة سجل يحدده الطلب باستخدامFirst/Singleبالطريقة نفسها تحت السجل غير موجود: إذا لم يكن السجل موجودًا ينتهي الطلب بخطأ 500 بدلًا من “غير موجود”. - حذف تمنعه سجلات مرتبطة (.NET, Java, Kotlin, Python, Go, Ruby, PHP) - يُحذف سجل فعليًا (وليس حذفًا منطقيًا) بينما قد تظل سجلات أخرى تشير إليه عبر
RestrictأوNoActionأوClientSetNull؛ فترفض قاعدة البيانات الحذف بخطأ مفتاح أجنبي. لا تُعرض المسارات التي تفحص هذه السجلات أو تحذفها أو تعيد ربطها أولًا. - قيمة خارج ما يتسع له العمود (.NET؛ حالة decimal أيضًا في Java وKotlin وPython وGo وRuby وPHP؛ وحالة enum أيضًا في Ruby وPHP) - رقم أكبر مما يتسع له عمود
decimal(p, s)، أو تاريخ قد لا يرسله الطلب فيصل إلى عمودdatetimeفي SQL Server بقيمة 0001-01-01، أو قيمة غير معرّفة تصل إلى عمود enum في PostgreSQL.
اختر مشروعًا وافتح فئة: تُجمَّع المخاطر حسب الطبقة والخدمة (أو حسب نوع الطلب). يعرض الخطر المفتوح السلسلة خطوة بخطوة مع الملف والسطر، والشيفرة، والحل، وموجّهًا (prompt) يمكن نسخه إلى مساعد ذكاء اصطناعي. يمكن إغلاق الخطر (إنذار كاذب، خطر مقبول، لن يُصلَح) ويبقى مغلقًا ما دام الخطر نفسه موجودًا.
في المستهلك يُعاد إرسال الرسالة (أو تُبتلع خلف catch عام)، وفي المهمة يفشل التشغيل. ليس للمهمة طلب، لذا تُفحص فقط من حيث البيانات المكتوبة جزئيًا.
في واجهة TypeScript الأمامية (React وNext.js) تبدأ السلسلة حيث يتصرف المستخدم أو حيث يرسم الإطار الصفحة - معالج أحداث JSX، أو useEffect، أو العرض على الخادم (getServerSideProps أو صفحة غير متزامنة)، أو معالج مسار في Next.js - وتمر عبر الـ hooks وthunks في Redux والخدمات حتى الطلب (fetch وaxios)، بما في ذلك الانتقال من طلب العميل إلى مسار API الخاص بالمشروع. الفئات هناك: طلب غير معالج (فشل طلب لا يلتقطه شيء: لا يُبلَّغ المستخدم بشيء، أو يرد العرض على الخادم بخطأ 500)، وفشل يُمرَّر كنجاح (فشل يُلتقط ويُعاد كقيمة عادية، أو رد خطأ من fetch يُقرأ كبيانات، أو رفض thunk لا ينظر إليه أحد)، والسجل غير موجود (تُقرأ تلك القيمة الفارغة بعد ذلك فتظهر الشاشة خطأ)، وبيانات مكتوبة جزئياً (طلبا كتابة متتاليان إلى الواجهة الخلفية الخاصة). عميل HTTP يعرض كل فشل للمستخدم (رسالة toast في interceptor) يُعد معالجة للخطأ.
تُتتبَّع الواجهات الخلفية في Ruby on Rails وKotlin Spring كما في .NET: إجراءات المتحكمات (ونقاط Grape)، والمهام والمستهلكون حتى ActiveRecord أو Spring Data / JPA، بالفئات نفسها؛ وتُقرأ حدود الأعمدة من db/schema.rb أو من تعليقات @Column. أما تطبيقات Android (Kotlin) وiOS (Swift) فتُتتبَّع مثل الواجهة الأمامية: من لمسة أو دورة حياة شاشة أو view model حتى الطلب (Retrofit وOkHttp وKtor؛ URLSession وAlamofire وMoya). وهناك يؤدي فشل طلب غير معالج يفلت من coroutine، أو استخدام try!، إلى انهيار التطبيق؛ ويُبلَّغ عن الفشل الذي يتحول إلى nil أو إلى قيمة افتراضية كفشل يُمرَّر كنجاح.
تُتتبَّع الواجهات الخلفية في Java (Spring Data وJPA وJdbcTemplate وMyBatis) وPython (Django وDRF وFlask وFastAPI وCelery؛ Django ORM وSQLAlchemy) وGo (net/http وgin وecho وchi وfiber وgRPC؛ database/sql وsqlx وGORM وpgx) وPHP (Laravel وSymfony؛ Eloquent وDoctrine) بالطريقة نفسها وبالفئات نفسها. في Go يكون السجل المفقود خطأً لا قيمة null: فإذا تُجوهل خطأ «غير موجود» فاستُخدم سجل فارغ كأنه وُجد وردّ الطلب بالنجاح، يظهر ذلك بتأثير صامت. ويُبلِّغ Go أيضًا عن عملية كتابة يُتجاهَل خطؤها (استدعاء db.Create(...) منفرد، أو _ =، أو خطأ يُسجَّل فقط) بينما يردّ الطلب بالنجاح: فيُقال للعميل إن البيانات حُفظت وقد لا تكون حُفظت.
يُفعَّل SmartScan لكل مشروع على حدة وهو متوقف افتراضيًا: المشروع → الإعدادات → الفحص → تشغيل SmartScan. بعدها يعمل في الفحوص العميقة لذلك المشروع بدءًا من تشغيل خط الأنابيب التالي، دون أي تعديل على خط الأنابيب. يتطلب وحدة SmartScan التي يمكن للمسؤول إيقافها من الإدارة → الإعدادات → الوحدات.