07 · ARCHITECTURE المعمارية

المعمارية اللي هنشتغل بيها

نظام واحد بيخدم الموقع ولوحة الإدارة والمخازن ومحطات التقفيل: موقع نشر واحد، أربع طبقات واضحة، ووحدات (Modules) جوه كل طبقة على حسب البيزنس — المخزون، الطلبات، البضاعة الداخلة، الجملة، التسويق. الصفحة دي بتشرح الشكل العام، وبعدين كل آلية حساسة لوحدها: سجل المخزون، آلة حالات الطلب، تنبيهات «اللمبة»، الواتساب، الطباعة والسكان، العلامة المائية لصور الجملة، ومحرك الأسعار.

.NET 10 LTSSQL Server + EF Core 10MVC للوحة REST API للموقعSignalRHangfireموقع نشر واحدعربي + إنجليزيموقع + تطبيق
01

القرار في سطور

إيه اللي هنبنيه، وليه بالشكل ده بالذات.

🧱

مونوليث منظّم بالوحدات

تطبيق واحد وداتابيز واحدة، بس الكود متقسم وحدات واضحة (مخزون، طلبات، جملة…). ده أسرع في البناء والنشر من الخدمات المنفصلة، ومعاه حدود نضيفة تسمح نفصل أي وحدة بعدين لو احتجنا.

🗂️

أربع طبقات

Domain (الكيانات والقواعد) ← Application (الخدمات وحالات الاستخدام) ← Infrastructure (الداتابيز والتكاملات) ← Web (الـ API واللوحة). النمط: واجهة + خدمة، من غير طبقات زيادة مالهاش لازمة.

🌐

موقع نشر واحد

الـ API للموقع على /api/v1، ولوحة الإدارة على /dashboard، واللحظي على /hubs، والجوبز على /hangfire — كله في نفس الاستضافة بنفس الدخول والصلاحيات.

📒

المخزون سجل مش رقم

كل قطعة بتتحرك ليها سطر في سجل حركات مايتمسحش ولا يتعدّل (استلام، تحويل، حجز، بيع، مرتجع، تالف…). الرصيد = نتيجة السجل. ده اللي بيحل مشكلة «الفلوس مش شايفها» و«التالف بيتسرق».

🔁

الطلب آلة حالات

مفيش حد بيكتب الحالة بإيده. كل نقلة ليها شرط (مين، وإيه لازم يكون حصل) وأثر (مخزون، رسالة، سجل). الأدمن بس يقدر يتخطى، وبسبب مكتوب.

🎛️

كل حاجة من اللوحة

المهلات، عدد رسائل التأكيد، حدود VIP، شرائح الجملة، نقاط الولاء، قوالب الرسائل، مفاتيح التكاملات — كلها إعدادات ليها حد أدنى وأقصى وسجل تغييرات.

02

الخريطة العامة

مين بيكلم السيستم، والسيستم بيكلم مين.

المستخدمين والأجهزة
🛍️ الموقع + 📱 التطبيقعملاء القطاعي والتجار — عربي وإنجليزي، نفس الـ API/api/v1/store · /merchant
🧑‍💼 لوحة الإدارةالإدارة، المودريشن، خدمة العملاء، المحاسب/dashboard
📦 محطات المخزنتابلت/كمبيوتر + سكانر USB: تجميع، تقفيل، تسليم/dashboard/ops
🖨️ الطابعاتإيصال 80 مم + ملصقات باركود — طباعة من المتصفحprint views
🚚 شركات الشحندخول محدود على الطلبات + ملفات Excel/dashboard/courier
▼
موقع النشر الواحد — ASP.NET Core (.NET 10)
REST APIJWT للعملاء والتجار، أكواد أخطاء ثابتة، ترقيم صفحات/api/v1/...
لوحة MVCCookie، عربي/إنجليزي، فاتح/غامق، صفحة = CSS + JS/dashboard
SignalRجرس الطلبات، اللمبة، طلبات التحويل، محطة التقفيل/hubs/ops
Hangfireتذكيرات، تنبيهات 24 ساعة، VIP، طابور الواتساب/hangfire
▼
الوحدات (Application) — التفاصيل تحت
الكتالوج والأكوادمنتجات، متغيرات، نطاقات أكواد، أسعار
المخزونمخازن، أماكن، سجل حركات، حجز، تحويلات
البضاعة الداخلةأذون شراء، شحنات، استلام، عد، فرز، تالف
الطلبات والتجهيزحالات، استثناءات، تقفيل، تسليم، مرتجعات
العملاء والجملة والتسويقتجار، Prime/VIP، عروض، كوبونات، ولاء
▼
التخزين والتكاملات الخارجية
SQL Serverالداتابيز الوحيدة + جداول Hangfire
تخزين الصورمحلي أو ImageKit — قابل للتبديل من اللوحة
واتساب «حلول»إرسال + استقبال ردود الأزرار (Webhook)
شركات الشحنExcel الآن، ربط برمجي لاحقاً لكل شركة
الإيميل / SMSSMTP لاستعادة الحساب، SMS اختياري
03

الطبقات ومسؤولية كل واحدة

القاعدة: الطبقة الداخلية ماتعرفش حاجة عن اللي برّاها. Domain مايعرفش EF، وApplication مايعرفش MVC.

الطبقةفيها إيهممنوع فيهامثال من فلوكة
Domainالكيانات، القيم (Money، Code، Quantity)، الـ Enums، قواعد الكيان نفسه، أحداث الدومينأي مكتبة خارجية، EF، HTTPOrder.CanMoveTo(Preparing)، StockMovement، CodeRange.Contains(code)
Applicationالخدمات (حالات الاستخدام)، الواجهات للتكاملات، الـ DTOs، التحقق (FluentValidation)، الصلاحيات المطلوبة لكل عمليةControllers، Razor، تفاصيل SQLIOrderWorkflow، IStockLedger، IPricingEngine، IWhatsAppSender
InfrastructureEF Core و الهجرات، Dapper للتقارير، مزودي الواتساب والتخزين والإيميل، Hangfire، توليد الباركود، العلامة المائية، Excelمنطق بيزنسHololWhatsAppSender، ImageSharpWatermarker، ClosedXmlExporter
WebControllers الـ API، لوحة MVC (Views + CSS/JS لكل صفحة)، SignalR Hubs، Middleware الأخطاء، Swagger، الإعدادات العامةمنطق بيزنس، استعلامات مباشرةOrdersController، /dashboard/ops/packing، OpsHub
testsاختبارات وحدات للحسابات والحالات، اختبارات عقد للـ API، اختبارات معمارية للحدود—«ماينفعش الطلب يروح جاري التحضير من غير طباعة»
ليه من غير MediatR أو Generic Repository؟

كل خدمة واجهة واضحة باسم البيزنس (IOrderWorkflow.ConfirmAsync) — أسهل في القراية والتتبع والاختبار، وأقل طبقات لمشروع حجمه زي ده. التحويل بين الكيان والـ DTO يدوي (ToDto()) عشان نتحكم بالظبط في اللي بيطلع للموقع — مهم جداً عشان منتجات Prime وسعر التكلفة مايطلعوش بالغلط.

04

الوحدات (Modules)

كل وحدة فولدر في Domain وApplication وInfrastructure وWeb بنفس الاسم. الرقم تحت كل وحدة = المرحلة اللي بتتبني فيها.

🔐الدخول والصلاحياتIdentity

مستخدمي اللوحة، الأدوار، الصلاحيات بالصفحة والزرار، التحقق بخطوتين، حسابات العملاء والتجار (منفصلة)، التوكنات.

مرحلة 0
🏷️الكتالوجCatalog

المنتجات، المتغيرات (لون/مقاس/خامة)، الأقسام، البراندات، الصور، الظهور (قطاعي/جملة/Prime)، حالة المنتج (متكوّد ومنتظر ← منشور).

مرحلة 1
🔢الأكوادCoding

البادئات (N، Pin، Mobile…)، نطاقات محجوزة ومقفولة، اقتراح الكود التالي، منع التكرار، طباعة الباركود.

مرحلة 1
💰الأسعارPricing

تكلفة، قطاعي، عرض بتاريخ، جملة + شرائح كمية، سجل تغيير الأسعار، محرك حساب السلة.

مرحلة 1
🏬المخزونInventory

المخازن (رئيسي، جملة، أونلاين، فرع، تالف)، الأماكن، سجل الحركات، الأرصدة، الحجز، التحويلات بالموافقة، الجرد والمراجعة.

مرحلة 1
🚢البضاعة الداخلةInbound

الموردين، أذون الشراء ومدفوعاتها، الشحنات/الحاويات، الاستلام، العدّاد، العينات، إعادة حساب التكلفة.

مرحلة 3
🔍الجودة والتالفQuality

دفعات الفحص لكل براند، فرز أول/تاني/تالف، حالات التالف، لجنة المراجعة، إعدام أو إصلاح، الخامات المسحوبة.

مرحلة 3
🧾الطلباتOrders

إنشاء الطلب (موقع/لوحة/جملة)، آلة الحالات، الاستثناءات، الحجز بنوعيه، العاجل والوسوم، سجل الحالات والملاحظات.

مرحلة 2
📦التجهيزFulfillment

الطباعة وعدّادها، أقسام التجهيز، التجميع بالمكان، محطة التقفيل بالسكان، الأخطاء والأصوات، ستاند المواقف.

مرحلة 2
🚚الشحن والتسليمShipping

شركات الشحن، أسعار المحافظات، دفعات التسليم بالسكان، Excel التسليم، مطابقة فريق المراجعة، دخول شركة الشحن.

مرحلة 2
↩️المرتجعاتReturns

تسجيل المرتجع (كلي/جزئي)، فحص قطعة قطعة، القرار (للمخزون / تالف / غلط)، الإرجاع للمخزون بإيد مسؤول.

مرحلة 2
🤝العملاء والتجارCustomers

حسابات العملاء، طلبات التجار ومراجعتها، Prime (يدوي)، VIP (تلقائي)، قبول الشروط بإصدارها، رقم التاجر للعلامة المائية.

مرحلة 2 + 4
🎁التسويقMarketing

العروض الخمسة، الكوبونات، نقاط الولاء ومستوياتها، منتج الصور وباقاته، (المحفظة لو اتقررت).

مرحلة 5
💬الرسائلMessaging

قوالب الرسائل، جدول تذكيرات التأكيد، طابور الإرسال، استقبال ردود الأزرار، سجل الرسائل وحدود الإرسال.

مرحلة 2
📊التقارير والماليةReporting

الرئيسية الإحصائية، تقارير المبيعات والمخزون والتالف والمطابقة، الموردين، المصاريف والإيرادات المبسطة.

مرحلة 6
🏪الفروع ونقطة البيعPOS

استلام الفرع، تخفيض مدير الفرع، البيع بالباركود، البازارات كمخازن مؤقتة.

مرحلة 7
⚙️الإعدادات والمحتوىPlatform

الإعدادات بحدودها، مفاتيح التكاملات المشفّرة، صفحات المحتوى، الأسئلة الشائعة، البانرات، سجل التعديلات، المحذوفات.

مرحلة 0
05

شكل الحل (Solution)

نفس أسماء الوحدات في كل طبقة — أي حد يدور على «التحويلات» يلاقيها في نفس المكان في الأربع طبقات.

// Flouka.slnx src/ Flouka.Domain/ Common/ BaseEntity, Money, Quantity, ISoftDeletable, DomainEvent Catalog/ Product, ProductVariant, Category, Brand, ProductImage Coding/ CodePrefix, CodeRange Inventory/ Warehouse, Location, StockMovement, StockBalance, StockReservation, Transfer Inbound/ Supplier, PurchaseOrder, Shipment, GoodsReceipt, CountSheet Quality/ QcBatch, DamageCase Orders/ Order, OrderLine, OrderStatus, OrderException, OrderTag Fulfillment/ PrintLog, PackingSession, ScanEvent Shipping/ Courier, ShippingRate, HandoverBatch, Reconciliation Returns/ ReturnCase, ReturnLine Customers/ Customer, MerchantApplication, MerchantProfile, VipLevel Marketing/ Offer, Coupon, LoyaltyLedger, PhotoPackage Messaging/ MessageTemplate, OutboundMessage, ConfirmationRule Platform/ Setting, AuditEntry, ContentPage, AdminUser, Role, Permission Flouka.Application/ // نفس الفولدرات: Services + Interfaces + Dtos + Validators لكل وحدة Orders/IOrderWorkflow.cs, OrderWorkflow.cs, Dtos/, Validators/ Inventory/IStockLedger.cs, ITransferService.cs ... Pricing/IPricingEngine.cs, PricingEngine.cs Flouka.Infrastructure/ Persistence/ FloukaDbContext, Configurations/, Migrations/, Interceptors/ (Audit, AppendOnly) Messaging/ HololWhatsAppSender, LoggingWhatsAppSender, WhatsAppQueueJob Media/ LocalStorage, ImageKitStorage, ImageSharpWatermarker Printing/ BarcodeGenerator (Code128) Excel/ ClosedXmlExporter, LegacyImporter Jobs/ AttentionScanJob, VipRecalcJob, ReminderJob ... Flouka.Web/ Api/V1/Store/ CatalogController, CartController, OrdersController, AccountController Api/V1/Merchant/ ApplicationController, WholesaleCatalogController Api/V1/Public/ AppConfigController, LookupsController, ContentController Api/Webhooks/ WhatsAppWebhookController Areas/Dashboard/ Controllers + Views لكل صفحة Hubs/OpsHub.cs wwwroot/dashboard/ css/pages/{page}.css · js/pages/{page}.js · vendor/ tests/ Flouka.UnitTests/ Flouka.ApiTests/ Flouka.ArchitectureTests/
06

التقنيات

كلها نسخ ثابتة ومحلية — مفيش مكتبات من CDN في اللوحة.

البندالاختيارالسبب
الإطار.NET 10 LTS (net10.0)دعم طويل لحد 2028؛ .NET 8 دعمه بينتهي نوفمبر 2026
الداتابيزSQL Server + EF Core 10 + Dapper للتقارير التقيلةمتاحة على الاستضافة، المعاملات قوية للمخزون
المعرّفاتGuid v7 + رقم عرض قصير للطلبات (FL-260412)ترتيب زمني، ومناسب للباركود على الإيصال
الفلوسdecimal(12,2) — والتكلفة decimal(12,4)تكلفة القطعة بتطلع كسور بعد قسمة الشحنة
الوقتتخزين UTC وعرض بتوقيت القاهرةتنبيهات الـ 24 ساعة والتقارير اليومية مظبوطة
اللوحةASP.NET MVC (Razor) + JS خفيف لكل صفحة + ApexChartsسريعة، من غير build معقد، وكل صفحة مستقلة
اللحظيSignalRجرس الطلبات واللمبة ومحطة التقفيل
الجوبزHangfire على SQL Serverالتذكيرات والتنبيهات وطابور الواتساب، بلوحة متابعة
الصورImageSharp (ضغط، WebP، علامة مائية) + تخزين محلي/ImageKitصور المنتجات وصور العملاء وصور الجملة المعلّمة
الباركودCode128 (توليد SVG في السيرفر)بيقراه أي سكانر، ومناسب للأكواد اللي فيها حروف وشرطة
ExcelClosedXMLتصدير كل القوائم + ملف التسليم + استيراد المنتجات
التحققFluentValidation + رسائل عربينفس الرسائل للـ API واللوحة
السجلاتSerilog لملفات (من غير باسوردات أو توكنات)تتبع المشاكل
اللغتينLocalizedText في الداتابيز + ملفات ترجمة (resx) للوحة والأخطاء + Accept-Language للـ APIاللوحة والموقع والتطبيق عربي وإنجليزي
إشعارات التطبيقFCM HTTP v1 + جدول أجهزة + صندوق إشعاراتحالة الطلب، العروض، قبول التاجر — بلغة العميل
الاختباراتxUnit + اختبارات عقد + اختبارات معماريةالحسابات والحالات مايتكسروش
07

سجل المخزون — قلب النظام

كل قطعة في فلوكة ليها قصة: اتطلبت في إذن، وصلت في شحنة، اتعدّت، اتحولت، اتفرزت، اتباعت، رجعت. السجل بيحكي القصة دي سطر سطر.

الفكرة

  • جدول حركات إلحاقي: كل سطر = متغير + مخزن (+ مكان) + كمية بالموجب أو السالب + نوع الحركة + المستند (إذن/تحويل/طلب…) + مين + إمتى.
  • جدول أرصدة بيتحدث في نفس المعاملة: متاح، محجوز، في الطريق.
  • مفيش «تعديل رصيد» — التسوية حركة جديدة بسبب ومين وافق.
  • Interceptor بيمنع أي تعديل أو مسح على جدول الحركات.

منع البيع الزيادة

  • الطلب بيعمل حجز للكمية أول ما يتعمل (حتى قبل التأكيد) — المتاح للموقع = الرصيد − المحجوز.
  • الحجز بيتفك لو الطلب اتلغى أو الطلب المركون عدّى مهلته (حسب الإعداد).
  • الخصم الفعلي من المخزون عند التقفيل (القطع خرجت من الرف).
  • قفل على مستوى الصف (UPDLOCK) + rowversion عشان طلبين على آخر قطعة مايعدّوش الاتنين.

أنواع الحركات

النوعالاتجاهالمستندبيحصل إمتى
استلام شحنة+ المخزن الرئيسيإذن استلامبعد العدّاد واعتماد العدد
عينة للمصوّر− المخزن (+ مخزن العينات)سند عينةالعدّاد يسحب عينة
تحويل خارج / داخل− المرسل / + المستلمطلب تحويلالإرسال ثم تأكيد الاستلام (الفرق = عجز تحويل)
فرز− انتظار الفحص / + أونلاين أو فرع أو تالفدفعة فحصنتيجة فحص الجودة
إعدام− التالفحالة تالفقرار اللجنة
إصلاح− التالف / + الوجهةحالة تالفمرتجع تالف
حجز / فك حجزالمتاح فقططلبإنشاء الطلب / إلغاؤه
بيع− مخزن الطلبطلبالتقفيل
مرتجع+ «مرتجعات تحت الفحص»حالة مرتجعاستلام المرتجع
إرجاع للمخزون− تحت الفحص / + المخزنحالة مرتجعقرار مسؤول المرتجعات
تسوية جرد±جردالمراجع لقى فرق — بموافقة
رصيد افتتاحي+استيرادنقل البيانات من النظام الحالي
النتيجة اللي العميل عايزها

أي قطعة «تالفة» ليها كود وسطر بمين أضافها — ماينفعش تختفي. وأي إذن شراء يتقفل بالكمية اللي وصلت فعلاً، والفرق بيبان في تقرير.

08

آلة حالات الطلب

خدمة واحدة IOrderWorkflow هي الوحيدة اللي بتغيّر حالة الطلب. كل نقلة متعرّفة في جدول: من، إلى، مين يقدر، الشرط، الأثر.

من ← إلىبيحصل بـالشرطالأثر
(جديد) ← بانتظار التأكيدإنشاء من الموقع أو اللوحةالمتاح يكفيحجز المخزون + جدولة رسائل التأكيد
بانتظار التأكيد ← تم التأكيدزرار «تأكيد» في الواتساب / تأكيد يدوي—إلغاء التذكيرات + سجل
بانتظار التأكيد ← استثناءزرار «تعديل» / يدويسبباللمبة + إشعار خدمة العملاء
تم التأكيد ← جاري التحضيرأول طباعة للإيصالصلاحية الطباعةسجل طباعة + يبدأ عدّاد الـ 24 ساعة
جاري التحضير ← استثناءالأوبريشن: قطعة ناقصةملاحظة (كود القطعة)علامة «على ستاند المواقف» + اللمبة
استثناء ← تم التأكيدخدمة العملاء كتبت الحلنص الحلتطفي اللمبة + علامة «اتجمع قبل كده»
جاري التحضير ← تم التحضيرمحطة التقفيلكل السطور اتسكانت صحخصم المخزون (بيع)
تم التحضير ← جاهز للمندوبتلقائي بعد التقفيل—يظهر في شاشة التسليم
جاهز للمندوب ← تم الشحنسكان في دفعة تسليمالطلب جوه الدفعةسطر في Excel الدفعة + رسالة للعميل
تم الشحن ← تم الاستلام / مرتجعالمراجعة أو استيراد ملف الشحن—VIP + نقاط الولاء (عند الاستلام)
مرتجع ← اتفحص ← رجع المخزونمسؤول المرتجعاتقرار لكل قطعةحركات المخزون
أي حالة قبل الشحن ← ملغيخدمة العملاء / الأدمنسبب من القايمةفك الحجز (أو إرجاع للمخزون لو اتقفل)
أي ← أيالأدمن فقط («حالة الطلب ينزل فين»)سبب مكتوبسجل تخطي مميّز في التقارير
الحالات الجانبية مش حالات

عاجل، لون الشريط، قسم التجهيز (بورسعيد/محافظات/جملة/صور)، ومؤجل الشحن ومركون — دي صفات على الطلب بتأثر على الترتيب والعرض، مش بتكسر خط الحالات. كده الفلترة والتقارير تفضل بسيطة.

09

«اللمبة» والتنبيهات

اللمبة هي طريقة العميل إنه يطلّع الطلب اللي فيه مشكلة لأول القايمة مهما كان تاريخه. بنعملها كدرجة انتباه محسوبة.

الترتيب في كل قوائم التشغيل

  1. عاجل (أحمر) — يدوي.
  2. محتاج انتباه (اللمبة) — استثناء مفتوح أو تنبيه.
  3. «اتجمع قبل كده» — يطبع ويجيبه من الستاند.
  4. الباقي بالتاريخ.

كل طلب فيه AttentionLevel وAttentionReason، والفهرس عليهم.

جوب كل 5 دقايق Hangfire

  • بانتظار التأكيد > 24 ساعة بعد آخر رسالة ← «محتاج مكالمة».
  • جاري التحضير > 24 ساعة ← «الإيصال ضاع؟ اطبع تاني».
  • مركون عدّى مهلته (5–7 أيام) ← أحمر وفوق.
  • مؤجل الشحن: قبل الميعاد بـ X أيام ← رسالة تأكيد جديدة.

كل الأرقام من الإعدادات، والتغيير بيوصل اللوحة لحظياً بـ SignalR.

10

الواتساب

العميل شغال على مزود اسمه «حلول» وعنده ربط برمجي. بنحطه ورا واجهة واحدة عشان لو اتغير المزود مانلمسش البيزنس.

1حدثطلب جديد / حجز / قبول تاجر

الخدمة بتطلب رسالة من القالب المناسب بالمتغيرات.

2طابورجدول الرسائل الصادرة

الرسالة تتسجل «في الانتظار» مع ميعاد الإرسال (التذكيرات بتتجدول).

3إرسالجوب Hangfire

فاصل بين الرسائل، إعادة محاولة، حد يومي، ساعات هدوء — من الإعدادات.

4رد العميلWebhook

زرار «تأكيد» أو «تعديل» يوصل للنظام ويتنفذ مرة واحدة بس حتى لو اتبعت مرتين.

5بديللو الأزرار مش متاحة

لينك تأكيد موقّع في الرسالة يفتح صفحة صغيرة فيها «تأكيد / تعديل».

الإعدادمثالمن اللوحة
عدد رسائل التأكيد في اليوم الأول2✓
الفاصل بين رسائل التأكيد6 ساعات✓
عدد الأيام قبل اعتبار الطلب «محتاج مكالمة»1 (24 ساعة)✓
تذكير مؤجل الشحن قبل الميعاد3 أيام✓
نص كل رسالة + الأزرار«أهلاً {name}، طلبك {code} بـ {total}…»✓
ساعات الهدوء11 م – 9 ص✓
تكلفة الرسالة (للتقارير)0.50 ج✓
11

السكان والطباعة

السكانر بيشتغل كأنه كيبورد — من غير برامج على الجهاز. الصفحة بتلقط الكود وتبعته للسيرفر وترد بصوت وعلامة.

🧾 الإيصال

صفحة طباعة 80 مم فيها باركود رقم الطلب، القطع بأكوادها وأماكنها (للتجميع)، والقسم. أول طباعة بتنقل الطلب «جاري التحضير»، والطباعة التانية بتتسجل وبتكتب «نسخة 2».

📟 محطة التقفيل

سكان الإيصال ← يظهر الطلب. سكان كل قطعة ← العدّاد يزيد. صنف غلط أو عدد زيادة ← صوت خطأ أحمر. سكان الإيصال تاني ← لو كله تمام: علامة صح وصوت نجاح والطلب «تم التحضير». كل سكان متسجل بمين وإمتى.

🚚 التسليم للمندوب

تفتح دفعة لشركة شحن ← سكان الطلبات واحد واحد ← العدد قدامك ← تقفل الدفعة ← Excel بالطلبات للمراجعة + نموذج توقيع بالعدد للدفتر.

🏷️ ملصقات الباركود

من صفحة المنتج أو من إذن الاستلام: اختار الأكواد والعدد ← صفحة طباعة بمقاس الملصق (افتراضي 40×25 مم) — المقاس من الإعدادات.

🔫 المراجعة بالمسدس

المراجع يختار مكان ← يسكان القطع ← السيستم يقارن بالمسجل ويعرض صورة المنتج من الموقع جنب كل سكان. الفروق تطلع جرد للموافقة.

📷 طلبات الصور

خطوة «طباعة الصور» قبل التقفيل: تحميل صور كل قطعة مرتبة باسم الطلب ورقم القطعة، وعلامة «اتطبعت» قبل ما محطة التقفيل تقبل الطلب.

12

حماية صور الجملة (العلامة المائية)

العميل عايز يعرف مين سرّب صورة من الجملة. منع السكرين شوت على المتصفح مش ممكن تقنياً، فالحل إن الصورة نفسها تبقى «بتشهد» على صاحبها.

إزاي

  1. كل تاجر ليه رقم عام قصير (مثلاً T-0457).
  2. صور الجملة مابتطلعش برابط ثابت: بتطلع من رابط موقّع ومؤقت خاص بالتاجر.
  3. السيرفر بيرسم رقم التاجر على الصورة بشفافية بسيطة في كذا مكان، ويحفظ النسخة دي (كاش) عشان مايترسمش كل مرة.
  4. الموقع كمان بيحط علامة عائمة برقم التاجر فوق الشاشة (للتصوير بموبايل تاني).

إيه اللي بيحميه وإيه اللي لأ

  • ✓ صورة اتنزلت أو اتعمل لها سكرين شوت ← الرقم فيها.
  • ✓ تصوير الشاشة بموبايل ← العلامة العائمة ظاهرة.
  • ✗ منع السكرين شوت نفسه — مش ممكن في المتصفح (التطبيقات زي المحافظ بتقدر لأنها تطبيق موبايل).
  • صور القطاعي العادية مش بتتأثر — بتفضل سريعة ومن غير علامة.
13

محرك الأسعار

مكان واحد بيحسب سعر أي سطر وأي سلة — للموقع وللوحة ولطلبات الجملة — والنتيجة بتتحفظ صورة منها على الطلب.

1القناة

قطاعي ولا جملة؟ (الجملة: مخزن الجملة وأسعارها بس).

2السعر الأساسي

سعر القطاعي، أو سعر العرض لو جوه تاريخه = «آخر سعر».

3شرائح الجملة

حسب الكمية (12، 120…) لو القناة جملة.

4الإضافات

باقة الصور لكل قطعة.

5العروض

عرض واحد لكل قطعة (الأفضل للعميل) — الخمس أنواع.

6الكوبون والنقاط

بعد العروض، بحدودهم.

7الشحن

من جدول المحافظات (وهدية الشحن المجاني).

محتاج قرار من العميل

هل العروض بتتجمع مع الكوبون ونقاط الولاء؟ الموقع التجريبي بيقول آه. المحرك جاهز للحالتين بإعداد واحد.

14

الـ API للموقع

فريق الموقع بيبني على الـ API ده. البادئات بتفصل كل جمهور، والعقد بيتكتب ويتصدّر openapi.json قبل التنفيذ.

البادئةلمينأمثلة
/api/v1/publicأي حدإعدادات الموقع، المحافظات وأسعار الشحن، صفحات المحتوى، الأسئلة الشائعة، البانرات، شروط الجملة
/api/v1/storeعملاء القطاعيالكتالوج والبحث والفلاتر، المنتج، السلة وحسابها، الطلب، رفع صور المنتج، المفضلة، المقارنة، النقاط، حسابي وطلباتي
/api/v1/merchantالتجارتقديم الطلب وحالته، كتالوج الجملة (Prime مخفي لغير الـ Prime)، الصور المعلّمة، طلبات الجملة
/api/v1/authالكلدخول، تسجيل، تجديد التوكن، لينك الدخول السحري للتجار، استعادة الباسورد
/api/webhooksالمزودينردود الواتساب، (شركات الشحن لاحقاً)
شكل الرد

لو فريق الموقع بعت عقد ← يتنفذ حرفياً. غير كده: قوائم مترقّمة دايماً { items, page, pageSize, total, hasMore }، وأخطاء بكود ثابت وحالة HTTP صح، ورسائل بلغة الطلب (عربي أو إنجليزي). أي عملية فيها فلوس أو إنشاء طلب بتقبل Idempotency-Key عشان الضغط مرتين مايعملش طلبين.

15

عربي وإنجليزي في كل حاجة + التطبيق

اللوحة والموقع والتطبيق بلغتين، والعربي الافتراضي. اللغة مش «ترجمة بعدين»: بتتبني في الداتابيز والـ API واللوحة من أول يوم. ونفس الـ API بيخدم الموقع وتطبيق الموبايل.

🗄️

في الداتابيز

كل نص بيظهر للعميل عمود LocalizedText فيه {ar, en}: اسم المنتج ووصفه وخامته، الألوان والمقاسات (من قوائم)، الأقسام، العروض، باقات الصور، مستويات VIP والنقاط، الشروط، صفحات المحتوى، الأسئلة الشائعة، البانرات، وقوالب الرسائل.

🔌

في الـ API

الموقع والتطبيق بيبعتوا Accept-Language: ar أو en، والرد بييجي بلغة واحدة جاهزة للعرض. لو الترجمة ناقصة بيرجع للغة التانية بدل ما يرجع فاضي. رسائل الأخطاء كمان باللغتين.

🧑‍💼

في اللوحة

زرار تبديل بيتحفظ لكل مستخدم، كل نصوص الشاشات من ملفات ترجمة (ممنوع نص ثابت في الصفحة)، الاتجاه بيتقلب لوحده، وكل حقل نص للعميل بيتكتب في تبويبين: عربي / English.

💬

الرسائل بلغة العميل

كل عميل وتاجر ليه PreferredLanguage. رسائل الواتساب والإيميل والإشعارات بتطلع بلغته، وكل قالب ليه نسخة عربي وإنجليزي من اللوحة.

🔎

الروابط والبحث

رابط (Slug) وعنوان ووصف SEO لكل لغة للمنتجات والأقسام. البحث بيدور في الاسم العربي والإنجليزي والكود مع بعض، ومش حساس لحالة الحروف.

🖨️

الطباعة

الإيصال والملصق بلغة اللوحة (الافتراضي عربي)، واسم المنتج بيطلع باللغة المتاحة.

تعارض جديد C16: المنتجات الحالية أسماؤها إنجليزي بس

البيانات الحالية (زي ayatul kursi ring) إنجليزي بس، ومعيارنا إن العربي إجباري. القرار المقترح: لغة واحدة على الأقل إجبارية، والناقصة بترجع للتانية، ومعاهم تقرير «منتجات ناقصها ترجمة» في اللوحة واستيراد Excel للترجمات بالجملة. الترجمة نفسها مسؤولية العميل صاحب السيستم؛ إحنا بنوفر الأدوات (التقرير والاستيراد) بس.

التطبيق: الإضافات اللي لازم تبقى موجودة

البندإزاي
نقطة إعدادات واحدةGET /api/v1/public/app-config: الإصدارات، الصيانة، التواصل، السوشيال، تشغيل المزايا — بقائمة سماح
التحديث الإجباريآخر إصدار وأقل إصدار مسموح، إجباري ولا لأ، وملاحظات التحديث باللغتين — لكل منصة (أندرويد / آيفون)
وضع الصيانةتشغيل وإيقاف من اللوحة برسالة باللغتين
الإشعاراتFCM + جدول أجهزة (توكن، منصة، لغة) + صندوق إشعارات بمقروء/غير مقروء + إشعار جماعي من اللوحة
حذف الحسابمن التطبيق ومن صفحة ويب، بمهلة — مطلب المتاجر
صفحات المتاجرالخصوصية والشروط والدعم وحذف الحساب كصفحات ويب ثابتة من السيرفر
حدود شغلنا: الباك إند بس

التطبيقات مسؤولية مطوري التطبيقات، ومش علينا. إحنا علينا الـ API اللي هيشتغلوا عليه، ومعاه كل اللي التطبيق محتاجه من السيرفر: إعدادات التطبيق، التحديث الإجباري، الصيانة، الإشعارات، وحذف الحساب. كمان الـ API بيدعم العملاء والتجار من الأول، فلو اتقرر بعدين إن التطبيق هيخدم التجار مش هنحتاج نغيّر حاجة.

16

اللحظي والجوبز

اللوحة بتتحدث لوحدها، والشغل المؤجل بيتعمل في الخلفية.

حدث لحظي (SignalR)مين يشوفه
طلب جديد (بصوت)المودريشن، خدمة العملاء
لمبة اتولعت / اتطفتخدمة العملاء، الأوبريشن
طلب تحويل مستني تأكيدكمسؤول المخزن المستلم
طلب تاجر جديدمسؤول الجملة
نتيجة السكاننفس محطة التقفيل
تنبيه مخزون (نفد / قرّب يخلص)الأدمن، إدخال البيانات
جوب (Hangfire)كل قد إيه
إرسال طابور الواتسابكل دقيقة
فحص التنبيهات (اللمبة)كل 5 دقايق
تذكيرات مؤجل الشحن والملاحظات الداخليةكل ساعة
إعادة حساب VIPيومياً + عند الاستلام
تفعيل/إنهاء العروض والأسعار المؤقتةكل 5 دقايق
تنضيف الكاش وصور الجملة القديمةيومياً
17

الأمان

الأسعار والتكلفة ومنتجات Prime معلومات حساسة للعميل — والحماية بتبدأ من شكل الـ DTO نفسه.

الدخول

  • الموقع: JWT ساعة + تجديد بتدوير.
  • اللوحة: Cookie + تحقق بخطوتين للأدمن.
  • باسوردات BCrypt، وحد لمحاولات الدخول.

الصلاحيات

  • كل زرار ليه كود صلاحية، والسيرفر بيتحقق عليه.
  • المودريشن «جملة بس» مايشوفش زرار الجملة غير لو مسموح.
  • شركة الشحن تشوف طلباتها بس.

البيانات

  • سعر التكلفة مابيطلعش في أي API للموقع — اختبار بيفشّل البناء لو ظهر.
  • منتجات Prime فلتر في الاستعلام نفسه.
  • مفاتيح التكاملات مشفّرة في الداتابيز.

الأسرار

  • مفيش سر في الكود أو appsettings.json.
  • التشغيل يرفض يقوم من غير المفاتيح المطلوبة.
  • الأدمن الأول من متغيرات البيئة.

السجلات

  • سجل تعديلات لكل حاجة في اللوحة (قبل/بعد).
  • سجل الحركات والسكان مايتعدّلش.
  • مفيش باسورد أو توكن في ملفات السجل.

الحماية العامة

  • حدود معدل للـ API والدخول.
  • هيدرز أمان + CSP للوحة.
  • Swagger مقفول في الإنتاج.
18

النشر والبيئات

نشر بدري على سيرفر تجريبي عشان فريق الموقع يشتغل على بيانات حقيقية من الأسبوع الأول.

البيئةالغرضالداتابيزملاحظات
التطويرجهاز المطورمحليةبيانات تجريبية + مرسل واتساب وهمي بيكتب في السجل
التجريبيفريق الموقع والعميل يجربوامنفصلةبيانات منقولة من النظام الحالي + حسابات تجريبية لكل دور
الإنتاجالشغل الحقيقيمنفصلة + نسخ احتياطي يوميبعد اختبار رحلة كاملة على التجريبي

الهجرات بتتطبق عند التشغيل أو بسكريبت محفوظ — مفيش تعديل يدوي على الداتابيز. WebSockets متفعّلة للـ SignalR. ملف DEPLOYMENT.md فيه خطوات النشر والرجوع.

19

أهداف الأداء

أرقام بنقيس عليها قبل التسليم.

< 200ms
رد السكان في محطة التقفيل
< 400ms
صفحة كتالوج (أول 24 منتج)
٥٬٠٠٠+
منتج ومتغير من غير بطء
0
طلب يتباع على قطعة مش موجودة
20

المخاطر وإزاي نتعامل معاها

الحاجات اللي ممكن تأخر أو تكسر، وخطتنا لكل واحدة.

الخطرالأثرالتعامل
«حلول» مايدعمش الأزرار والردود برمجياًالتأكيد التلقائي يقفلينك تأكيد موقّع كبديل + واجهة لمزود تاني
بيانات النظام الحالي غير نضيفة (أكواد مكررة، أرصدة غلط)المخزون يبدأ غلطاستيراد بتقرير أخطاء + جرد افتتاحي لكل مخزن
تعارض بين الموقع التجريبي وكلام العميل (الجملة، VIP، المحفظة)شغل يتعادعقد API مكتوب ومعتمد قبل التنفيذ
كبر النطاق (مخازن + طلبات + جملة + نقطة بيع)التسليم يتأخرمراحل بتسليمات شغالة؛ الطلبات قبل نقطة البيع
أجهزة المخزن (سكانر، طابعة، تابلت)المحطات ماتشتغلشنحدد الأجهزة بدري ونجرب عليها في المرحلة 2
القيود التفصيلية للأدوار لسه مش متحددةصلاحيات غلطمصفوفة افتراضية قابلة للتعديل من اللوحة