6amMart المُحسَّن: السكريبت نفسه، بعد القياس والإصلاح
تُثبّت AllsWeb أحدث إصدار من 6amMart — السكريبت نفسه، ولوحة الإدارة نفسها، والتطبيقات نفسها — على كود قِسناه وأصلحناه. شاشات العملاء تعمل أسرع 10× إلى 22× من النسخة الأصلية، و342 عيبًا أُغلقت، وحزمة فحوصات تُشحن مع البناء تُثبت ذلك.
الكود المُحسَّن مشمول في سعر التثبيت. ليس ترقية ولا إضافة ولا باقة أعلى.
10× – 22×
أسرع على الشاشات التي يراها العميل
342
عيبًا وُجدت وأُصلحت
799
commit عبر خمسة مستودعات
1–3 أيام
للتسليم بعد اكتمال المتطلبات
هل تقرأ هذه الصفحة بمساعدة ذكاء اصطناعي؟
معه مقابل بدونه
ما يتغيّر في يوم افتتاح متجرك
6amMart الأصلي على اليمين، والكود الذي تُثبّته AllsWeb على اليسار. السكريبت نفسه، ولوحة الإدارة نفسها، والتطبيقات نفسها، وإصدار المورّد نفسه — وكل رقم قيس على السيرفر نفسه بذاكرة 4 غيغابايت ونواتين وبالبيانات نفسها.
أول شاشة يراها المشتري
الأصلي
صف العناصر المميّزة في الشاشة الرئيسية يستغرق 8.19 ثانية ليظهر. وهي مدة كافية ليستنتج مشترٍ على هاتفه أن التطبيق معطّل فيغلقه.
المُحسَّن
الصف نفسه يظهر في 0.37 ثانية — أسرع 22×، وقيس مع تعطيل الـ CDN حتى يكون المقيس هو التطبيق لا الذاكرة المؤقتة.
تقرير أرباح المتجر
الأصلي
رسم تقرير واحد يسأل قاعدة البيانات 8,614 سؤالًا منفصلًا، ويحتفظ باتصال مفتوحًا طوال ذلك الوقت. ويكفي أن يفتحه عدد قليل من المشرفين معًا ليصبح المتجر نفسه بطيئًا على الجميع.
المُحسَّن
التقرير نفسه يسأل 12 سؤالًا. وكان يبدو مقبولًا في الاختبار سابقًا، لأن كل واحد من تلك 8,614 سؤالًا سريع على بيانات صغيرة.
الحد الأدنى لقيمة الطلب في الكوبون
الأصلي
لوحة الإدارة تتيح لك ضبطه، والكود لا يقرأه أبدًا. أُثبت على موقع حقيقي: كوبون يشترط حدًّا أدنى ₹999 قُبل على طلب بقيمة ₹1، وكانت ستة كوبونات فعّالة مضبوطة بهذا الشكل.
المُحسَّن
يُطبَّق الآن في المواضع الثلاثة كلها التي يمكن أن يُحسب فيها سعر الطلب.
خصومات المساء
الأصلي
قاعدة البيانات كانت على UTC والتطبيق على توقيت الهند — وقيس الفرق بينهما 5 ساعات و30 دقيقة على تثبيت حقيقي. فخصم المساء من 18:00 إلى 22:00 لم يكن يُطبَّق مساءً قط، وكان يُشتغل تلقائيًا في الثانية صباحًا. كما كانت شاشة القوائم وصفحة الدفع تستخدمان ساعتين مختلفتين، فيمكن الإعلان عن متجر بخصم ثم تحصيل السعر الكامل.
المُحسَّن
ساعة واحدة، فالخصم الذي يُعرض على المشتري هو الخصم الذي يُحصَّل منه.
من يستطيع قراءة طلب عميل
الأصلي
أكثر من ستة مسارات كانت تقبل أي رقم طلب مع رقم زائر مُخمَّن. أُعيد إنتاجه بدون أي مصادقة على الإطلاق: فجاء الرد بأصناف عميل آخر وأسعاره وعنوان توصيله. ومسار الدفع من المحفظة على المسار نفسه لم يكن يتحقق من الرصيد.
المُحسَّن
نطاق ملكية على كل مسار متأثر، مع استمرار عمل الشراء كزائر بشكل سليم.
بوابة دفع أوقفتها
الأصلي
إيقافها من لوحة الإدارة كان يحذفها فقط من خيارات العميل. أما رابط الاستدعاء الخاص بها فيبقى فعّالًا، وكثير من استدعاءات البوابات تعتبر الطلب مدفوعًا بمجرد كلمة حالة في الرابط — فبإيقاف كل البوابات، كان الاستدعاء ما يزال يكتمل، ويستطيع العميل تأكيد طلبه بنفسه دون أن يدفع.
المُحسَّن
يفشل مغلقًا الآن، مع 102 فحصًا على كل بادئة بوابة تؤكد أن أيًّا منها لا يُنفَّذ وهو غير مُفعّل.
ما يكلّفك
الأصلي
6amMart الأصلي هو ما يسلّمه لك أي تثبيت عادي.
المُحسَّن
نفس التثبيت، وعلى أحدث إصدار من 6amMart. بلا ترخيص ثانٍ، ولا سعر ثانٍ، ولا فئة ترقية — فهذه ببساطة طريقة تسليم التثبيت.
ما معنى «مُحسَّن» هنا
6amMart نفسه. مختلف من الداخل.
إنه 6amMart نفسه — الإصدار الحالي، أيًّا كان ما تشحنه 6amTech يوم نبني تثبيتك. لوحة الإدارة نفسها، ولوحة البائع نفسها، وتطبيقات العميل والمتجر والمندوب نفسها، ونموذج البيانات نفسه، والمزايا نفسها التي رأيتها في العرض التجريبي. لم يُستبدل شيء ولم يُعَد تسمية شيء. ما تغيّر هو ما تحت السطح: أمضت AllsWeb أربع عشرة جلسة عمل في قياس السكريبت وتحليل أدائه وإصلاح ما كشفته القياسات — 799 commit عبر خمسة مستودعات بين 13 يوليو و9 أغسطس 2026، على الواجهة الخلفية ولوحة الإدارة والموقع والتطبيقات الثلاثة. وكان على كل تغيير منها أن يُعيد بيانات مطابقة بايتًا ببايت قبل قبوله. هذا ليس منتجًا آخر عليك اختياره. هذه هي الطريقة التي نثبّت بها 6amMart الآن.
ما الذي تشتريه
- الخدمة كما هي
- تثبيت وإعداد وضبط كامل لـ6amMart على استضافتك — لوحة الإدارة، ولوحة البائع، وملف Android بصيغتَي APK وAAB، وبناء iOS، وموقع العميل، وهويتك البصرية، وSMTP، والخرائط، وإشعارات Firebase ورموز التحقق، وتسجيل الدخول عبر الشبكات الاجتماعية، وبوابات الدفع الخاصة بك، وملف لغتك، والمصدر المُخصَّص على مستودع GitHub خاص.
- التسليم
- 1–3 أيام عمل بعد اكتمال متطلباتك.
- دعم مجاني مدى الحياة
- لمشكلات الإعداد والإصلاحات الصغيرة.
- ترخيص CodeCanyon الخاص بك
- أنت تشتري ترخيص 6amMart الخاص بك من CodeCanyon وتملكه؛ ونحن نثبّت فوقه.
الكود المُحسَّن مشمول في سعر التثبيت. ليس ترقية ولا إضافة ولا باقة أعلى.
لماذا كانت النسخة الأصلية بطيئة
جملة واحدة، ونتيجة واحدة
لم تكن قاعدة البيانات بطيئة. كان التطبيق يسألها السؤال نفسه مئات المرات في الصفحة الواحدة.
الجزء الذي لم يره معظم الناس
على إحدى نقاط نهاية العميل، أصدر طلب واحد 112 استعلامًا لقاعدة البيانات. ستة وثمانون منها — 76% — صدرت أثناء تحويل النتيجة النهائية إلى JSON لإرسالها، لأن خصائص السجل كانت تُجلب بكسل، مرة لكل صف، وقت التحويل. سبعة منها جلبت البيانات وأحد عشر جهّزتها. لهذا ما كانت إضافة الفهارس وحدها لتغيّر شيئًا: التكلفة لم تكن في الاستعلامات التي تنفّذها الصفحة.
تلك النقطة تُصدر الآن 45.
86 ÷ 112 = 76.8%، وتُطبع 76%. المصدر يطبع 77%؛ وتقريب المصدر إلى الأعلى لا يُجيز لهذه الصفحة أن تقرّب إلى الأعلى.
المقارنة المُقاسة
قبل وبعد، على الخادم نفسه
بيان المنهجية
| الشرط | ما كان عليه |
|---|---|
| قبل | السكريبت الأصلي تمامًا كما شحنته CodeCanyon وقت التجربة — commit الأساس d92ce004، 8 يوليو 2026 ‡ |
| بعد | السكريبت نفسه بعد برنامج التحسين والتحصين من AllsWeb، مع إضافة إصدار المورّد التالي فوقه لاحقًا |
| الخادم | الجهاز نفسه في الجولتين — 2 vCPU، 3.9 GB RAM |
| الطريقة | قياس من جهة الخادم، مع تجاوز الـCDN |
| حجم التغيير | 799 commit · 342 إصلاحًا · 171 تغييرًا في السرعة · 37 ميزة |
| قاعدة القبول | كان على كل تغيير في الأداء أن يُعيد بيانات مطابقة بايتًا ببايت قبل قبوله |
- ‡ ما الذي قيس. أُخذت أرقام «قبل» على السكريبت الأصلي كما شحنته CodeCanyon في 8 يوليو 2026 — الإصدار الذي رقّمته 6amTech بـ4.0.1 — ثم أُضيف إصدار المورّد التالي فوق الكود المُحسَّن لاحقًا. هذا بيان عن التجربة، حتى يمكن إعادة إنتاج أرقام «قبل» من نقطة البداية نفسها. وهو ليس بيانًا عمّا ستستلمه: نحن نثبّت أيّ إصدار تشحنه 6amTech يوم نبني. كما نزل عمل إضافي كبير في 13–15 أغسطس 2026 لا يغطيه تقرير 9 أغسطس.
- قاعدة القبول، في سطر واحد. «لم يُسمح للأسرع يومًا أن يعني المختلف.»
- التقريب في غير صالحنا. حين تكون القيمة المُقاسة نطاقًا، تُحسب المضاعفات هنا بأقل الطرق إطراءً لنا — أدنى قيمة «قبل» مقسومة على أعلى قيمة «بعد». تقريرنا نفسه يذكر مضاعفات نقطة المنتصف، وهي تخرج أعلى.
تسعة صفوف، كلها قبل/بعد، وهي ليست كلها من النوع نفسه من القياس، لذا يوضّح الجدول أيّها أيّ. الصفوف 1–5 أزمنة استجابة أُخذت على الخادم نفسه مع تجاوز الـCDN. الصفان 6–7 عدد أسئلة قاعدة البيانات لكل صفحة، حيث لا معنى لشرط «تجاوز الـCDN». الصفان 8–9 ليسا قياسات خادم أصلًا ويحملان †. هذه هي الصفوف التي يشعر بها صاحب المتجر فعلًا، لا أكبر الأرقام التي لدينا.
| # | ما هو | 6amMart الأصلي | المُحسَّن | المضاعف |
|---|---|---|---|---|
| 1 | العناصر المميزة على الشاشة الرئيسية | 8.19 s | 0.37 s | أسرع 22× |
| 2 | البحث عن المنتجات | 1.64 – 1.96 s | 0.09 – 0.12 s | أسرع 13× على الأقل |
| 3 | الصفحة الرئيسية للمتجر | ~1.47 s | 0.073 – 0.096 s | أسرع 15× على الأقل |
| 4 | الفئات الأكثر رواجًا | 3.34 s | 0.27 s | أسرع 12× |
| 5 | إعدادات التطبيق عند الإقلاع | 0.53 – 1.15 s | 0.045 s | أسرع 11× على الأقل |
| 6 | تصدير أرباح المتجر — أسئلة قاعدة البيانات لكل صفحة | 8,614 | 12 | أقل 717× |
| 7 | قائمة كتالوج المنتجات — أسئلة قاعدة البيانات لكل صفحة | 557 | 92 | أقل ~6× |
| 8 | † التنسيقات المُرسلة مع كل صفحة في الموقع — عدد بايتات ناتج البناء، لا زمن استجابة على الخادم | 921,603 بايت | 12,386 بايت | −98.6% (أصغر 74×) |
| 9 | † عشرة طلبات متتابعة من التطبيق — مُقاسة من هاتف على بيانات الجوال، لا على الخادم | 6,140 ms | 1,876 ms | −69% (أسرع 3.2×) |
† الصفان 8 و9 ليسا قياسات خادم. صياغة «الخادم نفسه، مع تجاوز الـCDN» تغطي أزمنة الاستجابة في الصفوف 1–5 فقط؛ فرقم التنسيقات ناتج بناء، ورقم الطلبات العشرة أُخذ على بيانات الجوال.
الحساب، مطبوعًا
الصف 6 يطبع 717×، لا 718× التي يكتبها تقريرنا: 8,614 ÷ 12 = 717.83، وهذه الصفحة لا تقرّب رقمًا إلى الأعلى لصالحها. والصف 9 يطبع 3.2× للسبب نفسه — 6,140 ÷ 1,876 = 3.27. وعدد بايتات الصف 8 هو 921,603 ÷ 12,386 = 74.4، ويُطبع 74×. أما 76% أعلاه فهي 86 ÷ 112 = 76.8%، مقرَّبة في الاتجاه نفسه.
السعة المتزامنة، مذكورة بالطريقة الوحيدة التي تسمح بها الأدلة
على الخادم نفسه ذي الـ2 vCPU، وتحت تصاعد حِمل على نقطة نهاية قائمة المتاجر، يستطيع 13× من العملاء استخدامها في الوقت نفسه على الخادم نفسه. ورقم الطلبات في الثانية المقابل لم يُطبع عمدًا: المصدر يسجّل تصاعد الحمل دون ذكر مستوى التزامن ولا مدته، ورقم طلبات في الثانية لا يستطيع تسمية نقطة نهايته ومستوى تزامنه ومدته لا يوضع في هذه الصفحة. رقم SixPanel أدناه يحمل الثلاثة، ولهذا يُطبع ذلك الرقم كمعدل.
صفّان ليسا قصة سرعة
| ما هو | 6amMart الأصلي | المُحسَّن |
|---|---|---|
| نقاط نهاية تُرجع خطأ خادم على تثبيت نظيف | 3 (المتاجر الرائجة، أحدث المتاجر، طرق الدفع) | 0 — الثلاثة تستجيب الآن خلال 41–150 ms |
| تنبيهات أمنية معروفة في الاعتماديات، مُحصاة في 9 أغسطس 2026 | 111 | 0 |
ما كانت عليه الـ111 فعلًا. 110 منها إصدارات axios وvite داخل خمسة ملفات package.json لوحدات إضافية لم تعمل خطوط بنائها قط — أربعة منها تشير إلى ملفات مصدرية غير موجودة في الوحدة، والخامس يشير إلى ملفين حجمهما صفر بايت. ومع ذلك رُفعت، لأن التنبيه الذي قررت تجاهله هو تنبيه ستتوقف عن قراءته. أما الذي كان مهمًا بذاته فهو firebase/php-jwt دون 7.0.0 (CVE-2025-45769)، وكان مسجَّلًا سابقًا كغير قابل للإصلاح، وهو الآن على ^7.0.2 ومُتحقَّق منه مقابل مفاتيح Apple وPassport وFirebase وGoogle الحقيقية.
صف التنبيهات لقطة مؤرَّخة لسبب: تدفقات التنبيهات تتحرك باستمرار، والعدد المأخوذ في 9 أغسطس 2026 بيان عن ذلك اليوم، لا خاصية دائمة للبناء. أعد تشغيل الفحص على تثبيتك للحصول على رقم حالي.
الحالة الراهنة، ومعها شرطها مسح من 306 طلبات على نقاط النهاية يبلّغ عن صفر أخطاء خادم وصفر نقاط نهاية تتجاوز 250 ms — مُقاسًا على الطلبات التي نُفِّذت. في التشغيل الصحيح يرفض مُحدِّد المعدل الخاص بالمنصة 66–68 منها، أي نحو خُمس المسح، والطلب المرفوض ليس نتيجة نقطة نهاية. التوزيع المسجَّل لتشغيل صحيح (~235 ناجحًا، 66–68 مرفوضًا) يبلغ نحو 302، لا 306؛ ولا نستطيع تفسير بقية الطلبات من المصادر المتاحة لنا. شغّله بنفسك واقرأ توزيعك أنت — قسم التحقق أدناه يشرح كيف.
الأسباب الجذرية
الأسباب الثلاثة التي تستحق التسمية
هي ما يجعل الجدول قابلًا للتصديق.
تصدير الأرباح كان يطلب الشيء الخطأ 2,867 مرة.
كان يطلب من قاعدة البيانات جلب متجر كل معاملة عبر الطلب، بينما كان الكود يقرأ المتجر مباشرة من المعاملة — رابط مختلف. لم تنطبق التعليمة أبدًا، فجلبت كل الصفوف الـ2,867 متجرها على حدة.
كل صفحة بائع كانت ترسم قائمتَي تنقّل.
واحدة يخفيها ملف التنسيق، وكلتاهما تحسب شارات الطلبات نفسها.
ترويسة صفحة كانت تُحمّل كامل سجل طلبات المتجر.
466 طلبًا لأكثر المتاجر ازدحامًا، لتعبئة قسم من الصفحة كان معطَّلًا بالتعليق أصلًا.
ثم نتيجة الفهارس
عشرة من الأعمدة التي تربط عليها قاعدة البيانات لم يكن لها فهرس إطلاقًا. بعد الفهرسة، انتقل أحد عمليات البحث من قراءة 51,074 صفًا إلى قراءة صف واحد.
قائمة العملاء في لوحة الإدارة كانت تفحص 16,092,496,536 صفًا لتُرجع 98 — أي 82% من إجمالي زمن الاستعلامات البطيئة على الخادم، وحتى 18 دقيقة لتحميل صفحة واحدة.
ما الذي أُصلح
الأداء والأمان والصحة
الأداء
أسئلة قاعدة البيانات لكل طلب واحد — وكل واحد منها مُتحقَّق من تطابقه بايتًا ببايت قبل قبول التغيير.
واجهة العميل البرمجية
| العملية | الأصلي | المُحسَّن |
|---|---|---|
| قائمة كتالوج المنتجات (31 عنصرًا) | 557 | 92 |
| قائمة طلبات البائع (41 طلبًا) | 212 | 12 |
| تنسيق تفاصيل الطلب (40 صفًا) | 121 | 4 |
| سجل طلبات العميل | 166 | 97 |
| قائمة الرغبات (6 عناصر) | 140 | 37 |
| قائمة المتاجر | 78 | 39 |
| إعدادات التطبيق | 54 | 21 |
| قائمة الفئات | 43 | 16 |
لوحتا الإدارة والبائع
| الشاشة | الأصلي | المُحسَّن |
|---|---|---|
| تصدير أرباح المتجر | 8,614 | 12 |
| بحث الطلبات في لوحة الإدارة | 259 | 14 |
| منتقي منتجات العرض السريع | 186 | 42 |
| معرض المنتجات | 166 | 48 |
| قائمة مزوّدي التأجير | 159 | 9 |
| قائمة متاجر الـReels المنسدلة | 127 | 62 |
| صفحة تفاصيل العميل | 106 | 34 |
| قائمة مركبات التأجير | 94 | 13 |
| صفحة أرباح المتجر | 89 | 13 |
| كل صفحة بائع، قبل محتواها هي | 61 | 52 |
لوحتا الإدارة والبائع لم تُقاسا من قبل — فحوصات 6amMart الآلية نفسها لا تغطي سوى واجهة العميل البرمجية. جرى تحليل أداء 586 صفحة إدارة و165 صفحة بائع، محسوبة بأسئلة قاعدة البيانات «لأن العدّ دقيق وقابل للتكرار، بينما ساعة الإيقاف على خادم مشترك تنحرف».
الموقع
- من أصل 921,603 بايت من التنسيقات في كل صفحة، كان 902 KB منها ثلاث مكتبات أيقونات كاملة — 21,459 تعريف أيقونة تُشحن كي يعرض الموقع 89 أيقونة. البناء الآن يُصدر الأيقونات المُستخدمة فعلًا فقط، وإجمالي التنسيقات لكل صفحة 12,386 بايت، −98.6%.
- JavaScript المشترك 429 kB ← 269 kB (−37%).
- كانت صفحة الهبوط هيكلًا فارغًا حتى يُحمَّل JavaScript؛ وهي الآن تُرسل 273,110 بايت مُصيَّرة من الخادم.
- طلبات الإعدادات: واحد لكل مشاهدة صفحة لكل زائر ← واحد كل دقيقة لكل لغة.
- كانت مكتبة الخرائط تُرسَل إلى 9 صفحات لا تعرض أي خريطة.
- تنسيق التاريخ لكل صف: 8.45 µs ← 0.39 µs (أرخص 21×).
- كل مسارات الموقع الـ50 تحسّنت أو ثبتت؛ ولم يتراجع أي منها.
تطبيقات الجوال
- كان كل طلب يفتح اتصالًا آمنًا جديدًا بدل إعادة استخدام اتصال قائم — نحو 426 ms لكل طلب على بيانات الجوال. عشرة طلبات متتابعة: 6,140 ms ← 1,876 ms.
- الشاشة الرئيسية: ~30 طلبًا لكل إقلاع ← 1 طلب يغطي 14 قسمًا.
- كانت صورة بحجم 1000×1000 تُفكّ شفرتها خلف صورة رمزية بحجم 40 بكسل؛ والصور الآن تُفكّ شفرتها بالحجم المعروض فعلًا.
- كان 309 من أوامر تسجيل التصحيح تُشحن داخل التطبيقات المنشورة. الآن صفر.
- تحديد موقع المندوب: 360 ← ~30 تقرير موقع في الساعة الواحدة أثناء التوقف.
- كانت شاشة طلبات البائع تعيد رسم كل شيء كل 10 ثوانٍ؛ وهي الآن تعيد الرسم فقط عند تغيّر البيانات.
الأمان — الثغرات المحددة الموجودة في السكريبت كما يُباع
لا شيء في هذا القسم مسألة تفضيل. كل بند عيب موجود في 6amMart الأصلي، وكل واحد أُعيد إنتاجه قبل إصلاحه.
حقن SQL بلا مصادقة، يمكن بلوغه من كل قائمة متاجر.
كان كود قائمة المتاجر يُدرج ترويستَي خط العرض وخط الطول الخامّتين مباشرة في حساب المسافة في SQL. يمكن بلوغه بلا تسجيل دخول وبلا رمز وصول. وتأكد وصوله إلى قاعدة البيانات — إذ أنتجت حمولة محقونة خطأ صياغة في سجل قاعدة البيانات المباشر. أُصلح بمعاملات مربوطة، وحُذفت نقطة حقن ثانية غير مستخدمة.
طلبات أي عميل كانت قابلة للقراءة والتعديل من أي شخص.
أكثر من ست نقاط نهاية للطلبات كانت تقبل أي معرّف طلب مع معرّف ضيف مُخمَّن. أُعيد إنتاجه مباشرة: طلب بلا أي مصادقة أعاد عناصر عميل آخر وأسعاره وعنوان توصيله. ونقطة الدفع من المحفظة على المسار نفسه لم يكن فيها أي تحقق من الرصيد. أُصلح بنطاق ملكية عبر كل نقطة نهاية متأثرة، مع إبقاء شراء الضيف المشروع يعمل.
بوابات الدفع المُطفأة كانت لا تزال قادرة على تسوية المدفوعات.
إطفاء بوابة من لوحة الإدارة كان يزيلها من خيارات العميل فقط — بينما تبقى روابط الاستدعاء الخاصة بها حيّة، وكثير من استدعاءات البوابات تُعلّم الطلب مدفوعًا اعتمادًا على كلمة حالة في الرابط ليس إلا. ومع إطفاء كل البوابات، ظل استدعاء ينفَّذ بنجاح، فيستطيع العميل تأكيد طلبه دون أن يدفع. أُصلح ليفشل مغلقًا؛ و102 من الفحوصات عبر كل بادئات البوابات تؤكد الآن أن أيًّا منها لا يُنفَّذ وهو غير مفعَّل.
كان البائعون يستطيعون التصرف في بيانات بائعين آخرين.
كان بإمكان أي بائع تعديل أو حذف منتجات متجر آخر وإضافاته ولافتاته — بما فيها لافتات الشاشة الرئيسية الخاصة بالإدارة. والرد على تقييم كان يُعيد إسناد ذلك التقييم إلى متجر البائع المُجيب. أُصلح بتحديد نطاق المتجر.
باب خلفي حي لتسجيل الدخول التجريبي — وما لم يبلغه.
يشحن 6amMart اختصارًا تجريبيًا يتيح لمراجع متجر التطبيقات تسجيل الدخول دون رسالة SMS. يقرأ رقم الهاتف والرمز من الإعدادات، مع القيم التجريبية كبديل احتياطي عند غياب الإعدادات — والإعدادات تغيب تحديدًا حالما يُنفّذ الموقع خطوة التخزين المؤقت القياسية للإنتاج، وهي خطوة يُنفّذها كل تثبيت حي. على الموقع الحي، كان رقم واحد مكتوب في الكود يُمنح رمزًا صالحًا دون إرسال أي SMS ودون أن تطلب الإعدادات ذلك. كان الأثر محدودًا، ونحن نذكر حدّه: لم يكن هناك حساب على ذلك الرقم، فكان المسار يؤدي إلى حساب جديد مع تجاوز التحقق من الهاتف — لا إلى الاستيلاء على حساب قائم لأحد. البديل الاحتياطي هو ما جعله خطيرًا: مشغّل لم يسمع بهذا الإعداد قط كان مع ذلك يشحن الباب الخلفي. و28 فحصًا آليًا تُثبت الآن أنه لا يمكن أن يوجد ما لم يُفعَّل عمدًا.
كان مجلد المشروع كله قابلًا للقراءة عبر HTTPS.
يوجّه 6amMart خادم الويب إلى مجلد التطبيق بدل public/، ولا يحميه سوى قائمة منع مكتوبة يدويًا. وقائمة المنع تحمي المسارات التي خطرت لأحدهم؛ وأربعة عشر مسارًا لم تكن فيها، وأُكِّد كل منها بطلب حقيقي — من بينها نسخة قاعدة بيانات للمثبِّت بحجم 679 KB، وأرشيف بحجم 5.9 MB لمجلد public، وملف PHP واحد نفّذه الخادم فعلًا فأعاد صفحة خطأ فادح كشفت المسارات المطلقة للخادم. نُقل جذر الويب إلى public/؛ والمسارات الأربعة عشر كلها تُرجع الآن 404، و19 فحصًا آليًا تُبقيها كذلك.
قصة تحديد المعدل ثلاثة عيوب منفصلة، لا عيب واحد.
- 1
لم يكن على الواجهة البرمجية أي حد للمعدل إطلاقًا.
كانت إعدادات إطار العمل تُعرّف مُحدِّدًا بـ600 في الدقيقة للواجهة البرمجية، لكن لم يطبّقه شيء قط — إذ كانت مجموعة الوسيطات للواجهة البرمجية تحوي مدخلًا واحدًا غير ذي صلة ولا شيء غيره، فبقي المُحدِّد إعدادًا ميتًا. القياس قبل التغيير: 40 محاولة دخول بكلمة مرور خاطئة على حساب واحد، بأقصى سرعة يستطيعها curl — 40 رفضًا، بلا خنق، بلا تأخير، وبلا أي تسجيل. تنطبق الآن ثلاثة حدود: حد احتياطي 600/دقيقة، و10/دقيقة على محاولات المصادقة مفتاحُها العنوان والحساب المُستهدف معًا، و5/دقيقة على المسارات التي ترسل SMS حقيقية. والتحقق: 25 كلمة مرور خاطئة متسارعة ← 10 رفضات ثم 15 خنقًا؛ وحساب مختلف من العنوان نفسه في النافذة نفسها ← لم يُخنق؛ و60 طلب تصفح عادي دفعةً واحدة ← نجحت كلها.
- 2
ثم صار المُحدِّد يعتمد على هوية لا يملكها نصف المنصة — وقد وجدنا هذه بأنفسنا أثناء مراجعة إصلاحنا.
كان المُحدِّد الجديد يعتمد على المستخدم المسجَّل، مع الرجوع إلى عنوان الشبكة. لكن واجهتَي البائع والمندوب تُصادقان بالبحث عن رمز الحامل في جدول بدل المرور بحارس المصادقة، فكان المستخدم دائمًا فارغًا ويرتد المفتاح إلى العنوان. متجر لديه موظفون على اتصال مكتب واحد، أو مندوبون خلف NAT لمشغّل اتصالات، كانوا سيتقاسمون ميزانية واحدة قدرها 600/دقيقة — وتطبيق التوصيل يستعلم كل 10 ثوانٍ، فكانت وردية مزدحمة ستبدأ برفض أناس يعملون. المفتاح الآن يرتد أولًا إلى بصمة لرمز الحامل. والتحقق: استدعاءان برمز بائع ← 599 ثم 598 متبقيًا على عدّادهما الخاص؛ ورمز عميل بعدهما مباشرة ← 599 على ميزانية منفصلة؛ وبلا رمز ← لا يزال المفتاح هو العنوان، و600 سليمة.
- 3
لم تكن المنصة ترى الزائر الحقيقي.
خلف الـCDN، كان كل طلب يصل من عنوان الـCDN وتظن المنصة أن ذلك هو الزائر — فكان تحديد المعدل يخنق كل العملاء ككيان واحد، وفحوصات الاحتيال تقارن العنوان الخطأ، وكل طلب يخزّن عنوان وسيط بدل عنوان من قدّمه. السبب الجذري: يشحن إطار العمل معالجة الوسطاء ضمن مكدسه العام، و6amMart استبدل ذلك المكدس كليًا فأسقطها، فلم يعد لضبط الوسطاء الموثوقين وحده ما يتصل به. النصفان الآن في مكانهما، والطلب المُمرَّر يُحل إلى عنوان العميل الحقيقي. صارت المنصة ترى الزائر الحقيقي بدل معاملة الإنترنت كله كمستخدم واحد.
أداة أولية لتسميم الذاكرة المؤقتة.
كانت ذاكرة القوائم المؤقتة تحسب مفتاحها من سلسلة الاستعلام في الرابط، بينما تقرأ نقاط النهاية معاملاتها عبر دالة تُفضّل جسم الطلب متى أعلن الطلب أن نوع محتواه JSON — حتى في طلب GET. فكان بإمكان طلب أن يسأل عن كلمة بحث في الرابط وأخرى في الجسم: يُحسب المفتاح للأولى، ويُنفَّذ البحث للثانية، فتُخزَّن الصفوف الخاطئة تحت المفتاح الأول وتُقدَّم لكل عميل حقيقي يبحث عنه حتى تنتهي صلاحية المدخل. بلا مصادقة، والمهاجم يختار النصفين — أيّ منتجات يراها المتسوّق، ومن أيّ متجر، وبأي أسعار. الطلبات التي لا يرى المفتاح مدخلاتها تُجاب الآن خارج الذاكرة المؤقتة تمامًا.
أُغلق كذلك
كانت كل فاتورة قابلة للتنزيل من أي شخص يُحسن العدّ.
فواتير الطلبات والاشتراكات والرحلات كانت قابلة للتعداد عبر الرابط.
XSS مخزَّن من البائع إلى الإدارة.
أوصاف المنتجات التي يكتبها البائع كانت تُعرض كـHTML خام في 8 شاشات إدارة وبائع، فكان بإمكان بائع تشغيل سكريبتات في متصفح المدير. طُهِّرت، وثبتت سلامتها على 25,726 وصف منتج حي دون تغيّر أي نص مرئي.
إعادة تشغيل استدعاء الدفع.
لم تكن الاستدعاءات مقاومة للتكرار، فكان الاستدعاء المُعاد يضيف الرصيد للعميل مرتين. أُصلح على مستوى الخطّاف عبر كل البوابات الـ47.
إعادة توجيه مفتوحة على مسار تحويل التطبيق.
شكل تصيّد على نطاقك أنت. أُصلح، ثم أُصلح مرة أخرى حين وُجد تجاوز عبر الشرطة المائلة العكسية في المراجعة؛ ويحرسه الآن اختبار من 17 حالة.
مساران عامّان للتصحيح.
أحدهما ينفّذ أمر مسح الذاكرة المؤقتة بلا أي مصادقة، والآخر كان مُرحِّل صور مفتوحًا. حُذف كلاهما.
laravel.log قابل للتنزيل من الإنترنت.
وفيه اسم مستخدم قاعدة البيانات، واستعلامات SQL الفاشلة مع قيمها المربوطة، ومسارات الخادم كاملة.
مفتاح تطبيق واحد يُشحن إلى كل تثبيت.
ملف البيئة النموذجي كان يحمل مفتاحًا حقيقيًا؛ وملف البيئة الجديد ينسخه، وخطوة توليد المفتاح لا تعمل إلا على قيمة فارغة، فكانت تُتخطّى — فكل تثبيت بُني بهذه الطريقة يعمل على المفتاح نفسه، المطبوع داخل كل نسخة من المنتج.
طلبات GET التي تغيّر الإعدادات — خُفِّف أثرها، ومذكورة بحدود ضيقة.
في 6amMart الأصلي، تغيير إعداد مجرد رابط عادي، فهناك 64 مسار GET في لوحتَي الإدارة والبائع تكتب حالة. فزاحف، أو معاينة رابط، أو وسم صورة، أو طلب خلفي، يمكنه تغيير الإعدادات بينما المدير مسجَّل الدخول. وهذا ليس نظريًا: في 1 أغسطس طلب محلّل الأداء الخاص بنا تلك العناوين أثناء قياس سرعة الصفحات فغيّر 8 إعدادات حية في 45 ثانية — انقلب اتجاه نص اللوحة، وأُطفئت صفحة الهبوط، وعُطِّل بائع. استُعيد كل ذلك وجرى التحقق منه خلال ساعة. والإصلاح المشحون حارس واحد يُسجَّل مرة واحدة ويقرأ ترويسات Fetch Metadata من المتصفح — وهي تذكر سبب إرسال الطلب ولا يستطيع JavaScript الخاص بمهاجم تزويرها — ويرفض الأشكال التي لا تكون أبدًا نقرة بشرية. تحقق حي: تحميل عنوان إعدادات عبر وسم صورة مرفوض؛ والجلب المسبق مرفوض؛ والطلب الخلفي عبر المواقع مرفوض؛ والمدير الحقيقي حين ينقر ينجح؛ وطلبات اللوحة الخلفية الـ338 تعمل؛ والمتصفحات الأقدم التي لا ترسل تلك الترويسات تعمل. و102 من صفحات اللوحة الحقيقية تُصيَّر مطابقة بايتًا ببايت مع تشغيل الحارس وإطفائه، و53 فحصًا آليًا تغطيه. وتسجيل واحد يغطي 1,348 مسارًا، بما فيها وحدات تُعرّف مجموعات مساراتها الخاصة.
مسار الاستغلال من المتصفح مغلق. أما المسارات نفسها فما زالت تكتب على GET — انظر الحدود الصريحة.
الصحة — عيوب المال
| العيب في 6amMart الأصلي | ما الذي قيس |
|---|---|
| الحد الأدنى للإنفاق في الكوبون لم يُطبَّق قط | كان بإمكان المديرين ضبطه؛ والكود لم يقرأه أبدًا. ثبت مباشرة: كوبون يشترط حدًا أدنى ₹999 قُبل على طلب بقيمة ₹1. ستة كوبونات حية كانت لها حدود دنيا مضبوطة. وهو الآن مُطبَّق في المواضع الثلاثة كلها التي يمكن تسعير الطلب فيها. |
| كانت الخصومات تُقاس بالساعة الخطأ | قاعدة البيانات تعمل بتوقيت UTC والتطبيق بتوقيت الهند — قيس الفارق حيًا عند 5h30m. خصم مسائي من 18:00–22:00 لم يتطابق قط في المساء وكان يُفعَّل عند 2–3 صباحًا. والأسوأ أن شاشة القائمة وصفحة الدفع كانتا تستخدمان ساعتين مختلفتين، فقد يُعلَن متجر بخصم ويُحاسَب بالسعر الكامل. |
| كانت كميات الإضافات تُحاسَب على الإضافة الخطأ | كانت الكميات تُقرَن بالإضافات حسب الموضع في قائمة، بينما يرسل تطبيق العميل ترتيب القائمة وتُعيد قاعدة البيانات ترتيب المعرّف الداخلي. أُثبت على الخادم: طلب مقصود بـ₹270 حوسب بـ₹550. أُصلح في المواضع الـ8 كلها في الكود التي فعلت ذلك. |
| كان المخزون يُخصم من المنتج الخطأ | شراء من حملة كان يبحث عن المنتج بمعرّف الحملة في جدول المنتجات. ومعرّفات الحملات الحية الثلاثة كلها كانت موجودة أيضًا كمعرّفات منتجات. |
| حارس المخزون عند الدفع كان يفحص رقمًا غير الذي يكتبه | الفحص النهائي كان يقارن المخزون الإجمالي للمنتج؛ بينما يحدث الخصم على مخزون الصنف المختار. قيس على بيانات حية: 56 منتجًا نشطًا كان سيُرفض فيها شراء مشروع، و1,451 كان البيع الزائد فيها سيمرّ دون كشف. |
| استدعاء بوابة متكرر كان يُضيف الدفعة مرتين | ويحدث أيضًا حين يُحدّث العميل صفحة العودة. أُصلح على مستوى الخطّاف عبر كل البوابات الـ47. |
| شراء «اشترِ الآن» كان يُسعّر ما يرسله الهاتف | بدل سلة الخادم. |
| كان يمكن اعتماد السحب مرتين وترك المحفظة بالسالب | أُعيد إنتاجه مباشرة: الاعتماد مرتين أضاف المبلغ المسحوب مرتين ودفع الرصيد المعلّق إلى −50.00. وكان زر الرجوع أو نقرة مزدوجة كافيًا. |
| كانت معرّفات الطلبات تُسنَد يدويًا | كان الكود يقرأ أعلى معرّف طلب موجود ويضيف واحدًا — أي إعادة تنفيذ سيئة للترقيم التلقائي، مع تصادم عند الشراء المتزامن. |
| كان بإمكان مندوبَين قبول الطلب نفسه | وبإمكان عميلَين شراء آخر وحدة. سباقات فحص-ثم-كتابة، صارت الآن مطالبات ذرية في قاعدة البيانات، مُثبتة بمعاملات متزامنة. |
عن العددين اللذين ستراهما مقتبسين. إجماليات المشروع نفسه تصنّف 4 من الثغرات الأمنية على أنها حرجة و6 من العيوب على أنها مؤثرة على المال، من أصل 342 عيبًا أُصلحت. هذان هما العددان المنشوران الأدنى، ولذلك هما ما تستخدمه هذه الصفحة. وهما ليسا عددًا للبنود المذكورة في هذه الصفحة: فقسم الأمان أعلاه يسمّي أكثر من أربعة عيوب أمنية، والجدول أعلاه يسرد عشرة عيوب مالية، لأننا نسرد كل ما أعدنا إنتاجه، لا ما يقع داخل العددين فقط.
صحّة غير مالية تستحق السرد
- لم يعمل المُجدوِل قط. خمس مهام خلفية مجدولة لم تُنفَّذ ولا مرة منذ النشر — إذ لم تُثبَّت مدخلة cron في النظام أصلًا.
- مهمة الدفعات الشهرية كانت تعمل أربع مرات في الشهر (كُتب الجدول «الأيام 28–31» بدل «آخر يوم في الشهر»).
- سجل الطلبات كان يبلّغ عن كل متجر بلا تقييم — 0 نجمة في كل مكان، بينما التقييم الحقيقي لأحد المتاجر 4.31 عبر 29 تقييمًا.
- توصيلات المندوبين لم تُحتسب قط في رواج المنتجات — إذ استخدمت حلقة الزيادة اسم خاصية غير موجود في ذلك السجل، فلم تفعل الكتلة شيئًا بصمت، مما شوّه كل ترتيب لـ«أفضل المنتجات».
- كانت الإشعارات الفورية معطّلة بصمت — تُدرَج في طابور عامل قد لا يكون موجودًا؛ فلا يصل شيء، ولا يُرفع أي خطأ.
- 34 خطأ خادم عبر لوحتَي الإدارة والبائع ← صفر.
- بائع بلا صف متجر كان يُسقط 9 من 12 صفحة في لوحته هو، وتسجيل دخول البائع على الويب، وتسجيل الدخول في تطبيق المتجر — إذ كانت دالة مساعدة مشتركة تُعيد أول عنصر من علاقة فارغة، وهو ما يرفع خطأ بدل أن يُعيد قيمة فارغة. 43 فحصًا، منها تأكيدات مزدوجة بأن البائع المشروع لا يزال يمر.
- أحد تقارير الإدارة لم يعمل قط في أي تثبيت لهذا البرنامج — إذ كان يُترجم إلى PHP غير صالح ويفشل دائمًا. اكتُشف بفحص كل قوالب الشاشات الـ895؛ وكان القالب المعطوب الوحيد.
ما يُشحن مع التثبيت المُحسَّن ولا يوجد في الأصلي
| القدرة | ما هي |
|---|---|
| حزمة تحقق آلية | سكريبتات تشغّلها بنفسك. كل تأكيد فيها ثبت فشله على الكود القديم قبل قبوله — فالاختبار الذي ينجح على نظام معطوب لا يُثبت شيئًا. عند تقرير 9 أغسطس كانت السكريبتات الـ60 مؤلفة من 55 تأكيدًا و5 أدوات تقارير، وأدوات التقارير لا تؤكد شيئًا. إضافةً إلى 49 اختبار وحدة وميزة. |
| إثبات قابلية إعادة إنتاج المخطط | يمكن إعادة بناء قاعدة البيانات من الكود وحده — وقد ثبت ذلك ببنائها من الصفر ومقارنة كل الجداول الـ184، عمودًا بعمود وفهرسًا بفهرس، دون أي فروق. |
| SixPreflight | أداة لجاهزية الخادم: نحو 134 فحصًا تغطي العتاد وPHP وصحة التطبيق والصلاحيات وخادم الويب والتخزين المؤقت وإعدادات قاعدة البيانات والانكشاف العام وكل خدمة خارجية. افتحها في متصفح قبل الإطلاق فتخبرك بما سينكسر. |
| دليل تشغيل النشر | تسلسلات تثبيت وتحديث موثّقة، إضافةً إلى المطبّات: أي الأوامر يمسح ذاكرة الإعدادات المؤقتة بصمت، وأي الذواكر المؤقتة لا تعيد بناء بعضها، وما الذي تتراجع عنه لوحة الاستضافة حين تحفظ إعدادًا. |
| بناءات iOS | التطبيقات الثلاثة موقَّعة وتُبنى لـApple كما لـAndroid — وهي أول بناءات Apple تُنتج لهذا المشروع. |
| تتبع الطلبات الحي يعمل فعلًا | خدمة الـwebsocket مُفعَّلة والعيبان اللذان أبقياها مطفأة أُصلحا؛ وثبت تجديد الشهادة. |
تحقّق بنفسك
تحقّق من كل رقم بنفسك
أكثر ما يُقنع في هذه الصفحة ليس رقمًا. بل أنك تستطيع التحقق من كل رقم فيها بنفسك.
حزمة التحقق تُشحن مع تثبيتك. على خادمك أنت:
bash tests/Scripts/run-all.sh # فحوصات التحققphp tests/Scripts/api-smoke.php # يمسح كل نقاط نهاية الواجهة البرمجية1كل تأكيد ثبت فشله على الكود القديم قبل قبوله.
الاختبار الذي ينجح على نظام معطوب لا يُثبت شيئًا.
2مسح نقاط النهاية يُطلق 306 طلبات.
ويبلّغ عن أخطاء الخادم وأزمنة الاستجابة لكل نقطة نهاية — فـ«صفر أخطاء خادم، صفر نقاط نهاية فوق 250 ms» شيء تعيد تشغيله، لا شيء تأخذه على كلمتنا. اقرأ عدد المرفوض في تشغيلك قبل أن تقرأ الأزمنة؛ انظر ملاحظة التشغيل أدناه.
3الحزمة تشمل التأكيدات الأمنية.
لا فحوصات السرعة فقط: مسح انكشاف جذر الويب، وفحص الباب الخلفي لرمز التحقق التجريبي، وفحص مقاومة تكرار خطّاف الدفع، وحُرّاس العبور بين الحسابات، وفحوصات تسميم الذاكرة المؤقتة، وتدقيق أي مسارات GET تكتب حالة.
4فحص المخطط يعيد بناء قاعدة البيانات من الكود وحده.
ثم يقارن كل الجداول الـ184 بجداولك الحية.
ملاحظة تشغيل صريحة شغّل مسح نقاط النهاية مرات كثيرة متتالية فسيُفعّل مُحدِّد المعدل الخاص بالمنصة. الطلبات المخنوقة لا تُنفّذ أي عمل في قاعدة البيانات، فينخفض إجمالي الاستعلامات ويبدو التشغيل أسرع بينما لا يختبر شيئًا تقريبًا. التشغيل الصحيح يُظهر نحو 235 طلبًا ناجحًا و66–68 مرفوضًا؛ ومئات المرفوضة تعني أن تُهمل التشغيل.
والحالة الراهنة للحزمة، مذكورة بدقة سجّل تقرير 9 أغسطس 60 سكريبتًا — 55 تأكيدًا و5 أدوات تقارير — و49 اختبار وحدة وميزة. وقد نما المجلد منذ ذلك الحين إلى 86 مدخلًا، وهي تشمل أدوات تقارير وملفات أخرى ليست تأكيدات، فليست عددًا للفحوص. وآخر تشغيل كامل مسجَّل نفّذ 70 منها: 61 نجاحًا، و2 فاشلًا، و7 متخطّاة. والفشلان مسمّيان في الأدلة — تقريرا إدارة تأجير يُرجعان خطأ خادم على تثبيتات بلا تأجير، وخريطة أصول ناقصة — وأُصلح على الأقل عيب التأجير بعد ذلك. أعد تشغيل الحزمة على تثبيتك واقرأ رقمك أنت.
حدود صريحة
ما لا تدّعيه هذه الصفحة
الصفحة التي تقول «هذا ما قِسناه، وهكذا تتحقق منه، وهذا ما لم نحلّه» أصعب في التكذيب من صفحة لا تطبع إلا انتصاراتها.
342 عيبًا وُجدت وأُصلحت. ولا أحد يستطيع حصر ما تبقّى.
هذه هي الصورة الصادقة لمنصة بهذا الحجم.
لا شيء في هذا البرنامج قاس عمل أي مورّد آخر.
فهذه الصفحة لا تدّعي شيئًا عن بناء أي جهة أخرى. كل رقم هنا هو السكريبت الأصلي كما شُحن في حينه مقابل كودنا المُحسَّن، على خادم واحد.
كل رقم في هذه الصفحة مقرَّب في غير صالحنا، لا لصالحنا.
على الشاشات التي يراها العميل، التحسّن المُقاس 10× إلى 22×، أي انتظار أقل بنسبة 90 إلى 95% — 22× تساوي 95.4% ونحن نطبع 95. وحين يكون القياس نطاقًا، فالمضاعف هو أدنى «قبل» على أعلى «بعد».
أرقام 10 ملايين طلب في هذه الصفحة اختبار حجم، لا أداء حي.
وهي تأتي من قاعدة بيانات مُعدّة خصيصًا محمّلة بـ10,000,000 طلب و1,000,000 منتج و200,000 عميل، شُغّلت عمدًا على تجمّع ذاكرة مؤقتة ضعيف بحجم 128 MB لتكون مقيَّدة بالقرص مثل خادم حقيقي ناقص الموارد. أما تثبيت الإنتاج الذي دُقِّق فيحمل 3,282 طلبًا.
ستة صفوف من اختبار الحجم لا تزال عند ثانية أو فوقها، ونحن نطبع الصفوف الأحد عشر كلها أدناه.
شارات التوزيع 12 s؛ وpopular_products 7.1 s؛ وقائمة طلبات الإدارة عند إزاحة صفحة بعيدة 3.1 s؛ وتقرير الأصناف 12.5 s لشهر واحد و131 s لكل الفترة؛ وقائمة عملاء الإدارة نحو 1–1.5 s. ورقم كل الفترة في تقرير الأصناف أسوأ ما قِسناه في أي مكان، والتشغيل الأصلي الذي كان ينبغي مقارنته به أُوقف عند 120 ثانية، فلا نستطيع حتى ادعاء تحسّن هناك — فقط أن تشغيلنا ينتهي.
طلبات GET التي تغيّر الإعدادات خُفِّف أثرها، ولم تُلغَ.
مسار الاستغلال عبر المتصفح مغلق ومُتحقَّق منه؛ أما المسارات الـ64 في لوحتَي الإدارة والبائع فما زالت تكتب حالة على GET، وتحويلها إلى نماذج محمية لم يُحاوَل عمدًا لأنه خطر انحدار كبير على منصة تعمل حاليًا عبر مشاريع مشتقة كثيرة.
الحارس أوسع من الثغرة.
حتى قائمة قراءة غير ضارة تُرفض إذا وصلت كجلب مسبق أو كتحميل صورة، لأن فصل عناوين اللوحة الـ860 تقريبًا المخصصة للقراءة عن الـ64 الخطيرة يحتاج تحديدًا إلى تلك القائمة الهشّة التي اخترنا ألا نكتبها. وهناك مفتاح من سطر واحد لإطفائه.
تحديد المعدل آمن بسبب موقع الخوادم، لا لأن الترويسات لا يمكن تزويرها.
الإعداد يثق بالترويسات المُمرَّرة، وهو ما يصح فقط ما دام لا شيء يستطيع بلوغ PHP إلا عبر سلسلة الوسطاء. وجهاز يمكن بلوغه مباشرة سيتيح للعميل تزوير الترويسة والحصول على حصة جديدة مع كل طلب.
حجم تنزيل التطبيق بالكاد تغيّر.
نحو 0.7 MB إجمالًا، لأن الكود غير المستخدم الذي أزلناه كان مترجم الإصدار يتخلص منه أصلًا. ولا ندّعي شيئًا بشأن حجم التطبيق.
ثلاثة بنود على التثبيت المرجعي مفتوحة ومُسمّاة بدل أن تُخفى.
مفاتيح Google Maps غير مقيَّدة وتحتاج إلى تقييد؛ ومفتاح Apple Sign-In خاص وضعته أداة الرفع المساعدة في 6amMart الأصلي نفسه في تخزين عام ويحتاج إلى إبطال وإعادة إصدار؛ وثلاثة بائعين لا يزالون بلا صف متجر — وأخطاء 500 التي كانت تسببها تلك الحالة أُصلحت، لكن الحالة نفسها لا تزال ممكنة لأن مساري التسجيل كليهما يحفظان البائع والمتجر خارج معاملة واحدة. الثلاثة كلها مذكورة في وثيقة التسليم.
على الخادم المرجعي، صار العتاد هو الحد، لا الكود.
اختُبر تحت حِمل 20–40 مستخدمًا متزامنًا بصفر أخطاء؛ وعند تلك النقطة يتشبّع جهاز الـ2 vCPU.
كل هذه القياسات على خادم واحد ومجموعة بيانات واحدة.
وهي تكفي لقول ما تغيّر على هذا التثبيت. وليست بيانًا عامًا عن كل عمليات نشر 6amMart.
6amMart الأصلي منتج تجاري واسع الاستخدام.
والعيوب أعلاه مذكورة كوقائع، وهذا يكفي.
اختبار الحجم، مطبوعًا كاملًا — كل صف، بما فيه السيئ
اختبار الحجم — قاعدة بيانات مُعدّة خصيصًا بـ10 ملايين طلب، لا حركة حية.
| الشاشة | الأصلي | المُحسَّن | لا يزال بطيئًا؟ |
|---|---|---|---|
| قائمة طلبات الإدارة، الصفحة الأولى | 27.4 s | 13.6 ms | |
| شارات عدد الطلبات في كل صفحة بائع | 136 ms | 20 ms | |
| تقرير الأصناف، this_week | أُوقف عند 120 s | 542 ms | |
| get_stores | 9.8 s | 901 ms | |
| شارات عدد الطلبات في كل صفحة إدارة | 8.5 s | 830 ms | |
| قائمة عملاء الإدارة، الصفحة الأولى | 20.7 s | ~1.0 – 1.5 s | 1 s فأكثر |
| قائمة طلبات الإدارة، إزاحة صفحة بعيدة | 100 s | 3.1 s | 1 s فأكثر |
| popular_products | 12.8 s | 7.1 s | 1 s فأكثر |
| شارات التوزيع | 29.8 s | 12 s | 1 s فأكثر |
| تقرير الأصناف، this_month | أُوقف عند 120 s | 12.5 s | 1 s فأكثر |
| تقرير الأصناف، all_time | أُوقف عند 120 s | 131 s (بحد أدنى 365 يومًا) | 1 s فأكثر — أسوأ صف لدينا |
حين يختلف مصدران على صف، يطبع هذا الجدول الرقم الأقل إطراءً على الجانبين.
تقريرنا نفسه يسجّل قائمة عملاء الإدارة عند ~1.0 s بينما يسجّل سجل أداة القياس الخام 1.5 s، فيُطبع النطاق. ويسجّل التقرير شارات الإدارة عند 8.5 s ← 830 ms حيث يقرأ السجل الخام 57.4 s ← 791 ms، وشارات البائع عند 136 ms ← 20 ms حيث يقرأ السجل الخام 270 ms ← 13 ms؛ وفي الحالتين تُطبع «قبل» الأصغر و«بعد» الأكبر.
هل يهمّني هذا؟
عند 100,000 طلب وهو رقم واقعي — أي ثلاثون ضعف الحجم الحالي للتثبيت المُدقَّق — ومع إطفاء نوافذ شارات الطلبات، تقيس الشاشات التسع كلها المحلَّلة عند ذلك الحجم 250 ms أو أقل، وستّ من التسع 50 ms أو أقل: شارات البائع 3.4 ms، وget_latest_products 10 ms، وقائمة العملاء 31 ms، وتقرير الأصناف 46 ms، والمنتجات الرائجة 47 ms، وقائمة المتاجر 50 ms، وشارات التوزيع 146 ms، وقائمة طلبات الإدارة 155 ms، وشارات الشريط الجانبي في الإدارة 179 ms. ونافذة الشارات (ORDER_BADGE_WINDOW_DAYS=60) إعداد مشحون، وتفعيلها يغيّر هذه الأرقام، لذلك نذكر الشرط الذي أُخذ القياس تحته.
الأسئلة الشائعة
أسئلة يطرحها المشترون فعلًا
اثنا عشر سؤالًا، مُجابة بالأرقام نفسها المستخدمة في بقية الصفحة.
ما الذي أشتريه فعليًا؟
الشيء نفسه الذي تبيعه AllsWeb دائمًا: تثبيت وإعداد وضبط كامل لـ6amMart على استضافتك — لوحة الإدارة، ولوحة البائع، وملف Android بصيغتَي APK وAAB، وبناء iOS، وموقع العميل، وهويتك البصرية، وSMTP، وGoogle Maps، وإشعارات Firebase ورموز التحقق، وتسجيل الدخول عبر الشبكات الاجتماعية، وبوابات الدفع الخاصة بك، وملف لغتك، والمصدر على مستودع GitHub خاص. يُسلَّم خلال 1–3 أيام عمل بعد اكتمال متطلباتك، مع دعم مجاني مدى الحياة لمشكلات الإعداد والإصلاحات الصغيرة. والكود المُحسَّن هو الطريقة التي يُبنى بها هذا التثبيت الآن.
هل أحصل على 6amMart نفسه؟
نعم — أحدث إصدار من 6amMart، أيًّا كان ما تشحنه 6amTech حين نبني تثبيتك. لوحة الإدارة نفسها، ولوحة البائع نفسها، وتطبيقات العميل والمتجر والمندوب نفسها، ونموذج البيانات نفسه، والمزايا نفسها. وكل تغيير في الأداء كان مشروطًا بإعادة بيانات مطابقة بايتًا ببايت قبل قبوله، فشاشاتك تعرض ما كانت تعرضه، لكن أسرع.
هل يكلّف الكود المُحسَّن مبلغًا إضافيًا؟
لا. لا يوجد منتج منفصل ولا ترخيص منفصل ولا باقة مميزة. سعر التثبيت في الكتالوج هو السعر، والكود المُحسَّن مشمول فيه. وتبقى أنت من يشتري ترخيص 6amMart الخاص به من CodeCanyon ويملكه.
كم هو أسرع فعلًا؟
على الخادم الحي، مع تجاوز الـCDN: العناصر المميزة 8.19 s ← 0.37 s (22×)، والفئات الأكثر رواجًا 3.34 s ← 0.27 s (12×)، والبحث عن المنتجات 1.64–1.96 s ← 0.09–0.12 s (13× على الأقل)، والصفحة الرئيسية للمتجر ~1.47 s ← 0.073–0.096 s (15× على الأقل). ومضاعفات الصفوف تُحسب بأقل الطرق إطراءً التي تسمح بها القياسات. والرقم المعتاد عبر الشاشات التي يراها العميل هو أسرع 10× إلى 22× — أي انتظار أقل بنسبة 90 إلى 95%.
من أين تأتي تلك الأرقام، وعلى أي عتاد؟
«قبل» هو السكريبت الأصلي تمامًا كما شحنته CodeCanyon وقت التجربة — وملاحظة المنهجية أعلاه توضّح في حاشيتها أي بناء كان ذلك ولماذا وُضعت الحاشية. و«بعد» هو السكريبت نفسه بعد البرنامج، مع إضافة إصدار المورّد التالي فوقه. وقيس الاثنان على الخادم نفسه بمواصفات 2 vCPU / 3.9 GB، من جهة الخادم، مع تجاوز الـCDN — لا على جهاز أكبر، ولا بترك الـCDN يقوم بالعمل. وصفّان في جدول المقارنة ليسا زمنَي خادم وهما مُعلَّمان بذلك: عدد بايتات ناتج البناء، وقياس من هاتف على بيانات الجوال.
هل أستطيع التحقق من أي من هذا بنفسي، أم عليّ الوثوق بالصفحة؟
تستطيع التحقق من كل ذلك. حزمة التحقق تُشحن مع تثبيتك: bash tests/Scripts/run-all.sh يشغّل الفحوصات، وphp tests/Scripts/api-smoke.php يمسح 306 طلبات على الواجهة البرمجية ويطبع أزمنة الاستجابة. وكل تأكيد ثبت فشله على الكود القديم قبل قبوله، فالنجاح يعني شيئًا. وهناك تحفظ واحد نفضّل إخبارك به بدل أن تكتشفه: المسح الصحيح يُرفض فيه نحو 66–68 طلبًا بواسطة مُحدِّد المعدل الخاص بالمنصة، والتشغيل الذي تُرفض فيه مئات ينبغي إهماله.
هل ستظل تحديثات 6amTech نفسها تعمل عليه؟
ميكانيكيًا، نعم — وقد جرى ذلك فعلًا. أُضيف إصدار المورّد التالي فوق الكود المُحسَّن، ونزل عمل إضافي بعد تقرير 9 أغسطس: تحصين الذاكرة المؤقتة، وإعادة بناء قائمة المصروفات، وعيب في مفتاح التطبيق أثّر في كل تثبيت بُني من ملف الإعدادات النموذجي للمورّد. والتفصيل الصريح أن إصلاحاتنا تقع في الملفات نفسها التي تشحنها 6amTech، فإصدار المورّد دمج ننفّذه لك، لا استبدال ملف بملف تشغّله أنت.
ماذا يحدث حين تشحن 6amTech إصدار 6amMart التالي؟
إن كنت تشتري الآن فستحصل عليه — نحن نثبّت ما هو حالي يوم نبني. أما لتثبيت سلّمناه سابقًا، فيحدث ما يحدث لأي عميل على أي من سكريبتات كتالوجنا: الانتقال إلى إصدار أحدث هو خدمة التحديث القياسية بـ50% من سعر التثبيت، لأن الإعداد من تجهيزك الأول يُعاد استخدامه. وتطبيقه على الكود المُحسَّن هو الدمج الموصوف في الإجابة السابقة، وهو عملنا لا عملك.
ما المشكلات الأمنية التي كانت فعلًا في السكريبت الأصلي؟
أُعيد إنتاجها ثم أُصلحت: حقن SQL بلا مصادقة يمكن بلوغه من كل قائمة متاجر؛ وطلبات أي عميل وعنوان توصيله قابلة للقراءة دون تسجيل دخول؛ وبوابات دفع مُطفأة في الإدارة لكن استدعاءاتها لا تزال تُسوّي المدفوعات؛ وبائعون قادرون على تعديل منتجات ولافتات بائعين آخرين؛ وباب خلفي حي لتسجيل الدخول التجريبي (محدود الأثر — كان يؤدي إلى حساب جديد مع تجاوز التحقق من الهاتف، لا إلى الاستيلاء على حساب قائم)؛ وأربعة عشر مسارًا في المشروع قابلة للقراءة عبر HTTPS، من بينها نسخة قاعدة بيانات للمثبِّت بحجم 679 KB؛ وكل فاتورة قابلة للتعداد عبر الرابط؛ وواجهة برمجية بلا أي حد للمعدل إطلاقًا — 40 محاولة بكلمة مرور خاطئة متتالية قُبلت كلها بلا خنق وبلا أي تسجيل.
هل سيبقى سريعًا حين يكبر متجري؟
حتى نحو 100,000 طلب، نعم: تسع شاشات حُلِّل أداؤها عند ذلك الحجم، مع إطفاء نوافذ شارات الطلبات، تقيس كلها 250 ms أو أقل، وستّ من التسع 50 ms أو أقل. وهذا ثلاثون ضعف الحجم الحالي للتثبيت المُدقَّق. وبعد ذلك، اقرأ اختبار الحجم في الحدود الصريحة أعلاه — فليس كله انتصارات. عند 10,000,000 طلب مقابل قاعدة بيانات ناقصة الموارد، تنتقل قائمة طلبات الإدارة من 27.4 s إلى 13.6 ms، لكن شارات التوزيع لا تزال 12 s، والمنتجات الرائجة 7.1 s، وتقرير الأصناف لكل الفترة 131 s. وهذه أرقام اختبار حجم على قاعدة بيانات مُعدّة خصيصًا، لا على خادمك الحي.
هل تدّعون أنه لم تعد هناك عيوب؟
لا. 342 عيبًا وُجدت وأُصلحت. ولا أحد يستطيع حصر ما تبقّى في منصة بهذا الحجم. ما نستطيع أن نريك إياه هو ما قيس، وكيف تعيد قياسه، وأي البنود لا تزال مفتوحة — وقسم الحدود الصريحة في هذه الصفحة يسردها، بما فيها صفوف اختبار الحجم التي لا تزال بطيئة والمسارات التي خفّفنا أثرها بدل إعادة كتابتها.
ما الذي لا تزالون غير راضين عنه؟
أشياء عدة، ونفضّل أن تقرأها هنا. في اختبار الحجم بـ10 ملايين طلب، ستة صفوف لا تزال عند ثانية أو فوقها — أسوأها تقرير الأصناف لكل الفترة عند 131 ثانية، والتشغيل الأصلي الذي كان ينبغي مقارنته به أُوقف عند 120 ثانية، فلا نستطيع ادعاء أي تحسّن هناك إطلاقًا؛ وشارات التوزيع 12 ثانية. وأربعة وستون مسارًا في لوحتَي الإدارة والبائع لا تزال تغيّر الحالة على GET عادي — مسار الاستغلال عبر المتصفح مغلق ومُتحقَّق منه، لكن المسارات نفسها لم تُحوَّل. وعلى التثبيت المرجعي، مفاتيح Google Maps غير مقيَّدة، ومفتاح Apple Sign-In يحتاج إلى إبطال وإعادة إصدار، وثلاثة بائعين لا يزالون بلا صف متجر.
أدوات مصاحبة
أين يقع SixPanel وSixPreflight
كل ما سبق يخص كود 6amMart نفسه. وتقف أداتان من AllsWeb على جانبيه — إحداهما تدير الخادم الذي يعيش عليه المتجر، والأخرى تخبرك إن كان خادم لديك أصلًا جاهزًا له. وقد قِيست أرقامهما في وقت مختلف وعلى أجهزة مختلفة، فنبقيها في جداولها الخاصة ولا نخلطها أبدًا بالأرقام أعلاه.
SixPanel
حين تريد إدارة الخادم نيابةً عنك
ما هي
لوحة إدارة تشغّل متجر 6amMart واحدًا، أو عدة متاجر، على خادم افتراضي مستأجر واحد — MariaDB وRedis وnginx وخدمة websocket لتتبّع الطلبات الحي، ومتجر Next.js اختياري. بيئتا تشغيل: الموصى بها تثبّت كل شيء مباشرة على الجهاز من أرشيف التوزيعة الخاص بالإصدار نفسه تحت systemd، و SixPanel Docker يشغّل المجموعة نفسها كخدمات Docker Compose. أمر تثبيت واحد، ونشر من ملف zip من CodeCanyon أو من git، وشهادات Let's Encrypt تلقائية مع تجديد تلقائي، ونسخ احتياطي تزايدي مجدول بـ restic مع مدة احتفاظ، ومضيف افتراضي لكل مشروع، وضبط تلقائي على العتاد، ومراقب يعالج نفسه فيعيد تشغيل الخدمات التي تعمل ولا تؤدي عملها. ثلاث واجهات: اللوحة في المتصفح، وأمر sixpanel على الجهاز، والمُثبِّت. ويأتي معه دليل عميل من 24 فصلًا، يُقدَّم داخل اللوحة نفسها.
مُقاس، وآمن للنشر
| ما الذي قيس | الرقم، مع شروطه |
|---|---|
| الطلبات المُخدَّمة — نقطة نهاية البحث، 20 متزامنًا، 30 ثانية | أنجز خادم بـ2 نواة / 4 GB نحو 53 طلبًا في الثانية على كتالوج متجر حقيقي فيه 66,701 طلب، مع إجابة قاعدة البيانات على 99.99% من القراءات من الذاكرة. وهذا يصف تلك النقطة وتلك البيانات و2 نواة. وليس رقمًا عامًا للمنصة. |
| زمن التثبيت دون تدخل | 273 – 303 ثانية عبر أنظمة التشغيل الثلاثة المُختبرة — نحو خمس دقائق |
| السرعة في مواجهة منافس مضبوط بالكامل | أسرع بمقدار 1.76× من aaPanel مضبوط بالكامل عند طلب واحد، و1.82× مع أربعة طلبات في آن واحد، على عتاد متطابق يشغّل المتجر نفسه بـ 66,701 طلب — مع عزو نحو 60% من الفارق إلى قيد أدلّة في PHP، و8% إلى وضع JIT الخاطئ، و0% إلى إصدار PHP، ونحو 32% نُشر على أنه غير مُفسَّر |
| نظام التشغيل الموصى به | Ubuntu 26.04 LTS، بتحديثات أمنية حتى أبريل 2031. وUbuntu 24.04 LTS وDebian 13 هما الإصدارَان المدعومان الآخران — ثلاثة في المجموع، ولا شيء غيرها |
أمر آخر يستحق القول، لأن أحدًا تقريبًا لا ينشره. قِسنا ثلاثة أنظمة تشغيل على عتاد متطابق وبالبيانات الحقيقية نفسها. فتعادلت — إذ كان الفارق بينها أصغر من فارق جهاز واحد مع نفسه. فاخترنا بناءً على مدى الدعم لا على السرعة، ولن نذكر فرق سرعة لم نستطع قياسه.
حدود صريحة — SixPanel
- الاستعادة تعود إلى الجهاز نفسه. الاستعادة على جهاز مختلف تُبقي كلمة مرور قاعدة بيانات الجهاز القديم ومساراته، فلا يستطيع التطبيق الاتصال حتى تُشغَّل عملية تحديث؛ كما أن مهمة الاستعادة لا تُشغّل خطوة ترحيل قاعدة البيانات أبدًا، فتبقى نسخة أقدم تحت كود أحدث متأخرة عن المخطط. وكلاهما مسجَّل كمعطوب — مسجَّل، لا مُصلَح — ولكليهما حلّ يدوي.
- المراقب الذاتي لا يرى خدمتين من الخدمات المذكورة في قائمة المزايا أعلاه. فخدمة الـwebsocket ومتجر Next.js الاختياري لا تحملان فحص صحة، فلا يغطيهما المراقب. بند مفتوح.
- التراجع لا يعكس ترحيلات قاعدة البيانات. فالتراجع عن الكود بعد ترحيل يحتاج إلى استعادة نسخة احتياطية.
- اللوحة تقرأ شهادة TLS الخاصة بها مرة واحدة عند الإقلاع. ومهمة التجديد اليومية تعيد تحميل nginx لا اللوحة، فتحتاج اللوحة إلى إعادة تشغيل لالتقاط شهادة مُجدَّدة.
- اللوحة مكافئة لـ root على الجهاز بحكم بنيتها — فهي تثبّت الحِزَم وتكتب إعدادات النظام وتعيد تشغيل الخدمات. وعلى بيئة Docker تضيف إلى ذلك ربط مقبس Docker وربط مجلد المجموعة بصلاحية الكتابة.
- يوجد حساب مدير واحد فقط ولا توجد أدوار. لا تعدد مستخدمين ولا فرق.
- لم تُقس سوى أجهزة بذاكرة 4 GB. ولا شيء في هذه الصفحة يصف 8 GB أو أكبر.
متى يناسبك SixPanel
حين تستأجر خادم VPS وتفضّل ألا تتولى بنفسك nginx وضبط MariaDB والشهادات والنسخ الاحتياطي وعمليات النشر — أو حين تريد أكثر من متجر على خادم واحد.
SixPreflight
حين تريد معرفة ما سينكسر قبل الإطلاق
ما هي
أداة PHP صغيرة تضعها في مجلد public/ لموقع Laravel وتفتحها في المتصفح خلف كلمة مرور. تُجري نحو 134 فحصًا تغطي العتاد وPHP وصحة التطبيق وملف البيئة والصلاحيات وخادم الويب والتخزين المؤقت وإعدادات قاعدة البيانات والانكشاف العام وكل خدمة خارجية — المدفوعات والبريد والرسائل النصية والخرائط والإشعارات — بالاتصال بكل منها فعليًا بدل قراءة إعداد. تعطيك تقديرًا بحرف، وحكمًا بلغة واضحة، وقائمة إصلاحات مرتبة حسب الأثر، مع قيمة جاهزة للّصق حيثما وُجدت. وتحصل على الإصدار الحالي.
على التثبيت المرجعي
أبلغت عن 103 نجاحًا و7 إخفاقات و24 تحذيرًا — وكانت الإخفاقات إعدادات استضافة لا أعطال تطبيق.
متى تناسبك SixPreflight
على aaPanel أو CloudPanel أو cPanel؟ SixPreflight لك. تشغّل SixPanel؟ هذه الفحوصات مدمجة أصلًا في صفحة فحص المتجر فيه.
كل شيء يوصي الآن بنظام التشغيل نفسه، والسبب ليس السرعة. يوصي SixPanel وSixPanel Docker وSixPreflight جميعًا بـ Ubuntu 26.04 LTS. تأخذ بيئة التشغيل المباشرة PHP وMariaDB وnginx وRedis من أرشيف التوزيعة الخاص بالإصدار نفسه، والإصدارات المدعومة الثلاثة كلها تحمل مجموعة تعمل — 26.04 يعطي PHP 8.5 وMariaDB 11.8، وDebian 13 يعطي 8.4 و11.8، وUbuntu 24.04 يعطي 8.3 و10.11. ولا شيء من هذا توصية تتعلق بالسرعة: على ستة محاور مقيسة لم يُنتج أي تبديل إصدار فرقًا يستحق النشر، وجهازان متطابقان بايتًا ببايت اختلفا عن بعضهما بنسبة 11.6 %. والعامل الحاسم هو مدة الدعم المتبقية — فـ 26.04 يتلقى الترقيعات حتى أبريل 2031.
أيهما أحتاج؟
| حالتك | الجواب |
|---|---|
| تريد تثبيت 6amMart، أو أن 6amMart الحالي لديك بطيء أو أوقعك في مشكلة تسعير أو مدفوعات | تثبيت 6amMart المُحسَّن |
| لديك خادم VPS ولا تريد أن تتولى بنفسك nginx وMariaDB وشهادات SSL والنسخ الاحتياطي وعمليات النشر | SixPanel |
| لديك خادم على لوحة أخرى وتريد معرفة ما سينكسر قبل الإطلاق | SixPreflight |
كل رقم في هذه الصفحة قيس على تثبيت حي
والحزمة التي قاسته تُشحن مع بنائك.
تحتاج شيئًا يُبنى من الصفر بدلًا من ذلك؟ تحدّث إلينا عن العمل المخصص