الملخص التنفيذي
قمنا بتحميل مشروع ميز كاملاً من بيئة Replit وأجرينا عليه فحصاً فنياً دقيقاً ملفاً بملف. النتيجة باختصار:
التصميم والواجهات التي نفّذها عدنان ممتازة وتستحق البناء عليها، وسنحتفظ بها كأساس بصري بعد تحسينات. لكن الجانب التقني خلف الكواليس — قواعد البيانات، الباكاند، والحماية — مبني للعرض السريع وليس للتشغيل الحقيقي، وفيه تعارض فعلي (Conflict) بين طبقة قواعد البيانات والباكاند، إضافةً إلى ثغرات أمنية تجعل التطبيق غير آمن لإطلاقه على مستخدمين حقيقيين بوضعه الحالي.
القرار الفني: نأخذ التصميم فقط من المشروع الحالي، ونعيد بناء كل ما تحته (قاعدة البيانات + الباكاند + الحماية + النشر) من جديد على أساس سليم وآمن. هذا ليس انتقاصاً من العمل السابق، بل هو الطريق الصحيح لمنتج يتحمّل مستخدمين فعليين وبيانات حسّاسة.
الموعد المستهدف (1 يوليو) يمنحنا ~6 أسابيع فقط، وهي مدة ضيّقة لإعادة بناء كامل + فحص. القسم 10 يوضّح خطة واقعية لتحقيق ذلك، مع تحديد النطاق الأدنى القابل للإطلاق (MVP) بدقّة. الالتزام بالموعد ممكن بشرط تثبيت النطاق وعدم إضافة مزايا جديدة خلال الفترة.
وصف المشروع الحالي
ميز ليس تطبيقاً واحداً، بل مستودع موحّد (Monorepo) يضم ستة تطبيقات تتشارك مكتبات مشتركة، باستخدام pnpm workspaces:
| التطبيق | الوصف | التقنية |
|---|---|---|
myz | تطبيق الويب الرئيسي للزبائن (اكتشاف المطاعم، التقييمات، المفضلة) | React + Vite |
dashboard | لوحة تحكم الأدمن والتجار (المطاعم، المنيو، نقاط البيع، المستخدمون) | React + Vite |
landing | الموقع التسويقي + صفحات المنيو العامة | React + Vite |
mobile | تطبيق الهاتف (iOS / Android) | Expo / React Native |
mockup-sandbox | أداة داخلية لتصاميم الواجهات | Vite |
api-server | خادم الـ API الذي يربط الجميع | Express |
المكتبات المشتركة: عميل API مُولّد تلقائياً، مخططات تحقق (Zod)، طبقة قاعدة البيانات (Drizzle)، ومساعدات رفع الملفات.
تقييم عادل: البنية المعمارية للمشروع جيدة ومنظّمة — استخدام TypeScript في كل مكان، فصل واضح بين التطبيقات، توليد تلقائي لعميل الـ API من مواصفة OpenAPI. الأساس الهندسي محترم. المشكلة ليست في "كيف رُتّبت الملفات"، بل في الحماية، وسلامة قاعدة البيانات، والارتباط ببيئة Replit.
الستاك التقني ولغات البرمجة
| الطبقة | التقنية | الإصدار |
|---|---|---|
| اللغة الأساسية | TypeScript | ~5.9 |
| لغات ثانوية | JavaScript (سكربتات وخادم الموبايل) | — |
| بيئة التشغيل | Node.js | 24 |
| مدير الحزم | pnpm (workspaces) | إلزامي |
| الباكاند / API | Express | 5.x |
| قاعدة البيانات | PostgreSQL | 16 |
| طبقة قاعدة البيانات (ORM) | Drizzle ORM | 0.45 |
| التحقق من البيانات | Zod | 3.25 |
| توليد عميل API | Orval (من OpenAPI) | 8.5 |
| بناء الباكاند | esbuild | 0.27 |
| واجهات الويب | React 19 + Vite 7 + Tailwind 4 | — |
| التوجيه (Routing) | wouter / react-router-dom | — |
| مكونات الواجهة | Radix UI + shadcn | — |
| الموبايل | Expo ~54 + React Native 0.81 + expo-router | — |
| السجلّات (Logging) | pino + pino-http | — |
| تخزين الملفات | Google Cloud Storage عبر وسيط Replit | 7.19 |
| رفع الملفات (واجهة) | Uppy | — |
المشكلة الجوهرية — التعارض بين قاعدة البيانات والباكاند
أثناء الفحص، رصدنا عدداً من المشاكل البنيوية الحقيقية التي تجعل الاستمرار على المشروع الحالي مكلفاً أكثر من إعادة بنائه. وهذا تفصيلها ليرى الشركاء حجم العمل الفعلي:
٤.١ غياب نظام الترحيل (Migrations) لقاعدة البيانات
المشروع لا يحتوي على نظام Migrations منظّم. مزامنة المخطط (Schema) تتم عبر أمر drizzle-kit push المباشر فقط. هذا الأسلوب مقبول للتجربة، لكنه خطير جداً في الإنتاج — أي تعديل على بنية الجداول قد يؤدي إلى فقدان بيانات أو تعارضات بدون سجلّ يمكن التراجع عنه.
٤.٢ روابط مفقودة بين الجداول (Foreign Keys)
جداول جوهرية مثل المنيو (menu_categories, menu_items) والطلبات (orders) مربوطة بالمطاعم عبر رقم merchant_id بدون رابط رسمي (Foreign Key). النتيجة: قاعدة البيانات لا تحمي ترابط البيانات — يمكن نظرياً وجود منيو لمطعم محذوف، أو طلب لعنصر غير موجود.
٤.٣ تعارض طبقة الباكاند مع طبقة البيانات في التشغيل المحلي
الواجهات تنادي الـ API عبر روابط نسبية (/api/...)، لكن لا يوجد جسر (Proxy) يربط الواجهة بالخادم خارج بيئة Replit. عملياً، بمجرد تحميل المشروع على أجهزتنا، الواجهة لا تستطيع التحدث إلى الباكاند، والباكاند يتصل بقاعدة بيانات Replit الخاصة — أي أن الطبقتين كانتا مرتبطتين ببيئة Replit وليس ببعضهما بشكل مستقل. هذا هو "التعارض" الذي واجهناه فور التحميل.
٤.٤ ضخامة وتشابك منطق الباكاند
ملف واحد في لوحة التحكم (dashboard.ts) يتجاوز 1200 سطراً ويخلط مسؤوليات متعددة (مصادقة + مطاعم + مستخدمون + منيو + نقاط بيع + OAuth). هذا التشابك يجعل أي تعديل محفوفاً بالمخاطر، ويُبطئ التطوير، ويصعّب الفحص.
٤.٥ إعدادات بناء ميتة / غير دقيقة
وُجدت إعدادات لمكتبات غير مستخدمة فعلياً (مثل firebase-admin المُعرّف كـ external دون استخدام)، وسكربت post-merge.sh يحتوي على خطأ في اسم الحزمة يجعله لا يعمل. مؤشرات على بناء سريع غير مكتمل التدقيق.
هذه ليست أخطاءً سطحية تُصلَّح بساعات. هي مشاكل في الأساس (الحماية، سلامة البيانات، الارتباط بالبيئة). إصلاحها فوق البناء الحالي يعني إعادة كتابة معظمه على أي حال — ولذلك القرار الأنسب هندسياً ومالياً هو إعادة البناء النظيف مع الاحتفاظ بالتصميم.
الحماية — لماذا Replit والمشروع الحالي غير آمنين
هذا أهم قسم في التقرير، ويوضّح للشركاء لماذا لا يمكن إطلاق المنتج بوضعه الحالي.
٥.١ لا يوجد تحقق فعلي من هوية المستخدم خطر حرج
الباكاند يثق بأي رقم مستخدم (userId) يصله من المتصفح دون إثبات هوية. عملياً، يمكن لأي شخص تغيير الرقم في الطلب و:
- كتابة تقييمات باسم مستخدم آخر
- تعديل ملف أي مستخدم
- الاطّلاع على بيانات لا تخصّه
أي أن "تسجيل الدخول" الحالي شكليّ، ولا توجد جلسات (Sessions) أو رموز (Tokens) حقيقية تحمي المستخدمين.
٥.٢ نظام رمز التحقق (OTP) غير مكتمل خطر حرج
ميزة إرسال الرسائل النصية لم تُنفَّذ أصلاً. رمز التحقق يُعاد داخل رد الـ API نفسه (_devCode)، أي أن التحقق لا يتحقق من شيء. لا يمكن إطلاق المنتج للمستخدمين بهذا الوضع إطلاقاً.
٥.٣ كلمة سر ثابتة لإنشاء حساب أدمن خطر حرج
يوجد مسار مكشوف لإنشاء حساب أدمن محمي بكلمة سر ثابتة مكتوبة داخل الكود (MYZ-SETUP-2026). أي شخص يكتشفها يستطيع منح نفسه صلاحيات أدمن كاملة.
٥.٤ إعدادات أمنية أخرى ضعيفة متوسط
- CORS مفتوح بالكامل بدون قيود على المصادر.
- جلسات الأدمن تُحفظ بطريقة معرّضة لسرقتها عبر هجمات XSS (لا تستخدم httpOnly cookies).
٥.٥ لماذا بيئة Replit نفسها غير مناسبة للإنتاج
بصرف النظر عن الكود، بيئة Replit مصممة للتطوير السريع والتجربة، لا للإنتاج الجاد، وذلك للأسباب التالية:
- ارتباط بخدمات Replit الداخلية: تخزين الصور يعتمد على وسيط (Sidecar) يعمل داخل Replit فقط على عنوان داخلي (
127.0.0.1:1106). بمجرد الخروج من Replit، يتعطّل رفع الصور وعرضها بالكامل. - روابط المصادقة مربوطة بـ Replit: تسجيل الدخول عبر Google و Microsoft يعتمد على نطاقات Replit (
REPLIT_DOMAINS) ولا يعمل على نطاقنا الخاص دون إعادة إعداد. - عدم التحكم في البنية التحتية: لا تحكم كامل في الشبكة، الجدار الناري، النسخ الاحتياطي، أو سياسات الوصول لقاعدة البيانات — وكلها متطلبات أساسية لحماية بيانات المستخدمين.
- عدم ملاءمة للامتثال والخصوصية: بيانات المستخدمين الحقيقية (أرقام هواتف، عناوين، طلبات) تتطلب بيئة نتحكم في أمنها ونسخها الاحتياطية.
لهذه الأسباب مجتمعة، قرارنا هو الانتقال إلى بنية تحتية نتحكم بها بالكامل، وإعادة بناء الحماية من الصفر وفق ممارسات الإنتاج المعتمدة.
قواعد البيانات — البنية الحالية وكيف ستُعاد
٦.١ الجداول الموجودة حالياً
| المجموعة | الجداول |
|---|---|
| المستخدمون والمصادقة | users, otp_codes, admin_users |
| المطاعم والأماكن | places, place_photos |
| التقييمات | reviews, review_replies, review_helpful_votes |
| تفاعل المستخدم | user_favorites, user_addresses, user_gamification |
| المنيو والطلبات | menu_categories, menu_items, merchant_menu_settings, orders, order_items |
| التجار | merchant_requests |
| المحتوى والتسويق | blog_posts, banners, discounts, notifications |
البنية المنطقية للجداول معقولة ومدروسة، وسنستفيد منها كمرجع. لكن سنعيد بناءها على أساس سليم يعالج النواقص:
٦.٢ ما الذي سيتغيّر في إعادة البناء
- إضافة Migrations منظّمة — كل تغيير في المخطط مُسجّل وقابل للتراجع.
- فرض الروابط بين الجداول (Foreign Keys) خصوصاً المنيو والطلبات مع المطاعم — لحماية سلامة البيانات.
- فصل واضح للصلاحيات بين المستخدم العادي، التاجر، والأدمن على مستوى قاعدة البيانات والباكاند معاً.
- سياسة نسخ احتياطي دورية تلقائية.
- فهرسة (Indexing) للاستعلامات المتكررة (البحث عن المطاعم، التقييمات) لضمان الأداء عند النمو.
الـ API والتطبيقات
٧.١ بنية الـ API الحالية (Express)
كل المسارات تحت /api، منظّمة في ملفات حسب الوظيفة:
| المسار | الوظيفة |
|---|---|
| /healthz | فحص صحة الخادم |
| places | المطاعم (إضافة، عرض، مميّز، إحصائيات) |
| reviews | التقييمات والردود ومحرّك التقييم |
| auth | التسجيل والدخول (OTP) والملف الشخصي |
| favorites | المفضلة |
| dashboard | API لوحة التحكم (ضخم — سيُعاد تقسيمه) |
| storage | رفع الملفات والروابط الموقّعة |
| banners / discounts / notifications / addresses / blog-posts / rating | باقي الوظائف |
الـ API موصوف جزئياً بمواصفة OpenAPI، ومنه يُولَّد عميل الواجهة تلقائياً — وهذه نقطة قوة نحتفظ بها ونوسّعها لتغطي كامل المسارات.
٧.٢ التطبيقات وما سيحدث لكل منها
| التطبيق | القرار |
|---|---|
| تطبيق الموبايل | نحتفظ بالتصميم ونحسّنه + إعادة ربط بالباكاند الجديد |
| الواجهة الرئيسية (myz) | نحتفظ بالتصميم ونحسّنه + إعادة الربط |
| لوحة التحكم | إعادة بناء الباكاند خلفها + الحفاظ على التصميم |
| الموقع التسويقي | مراجعة بسيطة |
| mockup-sandbox | أداة داخلية — خارج نطاق الإطلاق |
القرار الاستراتيجي — ماذا نأخذ وماذا نعيد بناءه
KEEP ما سنحتفظ به (عمل عدنان)
التصميم وتجربة المستخدم (UI/UX) للتطبيقات والواجهات — عمل قيّم نبني عليه، مع تحسينات تشمل:
- تصميم تطبيقات الهاتف — تحسين التجربة والمظهر.
- الواجهة الرئيسية للموقع — تحسين الشكل والانسيابية.
REBUILD ما سنعيد بناءه من الصفر
- قاعدة البيانات — بنية سليمة، Migrations، وروابط محمية.
- الباكاند (API) — مفصّل ومنظّم وآمن.
- طبقة الحماية — مصادقة حقيقية، جلسات/رموز، صلاحيات، OTP فعلي.
- البنية التحتية والنشر — خارج Replit، على أمازون.
- الخدمات الخارجية — تخزين حقيقي، SMS للأرقام العراقية، OAuth على نطاقنا.
نحتفظ بالواجهة الجميلة، ونعيد بناء كل ما تحتها على أساس آمن وقابل للنمو.
الاستضافة والنشر (Deployment) على أمازون
بناءً على اقتراح رحمة وموافقة الفريق بالكامل، اعتُمدت خدمات أمازون السحابية (Amazon Web Services – AWS) كبيئة استضافة ونشر رسمية لمشروع ميز بعد الخروج من Replit.
لماذا أمازون (AWS) خيار سليم
- بيئة إنتاج حقيقية نتحكم فيها بالكامل (شبكة، جدار ناري، صلاحيات، نسخ احتياطي) — عكس بيئة Replit المشتركة.
- قاعدة بيانات مُدارة عبر Amazon RDS (PostgreSQL) مع نسخ احتياطي تلقائي.
- تخزين ملفات حقيقي عبر Amazon S3 — يحل مشكلة تعطّل رفع الصور خارج Replit.
- قابلية التوسّع مع نمو عدد المستخدمين دون إعادة بناء.
- أمان ومعايير امتثال على مستوى المؤسسات.
المكوّنات المتوقّعة على أمازون
| الخدمة | الاستخدام في ميز |
|---|---|
| Amazon RDS (PostgreSQL) | قاعدة البيانات الأساسية |
| Amazon S3 | تخزين الصور والملفات (بدل وسيط Replit) |
| EC2 / ECS / App Runner | تشغيل خادم الباكاند (API) |
| CloudFront | تسريع توزيع الواجهات والملفات |
| Route 53 | إدارة النطاق (Domain) |
| IAM | إدارة الصلاحيات والمفاتيح بأمان |
آلية إنشاء الحساب وإدارته — قراران أمام الفريق
يجب حسم مسؤولية حساب أمازون قبل بدء مرحلة البنية التحتية. أمامنا خياران:
يقوم عضو من الفريق بفتح حساب AWS (يتطلب بطاقة دفع وبيانات تفعيل)، ثم يمنحني صلاحيات الوصول التقني اللازمة (IAM) للعمل على البنية التحتية والنشر. يبقى الحساب وإدارته المالية تحت الفريق، وأتولّى أنا الجانب التقني فقط.
أتولّى كل شيء من البداية حتى النهاية: البرمجة، إعداد حساب أمازون وإدارته، تجهيز البنية التحتية، الربط على أمازون، حتى الإطلاق الرسمي. يكون لي التحكم الكامل في البيئة التقنية، على أن تُعتمد آلية واضحة لتغطية التكاليف الشهرية للخدمات.
لتسريع العمل وتجنّب تشتّت الصلاحيات خلال فترة الـ 6 أسابيع الضيّقة، الخيار الثاني (إسناد المهمة كاملة لي) هو الأنسب — يوحّد المسؤولية التقنية في يد واحدة ويمنع التأخير الناتج عن انتظار صلاحيات أو إعدادات من أطراف متعددة. يبقى القرار للفريق، لكن يجب حسمه خلال الأسبوع الأول.
ملاحظة مالية: أياً كان الخيار، استخدام أمازون يترتب عليه تكلفة تشغيل شهرية (قاعدة بيانات، خوادم، تخزين، نطاق). يُنصح باعتماد ميزانية تشغيل تقديرية قبل الأسبوع الثالث.
خطة العمل والجدول الزمني (حتى 1 يوليو)
نحن الآن في مرحلة إعادة بناء قواعد البيانات والبنية التحتية — وهي حجر الأساس الذي يُبنى عليه كل ما بعده.
آلية العمل
العمل يسير على مراحل متسلسلة ومترابطة: لا ننتقل لمرحلة قبل استقرار التي قبلها، لأن كل طبقة تعتمد على ما تحتها. الفحص جزء من كل مرحلة وليس مرحلة منفصلة في النهاية فقط.
الجدول الزمني التفصيلي
مراحل العمل بالترتيب (من البداية حتى الفحص)
- البنية التحتية (AWS): حسم حساب أمازون، تجهيز الاستضافة، الشبكة، الجدار الناري، الـ SSL، والنطاق.
- قاعدة البيانات: المخطط + Migrations + الروابط + النسخ الاحتياطي + الفهرسة.
- الباكاند: إعادة بناء الـ API مفصّلاً ونظيفاً.
- الحماية: المصادقة، الجلسات، الصلاحيات، تأمين كل المسارات.
- الخدمات الخارجية: SMS، التخزين، OAuth.
- ربط الواجهات: الموقع + لوحة التحكم بالباكاند الجديد.
- الموبايل: الربط + تحسين التصميم + بناء النسخ للمتاجر.
- الفحص: أمني + وظيفي + أداء + تجربة مستخدم.
- الإطلاق + المراقبة بعد الإطلاق.
المدة المتاحة (~6 أسابيع) ضيّقة لإعادة بناء بهذا الحجم. الالتزام بموعد 1 يوليو ممكن بشرطين:
- تثبيت النطاق (Scope Freeze): لا مزايا جديدة تُضاف خلال الفترة؛ أي ميزة إضافية تُجدول لما بعد الإطلاق.
- تحديد نطاق الإطلاق الأدنى (MVP): نُطلق المزايا الأساسية (اكتشاف المطاعم، التقييمات، المنيو، المصادقة الآمنة) أولاً، ونؤجّل الثانوية (نقاط البيع المتقدمة، الجيمفكيشن) لتحديثات لاحقة.
أوصي بمراجعة هذا النطاق مع الشركاء واعتماده مكتوباً قبل بدء الأسبوع الثاني.
المخاطر والتوصيات
| الخطر | التأثير | التوصية |
|---|---|---|
| ضيق الوقت | تأخّر الإطلاق أو إطلاق ناقص | تثبيت النطاق + اعتماد MVP واضح |
| إضافة مزايا أثناء البناء | تشتت وتأخّر | تجميد النطاق رسمياً |
| تكاليف التشغيل (أمازون + SMS) | تكلفة شهرية متكررة | اعتماد ميزانية تشغيل وحسم مسؤولية الحساب قبل الأسبوع الثالث |
| الاعتماد على شخص تقني واحد | عنق زجاجة (Bottleneck) | تحديد الأولويات ومراجعات أسبوعية |
الخلاصة
مشروع ميز يملك أساساً تصميمياً ممتازاً نفّذه عدنان، وفكرة منتج واضحة. لكن الطبقة التقنية تحت التصميم بُنيت للعرض لا للإنتاج، وتحتوي على تعارضات بنيوية وثغرات أمنية، إضافةً إلى ارتباطها ببيئة Replit غير المناسبة للإطلاق الجاد.
قرارنا الفني الواضح: نحتفظ بالتصميم (مع تحسينه)، ونعيد بناء كل ما تحته على أساس آمن ومستقل على أمازون. نحن الآن في مرحلة إعادة بناء البنية التحتية وقواعد البيانات، ونسير وفق خطة من تسع مراحل تستهدف الإطلاق الرسمي في 1 يوليو 2026، بشرط تثبيت النطاق واعتماد نطاق إطلاق أدنى واضح.
هذا الاستثمار في البناء الصحيح الآن يوفّر علينا مشاكل أمنية ومالية وتقنية ضخمة لاحقاً، ويعطي ميز أساساً يتحمّل النمو الحقيقي.