أَثل منصّة سحابية متعدّدة المستأجرين لتشغيل المقاهي والمطاعم: نقطة بيع، وشاشات مطبخ، ومخزون بالوصفة، وولاء، وتقارير للمالك، وفوترة زاتكا، وواجهة API للقراءة. وهذه الصفحة ليست عرضاً للمنتج — بل لطريقة بنائه.
أكثر ما بُني في أَثل لم يأتِ من مواصفةٍ تقنية، بل من سنةٍ وأربعة أشهر خلف الطاولة نفسها.
انتهى عملي مديرَ فروعٍ في أبريل ٢٠٢٦. وأوّل كوميت في أَثل كان في ٢١ مايو ٢٠٢٦. الشهر الذي بينهما هو شهر التصميم — وما بُني بعده منصّةٌ متعدّدة الفروع كتبها من كان يشغّل عدّة فروع قبل أسابيع.
وفوق ذلك، لم يُكتفَ بالتجربة الشخصية:
الفرق يظهر في الشيفرة نفسها. حين اكتُشف لاحقاً أن شاشة الكاشير تُفرَّغ صامتةً بعد إرسال الطلب للمطبخ، لم يكن العطب تقنيّاً — الطلب أُرسل بنجاح والقاعدة سليمة. العطب أن الصمت كان يُقرأ «تمّت المحاسبة» بينما لم يُقبض شيء. حلُّه سطرٌ يقول الحقيقة: «أُرسل الطلب — لم يُحاسَب بعد».
عطبٌ كهذا لا يظهر في اختبار. يظهر لمن وقف خلف الكاشير ورأى كيف يقرأ الشاشة.
المنحنى الشهريّ ليس نمواً مطّرداً. فيه لحظةٌ تبدّل فيها طبع المشروع كلّه.
وفي الوسط تقع نقطة التحوّل: خطّ التكامل verify.yml وُلد في ٢٢ يوليو، وأول طلب دمجٍ حقيقيّ في ٣١ يوليو — وهو نفسه أكثف يومٍ في تاريخ المستودع (١٠٩ كوميتات). ومن أول أغسطس صار الدمج بالسحق حصراً: ٣١٠ طلباً في شهر واحد.
الخلاصة التي تلخّص المشروع: الانضباط لم يسبق الفوضى — وُلد منها.
عشرة سكربتات وظيفتها الوحيدة منع خطأ يعرف المشروع أنه يقع — لأن كلّ واحدٍ منها كُتب بعد أن وقع ذلك الخطأ فعلاً وبلغ الفرع الرئيس.
check-migration-orderفرعٌ قديم يُنزل رقم هجرةٍ مكرَّراً — بلا تعارضٍ يُنبّه، لأن الاصطدام على الرقم لا الاسمcheck-service-only-callersنداءٌ من المتصفّح لما يجب أن يبقى خادميّاًcheck-db-types-no-lossأنواعٌ مولَّدة تنحرف صامتةً عن سكيما القاعدةcheck-shell-utf8-varsمتغيّرٌ عارٍ يكسر النصّ العربي في سكربتات التشغيلcheck-shared-db-driftقياسٌ يُؤخذ على قاعدةٍ انحرفت — فيُنسب عطبُ البيئة إلى الشيفرةcheck-security-scanner-blockingفاحصٌ أمنيّ يمرّ في خطّ التكامل بلا أن يحجب شيئاًcheck-workflow-runnerوظيفة تكاملٍ بلا عدّاءٍ يلتقطها — فتبدو ناجحةً وهي لم تعملوأربعةٌ منها لها اختبارها الخاص — حارسٌ للحارس، لأن حارساً أعمى أسوأ من غيابه: يمنح طمأنينةً بلا حماية.
كل قرارٍ معماريٍّ في أَثل مسجَّلٌ بحكمه وبالقياس الذي برّره — وما نقضه قرارٌ لاحق بقي في السجلّ ولم يُمحَ. هذه ثلاثة منها.
قرارٌ سابق حدّد موضع قفلٍ في مسار المال بناءً على تحليلٍ سليمٍ لدورةٍ واحدة. فأُعيد القياس باتّصالين متزامنين على قاعدةٍ معزولة، فظهر deadlock detected من أول محاولة — فسقط القرار السابق وحلّ محلّه علاجٌ أصغر: ترقية قراءةٍ قائمة بدل إضافة قفلٍ ثالث.
دفترُ كلفةٍ يحمل صفوفاً كُتبت بسعرٍ قديم. والحكم كان ألّا تُصحَّح رجعيّاً، بسببٍ مكتوب: «لم أقس عدد الصفوف المصابة ولا أستطيع — وكتابة تحديثٍ على دفترٍ ماليٍّ بحجمٍ مجهول أخطر من الضرر الذي تعالجه».
نُفّذت خطوةٌ قبل التحقّق من شرطها. الأثر كان صفراً، لكن الترتيب كان خطأً — فسُجّل: «يُسجَّل كي لا يُقرأ صمتُ السجلّ موافقةً».
أيّ مشروعٍ يستطيع أن يعرض عدد اختباراته. أمّا سجلٌّ يوثّق لماذا لم يُبنَ شيء — وقد تكرّر ذلك عشرات المرات — فهو ما يجعل النظام قابلاً للبناء عليه بعد سنة.
ما دخل الفرع الرئيس بين ١ و١٣ سبتمبر — ٦٤ طلب دمج. كلُّ بندٍ هنا مدموجٌ في الشيفرة، لا مخطَّط — ولم يشتغل منه شيءٌ بعد على مقهىً حقيقيّ.
API · MCPمفاتيح لكل منشأة، وقرّاء /api/v1، وخادم MCP فوقها — فيقرأ وكيلُ ذكاءٍ بيانات المقهى بمفتاح صاحبه لا بمفتاح المنصّةprep stationsمحطّات تحضيرٍ يعرّفها كلُّ مقهى ويفعّلها لكل فرع، بلوحٍ لكل محطّة — وترفض المنصّة إطفاءَ محطّةٍ عليها شاشاتٌ حيّةtemplatesقوالبُ تشغيلٍ جاهزة (أربعٌ للبداية): تُعايَن قبل التطبيق، وتُطبَّق بنداً بنداً لا دفعةً واحدةdelivery channelsوسمُ قناة التوصيل على الطلب — بسعرها وتسويتها وتقريرها — من نقطة البيع حتى المطبخ والماليةcurbsideالاستلام من السيارة (لوحة · لون · نوع) للطلب الإلكتروني، وزرُّ «وصلت» للزبونrefund linesالاسترجاع على مستوى السطر، يعكس معه النقاط والأختام على السطر نفسهtenant lifecycleكاتبٌ واحدٌ لحالة المنشأة، وإيقافٌ بمهلة لا يقطع ورديةً مفتوحة في منتصفهاdeployالهجراتُ تُرفع آلياً عند الدمج بعد نسخةٍ احتياطيّةٍ طازجةٍ إلزاميّة، والشيفرةُ لا تُنشر قبل هجرتهامنذ آخر تحديثٍ لهذه الصفحة (١٣ سبتمبر) — ٤٤ طلب دمج جديد. كلُّ بندٍ هنا مدموجٌ في الشيفرة، لا مخطَّط. ولا حركة إنتاج حقيقية بعد، إلا اختباراً ميدانياً واحداً لشاشة المخزون في ١٩ سبتمبر.
fraud controlsشاشة «الرقابة» لصاحب المنشأة، وأربعة كواشف تعمل عند إقفال الوردية، وموافقةٌ ثانية على الاسترجاع، وكلمة مرورٍ للتوقيع على إجراءات الضبطMoyasarاتصال مدفوعات مستقلّ لكل مقهى، لا مفتاحاً واحداً للمنصّة كلّهاself-serve signupتسجيلٌ ذاتيّ من athl.cloud/register بفحص السجل التجاري، تعتمده المنصّة يدوياً لكل منشأةinventory entryشاشة إضافة صنفٍ وتنبيهات نفاد المخزون — أوّل تشغيلٍ فعليّ لها كان في ١٩ سبتمبر، في اختبارٍ ميدانيّZATCA phase 1–2سلسلة التوقيع المباشر مبنيّة؛ تسجيل كل مقهى لدى زاتكا (المرحلة التالية) قيد البناء — لا فاتورة زاتكا موقّعة صدرت من أَثل حتى ذلك الحين (والجديد في القسم ٠٧)offline boardsلوحات طلباتٍ للقراءة فقط، تعمل دون اتصال بالإنترنتdata importأساسٌ لاستيراد البيانات من أنظمةٍ سابقة — أساسٌ فقط حينها، لا مسارُ ترحيلٍ كامل (والجديد في القسم ٠٧)Frankfurtالخوادم انتقلت لفرانكفورت قرب القاعدة، وتُبقى دافئةً بدالّةٍ مجدولة — البطء الأول كان بردَ البداية، لا ضعف النظاممذكرة الجاهزية تقيس المنصّة على ما يحتاجه أوّل يوم تشغيلٍ حقيقيّ. كانت ٦٧ من ١٠٠ في ١٨ أكتوبر، وصارت ٩٢ في ٢٠ أكتوبر — والنقاط الثماني الباقية كلّها تحتاج تجربةً على جهازٍ حقيقيّ أو خطوةً منّي. كلُّ بندٍ هنا مبنيّ وعليه اختبارٌ يمرّ.
ZATCA phase 2توقيعٌ مباشر مع الهيئة بلا وسيط: ختمٌ، ثم تحقّقٌ من التوقيع قبل الإرسال، ثم إبلاغ. ١٣ وثيقة (بيع، إشعار دائن، إلغاء، ضيافة، رسم توصيل، أسعار غير شاملة) خُتمت وأُبلغت كلّها بنجاح في بيئة المحاكاة لدى الهيئة في ١٩ أكتوبر — المحاكاة، لا الإنتاجlink ZATCAزرّ «اربط زاتكا» يربط به المالك وحدة الفوترة بنفسه، وتنبيهٌ إن بقيت فاتورةٌ ٢٠ ساعة دون إبلاغ، وإشعارٌ دائن عند كل مرتجعtill dayيومُ كاشيرٍ كامل في اختبارٍ آليّ: فتح الوردية، كاش وشبكة وتقسيم الدفع، خصمٌ بإذن المدير، كوبون، نقاط وأختام، مرتجع، إلغاء، ثم إقفال الدرجoffline guardsقبل البيع بلا نت يُفحص الجهاز (القائمة، الجلسة، ساعة الجهاز، تغيّر السعر)؛ والطلب لا يُحسب مرّتين لو انقطع الردّ أو فُتح تبويبان؛ وأرقام الطلبات لا تتكرّر بين الأجهزة حتى بلا نتrecipe stockالبيع ينقص المخزون بالوصفة بالضبط، وجردٌ يسجّل حركةً لكل صنف، ونقلٌ بين الفروع إرسالاً واستلاماً، وتنبيهُ نفادZ reportتقرير الإقفال والتقارير والقاعدة تتطابق بالهللةFoodics importالمنيو والمخزون والإضافات تُستورد من ملفات فودكس مباشرةً، مع تراجعٍ عن الاستيراد إن لزم9 rolesتسعة أدوار، والمشرف محصورٌ بفرعه — ومن التسجيل إلى أوّل بيعة لمقهىً جديد في اختبارٍ آليّ واحدكل رقمٍ هنا مأخوذ من المستودع بأمرٍ يمكن إعادة تشغيله.
153 daysأوّل كوميت ٢١ مايو ٢٠٢٦ إلى ٢١ أكتوبر — النشاط في ٩٢ يوم عمل، بمعدّل ١٦ كوميتاً في اليوم النشط (١٬٤٦٢ كوميتاً إجمالاً). ويسبقها شهرٌ من التصميم قبل أن يُكتب سطرٌ واحد232 tables · 1,247 functionsفي مخطّط public كما تظهر في الأنواع المولَّدة من القاعدة (بلا أقسام السجلّ الشهرية) — وكلُّ كتابةٍ تمرّ بدالّةٍ مختومة، لا بكتابةٍ مباشرة من العميل1,000+ error codesلكلّ حالة فشلٍ رمزٌ ورسالةٌ عربيّة — لا «حدث خطأ ما» — كلُّها في كتالوجٍ واحدٍ داخل القاعدة1,964 test files١٬٢٨٢ بـvitest و٦١٤ بـpgTAP داخل القاعدة و٦٨ رحلة e2e في المتصفّح — ١٣٬٦٤٥ توكيداً مخطّطاً في pgTAP358 suites as a userسويتات قاعدةٍ تعمل بصفة مستخدمٍ مسجّل لا بصلاحية المشرف — فتختبر الصلاحيات وعزل البيانات كما يعيشها المستخدم فعلاً143,333 linesاختبارات SQL وحدها — أي ٦٢٪ من حجم الهجرات نفسها70+ race proofsبراهين سباقٍ باتّصالين حقيقيين على قاعدةٍ معزولة — لا اختبار قاعدةٍ واحدة17 edge fnsمكتوبة، وكلُّها منشورةٌ في الإنتاجهذا القسم موجودٌ عمداً. سجلٌّ بلا حدودٍ معلَنة دعايةٌ لا سجلّ.