# تقرير اختبارات مركز اكتشاف الرياض

**التاريخ:** 2026-10-19  
**البيئة:** `http://10.10.10.100/` — المنفذ 80 مباشرة  
**النسخة:** `app.js?v=47` · `style.css?v=36`

## الملخص

| المجموعة | النتيجة |
|---|---|
| اختبارات API الأساسية | **19/19 ناجحة** |
| اختبار التزامن | **36/36 ناجحة** · 10 طلبات متوازية |
| بحث المتغيرات العربية | كل الصيغ المختبرة أعادت نفس القطعة |
| دفعة عشوائية كاملة (50 قطعة) | **50/50 ملفات حقيقية** · 1023.1 م.ب |
| دفعة عشوائية سابقة (10 قطع) | **10/10 ملفات حقيقية** · 382.2 م.ب |
| دفعة صريحة صغيرة | **1/1 حقيقي** · 26,248 بايت · صفحة واحدة |
| ملف كبير | **250 صفحة** · 150,016,541 بايت · بحث «صك» صفحة 1 |
| صفحات نائبة داخل مجلد السحب | **0** |
| PMTiles / Range | **206 Partial Content** · 66,301,165 بايت |
| واجهة المتصفح | بحث متقدم، إبراز 120 قطعة، ملفات تلقائية، عارض، جوال |

## اختبارات API

الملف التفصيلي: `final-api-results.json`

| الاختبار | النتيجة |
|---|---|
| `/api/health` وكل قواعد البيانات | ناجح · `archiveIndex=698912` |
| مخطط 472 + قطعة 15/67 | 13688218 |
| طلب 3414/1424 | 78894 |
| رخصة 2641/1424 | 78894 |
| بحث الهوية | نتيجتان تشمل 78894 |
| مالك بمقطعين | 67 نتيجة فريدة تشمل 78894 |
| طلب بأرقام عربية | 78894 |
| مخطط 2516 فقط | 9,939 مطابقة · يعرض 120 |
| مخطط 2516 + قطعة 1138 | 13600273 و13600737 |
| مخطط 1270/ب + قطعة 1933/1 | 13957236 |
| همزة 1863/أب + 1090 | 3111410 |
| طلب بلا سنة | رفض 400 |
| رخصة بلا سنة | رفض 400 |
| هوية قصيرة | تجاهل آمن · 0 نتائج |
| مخطط غير موجود | 0 نتائج |
| صفحة 2 للمخطط 2516 (`offset=120`) | 120 نتيجة · بلا تداخل مع الصفحة 1 |
| الصفحة الأخيرة (`offset=9900`) | 39 نتيجة · `hasMore=false` |
| مالك `offset=60` | 7 نتائج أخيرة من 67 |
| `offset` خارج النطاق (`999999`) | يُقص إلى 100000 · الإجمالي يبقى 9,939 · 0 نتائج |

**الأداء:** متوسط 212.1 مللي · p95 = 1,109.9 مللي (بعد تسخين الكاش).

### اختبار التزامن

36 طلبًا موزعة على 6 أنواع، 10 طلبات متوازية:

| المقياس | القيمة |
|---|---:|
| نجاح | 36/36 |
| متوسط الاستجابة | 807 مللي |
| p95 | 2,025.7 مللي |
| أقصى استجابة | 2,057.2 مللي |

الملف: `concurrency-results.json`.

## البحث العربي والرموز

كل الصيغ التالية أعادت القطعة `13688218` (مخطط 472 / قطعة 15/67):

`15/67` · `15-67` · `15_67` · `15 67` · `١٥/٦٧`

وكل الصيغ التالية أعادت القطعة `3111410` (مخطط 1863/أب):

`1863/اب` · `1863/آب` · `١٨٦٣/أب` · `1863-اب`

اختبار اسم مالك:

| الصيغة | النتائج |
|---|---:|
| `عبدالعزیز` + `الخضیر` | 67 |
| `عبد العزيز` + `الخضير` | 72 |
| `عبدالعزيز` + `الخضير` | 67 |

كما اختُبر مخطط/قطعة بكلمات فقط (`بدون` + `بدون`) وأعاد 3 نتائج دون خطأ.

## ملفات PDF

### القطعة 13688218

| الملف | الصفحات | الحجم |
|---|---:|---:|
| 62592-1446-1.pdf | 102 | 22.17 م.ب |
| 62592-1442-1.pdf | 13 | 20.02 م.ب |
| 62592-1441-1.pdf | 58 | 19.72 م.ب |
| 62592-1435-1.pdf | 6 | 1.98 م.ب |

الإجمالي: **63.89 م.ب**. كل ملف يبدأ بـ `%PDF-` ونجح `pdfinfo`.

### عينات أخرى

| القطعة | الحجم | الصفحات |
|---|---:|---:|
| 14397151 | 14.22 م.ب | 36 |
| 13957236 | 17.39 م.ب | 60 |
| 912144378 | 28.44 م.ب | 87 |
| 78894 (ملفان) | 0.05 م.ب | 1 + 1 |
| 1875355 (بلا رخصة/طلب) | 0 ملفات · رسالة واضحة بلا خطأ |

### حالة الطلب 62592/1440

- `62592/1440` يعيد صفحة نائبة من الأمانة (5,160 / 31,026 بايت).
- المرفقات الحقيقية موجودة تحت سنة الرخصة **1446** (وأيضًا 1442/1441/1435).
- طلب `62592/1440` يدويًا أعاد **62592-1446-1.pdf** · 23,245,745 بايت · 102 صفحة.
- الواجهة تعرض نجاح السحب مع ملاحظة صريحة: «الطلب 62592/1440 أعاد صفحة نائبة، وتم استخدام سنة الرخصة 1446».
- في دفعة صريحة للقطعة 13688218: `files=1` · `real=1` · **errors=0** · **warnings=2** (محاولتا 1440 و1446 غير القاتلتين).

### القطعة 13688228 (مخطط 472 / قطعة 9)

هذه القطعة موجودة في الأرشيف ولها ملفات حقيقية، لكنها كانت مدفونة بين ملفات JSON والنصوص:

| المصدر | الملف | الصفحات | الحجم |
|---|---|---:|---:|
| الأرشيف | المرفقات.pdf (رخصة 294/1411 + طلب 124427/1447) | 45 | 36.1 م.ب |
| الأرشيف | مستند-الرخصة-294-1411.pdf | 13 | 2.8 م.ب |
| الأرشيف | المرفقات.pdf (رخصة 2963/1446 + طلب 127555/1446) | 1 | 93 ك.ب |
| سحب الأمانة | 294-1411-req124427-1447-1.pdf | 45 | 36.1 م.ب |
| سحب الأمانة | 294-1411-req124427-1445-1.pdf | 193 | 34.6 م.ب |
| سحب الأمانة | 294-1411-req124427-1441-1.pdf | 4 | 267 ك.ب |

الواجهة تعرض الآن **6 PDF · 3 مجلد** في قسم **«ملفات PDF المتاحة»** أعلى قائمة الملفات، مع عارض وتنزيل لكل ملف. تم أيضًا دمج 5 صفوف مكررة إلى 3 مستندات فريدة في ملخص الأرشيف، وإخفاء المجلد الفارغ.

رابط مباشر للقطعة وملفاتها: [http://10.10.10.100/?id=13688228](http://10.10.10.100/?id=13688228).

### الرخصة 8610/1447

- الرخصة مرتبطة بالقطعة **1475481** · مخطط **3020** · قطعة **3173** · حي ضاحية نمار.
- المالك: محمد مبارك فرج ال عاطف القحطاني.
- الطلب: **48976/1447**.
- الملف: `8610-1447-req48976-1447-1.pdf` · **44,603,430 بايت** · **178 صفحة**.
- الصفحة الأولى تعرض صك الملكية، مخطط 3020، قطعة 3173، مساحة 750 م²، واسم المالك.
- رابط مباشر للقطعة: [http://10.10.10.100/?id=1475481](http://10.10.10.100/?id=1475481).

### فصل مستند الرخصة عن المرفقات

- مستند الرخصة للقطعة 13688228 موجود منفصلًا: `مستند-الرخصة-294-1411.pdf` · **2,987,614 بايت** · **13 صفحة**.
- المرفقات منفصلة: `المرفقات.pdf` · 37,849,796 بايت · 45 صفحة.
- الواجهة ترتب ملف الرخصة أولًا بشارة **«رخصة فقط»**، وتضع شارة **«مرفقات»** على المرفقات.
- أضيف للـAPI معامل `attachType`: `1` لمستند الرخصة، و`2`/`5` للمرفقات والتقرير المساحي.
- اختبار الرخصة 294/1411 بنوع `attachType=1`: أعاد `294-1411-req124427-1447-1.pdf` · 37,861,134 بايت · بلا أخطاء، بعد ربط الطلب الصحيح 124427/1447 من `comp`.
- درس الجلب الكامل: [lesson-license-document.md](http://10.10.10.100/downloads/lesson-license-document.md).

#### زر «جلب صورة الرخصة»

- أضيف زر ظاهر داخل بطاقة القطعة باسم **«جلب صورة الرخصة»**.
- يأخذ الرخصة الأساسية للقطعة ويستدعي `POST /api/amanah/pull` مع `attachType=1`.
- لا ينزّل المرفقات `2/5`.
- اختبار القطعة 13688228: أعاد ملفًا واحدًا `294-1411-req124427-1447-1.pdf` بحجم 37,861,134 بايت داخل 3.5 ثانية (الملف موجود مسبقًا).

### الدفعة العشوائية الجديدة

`batch-20261018205256-5418f6`

| المقياس | القيمة |
|---|---:|
| القطع | 10 |
| ملفات حقيقية | 10/10 |
| الحجم | 382.2 م.ب |
| أصغر/وسيط/أكبر | 5.23 / 20.65 / 100.5 م.ب |
| الصفحات | 24–270 |
| الزمن | 535 ثانية |

كل ملف اجتاز `%PDF-` و`pdfinfo` وتصيير الصفحة الأولى.

### الدفعة الكاملة بعد التعديلات

`batch-20261018211132-c7a480`

| المقياس | القيمة |
|---|---:|
| القطع | 50 |
| ملفات حقيقية | 50/50 |
| الحجم | 1023.1 م.ب |
| أصغر/وسيط/أكبر | 1.01 / 11.42 / 100.5 م.ب |
| الصفحات | 2–270 · الوسيط 35 |
| الزمن | 1,273.8 ثانية (21.2 دقيقة) |
| التكرار | 50 معرّفًا فريدًا |

هذه هي الدفعة المرجعية النهائية: كل قطعة أعادت ملف PDF واحدًا حقيقيًا على الأقل، وكل ملف اجتاز التحقق والتصيير.

### الملف الكبير

| المقياس | القيمة |
|---|---:|
| الحجم | 150,016,541 بايت |
| الصفحات | 250 |
| النص | «صك الملكية» |
| البحث العربي | «صك» ⇒ صفحة 1 |
| التنقل | صفحة 1 → 2 |
| التكبير | 125% → 150% |
| Range | 206 Partial Content |

## الواجهة والمتصفح

| الاختبار | النتيجة |
|---|---|
| نافذة البحث المتقدم | تعمل على سطح المكتب |
| مخطط 2516 | يعرض `120 / 9,939` |
| «عرض المزيد» | 120 → 240 → 360 نتيجة · مع بقاء الإجمالي 9,939 |
| إبراز النتائج | **120 مسارًا ذهبيًا** على الخريطة |
| القطعة 13688218 | تظهر ملفات PDF الأربعة تلقائيًا |
| روابط الملفات | عرض داخلي + تنزيل |
| صفحة الدفعة | اكتملت وعرضت النتيجة والتقرير |
| الجوال 390×844 | لا يوجد تجاوز أفقي · الأزرار ظاهرة |
| جوال — صفحة الدفعات | الجدول يتسع 323px داخل 390 · بلا تجاوز |
| جوال — عارض PDF | الشريط يلتف إلى صفين · البحث وزر البحث ظاهران |
| جوال — نتائج المخطط | 120 → 240 عند «عرض المزيد» · بلا تجاوز |
| أخطاء JavaScript في الصفحات المختبرة | **0** (أضيفت أيقونة للعارض والدفعات والطبقة) |

لقطات:

- `large-viewer-250-search.png`
- `parcel-13688218-auto-files.png`
- `pmtiles-final-test.png`
- `mobile-advanced-390-fixed.png`
- `batch-explicit-1-finished.png`

## التصدير والأرشيف

| الاختبار | النتيجة |
|---|---|
| CSV لقطعتين | 527 بايت · صفان + ترويسة |
| GeoJSON لقطعتين | FeatureCollection · ميزتان |
| CSV لكل نتائج مخطط 2516 | **9,939 صفًا** · 1,345,914 بايت · 83 صفحة جمع |
| GeoJSON لكل نتائج مخطط 2516 | **9,939 ميزة** · 3,908,454 بايت |
| قطعة برمز قصير `1` | CSV صف واحد · 2459/680/م · 12 رخصة |
| ZIP لمجلد 13688218 | 60,066,221 بايت · 4 ملفات PDF |
| فهرس أرشيف 14765050 | مجلد واحد · ملف واحد |

عينات التصدير: [CSV 9,939](http://10.10.10.100/downloads/sample-export-9939.csv) · [GeoJSON 9,939](http://10.10.10.100/downloads/sample-export-9939.geojson) · [ملخص الأداء](http://10.10.10.100/downloads/export-all-results.json).

## سحب البوابة

| الاختبار | النتيجة |
|---|---|
| بيانات 6 طبقات | 6/6 استجابت · الرخص 77 حقلًا · القطع 48 حقلًا |
| طلب Pull للقطعة `OBPID=1` | سجل واحد · 1,060 بايت · تحقق «العدد مطابق» |
| ملف NDJSON.gz | 612 بايت · سطر واحد · 49 حقلًا |
| طلب 1.89M سجل بحد 5 | رفض واضح: «العدد يتجاوز الحد — ضيّق الشرط» |

## الأمان والحدود

| الاختبار | النتيجة |
|---|---|
| `/api/pdf?p=/etc/passwd` | 403 |
| `../` في مسار الأمانة | 403 |
| معرّف دفعة غير صالح | 400 |
| إدخال يشبه SQL | 0 نتائج بلا خطأ |
| مضيف رابط غير مسموح | رفض برسالة واضحة |
| رفع ملف ليس PDF | رفض برسالة واضحة |

## الإصلاحات التي ظهرت أثناء الاختبار

1. **أرقام عربية في سحب PDF:** أصبحت `٣٤١٤/١٤٢٤` و`٢٦٤١/١٤٢٤` تعمل في السحب المباشر.
2. **ملفات صغيرة حقيقية:** كان تقرير الدفعة يعدّ 26 ك.ب غير حقيقي بسبب حد 1 م.ب؛ أصبح التحقق يقبل أي PDF صالح ≥ 2 ك.ب.
3. **عنوان التقرير:** لم يعد ثابتًا «50 قطعة»؛ يعرض عدد القطع الفعلي.
4. **استمرارية الدفعات:** نُقلت الدفعات إلى وحدة `systemd-run` مؤقتة، فلم تعد إعادة تشغيل الموقع تقتل العملية.
5. **إعادة المحاولة:** دفعة PDF تعيد محاولة الاتصال بالـAPI 3 مرات عند إعادة تشغيل قصيرة.
6. **واجهة الجوال:** نافذة البحث المتقدم أصبحت تتسع للأزرار دون قصّ.
7. **عرض الملفات:** ملفات الأمانة المحفوظة تظهر تلقائيًا مع القطعة، وروابطها تفتح العارض الداخلي.
8. **تصفح النتائج الكبيرة:** أضيف `offset` وزر «عرض المزيد»، حتى لا يتوقف مخطط كبير عند أول 120 نتيجة.
9. **عارض PDF على الجوال:** شريط الأدوات أصبح متعدد الصفوف، ومنطقة العرض تُحسب تلقائيًا من ارتفاع الشريط.
10. **تصدير كل النتائج:** CSV وGeoJSON يجمعان الصفحات تلقائيًا (حتى 20,000) بدل الاقتصار على النتائج المعروضة.
11. **معرّفات قصيرة:** لم تعد القطع ذات الرمز القصير مثل `1` تُستبعد من التصدير أو إبراز الخريطة.
12. **رسالة 62592/1440:** لم تعد الصفحة النائبة تظهر كفشل نهائي؛ يُجرّب بديل سنة الرخصة، وتُعرض ملاحظة توضيحية مع الملف الحقيقي. كما تُحوّل أخطاء المحاولات غير القاتلة إلى `warnings` عند وجود ملف حقيقي.
13. **إبراز PDF:** أضيف قسم بارز أعلى ملفات القطعة، مع دمج النسخ المتطابقة بالاسم والحجم، وسياق الرخصة/الطلب، وإخفاء المجلدات الفارغة. هذا حل مشكلة «الملفات موجودة لكن لا تظهر» للقطعة 13688228.
14. **رابط مباشر للقطعة:** `/?id=13688228` يفتح بطاقة القطعة وقسم PDF فورًا، دون البحث اليدوي.
15. **ربط مجلد الرخصة/الطلب:** `/api/files` يضيف الآن مجلدات `license-<lic>-<year>` و`request-<req>-<year>` و`manual/<id>` المرتبطة بالقطعة، لذلك يظهر PDF المسحوب بالرخصة داخل بطاقة القطعة دون إعادة السحب.
16. **فصل نوع المرفق:** يدعم `POST /api/amanah/pull` المعامل `attachType` لتنزيل نوع واحد فقط، ويستخدم `comp` لربط الرخصة بالطلب الصحيح عندما تختلف سنة الرخصة عن سنة الطلب.
17. **درس تشغيلي:** أضيف درس كامل يشرح الوصول إلى مستند الرخصة وحده، مع الخريطة والخطوات والتحقق، ورابط «درس الجلب» داخل قسم PDF.
18. **زر جلب صورة الرخصة:** زر مخصص يستدعي نوع `type_attach=1` فقط للرخصة الأساسية، ويعرض الناتج منفصلًا عن المرفقات.

## ملاحظات تشغيلية

- بعض المستندات الممسوحة ضوئيًا لا تحتوي طبقة نص (`text_len=0`) لكنها PDF حقيقية وتُعرض وتُرسم بنجاح.
- ملفات 100 م.ب قد تستغرق دقيقتين أو أكثر حسب سرعة بوابة الأمانة.
- البحث باسم المالك هو الأثقل (نحو 1 ثانية) بسبب `LIKE` على 339,818 مكوّن رخصة؛ لم يظهر فشل تحت 10 طلبات متوازية.
- النسخة `10.10.10.99:9090` مرآة بحث خفيفة، والنسخة الكاملة بالميزات الجديدة هي `10.10.10.100`.

## تحسينات السرفر المطبقة (2026-10-19)

| التحسين | الحالة والدليل |
|---|---|
| فهرس PDF | 517 ملفًا · 257 فريدًا · 176 قطعة · 241 رخصة · 13.7GB · شارة `PDF 8` في نتيجة 13688228 |
| بحث المالك | FTS5 trigram · 339,644 سجلًا · من 1,267ms إلى 0.3–0.8s · النتائج 67/72 محفوظة |
| OCR | Tesseract 5.5 + العربية · 144+/517 PDF مفهرس · بحث «الموقع» أعاد 15 نتيجة |
| بحث نص PDF | `/api/pdf-text-search` + نافذة **بحث داخل مستندات PDF** |
| مختبر MarkItDown | `markitdown 0.1.8` · صفحة `/markdown.html` · 37MB PDF → 33,948 حرفًا في 8s · DOCX ناجح |
| الوصول | تسجيل الدخول معطّل حاليًا · السرفر مفتوح على الشبكة الداخلية |
| HTTPS | https://10.10.10.100:8443 بشهادة self-signed · HTTP 80 متاح بدون مصادقة |
| التدقيق | `logs/audit.log` يسجل المستخدم وIP والملف والحجم |
| المراقبة | `/api/metrics`: الطلبات، البحث، السحب، التنزيلات، الذاكرة، القرص، الفهارس |
| النسخ الاحتياطي | نسخة 2.6GB · مؤقت يومي 02:30 · الاحتفاظ بآخر 7 |
| دوران السجلات | logrotate يومي · 14 نسخة · ضغط |
| الإصدارات | `releases/` + symlink `app` · سكربت نشر وفحص صحة وتراجع |
| مؤقتات | PDF index كل 15 دقيقة · Owner FTS يوميًا · OCR كل 6 ساعات · Backup يوميًا |
| تقدير التخزين | الرخصة الواحدة ~2.98MB · 339,814 رخصة ≈ **1.06TB** · كل PDFs ≈ **9.02TB** · المتاح على الخادم 89GB |

تفاصيل التخزين: [storage-estimate.json](http://10.10.10.100/downloads/storage-estimate.json).

**حدود واقعية:** السحب الكامل لـ339,814 رخصة لم يُشغّل داخل هذه الجولة لأنه يحتاج تخزينًا خارجيًا (D:/NAS/S3) وعاملًا مستقلًا لأسابيع. البنية والـAPI والتحقق والتقارير جاهزة، والمطلوب هو وجهة التخزين النهائية.
