Javis OS
Javis OS is an Agentic AI that assists entrepreneurs in business tasks, helping them grow their work.
AI translation
منصة إدارة التوصيل، البوتات الذكية، والحملات الإعلانية — وبوابات الدفع الإلكترونية العراقية (زين كاش وكي كارد) قريباً
Translation pending
BusinessTypeScript · JavaScriptGitHub @Hussein253OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗منصة "شركة المندوب للتوصيل السريع" التي تربط قنوات المراسلة (واتساب، إنستغرام، ماسنجر) بنظام إدارة الطلبات والشحن، من أول رسالة للزبون حتى التسوية المالية مع التاجر.
الدخول: بريد واحد وزر واحد — لا كلمة مرور ولا خطوة تهيئة قبل أول تشغيل. بريد مالك المنصة (يُضبط بـ
PLATFORM_OWNER_EMAILS) يدخل أدمِناً إلى/admin، وكل بريد آخر يدخل مشتركاً على باقة Spark المجانية. التفاصيل فيlib/platform-owner.ts. وحالة الأمان الكاملة فيdocs/security-open-items.md.
قواعد التطوير الملزمة في
CLAUDE.md— اقرأها قبل أي تعديل. أهمّها: منع تخمين المعرّفات والمبالغ المالية، واعتماد هيكل البيانات قبل كتابة منطق الأعمال.
npm install
cp .env.example .env.local # ثم املأ المفاتيح والأسرار
npm run dev
يفتح على http://localhost:3000.
npm run typecheck # tsc --noEmit
npm run lint # eslint
npm test # vitest run
npm run build # next build
الأربعة تعمل على كل دفعة في .github/workflows/ci.yml.
| المتغيّر | الاستخدام |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | عنوان مشروع Supabase |
NEXT_PUBLIC_SUPABASE_ANON_KEY | مفتاح المتصفح — محكوم بسياسات RLS |
SUPABASE_SERVICE_ROLE_KEY | مفتاح الخادم حصراً — لا يُستورد أبداً في كود المتصفح |
BARIQ_BOT_WEBHOOK_SECRET | سرّ توقيع /api/webhooks/bot |
BARIQ_DELIVERY_SYNC_SECRET | سرّ توقيع /api/delivery/sync |
N8N_WEBHOOK_URL | نقطة إرسال ردود اللوحة إلى واتساب عبر n8n |
BARIQ_N8N_OUTBOUND_SECRET | السرّ المُرسل مع كل رد إلى n8n — docs/n8n-dashboard-reply.md |
الأسرار إلزامية: المسار الذي يغيب سرّه يردّ ٥٠٣ ولا يقبل شيئاً. نسيان الضبط يجب أن يوقف المسار لا أن يفتحه.
| المسار | الوصف |
|---|---|
/ | صفحة التعريف بالمنصة والباقات — عامة |
/login | تسجيل الدخول — الطريق الوحيد إلى ما تحته |
/operations | لوحة العمليات: الطلبات، التجار، المروّجون، الحملات |
/operations/chats | خدمة العملاء: محادثات القنوات الثلاث عبر Supabase Realtime |
/operations/whatsapp | لوحة واتساب المستقلة |
/workspace | مساحة التاجر: الكتالوج، الموظفون الأذكياء، الإعدادات |
/admin | لوحة مالك المنصة |
/dashboard | تتبّع الشحنات الميداني وحالاتها المالية |
الدور (profiles.role) | يرى |
|---|---|
platform_owner | كل شيء بما فيه /admin، وله فتح مساحة أي تاجر (مع تقييد في admin_impersonation_log) |
staff | /operations و /operations/chats و /dashboard |
merchant | /workspace — تاجره وحده |
الدور يُحسم بالبريد لحظة أول دخول، لا بإنشاء يدوي: بريد في
PLATFORM_OWNER_EMAILS ← platform_owner، وأي بريد آخر ← merchant
بتاجر واشتراك Spark يُنشآن معه. دور staff وحده يُمنح يدوياً من
supabase/seed/001_bootstrap_platform_owner.sql
أو من /admin/users.
جلسة صالحة بلا صفّ في profiles تعني حساباً جديداً يُوجَّه إلى /onboarding
فيُمنح دوره هناك — لا تُنهى جلسته.
middleware.ts يمنع غير الداخل، وrequireRole في الصفحة تفحص الدور.
الفحصان مفصولان عمداً: فحص الدور يحتاج قراءة من القاعدة، ووضعه على حافة
الشبكة يُبطّئ كل طلب ويجعل الصلاحية تُفحص في مكانين فيفترقان.
POST /api/orders — إنشاء طلب من نظام التاجرcurl -X POST https://<host>/api/orders \
-H "Authorization: Bearer brq_live_xxxxxxxx" \
-H "Idempotency-Key: order-2026-09-15-0042" \
-H "Content-Type: application/json" \
-d '{
"customer_name": "أحمد الجبوري",
"customer_phone": "07701234567",
"governorate": "بغداد",
"district": "الكرادة",
"full_address": "شارع ٦٢، قرب صيدلية النور",
"order_content": "حذاء رياضي أسود قياس ٤٢",
"cod_amount_iqd": 35000,
"delivery_fee_iqd": 5000
}'
merchant_id من المُرسِل.Idempotency-Key إلزامية. إعادة الإرسال بنفس المفتاح تُعيد الشحنة
الأصلية ولا تُنشئ ثانية.cod_amount_iqd وdelivery_fee_iqd حقلان مستقلان مطلوبان. لا قيمة
افتراضية لأيّهما: الحقل الغائب يُرفض برد ٤٢٢ ولا يُخمَّن.GET /api/orders بنفس المفتاح يُعيد شحنات صاحبه فقط، مع ?status= و?search=.
POST /api/delivery/sync — تحديث حالة شحنةموقَّع بـ x-bariq-signature. يقبل tracking_number وaction من:
pickup · in_transit · out_for_delivery · delivered · postponed ·
returned · settled. التأجيل والإرجاع يلزمهما reason.
الانتقال المخالف للتسلسل يُرفض بـ ٤٠٩ مع قائمة الانتقالات المسموحة.
الحالة نفسها مرّتين ترجع unchanged: true بلا أثر مكرر.
POST /api/webhooks/bot — أحداث البوتموقَّع بـ x-bariq-signature. الأحداث: message_received · message_sent ·
order_created · order_status_query · human_handover.
/api/payments/* تردّ ٥٠١. التكامل غير مبنيّ — التفاصيل في
lib/payments/index.ts.
docs/الأرقام العربية موحّدة في كل الواجهات. استخدم دوال lib/formatters.ts
(toArabicDigits, formatArabicCurrency, formatArabicNumber) ولا تطبع أرقاماً خاماً.
فصل الخادم عن المتصفح. ملفات *-server.ts تستعمل service_role ويُمنع استيرادها
في مكوّنات العميل. ما يُقرأ بمفتاح anon يجب أن تحميه سياسة RLS.
لا مبلغ افتراضي ولا رقم هاتف افتراضي. الحقل المالي الغائب يُرفض
(lib/order-validation.ts)، ولا يُملأ بقيمة مُقدَّرة.
الاختبارات في tests/order-validation.test.ts تحرس هذا.
هوية التاجر من الجلسة لا من الرابط. في المسارات استعمل
requireMerchantScope، وفي الصفحات
loadWorkspaceContext. searchParams.get('merchant_id')
ليس هوية — هو طلب يُمحَّص، ويُتجاهل لغير مالك المنصة.
لا يُطبع رقم هاتف زبون في السجلات. استعمل lib/log.ts: maskPhone
لرقم الهاتف وmaskText لنص الرسالة. سجلات Vercel تُقرأ خارج حماية RLS.
آلة حالات الشحنة تتبع تدفقاً صارماً لا يقبل القفز العشوائي:
ORDER_RECEIVED → PICKED_UP_SAME_DAY → IN_TRANSIT_HUB → OUT_FOR_DELIVERY
→ DELIVERED | POSTPONED | RETURNED → SETTLED_FINANCIALLY
الفرض في مُحفّز قاعدة البيانات، ونسخة lib/shipments.ts لتوجيه
الواجهة فقط. اختبار في tests/shipment-state-machine.test.ts
يقرأ خريطة المُحفّز من ملف الترحيل ويقارنها بنسخة الكود، فيكشف أي افتراق.
الفصل المالي إلزامي: قيمة البضاعة (COD) وأجرة التوصيل حقلان منفصلان، وصافي
مستحق التاجر عمود محسوب في القاعدة (GENERATED ALWAYS) لا يُخزَّن مُخمَّناً.
كل المخطط موثَّق في supabase/migrations/. الترحيل
010_document_live_schema.sql يوثّق الجداول الـ ١٨ التي كانت تعيش في لوحة
Supabase فقط — مُستخرَجة من القاعدة الحية لا مكتوبة من الذاكرة.
أي تغيير في المخطط يبدأ بملف ترحيل، لا بلوحة Supabase. التعديل في اللوحة لا يمرّ بمراجعة ولا يترك أثراً، ويجعل إنشاء بيئة اختبار مستحيلاً.
تُقرأ من جدول plans وتُعرض في / فوراً عند أي تعديل، بلا إعادة نشر.
الباقة التي لم يُعتمد سعرها بعد (price_iqd_monthly IS NULL) تظهر "قريباً" بدل رقم مُخمَّن.
حدود الباقة مفروضة بمُحفّز enforce_plan_limit في القاعدة، لا في الكود.
يُنشر تلقائياً على Vercel عند الدفع إلى main بعد نجاح CI. تأكّد من ضبط كل
متغيّرات البيئة أعلاه في إعدادات المشروع على Vercel قبل أول نشر.