منظومة Oikosmou — دليل النشر الكامل

كل ما تحتاجه لتنزيل النظام من GitHub وتشغيله محلياً، ثم استضافته على الإنترنت — بما في ذلك قاعدة البيانات، تهيئة الواجهة (Webhost)، والمفاتيح السرّية، مع أفضل ٣ حلول استضافة مجانية وخطوات النقل التفصيلية لكلٍّ منها.

FastAPI + PostgreSQL 16 Flutter User App Flutter Web Admin Landing PWA JWT + Google OAuth Web Push + FCM 3 لغات (EL / EN / AR)

١. نظرة عامة على النظام

تتكوّن منظومة Oikosmou من أربعة مكوّنات تتواصل عبر REST API واحد:

المكوّنالتقنيةالمجلدالدور
الخادم الخلفي (Backend)Python · FastAPI · SQLAlchemyoikosmou_backend/الـ API وقاعدة البيانات والمصادقة والإشعارات والبريد
تطبيق المستخدمFlutter (Android/iOS/Web)oikosmou_app/تجربة الألوان، الحاسبة، المتاجر، الطلبات، المكافآت
لوحة الإدارةFlutter Weboikosmou_admin/إدارة المحتوى والمستخدمين والطلبات والتقارير
الحزمة المشتركةDart Packageoikosmou_shared/نماذج DTO و enums و validators مشتركة
صفحة الهبوطHTML/JS · PWAlanding/صفحة تعريفية + Web Push + تنزيل APK
قاعدة البياناتPostgreSQL 16database/نسخة SQL كاملة جاهزة للاستعادة (٢١ جدول)
# تدفّق البيانات
User App  ─┐
           ├──►  FastAPI Backend  ──►  PostgreSQL 16
Admin Web ─┘            │
Landing PWA ───────────►┘   (REST/HTTPS + JWT)

٢. المتطلبات الأساسية

الأداةالإصدارلازمة لـ
Git≥ 2.30تنزيل المشروع
Docker + Docker ComposeDocker ≥ 24 / Compose ≥ 2.20قاعدة البيانات (الأسهل)
Python3.11 أو 3.12تشغيل الـ Backend
PostgreSQL16قاعدة البيانات (بديل Docker)
Flutter SDK≥ 3.19 (Dart ≥ 3.3)بناء التطبيق ولوحة الإدارة
لتشغيل الـ Backend + قاعدة البيانات + لوحة الإدارة (الويب) فقط، تحتاج Docker و Python و Flutter. تطبيق الموبايل (APK) جاهز مسبقاً في downloads/ ولا يلزمك Android Studio إلا لإعادة بنائه.

٣. التنزيل من GitHub

# استنساخ المستودع
git clone git@github.com:bodoorzahera/oikosmou.git
# أو عبر HTTPS
git clone https://github.com/bodoorzahera/oikosmou.git
cd oikosmou

بنية المجلدات بعد الاستنساخ:

oikosmou/
├── oikosmou_backend/     # FastAPI + Alembic + Docker
├── oikosmou_app/         # تطبيق المستخدم Flutter
├── oikosmou_admin/       # لوحة الإدارة Flutter Web
├── oikosmou_shared/      # الحزمة المشتركة Dart
├── landing/              # صفحة الهبوط PWA
├── database/             # ← نسخة SQL كاملة (schema + بيانات)
├── downloads/            # APK جاهز للتثبيت
├── deploy.html           # ← هذا الملف
└── Features.html         # صفحة الميزات الدعائية

٤. قاعدة البيانات

النظام يأتي مع نسخة قاعدة بيانات كاملة في مجلد database/ (٢٠٦ لون، ٢٠ منتج، ٥ متاجر، عروض، تصاميم، وحسابات تجريبية). لديك طريقتان:

الطريقة أ — Docker (الأسرع، موصى بها)

cd oikosmou_backend
docker compose up -d            # PostgreSQL 16 على المنفذ 5433
# انتظر حتى تصبح الحاوية healthy، ثم استعِد البيانات:
cat ../database/oikosmou_full.sql | docker compose exec -T db psql -U oikosmou -d oikosmou

الطريقة ب — توليد البيانات من الصفر عبر Alembic + Seed

cd oikosmou_backend
source venv/bin/activate
alembic upgrade head                 # إنشاء كل الجداول (٢١ جدول)
python -m app.scripts.seed_data      # تعبئة البيانات التجريبية
المعطىالقيمة الافتراضية
Host / Portlocalhost : 5433 (Docker) — تأكد أن .env يطابقه
Databaseoikosmou
User / Passwordoikosmou / oikosmou_dev_2024
Admin loginadmin@oikosmou.gr / admin123456
تفاصيل الاستعادة الكاملة وملف المخطط المنفصل في database/README.md.

٥. الخادم الخلفي (Backend)

cd oikosmou_backend

# 1) بيئة افتراضية وتثبيت المكتبات
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

# 2) إعداد متغيّرات البيئة (موجود مسبقاً في .env)
#    عدّل DATABASE_URL والمفاتيح حسب الحاجة — انظر القسم ٧

# 3) تشغيل الخادم (تطوير)
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

# 4) أو للإنتاج (متعدّد العمّال)
gunicorn app.main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
تحقّق: افتح http://localhost:8000/docs لرؤية توثيق Swagger التفاعلي لكل الـ endpoints.

٦. الواجهات (Frontend)

لوحة الإدارة (Flutter Web)

cd oikosmou_admin
flutter pub get
# التشغيل للتطوير:
flutter run -d chrome
# أو بناء نسخة ويب للنشر:
flutter build web --release       # الناتج في build/web/

تطبيق المستخدم (Flutter)

cd oikosmou_app
flutter pub get
flutter run                       # على جهاز/محاكي
flutter build apk --release       # بناء APK
# APK جاهز أيضاً في: downloads/oikosmou-latest.apk

صفحة الهبوط (Landing)

# مجلد ثابت static — يُرفع كما هو على أي استضافة ويب
cd landing
python3 -m http.server 8080       # معاينة محلية
مهمّ — عنوان الـ API: قبل بناء الواجهات للإنتاج، غيّر baseUrl ليشير لعنوان خادمك:
  • oikosmou_app/lib/core/constants/api_constants.dart
  • oikosmou_admin/lib/core/constants/api_constants.dart

٧. متغيّرات البيئة والمفاتيح

كل إعدادات الـ Backend في oikosmou_backend/.env. أهمّ المفاتيح:

المتغيّرالوصفإلزامي؟
DATABASE_URLرابط PostgreSQL (asyncpg)نعم
SECRET_KEYمفتاح توقيع JWT — غيّره في الإنتاجنعم
ACCESS_TOKEN_EXPIRE_MINUTESعمر توكن الدخولافتراضي 30
CORS_ORIGINSقائمة النطاقات المسموح لها بالاتصالنعم
SMTP_*إرسال البريد/النشرة البريدية (Gmail App Password)للبريد
VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEYإشعارات Web Push للمتصفحللإشعارات
FCM_SERVER_KEY + firebase-service-account.jsonإشعارات الموبايل عبر Firebaseللموبايل
GOOGLE_CLIENT_ID / SECRET / REDIRECT_URIتسجيل الدخول عبر Googleلـ OAuth

توليد مفاتيح VAPID لإشعارات الويب

cd oikosmou_backend && source venv/bin/activate
python -c "from py_vapid import Vapid01; v=Vapid01(); v.generate_keys(); print(v)"
# أو استخدم vapid_keys.json الموجود ثم انسخ المفاتيح إلى .env

مفتاح SECRET_KEY عشوائي للإنتاج

python -c "import secrets; print(secrets.token_urlsafe(48))"
تحذير أمني: ملف .env وfirebase-service-account.json يحتويان أسراراً حقيقية. هذا المستودع خاص (private). إن جعلته عاماً يوماً ما، أزِل هذه الملفات من التتبّع أولاً (git rm --cached) وبدّل كل المفاتيح المسرّبة.

٨. أفضل ٣ حلول استضافة مجانية

النظام يحتاج ٣ أشياء على الإنترنت: (أ) خادم Python للـ API، (ب) قاعدة PostgreSQL، (ج) استضافة ملفات ثابتة للوحة الإدارة وصفحة الهبوط. الحلول الثلاثة التالية توفّر ذلك مجاناً بالكامل:

مجاني

الحل ١ · Render + Neon

الأسهل للمبتدئين. Backend على Render Free، قاعدة بيانات على Neon (Postgres مجاني سخي)، الواجهة على Netlify.

مجاني

الحل ٢ · Railway المتكامل

كل شيء في منصّة واحدة (Backend + Postgres) برصيد مجاني شهري، والواجهة على Cloudflare Pages.

مجاني

الحل ٣ · Fly.io + Supabase

الأقوى أداءً. حاويات Docker على Fly.io، Postgres على Supabase، الواجهة على GitHub Pages.

الحل ١ — Render + Neon + Netlify

المكوّنالمنصّةالباقة المجانية
Backend APIRender Web Service٧٥٠ ساعة/شهر (ينام بعد ١٥ دقيقة خمول)
قاعدة البياناتNeon٠.٥ GB تخزين + فرع واحد دائم
لوحة الإدارة + LandingNetlify١٠٠ GB نقل/شهر

الخطوات

١) إنشاء قاعدة البيانات على Neon

# 1. أنشئ حساباً على neon.tech ومشروعاً جديداً (اختر منطقة قريبة)
# 2. انسخ Connection String، ثم استعِد البيانات:
psql "postgresql://USER:PASS@ep-xxx.neon.tech/oikosmou?sslmode=require" \
     -f database/oikosmou_full.sql

٢) نشر الـ Backend على Render

أنشئ Web Service جديداً واربطه بمستودع GitHub، أو استخدم ملف render.yaml. الإعدادات:

Root Directory : oikosmou_backend
Build Command  : pip install -r requirements.txt
Start Command  : gunicorn app.main:app -w 2 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:$PORT

أضف متغيّرات البيئة في لوحة Render → Environment:

DATABASE_URL = postgresql+asyncpg://USER:PASS@ep-xxx.neon.tech/oikosmou?ssl=require
SECRET_KEY   = <مفتاح عشوائي 48 حرف>
CORS_ORIGINS = ["https://YOUR-ADMIN.netlify.app","https://YOUR-LANDING.netlify.app"]
SMTP_HOST=smtp.gmail.com  SMTP_PORT=587  SMTP_USER=...  SMTP_PASSWORD=...
لاحظ تحويل رابط Neon إلى صيغة asyncpg: استبدل postgresql:// بـ postgresql+asyncpg:// واستخدم ?ssl=require.

٣) نشر لوحة الإدارة + Landing على Netlify

# عدّل baseUrl في api_constants.dart ليشير لرابط Render، ثم:
cd oikosmou_admin && flutter build web --release
# اسحب مجلد build/web إلى Netlify Drop (app.netlify.com/drop)
# أو عبر CLI:
npx netlify-cli deploy --dir=build/web --prod
# كرّر نفس الشيء لمجلد landing/
النتيجة: API على https://oikosmou.onrender.com + لوحة إدارة على https://oikosmou-admin.netlify.app — مجاناً بالكامل.

الحل ٢ — Railway (متكامل) + Cloudflare Pages

المكوّنالمنصّةالباقة المجانية
Backend + DatabaseRailway$5 رصيد/شهر (يكفي مشروعاً صغيراً) — Postgres مُدار بنقرة
لوحة الإدارة + LandingCloudflare Pagesغير محدود تقريباً + CDN عالمي

١) المشروع وقاعدة البيانات

# على railway.app أنشئ مشروعاً جديداً ثم:
# New → Database → Add PostgreSQL  (يُنشئ DATABASE_URL تلقائياً)
# استعِد البيانات عبر رابط الاتصال العام:
psql "$RAILWAY_DATABASE_PUBLIC_URL" -f database/oikosmou_full.sql

٢) نشر الـ Backend

Railway يكتشف Dockerfile الموجود في oikosmou_backend/ تلقائياً.

Root Directory : oikosmou_backend
# Railway يبني من Dockerfile مباشرة. أضف المتغيّرات:
DATABASE_URL = ${{Postgres.DATABASE_URL}}   # مرجع داخلي + حوّله لصيغة asyncpg
SECRET_KEY   = <مفتاح عشوائي>
PORT         = 8000
عدّل CMD في الـ Dockerfile للإنتاج إلى gunicorn بدل uvicorn --reload، أو اضبط Start Command في Railway.

٣) نشر الواجهة على Cloudflare Pages

cd oikosmou_admin && flutter build web --release
npx wrangler pages deploy build/web --project-name=oikosmou-admin
# و landing/ بنفس الطريقة

الحل ٣ — Fly.io + Supabase + GitHub Pages

المكوّنالمنصّةالباقة المجانية
Backend (Docker)Fly.ioحتى ٣ آلات صغيرة مشتركة + لا ينام
قاعدة البياناتSupabase٥٠٠ MB Postgres + لوحة تحكّم غنية
لوحة الإدارة + LandingGitHub Pagesمجاني للمستودعات

١) قاعدة البيانات على Supabase

# أنشئ مشروعاً على supabase.com، ثم من Settings → Database انسخ الرابط:
psql "postgresql://postgres:PASS@db.xxx.supabase.co:5432/postgres" \
     -f database/oikosmou_full.sql

٢) نشر الـ Backend على Fly.io

مهمّ: شغّل أوامر Fly من داخل مجلد oikosmou_backend/ حيث يوجد الـ Dockerfile وfly.toml — وإلا سيظهر الخطأ Could not find a Dockerfile.

curl -L https://fly.io/install.sh | sh      # تثبيت flyctl
cd oikosmou_backend                          # ← لازم: هنا يوجد Dockerfile و fly.toml
fly launch --no-deploy --copy-config         # يستخدم fly.toml الجاهز بدل إعادة الكشف
fly secrets set DATABASE_URL="postgresql+asyncpg://postgres:PASS@db.xxx.supabase.co:5432/postgres" \
                SECRET_KEY="<عشوائي>"
fly deploy
إن نُفّذ الأمر من جذر المشروع يفشل الكشف لأن الـ Dockerfile داخل مجلد فرعي. المستودع يحوي oikosmou_backend/fly.toml جاهزاً (المنفذ الداخلي 8080، HTTPS إجباري). الـ Dockerfile يعمل في الإنتاج عبر gunicorn ويحترم $PORT تلقائياً.

٣) نشر الواجهة على GitHub Pages

cd oikosmou_admin
flutter build web --release --base-href /oikosmou-admin/
# ادفع محتوى build/web إلى فرع gh-pages في مستودع منفصل:
cd build/web && git init && git add -A && git commit -m "deploy"
git branch -M gh-pages
git remote add origin git@github.com:bodoorzahera/oikosmou-admin.git
git push -f origin gh-pages
# فعّل Pages من Settings → Pages → Branch: gh-pages

٩. تهيئة استضافة الواجهة (Webhost) — تفاصيل مهمّة

لوحة الإدارة وتطبيق الويب من نوع SPA (تطبيق صفحة واحدة) تستخدم توجيهاً داخلياً عبر GoRouter. أي استضافة ثابتة تحتاج إعداداً ليعمل التحديث (refresh) على المسارات الفرعية:

Netlify — ملف _redirects داخل build/web/

/*    /index.html   200

Vercel — ملف vercel.json

{ "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }] }

Apache — ملف .htaccess

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

Nginx

server {
  listen 80;
  root /var/www/oikosmou_admin;     # محتوى build/web
  index index.html;
  location / { try_files $uri $uri/ /index.html; }
  location /api/ { proxy_pass http://127.0.0.1:8000; }   # وكيل للـ API (اختياري)
}
٣ أمور لا تنسها عند نشر الواجهة:
  1. baseUrl: عدّل api_constants.dart ليشير لرابط الـ API الإنتاجي (https) قبل flutter build web.
  2. CORS: أضف نطاق الواجهة إلى CORS_ORIGINS في .env على الخادم، وإلا ستُرفض الطلبات.
  3. base-href: إن نُشرت في مجلد فرعي (مثل GitHub Pages) استخدم --base-href /اسم-المجلد/.

إشعارات الويب (Service Worker) لصفحة الهبوط

صفحة landing/ تتضمّن sw.js وmanifest.json لإشعارات Web Push. يجب أن تُخدَّم عبر HTTPS (كل المنصّات أعلاه توفّره مجاناً) ليعمل الـ Service Worker.

١٠. قائمة تحقّق الإنتاج

البند
تغيير SECRET_KEY إلى قيمة عشوائية طويلة
تعيين DATABASE_URL لقاعدة الإنتاج (مع +asyncpg و SSL)
استعادة database/oikosmou_full.sql على قاعدة الإنتاج
ضبط CORS_ORIGINS على نطاقات الواجهة الحقيقية (أزل *)
تحديث baseUrl في تطبيق المستخدم ولوحة الإدارة
استبدال gunicorn بـ uvicorn --reload في الإنتاج
تحديث GOOGLE_REDIRECT_URI ونطاقات OAuth المعتمدة في Google Console
تفعيل النسخ الاحتياطي التلقائي لقاعدة البيانات
التأكد من HTTPS لكل النطاقات (لازم لإشعارات Web Push)

١١. حلّ المشاكل الشائعة

المشكلةالحل
الواجهة لا تتصل بالـ API (CORS error)أضف نطاق الواجهة إلى CORS_ORIGINS وأعد تشغيل الخادم
refresh على مسار فرعي يعطي 404أضف قاعدة إعادة التوجيه (القسم ٩) حسب منصّتك
asyncpg يرفض الاتصال SSLأضف ?ssl=require لرابط Neon/Supabase
الخادم المجاني ينام (Render)طبيعي بعد ١٥د خمول — أول طلب يستغرق ~٣٠ث للإيقاظ، أو استخدم Fly.io
DuplicateObject: type already exists عند الترحيلالقاعدة مُهيّأة مسبقاً — استخدم الاستعادة من SQL بدل alembic upgrade
إشعارات الويب لا تعملتأكد من HTTPS وصحّة مفاتيح VAPID في .env
تطبيق Flutter web يظهر أبيضتأكد من --base-href الصحيح عند النشر في مجلد فرعي