185 lines
5.4 KiB
Markdown
185 lines
5.4 KiB
Markdown
# Flatlogic CI/CD + External DB + Ingestion API
|
|
|
|
هذا الإعداد يجعل المشروع يعمل بهذه الصورة:
|
|
|
|
- **GitHub** هو مصدر الحقيقة للكود.
|
|
- **Bolt / Replit** يدفعان التعديلات إلى نفس المستودع أو يرسلان `repository_dispatch`.
|
|
- **GitHub Actions** تبني المشروع وتتحقق منه ثم تنشره إلى VM الخاص بـ Flatlogic.
|
|
- **Flatlogic / API Server** يدير بيانات المنتجات القادمة من أدوات السحب وويبهوكات شي إن.
|
|
- **Supabase / PostgreSQL** هو مخزن البيانات الخارجي للمنتجات والفئات وسجل أحداث التكامل.
|
|
|
|
## ما تمت إضافته
|
|
|
|
- `.github/workflows/ci.yml`
|
|
- Typecheck + Build لكل Push / Pull Request.
|
|
- `.github/workflows/deploy-flatlogic.yml`
|
|
- ينشر تلقائيًا إلى VM عند التحديث على `main` أو `master`.
|
|
- يدعم `repository_dispatch` لأنواع:
|
|
- `bolt_sync`
|
|
- `replit_sync`
|
|
- `flatlogic_deploy`
|
|
- `scripts/flatlogic-deploy.sh`
|
|
- يسحب آخر نسخة من GitHub.
|
|
- يثبت الحزم.
|
|
- يشغل `typecheck` و `build`.
|
|
- يطبق schema قاعدة البيانات عبر Drizzle.
|
|
- يعيد تشغيل `extra-store` و `flatlogic-api` عبر PM2.
|
|
- `.env.example`
|
|
- كل متغيرات البيئة المطلوبة للـ DB والـ API والأمان.
|
|
- API endpoints جديدة داخل `artifacts/api-server`.
|
|
|
|
## الأسرار المطلوبة في GitHub Actions
|
|
|
|
أضف هذه القيم في **GitHub → Settings → Secrets and variables → Actions**:
|
|
|
|
### أسرار النشر إلى Flatlogic VM
|
|
|
|
- `FLATLOGIC_HOST`
|
|
- `FLATLOGIC_USER`
|
|
- `FLATLOGIC_SSH_KEY`
|
|
- `FLATLOGIC_PROJECT_DIR`
|
|
- `FLATLOGIC_DEPLOY_BRANCH` (اختياري)
|
|
|
|
### أسرار الـ backend
|
|
|
|
- `DATABASE_URL`
|
|
- `DB_SSL` = `require`
|
|
- `DB_POOL_MAX` = `20`
|
|
- `DB_QUERY_TIMEOUT_MS` = `15000`
|
|
- `DB_STATEMENT_TIMEOUT_MS` = `15000`
|
|
- `ADMIN_TOKEN`
|
|
- `API_INGEST_KEY`
|
|
- `WEBHOOK_SECRET`
|
|
- `SHEIN_WEBHOOK_SECRET`
|
|
- `API_PORT` = `8080`
|
|
- `STORE_PORT` = `3001`
|
|
|
|
## إعداد قاعدة البيانات الخارجية (Supabase / PostgreSQL)
|
|
|
|
الحد الأدنى المقترح لاستيعاب 2000 منتج من Extra + Shein:
|
|
|
|
- استخدم **Postgres خارجي** أو **Supabase**.
|
|
- يفضل في Supabase استخدام **transaction pooler** داخل `DATABASE_URL`.
|
|
- الإعدادات الافتراضية المضافة في الكود:
|
|
- `DB_POOL_MAX=20`
|
|
- `DB_QUERY_TIMEOUT_MS=15000`
|
|
- `DB_STATEMENT_TIMEOUT_MS=15000`
|
|
- `keepAlive=true`
|
|
- أضف الـ schema بالأمر:
|
|
|
|
```bash
|
|
pnpm --filter @workspace/db run push
|
|
```
|
|
|
|
> ملاحظة: الجدول `products` صار يدعم الآن `source`, `external_id`, `source_url`, `currency`, `availability`, `metadata`, `last_synced_at` مع فهارس مخصصة للبحث والتزامن.
|
|
|
|
## API Endpoints الجديدة
|
|
|
|
### 1) Bulk ingestion للمنتجات
|
|
|
|
`POST /api/ingest/products/bulk`
|
|
|
|
Headers:
|
|
|
|
```text
|
|
x-api-key: <API_INGEST_KEY>
|
|
content-type: application/json
|
|
```
|
|
|
|
Body مثال:
|
|
|
|
```json
|
|
{
|
|
"source": "shein",
|
|
"webhook_id": "apify-run-123",
|
|
"products": [
|
|
{
|
|
"external_id": "shein-10001",
|
|
"sku": "SKU-10001",
|
|
"name": "فستان صيفي",
|
|
"brand": "SHEIN",
|
|
"price": 149,
|
|
"original_price": 199,
|
|
"stock": 25,
|
|
"availability": "in_stock",
|
|
"sizes": ["S", "M", "L"],
|
|
"colors": ["Black", "Pink"],
|
|
"images": ["https://example.com/1.jpg"],
|
|
"category": {
|
|
"slug": "dresses",
|
|
"name": "فساتين"
|
|
},
|
|
"source_url": "https://example.com/product/10001"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 2) Upsert منتج مفرد
|
|
|
|
`POST /api/ingest/products/upsert`
|
|
|
|
نفس الحماية عبر `x-api-key`.
|
|
|
|
### 3) Webhook تحديثات شي إن
|
|
|
|
`POST /api/webhooks/shein/products`
|
|
|
|
Headers:
|
|
|
|
```text
|
|
x-api-key: <API_INGEST_KEY>
|
|
x-webhook-signature: sha256=<hmac_sha256_of_raw_body>
|
|
content-type: application/json
|
|
```
|
|
|
|
Body مثال:
|
|
|
|
```json
|
|
{
|
|
"webhook_id": "shein-webhook-987",
|
|
"event": "price.updated",
|
|
"products": [
|
|
{
|
|
"external_id": "shein-10001",
|
|
"price": 139,
|
|
"stock": 12,
|
|
"availability": "low_stock",
|
|
"sizes": ["S", "M"]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 4) Pipeline status
|
|
|
|
`GET /api/integrations/pipeline/status`
|
|
|
|
- محمي بـ `Authorization: Bearer <ADMIN_TOKEN>`
|
|
- يعرض:
|
|
- حالة إعداد الأمان
|
|
- حالة الـ DB
|
|
- عدد المنتجات حسب المصدر
|
|
- آخر أحداث التكامل
|
|
|
|
## ربط Bolt / Replit مع GitHub
|
|
|
|
أفضل سيناريو:
|
|
|
|
1. اجعل **Bolt** أو **Replit** يدفعان إلى نفس مستودع GitHub.
|
|
2. كل Push إلى `main` يشغل:
|
|
- `ci.yml`
|
|
- ثم `deploy-flatlogic.yml`
|
|
3. النتيجة: يتم تحديث الموقع والـ backend تلقائيًا.
|
|
|
|
إذا كانت الأداة لا تدفع مباشرة إلى GitHub، استخدم `repository_dispatch` من GitHub API بنوع:
|
|
|
|
- `bolt_sync`
|
|
- `replit_sync`
|
|
|
|
## ملاحظات تشغيلية
|
|
|
|
- الواجهة الأمامية الآن تدعم `VITE_API_BASE_URL` إذا أردت backend مختلفًا عن نفس الدومين.
|
|
- في وضع التطوير، Vite يمرر `/api` إلى `http://127.0.0.1:8080` عبر proxy.
|
|
- إذا لم تكن أسرار الـ backend موجودة، فسيستمر المتجر الأمامي بالعمل، لكن تشغيل خدمة الـ API سيتم تخطيه أثناء النشر.
|