- README rewritten for the real Next.js + Payload + Postgres stack (old one described the dead static prototype) - Logo + 4 live screenshots (home, articles, post, subscription) - Arabic flow explanations with mermaid diagrams: visitor journey, content pipeline, request path - Architecture table, quick start, API reference, security summary, deploy commands - AGENT.md: orientation for future AI agents (data model, trust rules, rate limits, routes, env, deploy, house rules) - GLOSSARY.md and docs/adr committed (linked from README)
181 lines
9.3 KiB
Markdown
181 lines
9.3 KiB
Markdown
<div align="center">
|
||
|
||
<img src="web/public/brand/icon-256.png" alt="شعار أنور بي آي" width="120"/>
|
||
|
||
# أنور بي آي — AnwarPi
|
||
|
||
**محتوى عربي عملي لتعلّم الذكاء الاصطناعي، بلا ضجيج.**
|
||
|
||
Arabic-first platform for learning AI: free guides, VIP deep-dives, a searchable library, and moderated community — built with **Next.js 15 + Payload 3 + PostgreSQL** behind Traefik.
|
||
|
||
**[anwarpy.ai](https://anwarpy.ai)** · [دليل الوكيل الآلي (AGENT.md)](AGENT.md) · [مسرد المصطلحات](GLOSSARY.md) · [قرارات التصميم](docs/adr)
|
||
|
||
</div>
|
||
|
||
---
|
||
|
||
## 🖼️ لقطات من الموقع
|
||
|
||
<table>
|
||
<tr>
|
||
<td align="center"><strong>الصفحة الرئيسية</strong></td>
|
||
<td align="center"><strong>المكتبة</strong></td>
|
||
</tr>
|
||
<tr>
|
||
<td><img src="docs/screenshots/home.png" alt="الصفحة الرئيسية — أنور بي آي" width="470"/></td>
|
||
<td><img src="docs/screenshots/articles.png" alt="المكتبة — أنور بي آي" width="470"/></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><strong>صفحة دليل</strong></td>
|
||
<td align="center"><strong>العضوية</strong></td>
|
||
</tr>
|
||
<tr>
|
||
<td><img src="docs/screenshots/post.png" alt="صفحة دليل — أنور بي آي" width="470"/></td>
|
||
<td><img src="docs/screenshots/subscription.png" alt="العضوية — أنور بي آي" width="470"/></td>
|
||
</tr>
|
||
</table>
|
||
|
||
## ما هو أنور بي آي؟
|
||
|
||
منصة عربية لتعلّم الذكاء الاصطناعي بشكل عملي: أدلة مجانية للجميع، وأدلة متعمقة لأعضاء **VIP**، ومكتبة قابلة للبحث والتصفية، وتعليقات مُراقَّبة، ومسارات تعلّم (كتالوج). الواجهة عربية بالكامل (RTL) وتعمل على الهاتف واللوحي وسطح المكتب.
|
||
|
||
## ✨ المميزات
|
||
|
||
- 📚 **المكتبة** — كل الأدلة مع بحث وتصفية حسب التصنيف (وكلاء، نماذج، استرجاع، سلامة، أدوات، أعمال).
|
||
- 🔓 **بوابة محتوى** — الأدلة المجانية كاملة؛ أدلة VIP تظهر بمعاينة مقفلة حتى يصبح القارئ مشتركًا.
|
||
- 👤 **حسابات** — تسجيل، دخول، استعادة كلمة المرور، تحقق البريد، وإعدادات حساب كاملة.
|
||
- 💬 **تعليقات مُراقَّبة** — دورة حياة `pending → approved`؛ يظهر العلني المعتمَد فقط.
|
||
- 🗺️ **الكتالوج والمسارات** — رحلة تعلّم مرتّبة حسب المستوى (مبتدئ/متوسط/متقدم).
|
||
- 🤖 **نشر آلي** — API للوكلاء الخارجيين (`/api/agent/posts` بمفتاح `x-agent-key`) لنشر الأدلة من خط إدارة المحتوى.
|
||
- 💳 **عضوية VIP** — Stripe جاهز؛ حتى تفعيل المفاتيح يعمل زر الاشتراك بوضع «قريبًا».
|
||
- 🌓 **هوية بصرية داكنة** — أشعة فضية ولمسة سماوية؛ انظر `brand-spec.md`.
|
||
|
||
## 🔄 كيف يعمل الموقع؟ (شرح التدفق)
|
||
|
||
### تدفق الزائر
|
||
|
||
```mermaid
|
||
flowchart RL
|
||
Z[الزائر] --> A[الصفحة الرئيسية]
|
||
A --> B[المكتبة / الكتالوج]
|
||
B --> C{نوع الدليل؟}
|
||
C -->|مجاني| D[قراءة كاملة + إعجاب وتعليق]
|
||
C -->|VIP| E[معاينة مقفلة]
|
||
E --> F[إنشاء حساب / دخول]
|
||
F --> G{مشترك VIP؟}
|
||
G -->|نعم| D
|
||
G -->|لا| H[صفحة العضوية]
|
||
H --> I[تهيئة مشترك VIP جديد]
|
||
I --> D
|
||
```
|
||
|
||
1. **تصفّح** — الزائر يفتح الرئيسية، يتصفح المكتبة أو الكتالوج، ثم يفتح دليلًا.
|
||
2. **قراءة** — الدليل المجاني يُقرأ كاملًا. دليل VIP يظهر جزءًا منه فقط مع طبقة قفل.
|
||
3. **حساب** — التسجيل يمنح دور `free` فقط (الخادم يجبر ذلك؛ طلب العميل لا يستطيع ترقية نفسه). بعد التحقق من البريد يمكن التعليق.
|
||
4. **ترقية** — صفحة العضوية تقود لـ Stripe؛ بعد الدفع الناجح يُفعَّل دور `vip` عبر مسار موثوق من الخادم، ثم معالجة تهيئة VIP الجديد.
|
||
|
||
### تدفق المحتوى (نشر الأدلة)
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
T[مواضيع المالك في AppFlowy] --> P[خط النشر الآلي]
|
||
P -->|POST/PUT مع x-agent-key| A[API الوكلاء]
|
||
A --> V[التحقق والتغطية الافتراضية للغلاف]
|
||
V --> D[(PostgreSQL)]
|
||
D --> S[anwarpy.ai]
|
||
```
|
||
|
||
- يملك المالك قائمة مواضيع؛ يعمل خط النشر FIFO (دليل واحد لكل تشغيل، الاثنين/الأربعاء/الجمعة).
|
||
- كل دليل يُوسم `free` أو `vip`؛ غير الموسوم = مجاني.
|
||
- الأغلفة 1200×630، ولكل تصنيف غلاف افتراضي احتياطي.
|
||
|
||
### تدفق الطلب عبر الخادم
|
||
|
||
```
|
||
المتصفح → Traefik (حدود المعدل: pagelimit / apilimit / connlimit)
|
||
→ Next.js 15 (الصفحات + /api)
|
||
→ Payload 3 (التحكم بالوصول + الخطافات)
|
||
→ PostgreSQL 16
|
||
```
|
||
|
||
## 🏗️ البنية التقنية
|
||
|
||
| الطبقة | التقنية |
|
||
|---|---|
|
||
| الواجهة | Next.js 15 (App Router) + React 19، عربية RTL |
|
||
| لوحة التحكم | Payload 3 (`/admin`) مع محرر Lexical |
|
||
| قاعدة البيانات | PostgreSQL 16 عبر `@payloadcms/db-postgres` |
|
||
| المصادقة | جلسات Payload، تجزئة PBKDF2-SHA256 600k تكرار |
|
||
| الوسيط | `web/src/middleware.ts` — حدود معدل لمسارات المصادقة |
|
||
| الحاوية | Docker Compose + Traefik (TLS + حدود معدل الحافة) |
|
||
| البريد | Cloudflare (توجيه + إرسال REST) |
|
||
| المدفوعات | Stripe (جاهز، بوضع «قريبًا» حتى المفاتيح) |
|
||
|
||
## 🚀 التشغيل محليًا
|
||
|
||
```bash
|
||
cd web
|
||
npm install
|
||
```
|
||
|
||
أنشئ `web/.env`:
|
||
|
||
```env
|
||
DATABASE_URI=postgres://anwarpi:anwarpi@127.0.0.1:5432/anwarpi
|
||
PAYLOAD_SECRET=<سري عشوائي طويل>
|
||
NEXT_PUBLIC_SITE_URL=http://localhost:3000
|
||
AGENT_API_KEY=<مفتاح نشر الوكلاء>
|
||
MAIL_FROM=noreply@anwarpy.ai
|
||
```
|
||
|
||
```bash
|
||
npm run dev # http://localhost:3000 — لوحة التحكم على /admin
|
||
npm run build # تحقق قبل النشر
|
||
npm run seed # تعبئة بيانات تجريبية
|
||
```
|
||
|
||
## 📡 أهم مسارات الـ API
|
||
|
||
| المسار | الوصف |
|
||
|---|---|
|
||
| `POST /api/users` | تسجيل (حد 5/ساعة لكل IP) |
|
||
| `POST /api/users/login` | دخول (حد 10/15دقيقة) |
|
||
| `POST /api/users/forgot-password` | استعادة (حد 5/ساعة) |
|
||
| `GET/PATCH /api/users/me` | حسابي |
|
||
| `GET /api/posts` و `GET /api/posts/[slug]` | الأدلة (المحتوى المقفل يُقتطع حسب الدور) |
|
||
| `POST /api/posts/[slug]/like` / `view` / `comments` | تفاعلات |
|
||
| `POST/PUT /api/agent/posts` | نشر آلي — يتطلب ترويسة `x-agent-key` |
|
||
| `POST /api/subscribe` | اشتراك Stripe (يعيد `comingSoon` حتى المفاتيح) |
|
||
| `POST /api/stripe/webhook` | ويبهوك Stripe — يتحقق من التوقيع |
|
||
|
||
## 🔐 الأمان
|
||
|
||
- **حدود المعدل** (وسيط Next): تسجيل 5/ساعة، دخول 10/15دقيقة، استعادة 5/ساعة — لكل IP، استجابة 429 مع `Retry-After` ورسالة عامة.
|
||
- **حدود الحافة** (Traefik): 60 طلب/دقيقة للصفحات (انفجار 120) و50 طلبًا جاريًا لكل IP، و`apilimit` للـ API.
|
||
- **قاعدة الكتابة الموثوقة**: طلبات العميل لا تستطيع تعيين الدور أو التحقق أو حقول الفواتير — تُحذف في خطاف `beforeChange` (`verificationToken`, `stripeCustomerId`, `role`, `emailVerified`).
|
||
- **HSTS** `max-age=63072000; includeSubDomains` على كل المسارات.
|
||
- **تكافؤ زمن الدخول**: البريد غير الموجود يستهلك نفس كلفة PBKDF2 (منع تعداد المستخدمين بالزمن).
|
||
- **التعليقات مُراقَّبة** ولا تُنشر قبل اعتماد المشرف.
|
||
|
||
## 📚 الوثائق
|
||
|
||
| الملف | المحتوى |
|
||
|---|---|
|
||
| [AGENT.md](AGENT.md) | شرح التطبيق والبنية للوكلاء الآليين (AI agents) |
|
||
| [GLOSSARY.md](GLOSSARY.md) | مسرد المصطلحات الموحّد (عضوية، مفتوح، موثّق…) |
|
||
| [docs/adr](docs/adr) | قرارات التصميم (ADRs) |
|
||
| [brand-spec.md](brand-spec.md) | الهوية البصرية والألوان |
|
||
| [web/docker-compose.vps.yml](web/docker-compose.vps.yml) | تكوين النشر على الـ VPS |
|
||
|
||
## 🚢 النشر
|
||
|
||
```bash
|
||
rsync -az --exclude node_modules --exclude .next --exclude .git \
|
||
--exclude media --exclude files-private --exclude '.env*' --exclude '*.tsbuildinfo' \
|
||
web/ root@<VPS>:/root/anwarpi/
|
||
|
||
ssh root@<VPS> "cd /root/anwarpi && docker compose -f docker-compose.vps.yml up -d --build"
|
||
```
|
||
|
||
أمر التشغيل داخل الحاوية ينفّذ `payload migrate` تلقائيًا قبل الإقلاع.
|