بنية التقرير
تقرير ProjectReport بصيغة JSON الناتج عن --json، حقلاً بحقل
cleanlens --json يطبع كائن ProjectReport. الأنواع معرّفة في src/types/index.ts. هذا الملف يصف كل حقل.
ProjectReport
| الحقل | النوع | الوصف |
|---|---|---|
schemaVersion | رقم | 2 لمحرّك commit-diff |
generatedAt | نص (ISO 8601) | وقت إنشاء التقرير |
engine | "commit-diff" | محرّك النسب المستخدم ("head-blame" كان القديم) |
analysisConfigHash | نص | بصمة القواعد + الاستثناءات + التقييم (وهي أيضاً مفتاح الذاكرة المؤقتة)؛ البصمات المتساوية تعني تقارير قابلة للمقارنة |
developerCount | رقم | عدد المطورين بعد دمج الهويات |
totalViolations | رقم | المخالفات في الكود الحالي |
unattributedViolations | رقم | المخالفات التي تعذّرت قراءة ملفها |
analyzedFiles | رقم | الملفات المحللة في فحص HEAD |
analyzedCommits | رقم | الـ commits التي أُعيد تشغيلها |
developers | Developer[] | انظر أدناه |
violations | Violation[] | انظر أدناه، مرتبة حسب الخطورة، ثم المسار، ثم السطر |
Developer
| الحقل | النوع | الوصف |
|---|---|---|
id | نص | dev-1 وdev-2، … حسب عدد الـ commits. ثابت داخل التقرير الواحد فقط. طابق المطورين بين التقارير باستخدام emails. |
displayName | نص | الاسم (الأسماء المدموجة تُربط بـ -) |
emails | مصفوفة نصوص | عناوين بريد الكتّاب بأحرف صغيرة |
cleanCodeScore | رقم | null | من 0 إلى 100، مقرّبة؛ null = لا يوجد كود محلل |
scoreExact | رقم | null | الدرجة غير المقرّبة |
scoreByCategory | كائن | { duplication, structure, hygiene }، كل منها { density, subScore }؛ وdensity هنا بعد التقليص |
violationCount | رقم | المخالفات التي أُدخلت بثقة high/medium |
weightedViolationPoints | رقم | مجموع أوزان تلك المخالفات |
analyzedLines | رقم | الأسطر المضافة/المعدّلة في الـ commits المحللة |
attributedCodeLines | رقم | نفس القيمة (اسم تاريخي) |
violationDensity | رقم | النقاط الموزونة لكل KLOC، قبل التقليص |
confidenceLevel | insufficient | provisional | reliable | highly_reliable | من الأسطر المحللة |
rankable | منطقي | لديه درجة وأسطر كافية لدخول الترتيب |
contributionPercent | رقم من 0 إلى 1 | حصته من كل الأسطر المحللة |
breakdown | كائن | انظر أدناه |
activeDays | رقم | أيام UTC المختلفة التي فيها commit (السجل كاملاً) |
firstContribution، lastContribution | نص (ISO) | تاريخ أول/آخر commit (السجل كاملاً) |
breakdown
| الحقل | الوصف |
|---|---|
introduced | المخالفات التي أُدخلت بثقة high/medium (مثل violationCount) |
fixed | المخالفات التي أزالتها الـ commits الخاصة به |
existing | المخالفات الموجودة سابقاً في الملفات التي غيّرها (للمعلومة) |
excluded | دائماً 0 على مستوى المطوّر (موجود لثبات البنية) |
unattributed | المخالفات التي جعلتها الـ commits الخاصة به غير قابلة للتحليل (للمعلومة) |
introducedWeighted | مجموع أوزان introduced |
fixedWeighted | مجموع أوزان fixed |
netQualityImpact | introducedWeighted − fixedWeighted (الموجب = أضاف دَيناً أكثر مما أزال) |
تذكّر أن introduced وfixed أعداد تاريخية عبر الـ commits المحللة، بينما violations[] تسرد فقط ما هو موجود في الكود الآن.
Violation
| الحقل | النوع | الوصف |
|---|---|---|
id | نص | بصمة القاعدة + المسار + السطر + الرسالة؛ فريدة داخل التقرير |
ruleId | نص | أحد معرّفات القواعد الأربعة عشر |
message | نص | تفصيل مقروء، مثل Function load has 58 lines (limit 40). |
severity | critical | high | medium | low | من إعداد القاعدة |
weight | رقم | وزن الخطورة |
category | duplication | structure | hygiene | |
filePath | نص | نسبي لجذر المستودع، بشرطات / |
startLine، endLine | رقم | يبدأ الترقيم من 1؛ وقد لا يوجد endLine |
symbolName | نص؟ | الدالة/الـ class المحيطة |
fingerprint | نص | هوية ثابتة (انظر 07) |
status | introduced | existing | fixed | excluded | unattributed | حالة النسب |
confidence | high | medium | low | ثقة النسب |
developerId | نص؟ | المطوّر الذي تُحسب عليه (فقط high/medium) |
introducedBy | نص؟ | المطوّر الذي أدخلها الـ commit الخاص به (بأي ثقة) |
introducedCommit | نص؟ | معرّف الـ commit |
introducedAt | نص؟ | تاريخ كتابة الـ commit (ISO) |
source | "internal" | دائماً internal حالياً (القيم eslint وruff وpylint محجوزة) |
مثال
{
"schemaVersion": 2,
"generatedAt": "2026-09-30T10:12:44.120Z",
"engine": "commit-diff",
"analysisConfigHash": "1x9k2ab",
"developerCount": 2,
"totalViolations": 1,
"unattributedViolations": 0,
"analyzedFiles": 12,
"analyzedCommits": 40,
"developers": [
{
"id": "dev-1",
"displayName": "Alice",
"emails": ["alice@example.com"],
"cleanCodeScore": 82,
"scoreExact": 81.7,
"scoreByCategory": {
"duplication": { "density": 0.8, "subScore": 95 },
"structure": { "density": 9.1, "subScore": 82 },
"hygiene": { "density": 12.4, "subScore": 72 }
},
"violationCount": 9,
"weightedViolationPoints": 27,
"analyzedLines": 2400,
"attributedCodeLines": 2400,
"violationDensity": 11.25,
"confidenceLevel": "reliable",
"rankable": true,
"contributionPercent": 0.8,
"breakdown": {
"introduced": 9, "existing": 3, "fixed": 4, "excluded": 0, "unattributed": 0,
"introducedWeighted": 27, "fixedWeighted": 10, "netQualityImpact": 17
},
"activeDays": 21,
"firstContribution": "2026-05-02T09:00:00+03:00",
"lastContribution": "2026-09-28T17:40:00+03:00"
}
],
"violations": [
{
"id": "k2j3h1",
"ruleId": "maxComplexity",
"message": "Function parse has complexity 14 (limit 10).",
"severity": "high",
"weight": 5,
"category": "structure",
"filePath": "src/parser.ts",
"startLine": 40,
"endLine": 96,
"symbolName": "parse",
"fingerprint": "1a2b3c",
"status": "introduced",
"confidence": "high",
"developerId": "dev-1",
"introducedBy": "dev-1",
"introducedCommit": "3f9e1c…",
"introducedAt": "2026-08-14T11:02:00+03:00",
"source": "internal"
}
]
}(القيم للتوضيح فقط.)
استعلامات مفيدة بـ jq
# الدرجات، الأدنى أولاً
jq -r '.developers | sort_by(.cleanCodeScore) | .[] | "\(.cleanCodeScore)\t\(.displayName)"' report.json
# المخالفات الحرجة ومن أدخلها
jq -r '.violations[] | select(.severity=="critical") | "\(.filePath):\(.startLine)\t\(.introducedBy // "-")"' report.json
# عدد المخالفات لكل قاعدة
jq -r '.violations | group_by(.ruleId) | map("\(length)\t\(.[0].ruleId)") | .[]' report.json