الهدف: نحوّل Moon ERP لمنتج زي الووردبريس — حزمة تتحمّل وتتركّب على أي استضافة، ولما ننزّل تحديث،
النسخة المركّبة تقدر تسحبه وتحافظ على بيانات العميل بالكامل وتاخد الكود الجديد + الـ migrations.
القرار المؤسِّس (اتفقنا عليه): ده نظام مستقل تمامًا عن نظام Ahmed، نبنيه من الصفر، بسيط ومعزول.
النظامين يفضلوا جنب بعض؛ ولما Ahmed يخلّص بتاعه نقرّر نعتمد عليه. دلوقتي: MoonStack بس، ومفيش أي تعديل في كود Ahmed.
١) ليه منفصل — ومبدأ التعايش
- عزل كامل: MoonStack ما بيعملش import أو reference لأي كلاس/كونفيج/مسار من نظام Ahmed. لو شِلنا MoonStack بالكامل، نظام Ahmed يفضل شغّال زي ما هو، والعكس.
- بساطة مقصودة: MoonStack يعمل تثبيت + تحديث + باك أب/استرجاع + تتبّع إصدار وبس. مفيش ترخيص SaaS/quotas/أوامر عن بُعد/تيليمتري — دي تخصّ نظام Ahmed.
- قابل للاستبدال: لما Ahmed يخلّص، نوقف MoonStack ونحوّل للـ Moon Central من غير أي تنظيف معقّد.
٢) حدود عدم التصادم (الأهم)
كل اسم/مسار في MoonStack مختلف تمامًا عن نظام Ahmed عشان يشتغلوا في نفس الريبو من غير تضارب:
| العنصر | نظام Ahmed — ممنوع نلمسه | MoonStack — الجديد |
| نقطة التثبيت | public/install.php · /install | public/moonstack-setup.php · /moonstack-setup |
| نقطة التحديث | public/update.php · /update | public/moonstack-update.php · /moonstack-update |
| الإعدادات | config/license.php + config/update.php | config/moonstack.php |
| الكود (Namespace) | App\Services\Update\* · MoonLicenseClient | App\MoonStack\* |
| الأوامر | license:* · moon:* | moonstack:* |
| تتبّع الإصدار | MOON_APP_VERSION + storage/installed | storage/moonstack/version.json + storage/moonstack/installed |
| الباك أب | storage/app/backups/ | storage/moonstack/backups/ |
| سيرفر التحديث | Moon Central (SaaS) | versions.json ثابت على CDN + API خفيف |
ملاحظة: الاتنين بيتشاركوا في حاجة واحدة بس — تطبيق Laravel وقاعدة البيانات — لكن كود التوزيع في كل نظام ما يعرفش عن التاني.
٣) فصل الكود عن الداتا (القلب)
الكود (يُستبدل كل تحديث)
Modules/ · app/ · config/ · routes/ · database/migrations/ · vendor/ (مُحزّم جاهز) · artisan · الـ Angular dist المبني مسبقًا.
الداتا (تُحفظ للأبد — لا تُلمس)
قاعدة MySQL (migrations بس) · .env (خصوصًا APP_KEY) · storage/app/** (رفع المستخدم) · public/uploads · أي إعداد خاص بالعميل.
التحديث = استبدال الكود + تشغيل migrations آمنة (إضافية فقط). ما يلمسش أبدًا صفوف الداتا أو .env أو الرفع أو الـ APP_KEY. القائمة دي تتعرّف في config/moonstack.php كـ manifest واحد (مصدر الحقيقة).
٤) قيود الاستضافة (cPanel) اللي بتشكّل كل القرارات
مفيش root، مفيش Docker، مفيش SSH مضمون؛
composer install غير موثوق؛
exec()/
mysqldump ممكن يكونوا متوقفين؛ ملفات cache بملكية root → 500؛ Angular محتاج build مش متاح على الهوست.
لذلك:
- المُحدِّث ويب (PHP) زي «Updates» في الووردبريس — مش shell.
- الحزمة مكتفية ذاتيًا:
vendor/ مُحزّم + الواجهة مبنية مسبقًا.
- الباك أب فيه fallback بـ PHP خالص لو
mysqldump متوقف.
- كل العمليات + artisan تشتغل بـ مستخدم الويب مع
HOME مضبوط (تفادي cache بملكية root).
- استخدام
ZipArchive + cURL، من غير أدوات نظام.
٥) المكوّنات الأربعة (مبسّطة)
① خط التحزيم (عندنا)
سكريبت build → حزمة zip موقّعة بإصدار = كود + vendor/ مُحزّم + الواجهة مبنية + manifest.json. يستثني .env والداتا.
② سيرفر التحديث (عندنا)
أبسط مسار: ملفات zip موقّعة ثابتة على CDN + versions.json صغير. (من غير سيرفر تقيل — ده الفرق عن Moon Central.)
③ المُثبِّت (داخل الحزمة)
معالج ويب أول تشغيل: فحص البيئة → إعداد DB → توليد .env+APP_KEY (مرة واحدة) → migrate+seed → أول أدمن/شركة.
④ المُحدِّث داخل التطبيق (داخل الحزمة)
شاشة «التحديثات» + محرّك: فحص → تنزيل → تحقق → باك أب → تطبيق → migrate → swap واجهة → استرجاع عند أي فشل.
٦) مسار التحديث (١١ خطوة)
- فحص: النسخة تكلّم السيرفر بـ
{current_version, php_version} → ترجع أحدث إصدار + changelog + الحد الأدنى للمتطلبات + رابط + sha256 + توقيع.
- Pre-flight: نسخة PHP/extensions، مساحة القرص، صلاحيات الكتابة. فشل → نقف قبل ما نبدأ.
- وضع الصيانة:
artisan down.
- باك أب: dump للداتابيز + zip للكود + storage →
storage/moonstack/backups/<version>/. شبكة الأمان.
- تنزيل + تحقق:
sha256 + توقيع (سلامة + أصالة).
- تجهيز وتطبيق: فك في staging، استبدال الكود مع الحفاظ على
.env وstorage/ وpublic/uploads/.
- Migrate:
migrate --force (إضافي) + seeders مرجعية idempotent.
- إعادة بناء:
dump-autoload -o + optimize:clear + كاش config/route.
- Swap الواجهة: حذف الـ dist القديم أولًا (تفادي chunks قديمة) ثم نسخ الجديد.
- تشغيل:
artisan up + فحص صحة.
- تقرير + استرجاع: أي فشل في أي خطوة → rollback (استرجاع الكود + الداتابيز +
artisan up).
٧) الـ ١٤ قاعدة المؤسِّسة
1
APP_KEY ثابت — يتولّد مرة واحدة عند التثبيت، ما يتغيّرش أبدًا (تغييره يكسر الأعمدة المشفّرة).
2
manifest كود/داتا — ملف يحدّد مسارات الداتا اللي ما تُستبدلش أبدًا.
3
انضباط الـ migrations — كل migration إضافي وآمن؛ الحذف على إصدارين؛ ممنوع تعديل migration مشحون.
4
seeders idempotent — مرجعية بـ firstOrCreate، ممنوع truncate وإعادة.
5
تبعيات مُحزّمة — vendor/ جاهز؛ بس dump-autoload على الهوست.
6
باك أب قبل التحديث — إجباري، تلقائي، استرجاع بضغطة.
7
حزم موقّعة + checksum — sha256 + توقيع بمفتاحنا الخاص يتحقّق بمفتاح عام مدمج.
8
بوابة توافق — كل إصدار يعلن الحد الأدنى لـ PHP/extensions/الإصدار السابق؛ يرفض لو مش متوفّر.
9
تشغيل بمستخدم الويب — كل العمليات + artisan (تفادي cache بملكية root).
10
ذرّي وقابل للعكس — staging ثم swap؛ استرجاع عند الفشل (DDL في MySQL مش transactional → الباك أب هو الضمان).
11
بدون افتراض shell — المُحدِّث ويب أساسي؛ CLI اختياري للهوستات اللي فيها SSH.
12
تتبّع نسخة DB — تسجيل app_version + schema_version؛ ترقية مرتّبة بلا قفز.
13
ترخيص خفيف (اختياري) — في MoonStack البساطة أولًا؛ مفتاح بسيط/أو بدون. (مش زي licensing بتاع Ahmed.)
14
بدون تعديل core عند العميل — التخصيص عبر config/modules فقط؛ التحديث يستبدل الـ core.
٨) الخطة على ٧ مراحل (معزولة)
0
الأساسات نبدأ هنا
manifest الكود/الداتا في config/moonstack.php · تتبّع app_version+schema_version معزول · توثيق انضباط migrations + ثبات APP_KEY · فحص idempotency للـ seeders اللي هيستخدمها المُثبِّت.
1
خط التحزيم بعدها
سكريبت moonstack:build → حزمة موقّعة (كود+vendor+واجهة+manifest+sha256).
2
المُثبِّت
معالج ويب moonstack-setup.php (فحص → DB → .env/APP_KEY → migrate+seed → أدمن/شركة).
3
سيرفر التحديث
versions.json + استضافة حزم موقّعة + توقيع/تحقق.
4
المُحدِّث داخل التطبيق
محرّك فحص/تنزيل/تحقق/باك أب/تطبيق/migrate/rollback + شاشة «التحديثات».
5
الباك أب/الاسترجاع
تقوية الـ rollback (كود + داتابيز) + fallback بـ PHP خالص + الاحتفاظ.
6
الترخيص (اختياري/خفيف)
تفعيل بسيط لو احتجناه — أبسط ما يكون.
7
التجربة (Pilot)
تثبيت كامل → تحديث → بروفة rollback على حساب cPanel نظيف.
٩) القرارات المفتوحة + توصياتي (كنقطة بداية)
| القرار | توصيتي |
| آلية التحديث | ويب أساسي + CLI اختياري |
| سيرفر التحديث | zip موقّعة ثابتة على CDN + versions.json خفيف |
| الترخيص | بدون ترخيص في البداية (أو مفتاح بسيط لاحقًا) — البساطة أولًا |
| المُثبِّت | معالج ويب كامل |
| تلقائي/يدوي | يدوي بضغطة افتراضيًا |
| طريقة باك أب DB | mysqldump مع fallback بـ PHP خالص |
| قناة الإصدار | stable فقط في البداية |
القرارات دي مش بتوقف Phase 0 — الأساسات مش معتمدة على أي منها، فنقدر نبدأ فيها فورًا بعد موافقتك على الخطة دي.
١٠) حقائق البيئة/الـ stack
- Backend:
/home/moonui/moon-erp-be (Laravel modular monolith, PHP 8.2). الفرع الحالي lis/lab-updates.
- Frontend source:
/home/moonui/public_html/moon-erp (Angular 21). هدف التثبيت: public/app/.
- تشغيل artisan/php كـ moonui:
runuser -u moonui -- php artisan … (مش كـ root). بعد تعديل BE: bash local-deploy.sh.
- موجود نقدر نتعلّم منه (من غير ما نلمسه): انضباط migrations في Laravel، seeders idempotent، البناء الثابت للـ Angular،
vendor/ حاضر.
الخلاصة: MoonStack نظام مستقل بسيط، أسماؤه ومساراته مختلفة تمامًا عن Moon Central، مفيش بينهم تقاطع كود.
نبدأ من Phase 0 (الأساسات) بعد موافقتك على الخطة دي.