{
    "openapi": "3.0.3",
    "info": {
        "title": "Mahalla On — Mobile API v1",
        "description": "واجهة برمجة التطبيقات الرسمية لتطبيق «المحلة أون».\n\n**كل** الاستجابات — الناجحة والفاشلة — تستخدم نفس المظروف الموحّد:\n\n```json\n{ \"status\": true, \"code\": 200, \"message\": \"...\", \"data\": {}, \"pagination\": {} }\n```\n\n`pagination` تظهر فقط في الـ endpoints المرقّمة، و`data` تُحذف عندما لا توجد بيانات (مثل تسجيل الخروج).\n\n### المعرّفات\nالـ API يرجع معرّفات مسبوقة (`plc_101`, `cat_17`, `usr_5`, `prd_201`, `off_301`, `rev_501`, `art_12`, `ntf_7`).\nعند الإرسال تقبل الـ endpoints أي من ثلاث صيغ: المعرّف المسبوق، الرقم المجرّد، أو الـ slug.\n\n### اللغة\nأرسل `Accept-Language: ar` (افتراضي) أو `en` للتحكم في لغة رسائل الأخطاء.\n\n### حدود المعدل\n`/auth/*` عشرة طلبات في الدقيقة، `/contact-us` خمسة، `/search/ai-analyze` ثلاثون. التجاوز يرجع `429` بنفس مظروف الخطأ.",
        "version": "1.0.0",
        "contact": {
            "name": "Mahalla On Dev Team",
            "email": "api-support@mahalla-on.com"
        }
    },
    "servers": [
        {
            "url": "http://127.0.0.1:8000/api/v1",
            "description": "Local"
        },
        {
            "url": "https://staging-api.mahalla-on.com/api/v1",
            "description": "Staging"
        },
        {
            "url": "https://api.mahalla-on.com/api/v1",
            "description": "Production"
        }
    ],
    "tags": [
        {
            "name": "Onboarding & Interests",
            "description": "شاشة التهيئة الأولى واهتمامات المستخدم"
        },
        {
            "name": "FAQ",
            "description": "الأسئلة الشائعة"
        },
        {
            "name": "Chats",
            "description": "محادثات البائع والمشتري في سوق المحلة"
        },
        {
            "name": "Subscriptions",
            "description": "الباقات وطلبات الترقية"
        },
        {
            "name": "Activity",
            "description": "متابعة نشاط المستخدم"
        },
        {
            "name": "Authentication",
            "description": "التسجيل وتسجيل الدخول واستعادة كلمة المرور"
        },
        {
            "name": "Profile",
            "description": "الملف الشخصي وكلمة المرور"
        },
        {
            "name": "Places Directory",
            "description": "التصنيفات ودليل الأماكن"
        },
        {
            "name": "Reviews",
            "description": "تقييمات الأماكن"
        },
        {
            "name": "Favorites",
            "description": "المفضلة"
        },
        {
            "name": "Mahalla Market",
            "description": "سوق المحلة والإعلانات المبوّبة"
        },
        {
            "name": "Offers & Coupons",
            "description": "العروض والكوبونات"
        },
        {
            "name": "Business Management",
            "description": "تبديل وضع المستخدم وإدارة النشاط وطلبات التعديل"
        },
        {
            "name": "Map & AI Search",
            "description": "الخريطة التفاعلية والبحث الذكي"
        },
        {
            "name": "Emergency",
            "description": "دليل الطوارئ"
        },
        {
            "name": "Banners",
            "description": "بانرات الصفحة الرئيسية"
        },
        {
            "name": "Articles",
            "description": "المقالات والأخبار"
        },
        {
            "name": "Notifications",
            "description": "إشعارات المستخدم"
        },
        {
            "name": "Support",
            "description": "التواصل والدعم"
        },
        {
            "name": "Taxonomy",
            "description": "شجرة التصنيف: نوع النشاط ← التصنيف ← التخصص الفرعي."
        },
        {
            "name": "Popup Ads",
            "description": "الإعلان المنبثق الذي يظهر عند فتح التطبيق — نظام منفصل عن بانرات الصفحة الرئيسية."
        },
        {
            "name": "Admin Moderation",
            "description": "مراجعة إعلانات سوق المحلة — متاحة لحسابات الإدارة فقط (is_admin)."
        },
        {
            "name": "System",
            "description": "حالة الخادم نفسه — أي نسخة شغالة عليه وأي مزايا موجودة فيها."
        },
        {
            "description": "Administrator operations",
            "name": "Admin"
        }
    ],
    "security": [],
    "paths": {
        "/app-config": {
            "get": {
                "summary": "إعدادات الوضع المجاني العامة",
                "description": "Read on startup, foreground resume and every 30 seconds while foregrounded. Do not cache. Hide subscription routes, payments, all badges and featured ads when free_mode is true. Existing stored subscription data is preserved. Creating subscriptions returns 409 while free mode is enabled.",
                "operationId": "getAppConfig",
                "security": [],
                "responses": {
                    "200": {
                        "description": "Current application mode",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "status": {"type": "boolean"},
                                        "code": {"type": "integer"},
                                        "message": {"type": "string"},
                                        "data": {
                                            "type": "object",
                                            "required": ["free_mode", "subscriptions_enabled", "payments_enabled", "badges_enabled", "featured_ads_enabled"],
                                            "properties": {
                                                "free_mode": {"type": "boolean"},
                                                "subscriptions_enabled": {"type": "boolean"},
                                                "payments_enabled": {"type": "boolean"},
                                                "badges_enabled": {"type": "boolean"},
                                                "featured_ads_enabled": {"type": "boolean"}
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/support": {
            "get": {
                "tags": [
                    "Support"
                ],
                "summary": "قائمة محادثات الدعم الخاصة بالمستخدم",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة مرقمة تضم id وsubject وstatus وlast_message_at وunread"
                    }
                }
            },
            "post": {
                "tags": [
                    "Support"
                ],
                "summary": "فتح محادثة دعم جديدة",
                "description": "مجاني لكل حساب. أرسل message أو attachment على الأقل. المرفق حتى 20 ميجابايت.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "subject"
                                ],
                                "properties": {
                                    "subject": {
                                        "type": "string"
                                    },
                                    "message": {
                                        "type": "string"
                                    },
                                    "attachment": {
                                        "type": "string",
                                        "format": "binary"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "تم فتح المحادثة"
                    }
                }
            }
        },
        "/support/{ticket}": {
            "get": {
                "tags": [
                    "Support"
                ],
                "summary": "تفاصيل محادثة الدعم",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "ticket",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تفاصيل المحادثة"
                    },
                    "404": {
                        "description": "غير موجودة أو لا تخص المستخدم"
                    }
                }
            }
        },
        "/support/{ticket}/messages": {
            "get": {
                "tags": [
                    "Support"
                ],
                "summary": "رسائل المحادثة بعد معرف محدد",
                "description": "يُستخدم للتحديث الدوري. يرجع حتى 100 رسالة بترتيب تصاعدي. كرر الطلب باستخدام آخر id.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "ticket",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "after_id",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "رسائل المحادثة"
                    }
                }
            },
            "post": {
                "tags": [
                    "Support"
                ],
                "summary": "إرسال رسالة أو مرفق للدعم",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "ticket",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "message": {
                                        "type": "string"
                                    },
                                    "attachment": {
                                        "type": "string",
                                        "format": "binary"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "تم إرسال الرسالة"
                    }
                }
            }
        },
        "/support/{ticket}/messages/{message}/attachment": {
            "get": {
                "tags": [
                    "Support"
                ],
                "summary": "تنزيل مرفق خاص من محادثة الدعم",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "ticket",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "message",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "محتوى المرفق"
                    },
                    "404": {
                        "description": "الملف غير موجود أو لا يخص المستخدم"
                    }
                }
            }
        },
        "/subscriptions/business-plans": {
            "get": {
                "tags": [
                    "Subscriptions"
                ],
                "summary": "باقات الأنشطة (باقات المحلاوي داخل صفحة النشاط)",
                "description": "قائمة منفصلة تماماً عن `/subscriptions/plans`. تلك باقات **الحساب** (رسائل المحلاوي في الصفحة الرئيسية وعدد إعلانات السوق)، وهذه باقات **النشاط**: الأسئلة التي تُحتسب على النشاط نفسه لا على الزائر. كل عنصر يحمل `quota_scope: \"business\"`.",
                "responses": {
                    "200": {
                        "description": "قائمة باقات الأنشطة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/business/form": {
            "get": {
                "tags": [
                    "Business Management"
                ],
                "summary": "حقول نموذج تسجيل النشاط",
                "description": "كتالوج الحقول التي يبنى منها نموذج «سجّل نشاطك» في التطبيق: الأقسام، نوع كل حقل، وأي endpoint يملأ خياراته، بالإضافة إلى أيام الأسبوع وأنواع الأصناف. الحقول المطلوبة ثلاثة فقط (`name`, `category_id`, `phone`) وكل ما عداها اختياري.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "كتالوج الحقول",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "غير مسجل الدخول",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/business/listings/{id}/assistant-settings": {
            "post": {
                "tags": [
                    "Business Management"
                ],
                "summary": "تحديد عدد أسئلة المحلاوي المسموح بها للزائر الواحد",
                "description": "الحد اليومي للنشاط كله (`assistant_daily_limit`) تحدده الباقة لأنه تكلفة تخصنا. أما كيفية تقسيمه بين الزوار فقرار صاحب النشاط: من دون هذا الحد كان أول زائر كثير الأسئلة يستهلك يوم النشاط كاملاً فيُغلق أمام باقي الزبائن. يُطبَّق فوراً بلا مراجعة إدارية، لأنه إعداد تشغيلي على نشاط صاحبه. أرسل `null` للعودة إلى رقم الباقة الافتراضي. الباقة تظل سقفاً: رقم أعلى من `assistant_visitor_limit_ceiling` يُرفض بـ422.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف النشاط (plc_12)."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "visitor_daily_limit"
                                ],
                                "properties": {
                                    "visitor_daily_limit": {
                                        "type": "integer",
                                        "nullable": true,
                                        "minimum": 1,
                                        "description": "عدد أسئلة الزائر الواحد خلال 24 ساعة. `null` = اتبع رقم الباقة."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم التحديث، ويُعاد ملخّص المحلاوي كاملاً",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "النشاط غير موجود أو غير تابع لحسابك",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "الرقم أعلى من سقف الباقة الحالية",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/business/listings/{id}/plan": {
            "get": {
                "tags": [
                    "Business Management"
                ],
                "summary": "باقة النشاط الحالية والباقات المتاحة واستهلاك أسئلته",
                "description": "شاشة «باقة نشاطي». مفصولة عن `/subscriptions/current` عمداً: تلك باقة الحساب، وهذه باقة النشاط — والأسئلة داخل صفحة النشاط تُخصم من هذه لا من تلك.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف النشاط (plc_12)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "باقة النشاط",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "النشاط غير موجود أو غير تابع لحسابك",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Business Management"
                ],
                "summary": "طلب ترقية باقة النشاط",
                "description": "يُنشئ طلباً قيد المراجعة. لا يتم تفعيل أي شيء هنا — الإدارة تراجع التحويل ثم تربط النشاط بالباقة.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف النشاط (plc_12)."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "plan",
                                    "payment_method"
                                ],
                                "properties": {
                                    "plan": {
                                        "type": "string",
                                        "example": "bplan_2",
                                        "description": "يقبل bplan_2 أو 2 أو business-standard."
                                    },
                                    "payment_method": {
                                        "type": "string",
                                        "example": "vodafone_cash"
                                    },
                                    "phone": {
                                        "type": "string"
                                    },
                                    "transaction_ref": {
                                        "type": "string"
                                    },
                                    "note": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "تم استلام الطلب",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الباقة أو النشاط غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "يوجد طلب قيد المراجعة أو بيانات ناقصة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/business/plan-requests/{id}": {
            "delete": {
                "tags": [
                    "Business Management"
                ],
                "summary": "إلغاء طلب باقة نشاط لم تتم مراجعته",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف الطلب (bpreq_3)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم الإلغاء",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الطلب غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "تمت مراجعة الطلب بالفعل",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/popups": {
            "get": {
                "tags": [
                    "Popup Ads"
                ],
                "summary": "الإعلان المنبثق المطلوب عرضه الآن",
                "description": "الإعلان الذي يظهر فوق الصفحة الرئيسية عند فتح التطبيق. **ليس** بانر السلايدر — نظام منفصل تماماً بجمهور وتكرار خاصين به.\n\nيرجع مصفوفة فيها عنصر واحد على الأكثر (أو صفر). التكرار (`once` / `daily` / `every_open`) محسوب على السيرفر لكل مستخدم، وللزائر عبر `device_id`.",
                "parameters": [
                    {
                        "name": "device_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف جهاز الزائر غير المسجل. يمكن إرساله أيضاً في ترويسة X-Device-Id."
                    },
                    {
                        "name": "all",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "إرجاع كل الإعلانات المتاحة بدل واحد فقط."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "إعلان منبثق أو قائمة فارغة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/popups/{id}/seen": {
            "post": {
                "tags": [
                    "Popup Ads"
                ],
                "summary": "تسجيل ظهور الإعلان المنبثق",
                "description": "يُستدعى لحظة رسم الإعلان. هذا ما يجعل «مرة واحدة» و«مرة كل يوم» لهما معنى؛ بدونه يعود نفس الإعلان في كل فتح.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف الإعلان (pop_3)."
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "device_id": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم التسجيل",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الإعلان غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/popups/{id}/click": {
            "post": {
                "tags": [
                    "Popup Ads"
                ],
                "summary": "تسجيل الضغط على الإعلان",
                "description": "يُحتسب كظهور أيضاً.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف الإعلان (pop_3)."
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "device_id": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم التسجيل",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الإعلان غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/popups/{id}/dismiss": {
            "post": {
                "tags": [
                    "Popup Ads"
                ],
                "summary": "تسجيل إغلاق الإعلان",
                "description": "مفصول عن `seen` لأن إعلاناً أغلقه المستخدم عمداً ليس كإعلان تجاهله.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف الإعلان (pop_3)."
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "device_id": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم التسجيل",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الإعلان غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/feed": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "سوق المحلة: المنتجات والطلبات في قائمة واحدة",
                "description": "كل عنصر يحمل `type` بقيمة `product` أو `request`، والتطبيق يبدّل شكل البطاقة عليه. `type=product` أو `type=request` يقصر النتيجة على نصف واحد.",
                "parameters": [
                    {
                        "name": "type",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "all",
                                "product",
                                "request"
                            ]
                        }
                    },
                    {
                        "name": "category",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "عناصر السوق",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/request-categories": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "أنواع طلبات السوق",
                "description": "الأنواع المستخدمة فعلاً أولاً مع عدد الطلبات في كل نوع، يليها اقتراحات ثابتة لسوق لم يُنشر فيه شيء بعد.",
                "responses": {
                    "200": {
                        "description": "أنواع الطلبات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/requests": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "الطلبات والخدمات المنشورة في السوق",
                "description": "الطلب هو «عايز حد يعملّي كذا». بيانات التواصل الخاصة بصاحب الطلب لا تُنشر — `contact` تكون null لأي شخص غير صاحب الطلب أو المنفّذ المختار.",
                "parameters": [
                    {
                        "name": "category",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "open_to",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "any",
                                "person",
                                "business"
                            ]
                        }
                    },
                    {
                        "name": "open_only",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "الافتراضي true: الطلبات التي ما زالت تستقبل عروضاً فقط."
                    },
                    {
                        "name": "min_budget",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "number"
                        }
                    },
                    {
                        "name": "max_budget",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "number"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "sort_by",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "latest",
                                "budget_asc",
                                "budget_desc",
                                "urgent",
                                "popular"
                            ]
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة الطلبات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "نشر طلب أو خدمة جديدة",
                "description": "يمرّ بالمراجعة مثل إعلانات السوق تماماً (`status: pending`) ما لم يكن `MARKET_AUTO_PUBLISH` مفعّلاً. `open_to` يحدد من يحق له تقديم عرض: `any` أو `person` أو `business`.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "title",
                                    "category",
                                    "phone"
                                ],
                                "properties": {
                                    "title": {
                                        "type": "string"
                                    },
                                    "description": {
                                        "type": "string"
                                    },
                                    "category": {
                                        "type": "string"
                                    },
                                    "budget_min": {
                                        "type": "number"
                                    },
                                    "budget_max": {
                                        "type": "number"
                                    },
                                    "needed_at": {
                                        "type": "string",
                                        "format": "date-time"
                                    },
                                    "location": {
                                        "type": "string"
                                    },
                                    "city_id": {
                                        "type": "integer"
                                    },
                                    "phone": {
                                        "type": "string"
                                    },
                                    "whatsapp": {
                                        "type": "string"
                                    },
                                    "open_to": {
                                        "type": "string",
                                        "enum": [
                                            "any",
                                            "person",
                                            "business"
                                        ]
                                    },
                                    "images": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "binary"
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "تم استلام الطلب",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "بيانات ناقصة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/requests/{id}": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "تفاصيل طلب السوق",
                "description": "صاحب الطلب يستلم معه قائمة العروض؛ غيره لا. `contact` تظهر لصاحب الطلب وللمنفّذ المختار فقط.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف الطلب (req_5)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تفاصيل الطلب",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الطلب غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "تعديل طلب لم يُقبل عليه عرض بعد",
                "description": "التعديل متاح فقط قبل اختيار منفّذ. بعد التعديل يعود الطلب للمراجعة إن كانت المراجعة مفعّلة.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف الطلب (req_5)."
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "title": {
                                        "type": "string"
                                    },
                                    "description": {
                                        "type": "string"
                                    },
                                    "category": {
                                        "type": "string"
                                    },
                                    "budget_min": {
                                        "type": "number"
                                    },
                                    "budget_max": {
                                        "type": "number"
                                    },
                                    "needed_at": {
                                        "type": "string",
                                        "format": "date-time"
                                    },
                                    "location": {
                                        "type": "string"
                                    },
                                    "phone": {
                                        "type": "string"
                                    },
                                    "whatsapp": {
                                        "type": "string"
                                    },
                                    "open_to": {
                                        "type": "string",
                                        "enum": [
                                            "any",
                                            "person",
                                            "business"
                                        ]
                                    },
                                    "images": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "binary"
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم التحديث",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الطلب غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "لا يمكن تعديل طلب تم اختيار منفّذ له",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "حذف طلب",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف الطلب (req_5)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم الحذف",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الطلب غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "يوجد منفّذ متعيّن على الطلب",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/requests/{id}/complete": {
            "post": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "تأكيد تنفيذ الطلب",
                "description": "صاحب الطلب وحده هو من يغلقه — لا المنفّذ. الإغلاق يزيد عدد الأعمال المكتملة للمنفّذ ويفتح باب التقييم.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف الطلب (req_5)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم الإغلاق",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الطلب غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "الطلب ليس في حالة تسمح بالإغلاق",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/requests/{id}/review": {
            "post": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "تقييم منفّذ الطلب",
                "description": "مرة واحدة لكل طلب، من صاحب الطلب، عن المنفّذ الذي قُبل عرضه، وبعد تأكيد التنفيذ. هذه السلسلة هي ما يجعل التقييم يستحق القراءة.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف الطلب (req_5)."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "rating"
                                ],
                                "properties": {
                                    "rating": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 5
                                    },
                                    "comment": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم التقييم",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الطلب غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "الطلب غير مكتمل أو تم تقييمه من قبل",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/requests/{id}/offers": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "عروض الطلب",
                "description": "كل العروض المقدَّمة على الطلب. مسار عام: أي مستخدم — وحتى غير المسجَّل — يرى كل العروض بأسعارها. قبول العرض وحده محصور في صاحب الطلب.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف الطلب (req_5)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة العروض",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الطلب غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "تقديم عرض على طلب",
                "description": "يشترط ملف منفّذ مكتمل (`/market/provider-profile`) — الاسم والتليفون والمدينة ومجال العمل. بدونه ترجع 422 ومعها `missing_fields`.\n\nإرسال العرض مرة ثانية يستبدل العرض السابق ولا يضيف عرضاً جديداً. `listing_id` يجعل العرض باسم نشاط مسجّل، وهو شرط الطلبات المفتوحة للأنشطة فقط.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف الطلب (req_5)."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "price"
                                ],
                                "properties": {
                                    "price": {
                                        "type": "number"
                                    },
                                    "duration_value": {
                                        "type": "integer"
                                    },
                                    "duration_unit": {
                                        "type": "string",
                                        "enum": [
                                            "hour",
                                            "day",
                                            "week"
                                        ]
                                    },
                                    "message": {
                                        "type": "string"
                                    },
                                    "listing_id": {
                                        "type": "string",
                                        "example": "plc_12"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "وصل العرض لصاحب الطلب",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "ملف المنفّذ موقوف",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الطلب غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "ملف المنفّذ غير مكتمل أو الطلب لا يقبل عرضك",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/offers/{id}/accept": {
            "post": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "قبول عرض وتعيين المنفّذ",
                "description": "يقبل عرضاً واحداً، يرفض باقي العروض ويُشعر أصحابها، ويكشف بيانات تواصل صاحب الطلب للمنفّذ المختار. عرض ثانٍ على نفس الطلب يُرفض بـ 422 بدل أن يستبدل الأول.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف العرض (bid_9)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم اختيار المنفّذ",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "العرض غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "الطلب ليس لك أو تم قبول عرض آخر",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/offers/{id}": {
            "delete": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "سحب عرض",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف العرض (bid_9)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم السحب",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "العرض غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "تم قبول العرض بالفعل",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/my-requests": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "طلباتي في السوق بكل حالاتها",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة طلباتي",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/my-offers": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "عروضي على طلبات الآخرين",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة عروضي",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/provider-profile": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "بياناتي كمنفّذ وما ينقصها",
                "description": "البوابة أمام تقديم أي عرض. لا يُسمح بالتقديم إلا بنشاط مملوك للحساب ومنشور وفعّال. `can_submit_offer` هي النتيجة النهائية، و`businesses` الأنشطة الصالحة للاختيار.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "بيانات المنفّذ",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "حفظ بيانات المنفّذ",
                "description": "اختيار نشاط منشور عبر `listing_id`. يمكن إرسال بيانات تواصل بديلة معه؛ لا يوجد تقديم بملف شخصي من غير نشاط.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "listing_id"
                                ],
                                "properties": {
                                    "full_name": {
                                        "type": "string"
                                    },
                                    "phone": {
                                        "type": "string"
                                    },
                                    "whatsapp": {
                                        "type": "string"
                                    },
                                    "city_id": {
                                        "type": "integer"
                                    },
                                    "area": {
                                        "type": "string"
                                    },
                                    "work_field": {
                                        "type": "string",
                                        "example": "سباك"
                                    },
                                    "bio": {
                                        "type": "string"
                                    },
                                    "experience_years": {
                                        "type": "integer"
                                    },
                                    "listing_id": {
                                        "type": "string",
                                        "example": "plc_12"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم الحفظ",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "بيانات ناقصة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/providers/{id}": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "بطاقة منفّذ: مجاله وتقييمه وعدد أعماله",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف المستخدم (usr_7)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "بيانات المنفّذ",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "المنفّذ غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/providers/{id}/reviews": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "تقييمات المنفّذ",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف المستخدم (usr_7)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة التقييمات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/market/pending-requests": {
            "get": {
                "tags": [
                    "Admin Moderation"
                ],
                "summary": "طلبات السوق في انتظار المراجعة",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "الافتراضي pending، و all لكل الحالات."
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة الطلبات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "غير مصرح",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/market/requests/{id}/approve": {
            "post": {
                "tags": [
                    "Admin Moderation"
                ],
                "summary": "نشر طلب سوق بعد المراجعة",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف الطلب (req_5)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم النشر",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "غير مصرح",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الطلب غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/market/requests/{id}/reject": {
            "post": {
                "tags": [
                    "Admin Moderation"
                ],
                "summary": "رفض طلب سوق مع ذكر السبب",
                "description": "السبب مطلوب ويصل لصاحب الطلب كإشعار — الرفض بدون سبب يعود كطلب مكرر.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "معرّف الطلب (req_5)."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "reason"
                                ],
                                "properties": {
                                    "reason": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم الرفض",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "غير مصرح",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "الطلب غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "سبب الرفض مطلوب",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/onboarding/interests": {
            "get": {
                "tags": [
                    "Onboarding & Interests"
                ],
                "summary": "التصنيفات المتاحة كاهتمامات وحالة التهيئة الحالية",
                "description": "الاهتمامات هي تصنيفات حقيقية من الدليل، وليست قائمة ثابتة. الاستجابة تحتوي على `should_show_onboarding` — الحقل الوحيد الذي يحتاجه التطبيق ليقرر عرض الشاشة من عدمه. متاح للزوار.",
                "parameters": [
                    {
                        "name": "onboarding_token",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "رمز الزائر إن وُجد."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة الاهتمامات وحالة التهيئة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Onboarding & Interests"
                ],
                "summary": "حفظ اهتمامات التهيئة وإنهاء الشاشة",
                "description": "يحفظ الاختيار ويعلّم التهيئة كمكتملة في نداء واحد. الزائر يستلم `onboarding_token` في الاستجابة ويستخدمه لاحقاً مع `/onboarding/claim`.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "interests"
                                ],
                                "properties": {
                                    "interests": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "example": "cat_17"
                                        },
                                        "description": "معرّفات التصنيفات المختارة (تقبل cat_17 أو 17)."
                                    },
                                    "note": {
                                        "type": "string",
                                        "description": "إجابة اختيارية على «بتدور على إيه؟». يُنقّى من الأرقام والبريد والروابط قبل التخزين."
                                    },
                                    "city_id": {
                                        "type": "string",
                                        "example": "el-mahalla-el-kubra"
                                    },
                                    "location_id": {
                                        "type": "string",
                                        "example": "loc_57"
                                    },
                                    "onboarding_token": {
                                        "type": "string",
                                        "description": "رمز التهيئة للزائر — يرجع من أول استجابة ويُرسل في الطلبات التالية حتى إنشاء الحساب.",
                                        "example": "Yq3xN1p8..."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم حفظ الاهتمامات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/onboarding/skip": {
            "post": {
                "tags": [
                    "Onboarding & Interests"
                ],
                "summary": "تخطي شاشة التهيئة",
                "description": "التخطي إجابة وليس غياباً لها — يُسجَّل لحساب نسبة التخطي. لا يمسح أي اختيار سابق.",
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "onboarding_token": {
                                        "type": "string",
                                        "description": "رمز التهيئة للزائر — يرجع من أول استجابة ويُرسل في الطلبات التالية حتى إنشاء الحساب.",
                                        "example": "Yq3xN1p8..."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم تخطي الخطوة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/onboarding/events": {
            "post": {
                "tags": [
                    "Onboarding & Interests"
                ],
                "summary": "تسجيل حدث تهيئة من التطبيق",
                "description": "للأحداث التي لا يمكن للخادم رؤيتها بنفسه — حالياً `onboarding_started` فقط. باقي خطوات القمع (اختيار/إزالة/ملاحظة/تخطي/إكمال) تُسجَّل في الخادم عند حدوثها فعلاً.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "name"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "enum": [
                                            "onboarding_started"
                                        ]
                                    },
                                    "onboarding_token": {
                                        "type": "string",
                                        "description": "رمز التهيئة للزائر — يرجع من أول استجابة ويُرسل في الطلبات التالية حتى إنشاء الحساب.",
                                        "example": "Yq3xN1p8..."
                                    },
                                    "city_id": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم تسجيل الحدث",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/onboarding/claim": {
            "post": {
                "tags": [
                    "Onboarding & Interests"
                ],
                "summary": "ربط اهتمامات الزائر بالحساب بعد التسجيل",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "ينقل إجابة التهيئة التي أعطاها المستخدم قبل إنشاء الحساب إلى حسابه. آمن للاستدعاء برمز غير معروف أو مستهلك — يرجع حالة الحساب الحالية.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "onboarding_token"
                                ],
                                "properties": {
                                    "onboarding_token": {
                                        "type": "string",
                                        "description": "رمز التهيئة للزائر — يرجع من أول استجابة ويُرسل في الطلبات التالية حتى إنشاء الحساب.",
                                        "example": "Yq3xN1p8..."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم ربط الاهتمامات بالحساب",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/profile/interests": {
            "get": {
                "tags": [
                    "Profile"
                ],
                "summary": "اهتمامات المستخدم الحالية",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "نفس قائمة التهيئة مع تحديد ما اختاره هذا الحساب، حتى تكون شاشة «اهتماماتي» في الإعدادات هي نفس الشاشة وليست نسخة ثانية منها.",
                "responses": {
                    "200": {
                        "description": "الاهتمامات الحالية",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            },
            "post": {
                "tags": [
                    "Profile"
                ],
                "summary": "تحديث اهتمامات المستخدم",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "استبدال كامل وليس إضافة: القائمة المرسلة هي الاختيار النهائي. إرسال قائمة فارغة يمسح كل الاهتمامات.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "interests"
                                ],
                                "properties": {
                                    "interests": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "example": "cat_17"
                                        },
                                        "description": "معرّفات التصنيفات المختارة (تقبل cat_17 أو 17)."
                                    },
                                    "note": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم تحديث الاهتمامات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/assistant/alerts": {
            "get": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "الطلبات المسجّلة للتنبيه عند التوفّر",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "الطلبات التي وافق المستخدم على إشعاره عند توفّر مقدّم خدمة مناسب لها.",
                "responses": {
                    "200": {
                        "description": "قائمة التنبيهات النشطة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            },
            "post": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "تسجيل طلب للتنبيه عند توفّر مقدّم خدمة",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "يُستدعى بعد موافقة المستخدم صراحةً على «تحب أسجّل طلبك وأبعتلك لما يبقى فيه حد؟». `tracking_id` هو نفسه الذي يرجع مع رد `/assistant/message`، فلا يحتاج التطبيق لمعرفة أي شيء عن بنية الطلب.\n\nيرجع `422` إذا كان الطلب لا يمثّل بحثاً عن شيء (تحية أو سؤال متابعة).",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "tracking_id"
                                ],
                                "properties": {
                                    "tracking_id": {
                                        "type": "string",
                                        "example": "asq_14.7f35c8d9e21a4f67b903d124"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم تسجيل التنبيه",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/assistant/alerts/{id}": {
            "delete": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "إلغاء تنبيه توفّر",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "alrt_12"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم إلغاء التنبيه",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/faq": {
            "get": {
                "tags": [
                    "FAQ"
                ],
                "summary": "الأسئلة الشائعة",
                "description": "مجمّعة حسب القسم كما تعرضها الشاشة، وغير مُرقّمة لأن القائمة كاملة تُعرض مرة واحدة.\n\n`answer` قد تكون `null` لسؤال لم تُكتب إجابته بعد — التطبيق يعرض دعوة للتواصل بدلاً منها.",
                "parameters": [
                    {
                        "name": "search",
                        "in": "query",
                        "description": "بحث نصي داخل الأسئلة والإجابات",
                        "schema": {
                            "type": "string",
                            "example": "كلمة المرور"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "أقسام الأسئلة الشائعة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/FaqCategory"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/chats": {
            "get": {
                "tags": [
                    "Chats"
                ],
                "summary": "قائمة المحادثات",
                "description": "محادثات المستخدم مرتّبة بأحدث رسالة. `name` و`unread_count` محسوبان من وجهة نظر المستخدم الحالي.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "المحادثات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Chat"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/chats/unread-count": {
            "get": {
                "tags": [
                    "Chats"
                ],
                "summary": "عدد الرسائل غير المقروءة",
                "description": "endpoint منفصل حتى تتحدّث شارة التبويب بدون تحميل قائمة المحادثات.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "العدد",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "unread_count": {
                                                            "type": "integer",
                                                            "example": 2
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/chats/start": {
            "post": {
                "tags": [
                    "Chats"
                ],
                "summary": "بدء محادثة من إعلان",
                "description": "عملية idempotent: استدعاؤها مرة أخرى لنفس الإعلان يرجع المحادثة القائمة بكود **200** بدلاً من إنشاء محادثة مكرّرة بكود 201.\n\nالمحادثة مرتبطة بـ (المشتري، البائع، الإعلان) وليس بالبائع وحده، حتى يظل حقل `product` ذا معنى عند مراسلة نفس البائع على أكثر من إعلان.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "product_id"
                                ],
                                "properties": {
                                    "product_id": {
                                        "type": "string",
                                        "example": "prd_1"
                                    },
                                    "message": {
                                        "type": "string",
                                        "maxLength": 2000,
                                        "example": "السلام عليكم، لسه متاح؟"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "المحادثة موجودة بالفعل",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Chat"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "201": {
                        "description": "تم بدء المحادثة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Chat"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/chats/{id}": {
            "delete": {
                "tags": [
                    "Chats"
                ],
                "summary": "حذف محادثة",
                "description": "تُخفى للطرف الطالب فقط — الطرف الآخر يحتفظ بنسخته من المحادثة، وأي رسالة جديدة تعيدها للظهور.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ChatId"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/chats/{id}/messages": {
            "get": {
                "tags": [
                    "Chats"
                ],
                "summary": "رسائل محادثة",
                "description": "الأحدث أولاً، فالصفحة الأولى هي ما يعرضه التطبيق عند الفتح.\n\nفتح المحادثة هو ما يعلّم رسائلها كمقروءة — لا يوجد endpoint منفصل لذلك.\n\nمحادثة تخصّ مستخدماً آخر ترجع **404** وليس 403.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ChatId"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "الرسائل",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ChatMessage"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            },
            "post": {
                "tags": [
                    "Chats"
                ],
                "summary": "إرسال رسالة أو مرفق",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ChatId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "text"
                                ],
                                "properties": {
                                    "text": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 2000,
                                        "example": "تمام، هبعتلك الموقع دلوقتي"
                                    }
                                }
                            }
                        },
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "attachment": {
                                        "type": "string",
                                        "format": "binary",
                                        "description": "صورة / فيديو / صوت / مستند. الحدود الافتراضية: صور 8 ميجا، فيديو 32 ميجا، صوت 16 ميجا، ملفات 16 ميجا."
                                    },
                                    "text": {
                                        "type": "string",
                                        "maxLength": 2000,
                                        "description": "تعليق اختياري مع المرفق."
                                    },
                                    "duration_ms": {
                                        "type": "integer",
                                        "description": "للرسائل الصوتية والفيديو — مدة التسجيل بالملي ثانية. العميل هو اللي بيبعتها؛ السيرفر ما بيقراهاش من الملف.",
                                        "example": 7400
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "تم الإرسال",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/ChatMessage"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "رسالة فاضية من غير مرفق، أو نوع/حجم ملف غير مسموح",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                },
                "description": "بيقبل `application/json` للنص العادي و`multipart/form-data` للمرفقات، من نفس المسار.\n\n**لازم تبعت `text` أو `attachment` أو الاتنين.** الاتنين فاضيين بيرجع 422.\n\nأنواع المرفقات: صورة / فيديو / صوت / ملف — النوع بيتحدد من محتوى الملف نفسه مش من امتداده، وبيرجع في `type`.\n\nالحدود بترجع في `attachment_rules` مع `GET /chats/{id}/updates` — اقراها منها بدل ما تكتبها ثابتة في التطبيق، عشان ترفض الملف قبل ما تصرف الرفع.\n\nالطرف التاني بيوصله إشعار Firebase فيه data payload: `{\"type\":\"chat_message\",\"chat_id\":\"chat_12\"}` مع notification block (عنوان/نص) عشان يظهر إشعار نظام والتطبيق مقفول."
            }
        },
        "/notifications/register-device": {
            "post": {
                "tags": [
                    "Notifications"
                ],
                "summary": "تسجيل جهاز لاستقبال الإشعارات",
                "description": "تُستدعى عند تسجيل الدخول وعند تدوير FCM للتوكن (`onTokenRefresh`).\n\nالتوكن فريد على مستوى الجدول كله وليس لكل مستخدم: جهاز انتقل لحساب آخر يعيد التسجيل فينتقل التوكن للحساب الجديد بدلاً من إرسال إشعارات حساب لآخر.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "fcm_token",
                                    "platform"
                                ],
                                "properties": {
                                    "fcm_token": {
                                        "type": "string",
                                        "maxLength": 512,
                                        "example": "eXaMpLeFcmTokenString..."
                                    },
                                    "platform": {
                                        "type": "string",
                                        "enum": [
                                            "android",
                                            "ios",
                                            "web"
                                        ],
                                        "example": "android"
                                    },
                                    "device_name": {
                                        "type": "string",
                                        "nullable": true,
                                        "example": "Samsung A54"
                                    },
                                    "app_version": {
                                        "type": "string",
                                        "nullable": true,
                                        "example": "1.4.0"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/notifications/unregister-device": {
            "post": {
                "tags": [
                    "Notifications"
                ],
                "summary": "إلغاء تسجيل جهاز",
                "description": "تُستدعى قبل `/auth/logout` مباشرة. آمنة إذا كان التوكن محذوفاً بالفعل، فإعادة محاولة تسجيل الخروج لا تفشل هنا.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "fcm_token"
                                ],
                                "properties": {
                                    "fcm_token": {
                                        "type": "string",
                                        "maxLength": 512,
                                        "example": "eXaMpLeFcmTokenString..."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/subscriptions/plans": {
            "get": {
                "tags": [
                    "Subscriptions"
                ],
                "summary": "الباقات المتاحة",
                "description": "عامة حتى يمكن عرض الباقات قبل تسجيل الدخول.\n\n`duration_days = null` تعني باقة لا تنتهي (المجانية)، و`ads_limit = null` تعني إعلانات غير محدودة — وهي غير `0` التي تعني منع النشر.",
                "responses": {
                    "200": {
                        "description": "الباقات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Plan"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/subscriptions/payment-methods": {
            "get": {
                "tags": [
                    "Subscriptions"
                ],
                "summary": "طرق الدفع المتاحة",
                "description": "لا توجد بوابة دفع بعد: الترقية تحويل يدوي تراجعه الإدارة، لذلك يحتاج التطبيق لمعرفة المحافظ وأرقامها. تأتي من إعدادات الخادم حتى تتغيّر الأرقام بدون إصدار جديد من التطبيق.",
                "responses": {
                    "200": {
                        "description": "طرق الدفع",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/PaymentMethod"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/subscriptions/current": {
            "get": {
                "tags": [
                    "Subscriptions"
                ],
                "summary": "الاشتراك الحالي",
                "description": "يرجع باقة دائماً: حساب لم يشترك قط يقع على الباقة الافتراضية (المجانية)، وهي حالة حقيقية تعرضها الشاشة وليست 404.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "بيانات الاشتراك",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/CurrentSubscription"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/subscriptions/requests": {
            "get": {
                "tags": [
                    "Subscriptions"
                ],
                "summary": "سجل طلبات الاشتراك",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "الطلبات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/SubscriptionRequest"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/subscriptions/requests/{id}": {
            "delete": {
                "tags": [
                    "Subscriptions"
                ],
                "summary": "سحب طلب اشتراك",
                "description": "يعمل فقط على طلب ما زال `pending`. طلب تمت مراجعته يرجع 422.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/SubscriptionRequestId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم الإلغاء",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/SubscriptionRequest"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/subscriptions/{plan}/subscribe": {
            "post": {
                "tags": [
                    "Subscriptions"
                ],
                "summary": "طلب ترقية الباقة",
                "description": "يسجّل **طلباً** ولا يفعّل شيئاً: الإدارة تتحقق من التحويل ثم توافق، والموافقة هي ما ينشئ الاشتراك.\n\nيُسمح بطلب مفتوح واحد فقط لكل مستخدم — طلب ثانٍ يرجع 422.\n\n`payment_method` يجب أن يكون أحد المفاتيح المرجعة من `/subscriptions/payment-methods`، و`phone` مطلوب للطرق التي `requires_phone = true`.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/PlanId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "payment_method"
                                ],
                                "properties": {
                                    "payment_method": {
                                        "type": "string",
                                        "example": "vodafone_cash"
                                    },
                                    "phone": {
                                        "type": "string",
                                        "nullable": true,
                                        "description": "الرقم المُحوَّل منه",
                                        "example": "01012345678"
                                    },
                                    "transaction_ref": {
                                        "type": "string",
                                        "nullable": true,
                                        "example": "TRX-99213"
                                    },
                                    "note": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 1000
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "تم إرسال الطلب",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/SubscriptionRequest"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/activity/summary": {
            "get": {
                "tags": [
                    "Activity"
                ],
                "summary": "ملخص النشاط",
                "description": "أرقام بطاقات شاشة «متابعة النشاط». الأعداد الثلاثة الأولى تخص إعلانات السوق، والباقي إضافي يغني عن نداءات أخرى.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "الملخص",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/ActivitySummary"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/activity/recent": {
            "get": {
                "tags": [
                    "Activity"
                ],
                "summary": "النشاط الأخير",
                "description": "سجل مكتوب لحظة وقوع الحدث، فيبقى نصّه صحيحاً بعد تعديل أو حذف ما يشير إليه.\n\n`related_id` هو المعرّف العام المسبوق (`prd_12`) فيمكن تمريره مباشرة للشاشة المقابلة.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "type",
                        "in": "query",
                        "description": "تصفية بنوع الحدث",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "ad_submitted",
                                "ad_approved",
                                "ad_rejected",
                                "ad_sold",
                                "ad_expired",
                                "review_submitted",
                                "subscription_requested",
                                "subscription_approved",
                                "subscription_rejected"
                            ]
                        }
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "النشاط",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Activity"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/auth/register": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "إنشاء حساب جديد",
                "description": "الحساب المسجَّل بالهاتف فقط يحصل داخلياً على بريد بديل `{phone}@phone.mahalla-on.com` — لا تعرضه للمستخدم.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "name",
                                    "gender",
                                    "password",
                                    "password_confirmation"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "example": "محمد علي المحلاوي"
                                    },
                                    "phone": {
                                        "type": "string",
                                        "pattern": "^01[0-9]{9}$",
                                        "nullable": true, "description": "اختياري. عند إدخاله: 11 رقماً يبدأ بـ 01، فريد",
                                        "example": "01012345678"
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "nullable": true,
                                        "description": "اختياري، فريد لو أُرسل",
                                        "example": "mohamed.ali@example.com"
                                    },
                                    "area": {
                                        "type": "string",
                                        "nullable": true,
                                        "example": "المحلة الكبرى - المنشية"
                                    },
                                    "gender": {
                                        "type": "string",
                                        "enum": [
                                            "male",
                                            "female"
                                        ],
                                        "example": "male"
                                    },
                                    "password": {
                                        "type": "string",
                                        "minLength": 6,
                                        "example": "Secret123"
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "example": "Secret123"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "تم إنشاء الحساب بنجاح",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AuthSuccessResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/auth/apple": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "تسجيل الدخول بأبل (نقرة واحدة)",
                "description": "نفس منطق `/auth/google` تماماً، لكن مع Sign in with Apple. يُتحقق من توقيع الـ `id_token` مقابل مفاتيح أبل المنشورة.\n\n**فرقان مهمان عن جوجل، وسببهما أبل نفسها:**\n\n1. **الاسم غير موجود داخل التوكن.** أبل ترسله للتطبيق مرة واحدة فقط عند أول تفويض، ولا ترسله للسيرفر أبداً. لذلك حقل `name` في جسم الطلب هو المصدر الوحيد المتاح ويُستخدم كما هو — أرسله في أول مرة وإلا ضاع.\n\n2. **البريد قد يكون مخفياً أو غائباً.** مع خاصية Hide My Email يأتي عنوان `@privaterelay.appleid.com`، وفي بعض الإعدادات لا يأتي بريد إطلاقاً عند تسجيلات الدخول التالية. لذلك الحساب مرتبط بـ `sub` وليس بالبريد، ولو لم يوجد بريد يُنشأ عنوان بديل `…@apple.mahalla-on.com`.\n\nباقي السلوك مطابق لجوجل: حساب موجود ⇒ دخول وربط، حساب جديد ⇒ إنشاء فوري بالقيم الافتراضية `area = \"المحلة الكبرى\"` و`gender = \"male\"` و`phone = null`.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "id_token"
                                ],
                                "properties": {
                                    "id_token": {
                                        "type": "string",
                                        "description": "الـ JWT الصادر من أبل. هذا هو الحقل الوحيد الذي يثق به السيرفر.",
                                        "example": "eyJraWQiOiJBSURPU0ExMS..."
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "description": "يُستخدم فقط إذا لم يحمل التوكن بريداً.",
                                        "example": "user@privaterelay.appleid.com"
                                    },
                                    "name": {
                                        "type": "string",
                                        "description": "المصدر الوحيد للاسم — أبل لا تضعه في التوكن. أرسله في أول تسجيل دخول.",
                                        "example": "اسم المستخدم"
                                    },
                                    "apple_id": {
                                        "type": "string",
                                        "description": "اختياري — يُقرأ من التوكن (`sub`) عند التعارض.",
                                        "example": "001234.abcdef..."
                                    },
                                    "provider": {
                                        "type": "string",
                                        "example": "apple"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم تسجيل الدخول بنجاح",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AuthSuccessResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "رمز أبل غير صالح أو منتهي الصلاحية",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/auth/send-otp": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "إرسال رمز تحقق على البريد الإلكتروني",
                "description": "يولّد رمزاً من 6 أرقام ويرسله بالبريد عبر SMTP. الرمز صالح 10 دقائق ولمرة واحدة، ويُخزَّن مُشفَّراً في الـ Cache.\n\nيرجع `200` سواء كان البريد مسجّلاً أو لا — اختلاف الرد كان سيتحول إلى وسيلة لاكتشاف الحسابات.\n\n**الحدود:** 5 طلبات لكل بريد خلال 10 دقائق (يرجع `429`)، بالإضافة إلى throttle عام 5 طلبات/دقيقة لكل IP. وإعادة الإرسال تُلغي الرمز السابق، فالرسالة الأحدث في البريد هي الوحيدة الصالحة.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "email"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "user@example.com"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/auth/verify-otp": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "التحقق من رمز البريد الإلكتروني",
                "description": "يتحقق من الرمز ويستهلكه — لا يمكن استخدام نفس الرمز مرتين. 5 محاولات خاطئة تُحرق الرمز نهائياً.\n\nعند النجاح يُسجَّل أن هذا البريد تم التحقق منه لمدة 30 دقيقة، ويمكن لـ `/auth/register` أن يعتمد على ذلك لإنشاء الحساب بـ `is_phone_confirmed = true` مباشرة.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "email",
                                    "otp"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "user@example.com"
                                    },
                                    "otp": {
                                        "type": "string",
                                        "example": "482910"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "422": {
                        "description": "رمز التحقق غير صحيح أو منتهي الصلاحية",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/auth/confirm-phone": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "تأكيد رقم الهاتف",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "يضبط `is_phone_confirmed = true` للحساب صاحب التوكن، ويحفظ الرقم عليه لو لم يكن له رقم (مثل الحسابات المسجّلة بجوجل أو أبل).\n\n**السيرفر يتحقق من `id_token` القادم من Firebase Phone Auth**، ويتأكد أن الرقم الموجود داخله (`phone_number`) هو نفس الرقم المطلوب تأكيده. بدون ذلك كان الحقل سيعني «التطبيق قال true» لا أكثر.\n\n> ملاحظة للتشغيل: طالما `FIREBASE_PROJECT_ID` غير مضبوط في `.env`، لا يوجد ما يُتحقق منه، فيُقبل الطلب على الثقة ويُسجَّل تحذير في اللوج. اضبطه ليصبح التأكيد حقيقياً.\n\n`is_confirmed: false` لا يلغي التأكيد — يرجع بيانات المستخدم كما هي دون تغيير.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "phone"
                                ],
                                "properties": {
                                    "phone": {
                                        "type": "string",
                                        "description": "بالصيغة المحلية `01XXXXXXXXX`.",
                                        "example": "01012345678"
                                    },
                                    "is_confirmed": {
                                        "type": "boolean",
                                        "example": true
                                    },
                                    "id_token": {
                                        "type": "string",
                                        "description": "توكن Firebase Phone Auth بعد نجاح رمز الـ SMS.",
                                        "example": "eyJhbGciOiJSUzI1NiIs..."
                                    },
                                    "firebase_uid": {
                                        "type": "string",
                                        "example": "p2O1k9L8m7"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم تأكيد رقم الهاتف بنجاح",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "code": {
                                            "type": "integer",
                                            "example": 200
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "تم تأكيد رقم الهاتف بنجاح"
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "user": {
                                                    "$ref": "#/components/schemas/User"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "422": {
                        "description": "تعذّر التحقق من الرقم، أو الرقم مسجل لحساب آخر",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/auth/google": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "تسجيل الدخول بجوجل (نقرة واحدة)",
                "description": "يستقبل الـ `id_token` القادم من Google Sign-In SDK، يتحقق منه لدى جوجل، ثم يسجّل الدخول فوراً — بدون أي خطوة إضافية.\n\nإذا كان الحساب موجوداً (بنفس `google_id` أو نفس البريد) يُسجَّل دخوله ويُربط بجوجل. وإذا كان جديداً يُنشأ حساب بالبيانات القادمة من جوجل، مع القيم الافتراضية `area = \"المحلة الكبرى\"` و`gender = \"male\"` و`phone = null`.\n\n**الحقل الوحيد المطلوب فعلياً هو `id_token`** — باقي الحقول تُقبل للتوافق لكن السيرفر يعتمد على البيانات الموجودة داخل التوكن نفسه، لأن جسم الطلب يمكن تزويره.\n\n`data.is_new_user` يخبر التطبيق إن كان هذا أول دخول، ليعرض شاشة ترحيب أو يطلب استكمال الملف الشخصي لاحقاً.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "id_token"
                                ],
                                "properties": {
                                    "id_token": {
                                        "type": "string",
                                        "description": "الـ JWT الصادر من جوجل. هذا هو الحقل الوحيد الذي يثق به السيرفر.",
                                        "example": "eyJhbGciOiJSUzI1NiIsImtpZCI6..."
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "description": "اختياري — يُقرأ من التوكن عند التعارض.",
                                        "example": "user@gmail.com"
                                    },
                                    "name": {
                                        "type": "string",
                                        "description": "اختياري — يُقرأ من التوكن عند التعارض.",
                                        "example": "أحمد محمود"
                                    },
                                    "avatar_url": {
                                        "type": "string",
                                        "description": "اختياري — يُقرأ من التوكن عند التعارض.",
                                        "example": "https://lh3.googleusercontent.com/a/..."
                                    },
                                    "google_id": {
                                        "type": "string",
                                        "description": "اختياري — يُقرأ من التوكن (`sub`) عند التعارض.",
                                        "example": "109283749283749283749"
                                    },
                                    "provider": {
                                        "type": "string",
                                        "example": "google"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم تسجيل الدخول بنجاح",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AuthSuccessResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "رمز جوجل غير صالح أو منتهي الصلاحية",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/auth/login": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "تسجيل الدخول",
                "description": "حقل `phone` يقبل رقم الهاتف **أو** البريد الإلكتروني، لدعم الحسابات المنشأة قبل إضافة الهواتف.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "phone",
                                    "password"
                                ],
                                "properties": {
                                    "phone": {
                                        "type": "string",
                                        "description": "رقم الهاتف أو البريد الإلكتروني",
                                        "example": "01012345678"
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "Secret123"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم تسجيل الدخول بنجاح",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AuthSuccessResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "بيانات الدخول غير صحيحة، أو حقول ناقصة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/auth/forgot-password": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "طلب رمز إعادة تعيين كلمة المرور",
                "description": "يرجع `200` دائماً حتى لو الحساب غير موجود، منعاً لاستكشاف الحسابات. الرمز من 6 أرقام وصالح لمدة ساعة.\n\nالحسابات المسجَّلة بالهاتف فقط: الرمز يُكتب حالياً في `storage/logs/laravel.log` لحين ربط بوابة SMS.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "email_or_phone"
                                ],
                                "properties": {
                                    "email_or_phone": {
                                        "type": "string",
                                        "example": "mohamed.ali@example.com"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/auth/reset-password": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "إعادة تعيين كلمة المرور بالرمز",
                "description": "إضافة خارج العقد الأصلي — `forgot-password` بلا معنى بدونها. عند النجاح تُلغى كل التوكنات السابقة للحساب.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "email_or_phone",
                                    "code",
                                    "password",
                                    "password_confirmation"
                                ],
                                "properties": {
                                    "email_or_phone": {
                                        "type": "string",
                                        "example": "mohamed.ali@example.com"
                                    },
                                    "code": {
                                        "type": "string",
                                        "example": "123456"
                                    },
                                    "password": {
                                        "type": "string",
                                        "minLength": 6,
                                        "example": "NewSecret123"
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "example": "NewSecret123"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "رمز التحقق غير صحيح أو منتهي الصلاحية",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/auth/logout": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "تسجيل الخروج",
                "description": "يبطل التوكن الحالي فقط، وتظل بقية الأجهزة مسجَّلة.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/auth/account": {
            "delete": {
                "tags": [
                    "Authentication"
                ],
                "summary": "حذف الحساب نهائياً",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/profile": {
            "get": {
                "tags": [
                    "Profile"
                ],
                "summary": "بيانات المستخدم الحالي",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "بيانات المستخدم",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "user": {
                                                            "$ref": "#/components/schemas/User"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/profile/update": {
            "post": {
                "tags": [
                    "Profile"
                ],
                "summary": "تعديل الملف الشخصي",
                "description": "كل الحقول اختيارية — أرسل ما تغيّر فقط. رفع صورة جديدة يحذف القديمة من التخزين.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "nullable": true
                                    },
                                    "phone": {
                                        "type": "string",
                                        "pattern": "^01[0-9]{9}$"
                                    },
                                    "area": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "gender": {
                                        "type": "string",
                                        "enum": [
                                            "male",
                                            "female"
                                        ]
                                    },
                                    "avatar": {
                                        "type": "string",
                                        "format": "binary",
                                        "description": "jpg/jpeg/png/webp، حد أقصى 4 ميجابايت"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم تحديث البيانات بنجاح",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "user": {
                                                            "$ref": "#/components/schemas/User"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/profile/change-password": {
            "post": {
                "tags": [
                    "Profile"
                ],
                "summary": "تغيير كلمة المرور",
                "description": "يُبقي الجهاز الحالي مسجَّلاً ويسجّل خروج بقية الأجهزة.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "current_password",
                                    "password",
                                    "password_confirmation"
                                ],
                                "properties": {
                                    "current_password": {
                                        "type": "string",
                                        "example": "Secret123"
                                    },
                                    "password": {
                                        "type": "string",
                                        "minLength": 6,
                                        "example": "New123456"
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "example": "New123456"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/categories": {
            "get": {
                "tags": [
                    "Places Directory"
                ],
                "summary": "قائمة التصنيفات",
                "description": "يرجع افتراضياً تصنيفات **دليل الأماكن** فقط (الشبكة الرئيسية في التطبيق). قاعدة البيانات تحتوي أيضاً على تصنيف الإعلانات المبوّبة القديم.",
                "parameters": [
                    {
                        "name": "listing_type",
                        "in": "query",
                        "description": "slug لنوع الإعلان، أو `all` لعرض كل التصنيفات. الافتراضي `directory`.",
                        "schema": {
                            "type": "string",
                            "default": "directory",
                            "example": "all"
                        }
                    },
                    {
                        "name": "listing_type_id",
                        "in": "query",
                        "description": "بديل رقمي لـ `listing_type`؛ لو أُرسل يتجاهل الفلتر الافتراضي.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "with",
                        "in": "query",
                        "description": "قائمة مفصولة بفواصل. القيم المدعومة: `categories`, `sub_categories`.",
                        "schema": {
                            "type": "string",
                            "example": "categories,sub_categories"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة التصنيفات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Category"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/categories/{id}": {
            "get": {
                "tags": [
                    "Places Directory"
                ],
                "summary": "تصنيف واحد",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CategoryId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "بيانات التصنيف",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Category"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/categories/{id}/sub-categories": {
            "get": {
                "tags": [
                    "Places Directory"
                ],
                "summary": "التخصصات الفرعية داخل تصنيف",
                "description": "التخصصات الفرعية المسجّلة تحت التصنيف. التصنيفات القديمة اللي لسه من غير تخصصات بترجع القيم النصية المستخدمة في حقل `sub_category` للأماكن المنشورة، بنفس مفتاحَي `title` و`places_count`.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CategoryId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "التخصصات الفرعية",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/SubCategory"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/places": {
            "get": {
                "tags": [
                    "Places Directory"
                ],
                "summary": "استعراض وفلترة دليل الأماكن",
                "description": "`distance_km` يكون `null` ما لم تُرسل `lat` و `lng` معاً.\n\nبدون `sort_by` الترتيب هو `distance` عند وجود إحداثيات، وإلا `newest` مع تقديم الأماكن المميّزة.",
                "parameters": [
                    {
                        "name": "category_id",
                        "in": "query",
                        "description": "`cat_17` أو `17` أو الـ slug. قيمة غير معروفة ترجع صفر نتيجة (وليس كل الأماكن).",
                        "schema": {
                            "type": "string",
                            "example": "cat_17"
                        }
                    },
                    {
                        "name": "sub_category",
                        "in": "query",
                        "description": "مطابقة تامة",
                        "schema": {
                            "type": "string",
                            "example": "عيادات عظام"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "description": "بحث في الاسم والوصف والعنوان والمنطقة واسم التصنيف",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "min_rating",
                        "in": "query",
                        "schema": {
                            "type": "number",
                            "format": "float",
                            "minimum": 0,
                            "maximum": 5,
                            "example": 4.5
                        }
                    },
                    {
                        "name": "is_open_now",
                        "in": "query",
                        "description": "حسب مواعيد العمل المسجَّلة، ويشمل المواعيد التي تعبر منتصف الليل",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "is_verified",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "is_featured",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "has_offer",
                        "in": "query",
                        "description": "الأماكن التي لديها عرض ساري",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "city_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "lat",
                        "in": "query",
                        "description": "يفعّل حساب المسافة — يجب إرساله مع `lng`",
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "minimum": -90,
                            "maximum": 90,
                            "example": 30.9706
                        }
                    },
                    {
                        "name": "lng",
                        "in": "query",
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "minimum": -180,
                            "maximum": 180,
                            "example": 31.1656
                        }
                    },
                    {
                        "name": "radius",
                        "in": "query",
                        "description": "نصف قطر البحث بالكيلومتر، يعمل فقط مع `lat`/`lng`",
                        "schema": {
                            "type": "number",
                            "format": "float",
                            "default": 50
                        }
                    },
                    {
                        "name": "sort_by",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "distance",
                                "rating",
                                "popular",
                                "newest"
                            ]
                        }
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "name": "location_id",
                        "in": "query",
                        "description": "يقبل `loc_57` أو `57` أو الـ slug، ويشمل كل المناطق التابعة لها — فلترة على `مركز المحلة الكبرى` ترجع أماكن قراه وتوابعها.",
                        "schema": {
                            "type": "string",
                            "example": "loc_54"
                        }
                    },
                    {
                        "name": "branch",
                        "in": "query",
                        "description": "`urban` لأماكن المدينة، `rural` لأماكن المركز.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "urban",
                                "rural"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة الأماكن مع الترقيم",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Place"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/places/featured": {
            "get": {
                "tags": [
                    "Places Directory"
                ],
                "summary": "الأماكن المميزة",
                "description": "غير مرقّم — قائمة مباشرة مرتّبة بالأعلى تقييماً.",
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 10
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "الأماكن المميزة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Place"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/places/{id}": {
            "get": {
                "tags": [
                    "Places Directory"
                ],
                "summary": "تفاصيل المكان الكاملة",
                "description": "كل طلب يزيد `views_count` تلقائياً. الأماكن غير المنشورة أو الموقوفة ترجع `404`.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/PlaceId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تفاصيل المكان",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PlaceDetails"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/places/{id}/reviews": {
            "get": {
                "tags": [
                    "Reviews"
                ],
                "summary": "تقييمات مكان",
                "description": "التقييمات المعتمدة فقط.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/PlaceId"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة التقييمات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Review"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            },
            "post": {
                "tags": [
                    "Reviews"
                ],
                "summary": "إضافة أو تعديل تقييم",
                "description": "المستخدم له تقييم واحد لكل مكان — الإرسال مرة ثانية **يعدّل** التقييم السابق ولا يفشل. متوسط تقييم المكان يُعاد حسابه فوراً.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/PlaceId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "rating"
                                ],
                                "properties": {
                                    "rating": {
                                        "type": "number",
                                        "format": "float",
                                        "minimum": 1,
                                        "maximum": 5,
                                        "description": "يقبل الأنصاف مثل 4.5",
                                        "example": 4.5
                                    },
                                    "comment": {
                                        "type": "string",
                                        "maxLength": 1000,
                                        "nullable": true,
                                        "example": "خدمة ممتازة وأسعار مناسبة جداً."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "تم حفظ التقييم",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Review"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Reviews"
                ],
                "summary": "حذف تقييمي على هذا المكان",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/PlaceId"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "description": "المكان غير موجود، أو لا يوجد تقييم لك عليه",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/favorites": {
            "get": {
                "tags": [
                    "Favorites"
                ],
                "summary": "قائمة المفضلة",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/Limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "الأماكن المفضلة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Place"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/favorites/ids": {
            "get": {
                "tags": [
                    "Favorites"
                ],
                "summary": "معرّفات المفضلة فقط",
                "description": "طلب خفيف لرسم أيقونات القلب عبر شاشة قائمة كاملة بطلب واحد.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "المعرّفات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "ids": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string",
                                                                "example": "plc_8"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/favorites/{id}/toggle": {
            "post": {
                "tags": [
                    "Favorites"
                ],
                "summary": "إضافة/إزالة مكان من المفضلة",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/PlaceId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "الحالة بعد التبديل",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "is_favorited": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/market/products": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "استعراض إعلانات سوق المحلة",
                "description": "الإعلانات المنشورة فقط — الإعلانات المعلّقة قيد المراجعة لا تظهر هنا.",
                "parameters": [
                    {
                        "name": "category",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "example": "موبايلات وإلكترونيات"
                        }
                    },
                    {
                        "name": "condition",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "example": "مستعمل بحالة ممتازة"
                        }
                    },
                    {
                        "name": "min_price",
                        "in": "query",
                        "schema": {
                            "type": "number",
                            "minimum": 0
                        }
                    },
                    {
                        "name": "max_price",
                        "in": "query",
                        "schema": {
                            "type": "number",
                            "minimum": 0
                        }
                    },
                    {
                        "name": "is_negotiable",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "sort_by",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "price_asc",
                                "price_desc",
                                "popular"
                            ]
                        }
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة الإعلانات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Product"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            },
            "post": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "إضافة إعلان جديد",
                "description": "⚠️ الإعلان الجديد يُحفظ بحالة **`pending`** ولا يظهر في القائمة العامة إلا بعد اعتماده من لوحة التحكم.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "title",
                                    "price",
                                    "category",
                                    "condition",
                                    "phone"
                                ],
                                "properties": {
                                    "title": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "example": "طقم انتريه خشب زان دمياطي"
                                    },
                                    "price": {
                                        "type": "number",
                                        "minimum": 0,
                                        "example": 14500
                                    },
                                    "old_price": {
                                        "type": "number",
                                        "minimum": 0,
                                        "nullable": true,
                                        "description": "يجب أن يكون أكبر من `price`"
                                    },
                                    "category": {
                                        "type": "string",
                                        "example": "أثاث ومفروشات منزلية"
                                    },
                                    "condition": {
                                        "type": "string",
                                        "example": "جديد بالكرتونة"
                                    },
                                    "location": {
                                        "type": "string",
                                        "nullable": true,
                                        "example": "المحلة الكبرى - أبو شاهين"
                                    },
                                    "phone": {
                                        "type": "string",
                                        "maxLength": 20,
                                        "example": "01012345678"
                                    },
                                    "whatsapp": {
                                        "type": "string",
                                        "maxLength": 20,
                                        "nullable": true
                                    },
                                    "description": {
                                        "type": "string",
                                        "maxLength": 5000,
                                        "nullable": true
                                    },
                                    "is_negotiable": {
                                        "type": "boolean"
                                    },
                                    "images": {
                                        "type": "array",
                                        "maxItems": 6,
                                        "items": {
                                            "type": "string",
                                            "format": "binary"
                                        },
                                        "description": "حتى 6 صور، 4 ميجابايت لكل صورة"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "تم استلام الإعلان وسيُنشر بعد المراجعة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Product"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/market/products/{id}": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "تفاصيل إعلان",
                "description": "يزيد عدّاد المشاهدات.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ProductId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تفاصيل الإعلان",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Product"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            },
            "post": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "تعديل إعلان",
                "description": "للمالك فقط، وإلا `403`. لتعليم الإعلان كمُباع أرسل `status=sold`.\n\nرفع `images` جديدة يستبدل الصور القديمة كلها ويحذفها من التخزين.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ProductId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "title": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "price": {
                                        "type": "number",
                                        "minimum": 0
                                    },
                                    "old_price": {
                                        "type": "number",
                                        "nullable": true
                                    },
                                    "category": {
                                        "type": "string"
                                    },
                                    "condition": {
                                        "type": "string"
                                    },
                                    "location": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "phone": {
                                        "type": "string",
                                        "maxLength": 20
                                    },
                                    "whatsapp": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "description": {
                                        "type": "string",
                                        "maxLength": 5000,
                                        "nullable": true
                                    },
                                    "is_negotiable": {
                                        "type": "boolean"
                                    },
                                    "status": {
                                        "type": "string",
                                        "enum": [
                                            "sold"
                                        ],
                                        "description": "القيمة الوحيدة المسموح بها من التطبيق"
                                    },
                                    "images": {
                                        "type": "array",
                                        "maxItems": 6,
                                        "items": {
                                            "type": "string",
                                            "format": "binary"
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم تحديث الإعلان",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Product"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "حذف إعلان",
                "description": "للمالك فقط.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ProductId"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/market/allowance": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "حدود باقتي في السوق",
                "description": "كام إعلان فاضل للحساب الشهر ده، وكام «إعلان مميز» يقدر يشغّل في نفس الوقت. الحد الشهري بيشمل إعلانات البيع وطلبات الخدمة مع بعض. الإعلانات المميزة **متزامنة** مش شهرية: `featured.limit` هو عدد الإعلانات اللي ينفع تكون مميزة في نفس اللحظة، و`featured.is_available: false` معناها إن الباقة (المجانية) مافيهاش تمييز أصلاً — التطبيق بيخفي زرار التمييز بدل ما ياخد الإعلان ويرفضه.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "حدود الباقة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "ads": {
                                                    "type": "object",
                                                    "properties": {
                                                        "limit": {
                                                            "type": "integer",
                                                            "nullable": true
                                                        },
                                                        "used": {
                                                            "type": "integer"
                                                        },
                                                        "remaining": {
                                                            "type": "integer",
                                                            "nullable": true
                                                        },
                                                        "is_unlimited": {
                                                            "type": "boolean"
                                                        },
                                                        "period": {
                                                            "type": "string",
                                                            "example": "month"
                                                        },
                                                        "label": {
                                                            "type": "string"
                                                        }
                                                    }
                                                },
                                                "featured": {
                                                    "type": "object",
                                                    "properties": {
                                                        "limit": {
                                                            "type": "integer",
                                                            "nullable": true
                                                        },
                                                        "used": {
                                                            "type": "integer"
                                                        },
                                                        "remaining": {
                                                            "type": "integer",
                                                            "nullable": true
                                                        },
                                                        "is_unlimited": {
                                                            "type": "boolean"
                                                        },
                                                        "is_available": {
                                                            "type": "boolean"
                                                        },
                                                        "period": {
                                                            "type": "string",
                                                            "example": "concurrent"
                                                        },
                                                        "label": {
                                                            "type": "string"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/market/my-products": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "إعلاناتي",
                "description": "بعكس القائمة العامة، يرجع الإعلانات بكل الحالات بما فيها `pending` حتى يرى البائع إعلاناته قيد المراجعة.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/Limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "إعلانات المستخدم",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Product"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/market/categories": {
            "get": {
                "tags": [
                    "Mahalla Market"
                ],
                "summary": "تصنيفات السوق المستخدمة",
                "description": "مبنية من التصنيفات الموجودة فعلياً في الإعلانات المنشورة.",
                "responses": {
                    "200": {
                        "description": "التصنيفات مع عدد الإعلانات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "title": {
                                                                "type": "string",
                                                                "example": "موبايلات وإلكترونيات"
                                                            },
                                                            "products_count": {
                                                                "type": "integer",
                                                                "example": 2
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/offers": {
            "get": {
                "tags": [
                    "Offers & Coupons"
                ],
                "summary": "العروض والكوبونات السارية",
                "description": "العروض المنتهية أو غير المفعّلة لا تظهر إطلاقاً. العرض بلا تاريخ انتهاء يُعتبر مفتوحاً. الترتيب بالأقرب انتهاءً مع تقديم المميّز.",
                "parameters": [
                    {
                        "name": "place_id",
                        "in": "query",
                        "description": "عروض مكان محدد",
                        "schema": {
                            "type": "string",
                            "example": "plc_8"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة العروض",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Offer"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/offers/{id}": {
            "get": {
                "tags": [
                    "Offers & Coupons"
                ],
                "summary": "تفاصيل عرض",
                "description": "يزيد عدّاد المشاهدات. العرض المنتهي يرجع `404`.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/OfferId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تفاصيل العرض",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Offer"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/map/markers": {
            "get": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "نقاط الخريطة التفاعلية",
                "description": "غير مرقّم — الحد الأقصى 300 نقطة لكل طلب.\n\nإحداثيات الـ viewport الأربعة تُرسل **معاً** وإلا يُتجاهل الحصر. الأماكن بلا إحداثيات لا تظهر أبداً.",
                "parameters": [
                    {
                        "name": "category_id",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "example": "cat_17"
                        }
                    },
                    {
                        "name": "north_east_lat",
                        "in": "query",
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "example": 31
                        }
                    },
                    {
                        "name": "north_east_lng",
                        "in": "query",
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "example": 31.3
                        }
                    },
                    {
                        "name": "south_west_lat",
                        "in": "query",
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "example": 30.9
                        }
                    },
                    {
                        "name": "south_west_lng",
                        "in": "query",
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "example": 31
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "is_verified",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "is_open_now",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 300,
                            "default": 300
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "نقاط الخريطة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/MapMarker"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/search/ai-analyze": {
            "post": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "البحث الذكي بالصوت أو النص",
                "description": "يأخذ جملة عربية حرة ويرجع النية المستخرجة **والنتائج المطابقة**، حتى يعرض التطبيق «فهمت إنك بتدور على …» فوق القائمة.\n\n**كيف يعمل:** محلّل نوايا عربي حتمي (وليس نداء نموذج لغوي) — لا يحتاج مفتاح API ولا اتصالاً خارجياً ولا تكلفة لكل بحث. يتعرّف على:\n\n| النية | أمثلة الكلمات |\n|---|---|\n| `is_nearby` | قريب، أقرب، جنبي، حواليا |\n| `is_open_now` | فاتح، مفتوح، شغال، دلوقتي، 24 ساعة |\n| `is_high_rating` | أفضل، أحسن، شاطر، ممتاز |\n| `has_offer` | عرض، خصم، كوبون، تخفيض |\n\nويربط التصنيف عبر قائمة مرادفات، لأن الجمع العربي المكسّر (مطعم/مطاعم) لا تنفع معه المطابقة النصية.\n\nحقول النوايا الأربعة والقوائم الثلاث **موجودة دائماً** حتى بلا نتائج.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "query"
                                ],
                                "properties": {
                                    "query": {
                                        "type": "string",
                                        "maxLength": 500,
                                        "example": "عايز صيدلية فاتحة دلوقتي قريبة من شارع البحر"
                                    },
                                    "user_lat": {
                                        "type": "number",
                                        "format": "double",
                                        "nullable": true,
                                        "example": 30.9706
                                    },
                                    "user_lng": {
                                        "type": "number",
                                        "format": "double",
                                        "nullable": true,
                                        "example": 31.1656
                                    },
                                    "limit": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 30,
                                        "default": 10
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "نتائج التحليل الذكي",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/AiSearchResult"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/search/suggestions": {
            "get": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "اقتراحات البحث الفوري",
                "description": "أسماء فقط، بدون علاقات — للـ type-ahead.",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "minLength": 2,
                            "maxLength": 100,
                            "example": "صيد"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "الاقتراحات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "id": {
                                                                "type": "string",
                                                                "example": "plc_9"
                                                            },
                                                            "name": {
                                                                "type": "string",
                                                                "example": "صيدلية العزبي - فرع المحلة"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/emergency": {
            "get": {
                "tags": [
                    "Emergency"
                ],
                "summary": "دليل أرقام وخدمات الطوارئ",
                "description": "غير مرقّم. الأرقام تُدار من لوحة التحكم كصفوف مسطّحة والتجميع حسب القسم يتم عند العرض.",
                "responses": {
                    "200": {
                        "description": "أرقام الطوارئ مقسّمة حسب الفئة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/EmergencyCategory"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/banners": {
            "get": {
                "tags": [
                    "Banners"
                ],
                "summary": "بانرات الصفحة الرئيسية",
                "description": "سلايدر الصفحة الرئيسية. غير مرقّم — القائمة صغيرة والشاشة تعرضها كاملة.\n\nالبانرات المطفأة أو المجدولة مستقبلاً أو المنتهية لا تظهر، والترتيب هو `sort_order`.",
                "parameters": [
                    {
                        "name": "placement",
                        "in": "query",
                        "description": "مكان العرض. الافتراضي `home`.",
                        "schema": {
                            "type": "string",
                            "example": "home"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة البانرات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Banner"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/articles": {
            "get": {
                "tags": [
                    "Articles"
                ],
                "summary": "قائمة المقالات والأخبار",
                "description": "المقالات غير المنشورة أو المجدولة مستقبلاً لا تظهر.",
                "parameters": [
                    {
                        "name": "category",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "example": "أخبار المدينة"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة المقالات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Article"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/articles/{id}": {
            "get": {
                "tags": [
                    "Articles"
                ],
                "summary": "محتوى المقال الكامل",
                "description": "يقبل `art_1` أو `1` أو الـ slug. يضيف `body` للتوافق و`content_blocks` المرتبة (نص/عنوان/اقتباس/صورة) ويزيد عدّاد المشاهدات.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ArticleId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "المقال",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/ArticleDetails"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/notifications": {
            "get": {
                "tags": [
                    "Notifications"
                ],
                "summary": "قائمة الإشعارات",
                "description": "تشمل إشعارات المستخدم الشخصية والإشعارات العامة (`is_broadcast: true`).",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "unread_only",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "الإشعارات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Notification"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/notifications/unread-count": {
            "get": {
                "tags": [
                    "Notifications"
                ],
                "summary": "عدد الإشعارات غير المقروءة",
                "description": "endpoint منفصل حتى تتحدّث الشارة بدون تحميل قائمة الإشعارات كاملة.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "العدد",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "unread_count": {
                                                            "type": "integer",
                                                            "example": 3
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/notifications/{id}/read": {
            "post": {
                "tags": [
                    "Notifications"
                ],
                "summary": "تحديد إشعار كمقروء",
                "description": "حالة القراءة محفوظة لكل مستخدم على حدة، فتعليم إشعار **عام** كمقروء لا يؤثر على بقية المستخدمين.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/NotificationId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم التحديد",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Notification"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/notifications/read-all": {
            "post": {
                "tags": [
                    "Notifications"
                ],
                "summary": "تحديد كل الإشعارات كمقروءة",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "عدد الإشعارات التي تم تحديدها",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "marked": {
                                                            "type": "integer",
                                                            "example": 2
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/notifications/{id}": {
            "delete": {
                "tags": [
                    "Notifications"
                ],
                "summary": "حذف إشعار",
                "description": "الإشعارات الشخصية فقط. الإشعار العام لا يمكن لمستخدم واحد حذفه ويرجع `404`.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/NotificationId"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/contact-us": {
            "post": {
                "tags": [
                    "Support"
                ],
                "summary": "إرسال رسالة تواصل أو دعم فني",
                "description": "يعمل مع أو بدون تسجيل دخول. لو المستخدم مسجّل دخول تُربط الرسالة بحسابه تلقائياً.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "name",
                                    "message"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "example": "محمود إبراهيم"
                                    },
                                    "phone": {
                                        "type": "string",
                                        "maxLength": 20,
                                        "nullable": true,
                                        "example": "01099887766"
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "nullable": true
                                    },
                                    "subject": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "nullable": true,
                                        "example": "طلب إضافة منشأة تجارية"
                                    },
                                    "message": {
                                        "type": "string",
                                        "minLength": 10,
                                        "maxLength": 5000,
                                        "example": "السلام عليكم، أرغب في توثيق ونشر بيانات مطعمي في التطبيق."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/listing-types": {
            "get": {
                "tags": [
                    "Taxonomy"
                ],
                "summary": "قائمة أنواع الأنشطة",
                "description": "أعلى مستوى في الشجرة. مع `?with=categories` بترجع تصنيفات كل نوع، ومع `?with=categories,sub_categories` بترجع التخصصات الفرعية كمان.",
                "parameters": [
                    {
                        "name": "with",
                        "in": "query",
                        "description": "قائمة مفصولة بفواصل. القيم المدعومة: `categories`, `sub_categories`.",
                        "schema": {
                            "type": "string",
                            "example": "categories,sub_categories"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "أنواع الأنشطة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ListingType"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/listing-types/{id}/categories": {
            "get": {
                "tags": [
                    "Taxonomy"
                ],
                "summary": "تصنيفات نوع نشاط",
                "description": "كل التصنيفات المسموح استخدامها مع النوع ده — سواء اللي بيمتلكها أو اللي متربطة بيه في جدول الربط.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ListingTypeId"
                    },
                    {
                        "name": "with",
                        "in": "query",
                        "description": "استخدم `sub_categories` لتضمين التخصصات الفرعية.",
                        "schema": {
                            "type": "string",
                            "example": "sub_categories"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "التصنيفات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Category"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "نوع النشاط غير موجود",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/cities/{id}/locations": {
            "get": {
                "tags": [
                    "Places Directory"
                ],
                "summary": "المناطق الجغرافية لمدينة",
                "description": "يرجع افتراضياً جذور الفروع فقط — «مدينة المحلة الكبرى» و«مركز المحلة الكبرى» — وهما كيانان إداريان مختلفان ولا يُدمجان في قائمة واحدة.\n\nللنزول مستوى: أرسل `parent_id`. للحصول على الشجرة كاملة متداخلة: `tree=1`.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "رقم المدينة أو الـ slug الخاص بها.",
                        "schema": {
                            "type": "string",
                            "example": "el-mahalla-el-kubra"
                        }
                    },
                    {
                        "name": "parent_id",
                        "in": "query",
                        "description": "يرجع المناطق التابعة مباشرةً لهذه المنطقة. يقبل `loc_54` أو `54` أو الـ slug.",
                        "schema": {
                            "type": "string",
                            "example": "loc_54"
                        }
                    },
                    {
                        "name": "branch",
                        "in": "query",
                        "description": "`urban` لمناطق المدينة، `rural` لقرى وتوابع المركز.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "urban",
                                "rural"
                            ]
                        }
                    },
                    {
                        "name": "type",
                        "in": "query",
                        "description": "تصفية بنوع المنطقة.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "city",
                                "markaz",
                                "district",
                                "section",
                                "shiyakha",
                                "area",
                                "local_unit",
                                "village",
                                "hamlet",
                                "kafr",
                                "nag",
                                "other"
                            ]
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "description": "بحث في الاسم العربي أو الإنجليزي أو الـ slug.",
                        "schema": {
                            "type": "string",
                            "example": "بشبيش"
                        }
                    },
                    {
                        "name": "tree",
                        "in": "query",
                        "description": "عند `1` تُرجع المناطق التابعة متداخلة داخل `children`.",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة المناطق الجغرافية",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Location"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "المدينة أو المنطقة الأعلى غير موجودة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/locations/{id}": {
            "get": {
                "tags": [
                    "Places Directory"
                ],
                "summary": "تفاصيل منطقة جغرافية",
                "description": "المنطقة نفسها، والمناطق الأعلى منها بالترتيب (لعرض «المركز ← بشبيش ← الأنشا»)، والمناطق التابعة لها مباشرةً.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "يقبل `loc_57` أو `57` أو الـ slug.",
                        "schema": {
                            "type": "string",
                            "example": "loc_57"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "بيانات المنطقة الجغرافية",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "location": {
                                                            "$ref": "#/components/schemas/Location"
                                                        },
                                                        "city": {
                                                            "type": "object",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "integer"
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true
                                                                },
                                                                "slug": {
                                                                    "type": "string",
                                                                    "nullable": true
                                                                }
                                                            }
                                                        },
                                                        "ancestors": {
                                                            "type": "array",
                                                            "items": {
                                                                "$ref": "#/components/schemas/Location"
                                                            }
                                                        },
                                                        "children": {
                                                            "type": "array",
                                                            "items": {
                                                                "$ref": "#/components/schemas/Location"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "المنطقة الجغرافية غير موجودة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/market/pending-products": {
            "get": {
                "tags": [
                    "Admin Moderation"
                ],
                "summary": "قائمة الإعلانات المعلقة",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "طابور المراجعة، **الأقدم أولاً** — الإعلان الذي انتظر أطول هو الأولى بالمراجعة.\n\nمتاح لحسابات `is_admin` فقط؛ أي حساب آخر يحصل على `403`.",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "pending"
                        },
                        "description": "الحالة المطلوبة، أو `all` لكل الإعلانات."
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 50,
                            "default": 15
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم جلب الإعلانات المعلقة بنجاح",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "code": {
                                            "type": "integer",
                                            "example": 200
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "تم جلب الإعلانات المعلقة بنجاح"
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Product"
                                            }
                                        },
                                        "pagination": {
                                            "$ref": "#/components/schemas/Pagination"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "description": "الحساب ليس حساب إدارة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/market/products/{id}/approve": {
            "post": {
                "tags": [
                    "Admin Moderation"
                ],
                "summary": "اعتماد الإعلان ونشره",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "يحوّل حالة الإعلان إلى `published` فيظهر فوراً في `/market/products`، ويمسح أي سبب رفض قديم كان عليه.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "prd_201"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم نشر الإعلان بنجاح",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "code": {
                                            "type": "integer",
                                            "example": 200
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "تم نشر الإعلان بنجاح"
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Product"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "description": "الحساب ليس حساب إدارة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/admin/market/products/{id}/reject": {
            "post": {
                "tags": [
                    "Admin Moderation"
                ],
                "summary": "رفض الإعلان مع ذكر السبب",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "يحوّل الحالة إلى `rejected` ويحفظ السبب.\n\n**`reason` مطلوب** — الرفض بدون سبب يجعل صاحب الإعلان يعيد إرساله كما هو، فيكبر الطابور بلا فائدة. السبب يظهر له في `/market/my-products`.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "prd_201"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "reason"
                                ],
                                "properties": {
                                    "reason": {
                                        "type": "string",
                                        "maxLength": 1000,
                                        "example": "الصور غير واضحة، برجاء رفع صور أوضح للمنتج."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم رفض الإعلان",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "status": {
                                            "type": "boolean",
                                            "example": true
                                        },
                                        "code": {
                                            "type": "integer",
                                            "example": 200
                                        },
                                        "message": {
                                            "type": "string",
                                            "example": "تم رفض الإعلان"
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Product"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "description": "الحساب ليس حساب إدارة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/places/{id}/assistant": {
            "get": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "محلاوي النشاط — حالته والمحادثة المحفوظة",
                "description": "المساعد الثاني: اللي جوّه صفحة النشاط نفسه، وبيرد على أسئلة عن المكان ده وحده — عمره ما بيرشّح مكان تاني.\n\nيرجع `assistant` (باقة النشاط وصلاحياتها)، و`business_assistant_quota`، والمحادثة المحفوظة للزائر مع النشاط ده (24 ساعة متحركة). لا يستهلك أي سؤال من رصيد النشاط.\n\nاستخدمه لتقرير إظهار زرار المحلاوي على صفحة المكان: `assistant.assistant_enabled`.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "حالة المساعد والمحادثة"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            },
            "post": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "اسأل محلاوي النشاط",
                "description": "سؤال عن هذا النشاط وحده: المواعيد، العنوان، التواصل، الأسئلة المسجّلة من صاحبه، والمنيو والأسعار لو باقة النشاط بتسمح.\n\n**الرصيد بتاع النشاط مش بتاع المستخدم.** كل سؤال هنا بيتخصم من `assistant_daily_limit` بتاع باقة النشاط، لأن السؤال ده عميل بيتوجّه للمحل. يعني مية زائر بسؤال واحد بيكلّفوا المحل زي زائر واحد بمية سؤال. لما يخلص بيرجع `429` ومعاه المحادثة المحفوظة.\n\nالحد اليومي بتاع المستخدم (`assistant_quota`) مالوش أي علاقة بالمساعد ده.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "message"
                                ],
                                "properties": {
                                    "message": {
                                        "type": "string",
                                        "minLength": 2,
                                        "maxLength": 500
                                    },
                                    "conversation_id": {
                                        "type": "string",
                                        "nullable": true,
                                        "description": "من الرد السابق. معرّف منتهي أو غير صالح بيبدأ محادثة جديدة بدل ما يفشل الطلب."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "رد المساعد"
                    },
                    "403": {
                        "description": "المحلاوي غير مفعّل على باقة النشاط"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/places/{id}/assistant/history": {
            "delete": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "مسح محادثة الزائر مع النشاط",
                "description": "يمسح المحادثة من عند هذا المستخدم على صفحة هذا النشاط. لا يعيد أي أسئلة إلى رصيد النشاط.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم المسح"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/assistant/history": {
            "get": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "محادثة المحلاوي كما تركها المستخدم",
                "description": "يرجع رسائل المستخدم وردود المحلاوي داخل نافذة الحد اليومي الحالية، مرتبة من الأقدم للأحدث، مع `assistant_quota` و`conversation_id` لمتابعة نفس المحادثة.\n\nلا يستهلك رسالة من الحد اليومي ولا يستدعي أي نموذج لغوي: فتح الشاشة لقراءة رد سابق ليس سؤالاً جديداً.\n\nمدة البقاء مربوطة بالحد اليومي وليست بالتقويم: الرسائل تفضل ظاهرة طول ما الحد متستهلك، وتتمسح بالكامل أول ما يتجدد. الباقات غير المحدودة ليس لها نافذة عدّاد فتحصل على 24 ساعة متحركة.\n\n`payload` في رسالة المحلاوي يحمل الكروت والردود السريعة و`tracking_id` لإعادة رسم نفس الرد بدون طلب جديد.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "المحادثة الحالية"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "مسح محادثة المحلاوي",
                "description": "يمسح المحادثة من شاشة المستخدم. لا يعيد أي رسائل إلى الحد اليومي — الرسائل المستهلكة تظل مستهلكة.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم المسح"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/assistant/message": {
            "post": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "المحلاوي الذكي — يفهم الطلب ويرد بنتائج من الدليل",
                "description": "مساعد محادثة للدليل. يتطلب تسجيل الدخول حتى يطبق السيرفر حد الرسائل اليومي للخطة. يعيد `assistant_quota` وفيه المستخدم والمتبقي وموعد التجديد بعد 24 ساعة. الرسالة الأولى تبحث وترشح، ثم ترجع `conversation_id` و`focus` للمتابعة.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "message"
                                ],
                                "properties": {
                                    "message": {
                                        "type": "string",
                                        "minLength": 2,
                                        "maxLength": 500,
                                        "example": "عايز بيتزا فراخ مش حارة في حدود 150"
                                    },
                                    "user_lat": {
                                        "type": "number",
                                        "format": "double",
                                        "nullable": true,
                                        "example": 30.9706
                                    },
                                    "user_lng": {
                                        "type": "number",
                                        "format": "double",
                                        "nullable": true,
                                        "example": 31.1656
                                    },
                                    "city_id": {
                                        "type": "string",
                                        "nullable": true,
                                        "description": "رقم المدينة أو الـ slug. الافتراضي أول مدينة مفعّلة.",
                                        "example": "el-mahalla-el-kubra"
                                    },
                                    "limit": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 30,
                                        "default": 10
                                    },
                                    "conversation_id": {
                                        "type": "string",
                                        "nullable": true,
                                        "description": "المعرّف الموقع من الرد السابق. احفظه طول عمر شاشة المحادثة.",
                                        "example": "aconv_12.13a96fc11bc85c03b41a51ce9bdd7b2a"
                                    },
                                    "focus_id": {
                                        "type": "string",
                                        "nullable": true,
                                        "description": "plc_… أو itm_… للكارت الذي اختاره المستخدم ويقصده بالسؤال التالي.",
                                        "example": "plc_42"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "رد المساعد",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/AssistantReply"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/assistant/outcome": {
            "post": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "تسجيل استخدام نتيجة من المحلاوي الذكي",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "يسجل أن المستخدم فتح المكان أو اتصل أو فتح واتساب. أرسل الطلب في الخلفية ولا تمنع الإجراء نفسه إذا فشل التتبّع. `tracking_id` موقّع ويأتي من رد `/assistant/message`.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "tracking_id",
                                    "outcome"
                                ],
                                "properties": {
                                    "tracking_id": {
                                        "type": "string",
                                        "example": "asq_14.7f35c8d9e21a4f67b903d124"
                                    },
                                    "outcome": {
                                        "type": "string",
                                        "enum": [
                                            "open_listing",
                                            "call",
                                            "whatsapp"
                                        ]
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "تم تسجيل التفاعل",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/offers/{id}/claim": {
            "post": {
                "tags": [
                    "Offers & Coupons"
                ],
                "summary": "حجز كوبون للمستخدم وإرجاع محتوى QR آمن",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "الكوبون محجوز مسبقاً"
                    },
                    "201": {
                        "description": "تم حجز الكوبون"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/offers/{id}/my-coupon": {
            "get": {
                "tags": [
                    "Offers & Coupons"
                ],
                "summary": "جلب حالة وQR كوبون المستخدم",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "حالة الكوبون"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/business/coupons/check": {
            "post": {
                "tags": [
                    "Business Management"
                ],
                "summary": "فحص QR دون صرف الكوبون",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "نتيجة الفحص"
                    },
                    "403": {
                        "description": "ليس مالك النشاط"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/business/coupons/redeem": {
            "post": {
                "tags": [
                    "Business Management"
                ],
                "summary": "تأكيد استخدام الكوبون مرة واحدة",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم الاستخدام أو كان مستخدماً"
                    },
                    "403": {
                        "description": "ليس مالك النشاط"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/business/context": {
            "get": {
                "tags": [
                    "Business Management"
                ],
                "summary": "بيانات تبديل المستخدم والأنشطة المتاحة",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "السياقات المتاحة"
                    }
                }
            }
        },
        "/business/registration": {
            "get": {
                "tags": [
                    "Business Management"
                ],
                "summary": "حالة تسجيل نشاط المستخدم",
                "description": "نفس كتلة `registration` التي يرجعها `/business/context`. `status` من: `none` (لا يمتلك نشاطاً ولم يقدّم طلباً) أو `pending` أو `changes_requested` أو `rejected` أو `active`.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "حالة الطلب"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/business/registration/{id}": {
            "get": {
                "tags": [
                    "Business Management"
                ],
                "summary": "استرجاع طلب تسجيل النشاط المحفوظ بمعرّفه",
                "description": "يستخدمه التطبيق عند فتح إشعار طلب استكمال. يرجع values لكل الحقول، وmedia لصور الشعار والغلاف والمعرض، وصور الأصناف. متاح لصاحب الطلب فقط.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": "breg_5"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "الطلب المحفوظ كاملًا"
                    },
                    "404": {
                        "description": "الطلب غير موجود أو ليس لصاحب الحساب"
                    }
                }
            }
        },
        "/business/register": {
            "post": {
                "tags": [
                    "Business Management"
                ],
                "summary": "تسجيل نشاط تجاري جديد باسم المستخدم",
                "description": "الطريق الوحيد الذي يصبح به حساب عادي مالكاً لنشاط، وبالتالي شرط تفعيل «تبديل المستخدم» وصفحة النشاط وطلبات التحديث.\n\nمتاح على كل الباقات بما فيها المجانية — الباقة تحدّد ما يفعله النشاط بعد التفعيل، لا ما إذا كان صاحبه يستطيع الوصول إليه. المطلوب فعلياً ثلاثة حقول فقط: `name` و`category_id` و`phone`؛ الباقي تُستكمل من صفحة النشاط أو من الإدارة.\n\nالطلب يدخل قائمة مراجعة في لوحة التحكم، وعند القبول يُنشأ النشاط منشوراً ومربوطاً بالحساب ويصل إشعار لصاحبه. طلب مفتوح واحد فقط لكل حساب: طلب `pending` ثانٍ يرجع 422، أما طلب `changes_requested` فإعادة الإرسال تعدّله في مكانه.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "name",
                                    "category_id",
                                    "phone"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "category_id": {
                                        "type": "string",
                                        "example": "cat_12"
                                    },
                                    "sub_category_id": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "city_id": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "location_id": {
                                        "type": "string",
                                        "nullable": true,
                                        "example": "loc_40"
                                    },
                                    "phone": {
                                        "type": "string",
                                        "maxLength": 30
                                    },
                                    "whatsapp": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "address": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "description": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "logo": {
                                        "type": "string",
                                        "format": "binary",
                                        "nullable": true
                                    },
                                    "user_note": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "تم استلام الطلب"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "422": {
                        "description": "طلب مفتوح بالفعل أو بيانات ناقصة"
                    }
                }
            }
        },
        "/business/change-requests": {
            "get": {
                "tags": [
                    "Business Management"
                ],
                "summary": "طلبات تعديل أنشطة المستخدم",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "قائمة الطلبات"
                    }
                }
            }
        },
        "/business/listings/{id}": {
            "get": {
                "tags": [
                    "Business Management"
                ],
                "summary": "صفحة نشاط المستخدم كما تظهر في التطبيق",
                "description": "الصفحة التي يدخل إليها صاحب النشاط بعد «تبديل المستخدم»: نفس شكل `PlaceDetails` الذي يراه بقية المستخدمين، لكن متاحة لصاحبها حتى لو لم تكن منشورة بعد. الصلاحية هي الملكية — نشاط لا يملكه الحساب يرجع 404.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "صفحة النشاط"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/business/listings/{id}/edit": {
            "get": {
                "tags": [
                    "Business Management"
                ],
                "summary": "بيانات وفورم تعديل النشاط",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "بيانات التعديل"
                    },
                    "403": {
                        "description": "الخطة لا تسمح"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/business/listings/{id}/change-requests": {
            "post": {
                "tags": [
                    "Business Management"
                ],
                "summary": "إرسال تعديل نشاط لمراجعة الإدارة",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "تم إرسال الطلب"
                    },
                    "403": {
                        "description": "الخطة لا تسمح"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/business/listings/{id}/offers": {
            "get": {
                "tags": [
                    "Business Management"
                ],
                "summary": "عروض وخصومات وكوبونات النشاط",
                "description": "شاشة إدارة العروض لصاحب النشاط: بتضم العروض المنشورة والمسودات والمنتهية، ومعاها قائمة أصناف النشاط اللي ينفع يتربط بيها العرض. العرض دايماً تابع لنشاط — مفيش عرض بغير بيزنس وراه.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "عروض النشاط"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            },
            "post": {
                "tags": [
                    "Business Management"
                ],
                "summary": "إضافة عرض أو خصم أو كوبون للنشاط",
                "description": "الإنشاء بيتم من جوه النشاط فقط، وصاحب النشاط بس هو اللي يقدر يعمله. العرض مابيعدّيش على مراجعة: أول ما `is_active` يبقى true والتواريخ تسمح، بيظهر في `/offers` وضغطة العميل عليه بتفتح صفحة النشاط. الكوبون من غير كود بيتولّد له كود تلقائي.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "title"
                                ],
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "offer",
                                            "discount",
                                            "coupon"
                                        ]
                                    },
                                    "title": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "description": {
                                        "type": "string",
                                        "maxLength": 2000
                                    },
                                    "discount_percent": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 100
                                    },
                                    "coupon_code": {
                                        "type": "string",
                                        "maxLength": 60
                                    },
                                    "image": {
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "starts_on": {
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "expires_on": {
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "terms": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    },
                                    "is_active": {
                                        "type": "boolean"
                                    },
                                    "listing_service_id": {
                                        "type": "integer",
                                        "description": "لازم يكون صنف تابع لنفس النشاط"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "تم إضافة العرض"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/business/listings/{id}/offers/{offerId}": {
            "post": {
                "tags": [
                    "Business Management"
                ],
                "summary": "تعديل عرض النشاط",
                "description": "POST مش PUT عشان الصورة بتتبعت multipart. ابعت `remove_image=true` عشان تشيل الصورة الحالية.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "offerId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": "off_12"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم تحديث العرض"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Business Management"
                ],
                "summary": "حذف عرض النشاط",
                "description": "العرض اللي اتستخدم من عملاء (فيه كوبونات مستهلكة) بيتوقف بدل ما يتمسح، عشان سجل الاستخدام مايضيعش.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "offerId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": "off_12"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم الحذف أو الإيقاف"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/business/listings/{id}/offers/{offerId}/toggle": {
            "post": {
                "tags": [
                    "Business Management"
                ],
                "summary": "نشر أو إيقاف عرض بضغطة واحدة",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "offerId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": "off_12"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "تم تغيير حالة العرض"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/chats/updates": {
            "get": {
                "tags": [
                    "Chats"
                ],
                "summary": "تحديثات قائمة المحادثات",
                "description": "الطريقة الرخيصة لتحديث شاشة المحادثات وهي مفتوحة.\n\nترجع فقط المحادثات التي وصلتها رسالة منذ `since`، مع عدّاد غير المقروء. استخدمها بدل `GET /chats` في الـ polling — تلك تجلب كل المحادثات بمشاركيها ومنتجاتها وهي أثقل من أن تُنادى على مؤقّت.\n\nالنافذة **شاملة** (`>=`) لأن `last_message_at` بدقّة الثانية: مقارنة صارمة كانت ستُسقط أي محادثة تصلها رسالة في نفس ثانية المؤشّر. لذلك قد تعود أحدث محادثة مرة ثانية — استبدلها بالـ id ولا تضفها.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "since",
                        "in": "query",
                        "required": false,
                        "description": "مؤشّر آخر تحديث (ISO 8601). أعد إرسال `cursor` من الاستجابة السابقة.",
                        "schema": {
                            "type": "string",
                            "format": "date-time"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "المحادثات التي تغيّرت",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "status": {
                                            "type": "boolean"
                                        },
                                        "code": {
                                            "type": "integer"
                                        },
                                        "message": {
                                            "type": "string"
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "chats": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Chat"
                                                    }
                                                },
                                                "unread_count": {
                                                    "type": "integer"
                                                },
                                                "cursor": {
                                                    "type": "string",
                                                    "nullable": true
                                                },
                                                "poll_after_ms": {
                                                    "type": "integer",
                                                    "example": 10000
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            }
        },
        "/chats/{id}/updates": {
            "get": {
                "tags": [
                    "Chats"
                ],
                "summary": "تحديثات محادثة (الرسائل الجديدة فقط)",
                "description": "ما الذي تغيّر في المحادثة منذ آخر مرة: الرسائل الجديدة، إيصالات القراءة، وهل الطرف الآخر يكتب أو موجود الآن.\n\n**هذه هي الطريقة الصحيحة لإبقاء الشاشة حيّة.** `GET /messages` هو السجلّ — مقسّم لصفحات والأحدث أولاً — وهو الشكل الصحيح لفتح الشاشة والتمرير للخلف، والخاطئ للمتابعة اللحظية. الـ polling عليه يعني إعادة جلب ثلاثين رسالة لاكتشاف واحدة، وعكس ترتيبها، ودمجها يدوياً — وهذا سبب أن الرد كان لا يظهر إلا بالخروج من الشاشة والعودة إليها.\n\nهنا العكس في كل ما يهمّ: **تصاعدي**، **الجديد فقط**، بلا غلاف صفحات، ورخيص بما يكفي للنداء كل ثانيتين.\n\nالوصول لهنا يعني أن المستخدم ينظر للمحادثة، فالرسائل الواردة تُعلَّم مقروءة — نفس ما يفعله فتح `/messages`.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ChatId"
                    },
                    {
                        "name": "after_id",
                        "in": "query",
                        "required": false,
                        "description": "آخر رسالة عند العميل (`msg_12`). بدونها تعود ذيل المحادثة.",
                        "schema": {
                            "type": "string",
                            "example": "msg_12"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 50
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "ما استجدّ في المحادثة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "status": {
                                            "type": "boolean"
                                        },
                                        "code": {
                                            "type": "integer"
                                        },
                                        "message": {
                                            "type": "string"
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "messages": {
                                                    "type": "array",
                                                    "description": "تصاعدي — أضفها في الآخر ولا تعكسها.",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ChatMessage"
                                                    }
                                                },
                                                "cursor": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "description": "أعد إرساله كـ `after_id` في النداء التالي."
                                                },
                                                "read_message_ids": {
                                                    "type": "array",
                                                    "description": "رسائلك أنت التي قرأها الطرف الآخر — بها يتحول «تم الإرسال» إلى «تمت القراءة».",
                                                    "items": {
                                                        "type": "string",
                                                        "example": "msg_12"
                                                    }
                                                },
                                                "counterpart": {
                                                    "type": "object",
                                                    "properties": {
                                                        "is_typing": {
                                                            "type": "boolean"
                                                        },
                                                        "is_active": {
                                                            "type": "boolean"
                                                        },
                                                        "last_active_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true
                                                        }
                                                    }
                                                },
                                                "poll_after_ms": {
                                                    "type": "integer",
                                                    "example": 3000,
                                                    "description": "كم تنتظر قبل النداء التالي. من السيرفر عشان تتظبط بدون إصدار جديد."
                                                },
                                                "attachment_rules": {
                                                    "type": "object",
                                                    "description": "حدود المرفقات كما يفرضها السيرفر. اقراها منها بدل ما تكتبها ثابتة في التطبيق — رفع أي حد بيبقى تغيير إعدادات مش إصدار جديد.",
                                                    "properties": {
                                                        "max_kb": {
                                                            "type": "object",
                                                            "description": "الحد الأقصى بالكيلوبايت لكل نوع",
                                                            "properties": {
                                                                "image": {
                                                                    "type": "integer",
                                                                    "example": 8192
                                                                },
                                                                "video": {
                                                                    "type": "integer",
                                                                    "example": 32768
                                                                },
                                                                "audio": {
                                                                    "type": "integer",
                                                                    "example": 16384
                                                                },
                                                                "file": {
                                                                    "type": "integer",
                                                                    "example": 16384
                                                                }
                                                            }
                                                        },
                                                        "mimes": {
                                                            "type": "object",
                                                            "description": "أنواع MIME المسموحة لكل نوع",
                                                            "additionalProperties": {
                                                                "type": "array",
                                                                "items": {
                                                                    "type": "string"
                                                                }
                                                            }
                                                        },
                                                        "text_max_length": {
                                                            "type": "integer",
                                                            "example": 2000
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/chats/{id}/typing": {
            "post": {
                "tags": [
                    "Chats"
                ],
                "summary": "«بيكتب دلوقتي…»",
                "description": "نادِها على مؤقّت أثناء الكتابة. المؤشّر ينتهي وحده بعد ثوانٍ، فنداء ضائع أو تطبيق مقفول لا يترك النقاط عالقة.\n\nإرسال رسالة يمسح المؤشّر تلقائياً — لا تحتاج نداءً لذلك.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ChatId"
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "stopped": {
                                        "type": "boolean",
                                        "description": "`true` لمسح المؤشّر فوراً (مسح المستخدم ما كتبه)."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/MessageOnly"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/business/listings/{id}/notifications/capabilities": {
            "get": {
                "tags": [
                    "Business Management"
                ],
                "summary": "صلاحيات وعدّاد إشعارات النشاط",
                "description": "كل اللي شاشة كتابة الإشعار محتاجاه قبل ما صاحب النشاط يكتب حرف: هل يقدر يبعت، فاضل كام، أنواع الجمهور اللي باقته بتسمح بيها، والوجهات المتاحة. ارسم الشاشة من هنا — بس متعتمدش عليها كحماية: الـ API بيرفض أي إرسال مخالف بغض النظر عن اللي التطبيق سمح بيه.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "`plc_101` أو `101`",
                        "schema": {
                            "type": "string",
                            "example": "plc_8"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "الصلاحيات والعدّاد",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "place_id": {
                                                            "type": "string",
                                                            "example": "plc_8"
                                                        },
                                                        "business_name": {
                                                            "type": "string"
                                                        },
                                                        "is_place_published": {
                                                            "type": "boolean",
                                                            "description": "لازم يكون true قبل أي إرسال"
                                                        },
                                                        "notification_permissions": {
                                                            "$ref": "#/components/schemas/NotificationPermissions"
                                                        },
                                                        "notification_types": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "type": {
                                                                        "type": "string",
                                                                        "example": "offer"
                                                                    },
                                                                    "label": {
                                                                        "type": "string",
                                                                        "example": "عرض"
                                                                    },
                                                                    "is_marketing": {
                                                                        "type": "boolean",
                                                                        "description": "لو true، الإرسال بيخصم من عدّاد الشهر"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "destinations": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "screen": {
                                                                        "type": "string",
                                                                        "example": "offer"
                                                                    },
                                                                    "label": {
                                                                        "type": "string"
                                                                    },
                                                                    "needs_target": {
                                                                        "type": "boolean"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "properties": {
                                                                "title_max": {
                                                                    "type": "integer",
                                                                    "example": 120
                                                                },
                                                                "body_max": {
                                                                    "type": "integer",
                                                                    "example": 500
                                                                },
                                                                "cooldown_minutes": {
                                                                    "type": "integer",
                                                                    "example": 10
                                                                },
                                                                "max_schedule_days": {
                                                                    "type": "integer",
                                                                    "example": 30
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/business/listings/{id}/notifications/usage": {
            "get": {
                "tags": [
                    "Business Management"
                ],
                "summary": "عدّاد إشعارات النشاط",
                "description": "نفس بلوك `notification_permissions` لوحده، للشاشة اللي عايزة تعرض «٤ من ١٠» وبس.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "`plc_101` أو `101`",
                        "schema": {
                            "type": "string",
                            "example": "plc_8"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "العدّاد",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "notification_permissions": {
                                                            "$ref": "#/components/schemas/NotificationPermissions"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/business/listings/{id}/notifications": {
            "get": {
                "tags": [
                    "Business Management"
                ],
                "summary": "سجل إشعارات النشاط",
                "description": "كل الحملات اللي النشاط بعتها، الأحدث أولاً. `targeted` و`sent` بيظهروا في كل الباقات؛ بلوك `analytics` بيظهر بس لو الباقة بتشمله.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "`plc_101` أو `101`",
                        "schema": {
                            "type": "string",
                            "example": "plc_8"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "الحملات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/NotificationCampaign"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            },
            "post": {
                "tags": [
                    "Business Management"
                ],
                "summary": "إرسال أو جدولة إشعار من النشاط",
                "description": "الإرسال بيتم من الطابور، فالرد بيرجع فوراً بحالة `scheduled` والإشعار بيخرج بعدها بلحظات.\n\nالرفض بيرجع دايماً `errors.code` عشان التطبيق يرسم الشاشة الصح:\n- `not_in_plan` (403) — الباقة ما بتشملش الإشعارات؛ اعرض الترقية\n- `notifications_suspended` (403) — موقوف من الإدارة؛ الترقية مش هتحلّه\n- `audience_not_allowed` (403) — الجمهور ده للإدارة بس (زي `all_users`)\n- `audience_not_in_plan` (403) — الباقة ما بتشملش الاستهداف ده؛ `data.audiences` فيها المتاح\n- `deep_links_not_in_plan` / `image_not_in_plan` / `scheduling_not_in_plan` (403)\n- `destination_not_owned` (403) — الوجهة لازم تكون بتاعة نشاطك\n- `quota_exhausted` (409) — خلصت إشعارات الشهر؛ `data.usage` فيها used/limit/reset_at\n- `cooldown` (409) — استنى؛ `data.retry_after_minutes`\n- `duplicate_campaign` (409) — نفس الإشعار اتبعت من شوية\n- `empty_audience` / `audience_too_large` / `invalid_destination` (422)\n\nرسايل النظام (تأكيد طلب، رسالة جديدة) مش بتتبعت من هنا ولا بتخصم من العدّاد.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "`plc_101` أو `101`",
                        "schema": {
                            "type": "string",
                            "example": "plc_8"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "title",
                                    "notification_type",
                                    "audience"
                                ],
                                "properties": {
                                    "title": {
                                        "type": "string",
                                        "maxLength": 120,
                                        "example": "عرض النهاردة 🔥"
                                    },
                                    "body": {
                                        "type": "string",
                                        "maxLength": 500,
                                        "example": "خصم 20% على البيتزا"
                                    },
                                    "notification_type": {
                                        "type": "string",
                                        "enum": [
                                            "marketing",
                                            "offer",
                                            "coupon",
                                            "announcement",
                                            "listing_update"
                                        ]
                                    },
                                    "image_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "nullable": true
                                    },
                                    "audience": {
                                        "type": "object",
                                        "required": [
                                            "type"
                                        ],
                                        "properties": {
                                            "type": {
                                                "type": "string",
                                                "enum": [
                                                    "listing_followers",
                                                    "listing_customers",
                                                    "listing_category",
                                                    "listing_city",
                                                    "location"
                                                ],
                                                "description": "ابعت اللي راجع في `capabilities.audiences` بس"
                                            },
                                            "location_id": {
                                                "type": "integer",
                                                "nullable": true,
                                                "description": "مع `location` فقط — بيشمل كل اللي تحتها"
                                            }
                                        }
                                    },
                                    "destination": {
                                        "type": "object",
                                        "nullable": true,
                                        "properties": {
                                            "screen": {
                                                "type": "string",
                                                "enum": [
                                                    "place",
                                                    "offer",
                                                    "coupon",
                                                    "offers"
                                                ]
                                            },
                                            "target_id": {
                                                "type": "string",
                                                "example": "off_12",
                                                "description": "لازم يكون موجود فعلاً وتابع لنشاطك"
                                            }
                                        }
                                    },
                                    "scheduled_at": {
                                        "type": "string",
                                        "format": "date-time",
                                        "nullable": true,
                                        "description": "سيبها null للإرسال حالاً"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "الإشعار في الطريق أو اتجدول",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "campaign": {
                                                            "$ref": "#/components/schemas/NotificationCampaign"
                                                        },
                                                        "audience_size": {
                                                            "type": "integer",
                                                            "example": 320
                                                        },
                                                        "usage": {
                                                            "$ref": "#/components/schemas/NotificationPermissions"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "description": "العدّاد خلص، أو مهلة الانتظار، أو إشعار مكرر — شوف `errors.code`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/business/listings/{id}/notifications/{campaignId}": {
            "get": {
                "tags": [
                    "Business Management"
                ],
                "summary": "تفاصيل إشعار واحد",
                "description": "الحملة ومعاها تفصيل «مين ما وصلهوش وليه» — بيظهر فقط لو الباقة بتشمل التقارير.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "`plc_101` أو `101`",
                        "schema": {
                            "type": "string",
                            "example": "plc_8"
                        }
                    },
                    {
                        "name": "campaignId",
                        "in": "path",
                        "required": true,
                        "description": "`ncam_12` أو `12`",
                        "schema": {
                            "type": "string",
                            "example": "ncam_12"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "التفاصيل",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "campaign": {
                                                            "$ref": "#/components/schemas/NotificationCampaign"
                                                        },
                                                        "skipped_breakdown": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "reason": {
                                                                        "type": "string",
                                                                        "example": "user_opted_out"
                                                                    },
                                                                    "label": {
                                                                        "type": "string",
                                                                        "example": "المستخدم موقف الإشعارات دي"
                                                                    },
                                                                    "count": {
                                                                        "type": "integer"
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Business Management"
                ],
                "summary": "إلغاء إشعار مسودة أو مجدول",
                "description": "بيلغي الحملة ويرجّع الإشعار لعدّاد الشهر. بيرفض بـ 409 لو الإرسال بدأ فعلاً — ساعتها فيه موبايلات وصلها بالفعل. الصف مابيتمسحش أبداً: الحملة سجل، والعدّاد لازم يفضل مفهوم قصادها.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "`plc_101` أو `101`",
                        "schema": {
                            "type": "string",
                            "example": "plc_8"
                        }
                    },
                    {
                        "name": "campaignId",
                        "in": "path",
                        "required": true,
                        "description": "`ncam_12` أو `12`",
                        "schema": {
                            "type": "string",
                            "example": "ncam_12"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "اتلغى، والعدّاد رجع",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "usage": {
                                                            "$ref": "#/components/schemas/NotificationPermissions"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "description": "بدأ إرساله ومش ممكن إلغاؤه",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/notifications/preferences": {
            "get": {
                "tags": [
                    "Notifications"
                ],
                "summary": "إعدادات إشعارات المستخدم",
                "description": "الحساب اللي عمره ما فتح الشاشة بيرجع بكل حاجة مفعّلة. `system_locked` دايماً true: رسايل الحساب والأمان مش بتتقفل.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "الإعدادات",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/NotificationPreferences"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    }
                }
            },
            "post": {
                "tags": [
                    "Notifications"
                ],
                "summary": "حفظ إعدادات الإشعارات",
                "description": "تعديل جزئي: اللي تبعته بيتغيّر واللي ما تبعتوش بيفضل زي ما هو. ابعت المفتاح اللي اتغيّر بس — كده جهاز بنسخة قديمة مايقدرش يرجّع يفعّل حاجة المستخدم قفلها من جهاز تاني.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "marketing_enabled": {
                                        "type": "boolean"
                                    },
                                    "offers_enabled": {
                                        "type": "boolean"
                                    },
                                    "coupons_enabled": {
                                        "type": "boolean"
                                    },
                                    "messages_enabled": {
                                        "type": "boolean"
                                    },
                                    "reminders_enabled": {
                                        "type": "boolean"
                                    },
                                    "updates_enabled": {
                                        "type": "boolean"
                                    },
                                    "system_enabled": {
                                        "type": "boolean"
                                    },
                                    "quiet_hours_enabled": {
                                        "type": "boolean"
                                    },
                                    "quiet_hours_start": {
                                        "type": "string",
                                        "example": "22:00"
                                    },
                                    "quiet_hours_end": {
                                        "type": "string",
                                        "example": "08:00"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "اتحفظت",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/NotificationPreferences"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/notifications/campaigns/{id}/opened": {
            "post": {
                "tags": [
                    "Notifications"
                ],
                "summary": "تسجيل فتح الإشعار",
                "description": "ابعتها لما المستخدم يضغط على الإشعار (من الـ push أو من صندوق الإشعارات). بتتحسب مرة واحدة لكل مستخدم مهما اتبعتت — فمافيش مشكلة لو النظام سلّم نفس الضغطة مرتين.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "معرّف الحملة `ncam_12` — جاي في `data.campaign_id` بتاع الإشعار، مش معرّف سطر الصندوق (`ntf_…`)",
                        "schema": {
                            "type": "string",
                            "example": "ncam_12"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "اتسجّل، أو كان مسجّل قبل كده",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "counted": {
                                                            "type": "boolean",
                                                            "description": "false يعني اتسجّل قبل كده — مش خطأ، وماينفعش تعيد المحاولة"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/notifications/campaigns/{id}/clicked": {
            "post": {
                "tags": [
                    "Notifications"
                ],
                "summary": "تسجيل الضغط على وجهة الإشعار",
                "description": "منفصلة عن `opened` لأنها سؤال تاني: `opened` يعني «شفته»، و`clicked` يعني «رحت للوجهة». ابعتها بعد ما تفتح الشاشة اللي في `destination` بنجاح.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "معرّف الحملة `ncam_12` — جاي في `data.campaign_id` بتاع الإشعار، مش معرّف سطر الصندوق (`ntf_…`)",
                        "schema": {
                            "type": "string",
                            "example": "ncam_12"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "اتسجّل، أو كان مسجّل قبل كده",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "counted": {
                                                            "type": "boolean",
                                                            "description": "false يعني اتسجّل قبل كده — مش خطأ، وماينفعش تعيد المحاولة"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/search/by-image": {
            "post": {
                "tags": [
                    "Map & AI Search"
                ],
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "summary": "البحث بصورة — المسار المدفوع الاحتياطي (Cloud Vision)",
                "description": "⚠️ **مش ده المسار الأساسي.** التطبيق بيستخدم `POST /search/by-labels` — أرخص وأسرع وأخصّ للخصوصية. استخدم ده بس لو ML Kit رجّع ولا حاجة، **و** `can_upload_image` رجعت `true`.\n\nهنا الصورة بتترفع فعلاً وGoogle Cloud Vision بيقراها على السيرفر. ميزته الوحيدة إنه **بيقرا اللافتات العربي**، واللي قراءة النص على الجهاز مش بتدعمها.\n\n**بيتكلّف فلوس عند جوجل في كل نداء**، فهو ورا تسجيل الدخول وبحد 6 طلبات في الدقيقة، و**مقفول تماماً** لو مفيش مفتاح Vision على السيرفر.\n\n**إزاي بيشتغل:** Vision بيقرا الصورة بس. البحث نفسه بيتعمل بمحرك البحث بتاعنا على الدليل — مفيش أي نتيجة جاية من جوجل. والرد نفس رد `by-labels` بالحرف.\n\n**الصورة:** إما `image` كملف multipart، أو `image_base64` (بيقبل data URL). لازم تكون صورة حقيقية — أي بايتات تانية بترفض من غير ما نكلّم جوجل.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "image": {
                                        "type": "string",
                                        "format": "binary",
                                        "description": "ملف صورة. مطلوب لو مفيش image_base64."
                                    },
                                    "image_base64": {
                                        "type": "string",
                                        "nullable": true,
                                        "description": "بديل الملف، لعملاء بيرجّعوا bytes مش file. بيقبل data URL."
                                    },
                                    "query": {
                                        "type": "string",
                                        "maxLength": 200,
                                        "nullable": true,
                                        "description": "أي كلام كتبه المستخدم جنب الصورة. بيتحط قبل كلمات الصورة في البحث.",
                                        "example": "اقرب واحد"
                                    },
                                    "user_lat": {
                                        "type": "number",
                                        "format": "double",
                                        "nullable": true,
                                        "example": 30.9706
                                    },
                                    "user_lng": {
                                        "type": "number",
                                        "format": "double",
                                        "nullable": true,
                                        "example": 31.1656
                                    },
                                    "limit": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 30,
                                        "default": 10
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "نتايج البحث بالصورة — نفس شكل /search/ai-analyze زيادة عليه اللي اتقرا من الصورة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/ImageSearchResult"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "422": {
                        "description": "الصورة مش صالحة أو مش مفهومة. `data.code` بيقول أنهي حالة: `nothing_recognised` (جرب صورة أوضح) أو `image_rejected` (محتوى غير مناسب).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/ErrorResponse"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "code": {
                                                            "type": "string",
                                                            "enum": [
                                                                "nothing_recognised",
                                                                "image_rejected"
                                                            ],
                                                            "example": "nothing_recognised"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "502": {
                        "description": "مشكلة عندنا مش في الصورة — Vision ما ردّش. `data.code` = `vision_failed`. اعرض زرار «جرب تاني»، مش «صوّر تاني»."
                    },
                    "503": {
                        "description": "الميزة مش مفعّلة على السيرفر (مفيش مفتاح). `data.code` = `vision_unavailable`. المفروض ما توصلش هنا أصلاً لو سألت status الأول."
                    }
                }
            }
        },
        "/search/by-image/status": {
            "get": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "حالة البحث بالصورة",
                "description": "مفتوح ومجاني وما بيكلّمش جوجل.\n\n`is_available` **دايماً `true`**: المسار اللي على الجهاز مش محتاج حاجة من السيرفر، فزرار الكاميرا عمره ما يتخفي.\n\n`can_upload_image` هي بس اللي بتتبع مفتاح Vision — اقراها عشان تقرر لو ينفع ترفع الصورة كاحتياطي لما ML Kit ما يرجّعش حاجة. لو `false` اعرض «جرب صورة أوضح» بدل الرفع.",
                "responses": {
                    "200": {
                        "description": "حالة الميزة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "is_available": {
                                                            "type": "boolean",
                                                            "description": "دايماً true — البحث على الجهاز شغّال دايماً.",
                                                            "example": true
                                                        },
                                                        "on_device": {
                                                            "type": "boolean",
                                                            "example": true
                                                        },
                                                        "can_upload_image": {
                                                            "type": "boolean",
                                                            "description": "هل رفع الصورة للسيرفر (Cloud Vision) متاح.",
                                                            "example": false
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/search/by-labels": {
            "post": {
                "tags": [
                    "Map & AI Search"
                ],
                "summary": "البحث بصورة — المسار اللي التطبيق بيستخدمه (ML Kit على الجهاز)",
                "description": "**ده المسار الأساسي للبحث بالصورة.** الموبايل بيوصف الصورة بنفسه بـ Google ML Kit **على الجهاز**، وبيبعت الكلمات. **الصورة نفسها عمرها ما بتخرج من التليفون.**\n\n**مجاني تماماً:** مفيش مفتاح، مفيش billing، مفيش حد شهري، ومفيش طرف تالت في الريكوست. عشان كده هو مفتوح للزوار ومحدود 30/دقيقة زي `ai-analyze` بالظبط — مش زي `by-image`.\n\n**الرد نفس رد `/search/ai-analyze` بالحرف** زيادة عليه اللي اتشاف في الصورة، فشاشة النتايج والـ parser واحدين.\n\n**في فلاتر:** `google_mlkit_image_labeling` → ابعت `label.label` مرتبين بالـ `confidence` (الأعلى الأول)، ويُفضّل تفلتر اللي تحت 0.5. ولو ضفت `google_mlkit_text_recognition` ابعت الناتج في `text`.\n\n> **ملاحظة مهمة:** قراءة النص على الجهاز بتدعم لاتيني/صيني/ياباني/كوري/هندي — **العربي مش منهم**. فلافتة محل مكتوبة بالعربي غالباً `text` هيرجع فاضي، والوصف (`labels`) هو اللي هيشتغل. براند لاتيني على لافتة بيتقرا عادي.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "labels"
                                ],
                                "properties": {
                                    "labels": {
                                        "type": "array",
                                        "minItems": 1,
                                        "maxItems": 20,
                                        "items": {
                                            "type": "string",
                                            "maxLength": 80
                                        },
                                        "description": "اللي ML Kit شافه، الأعلى ثقة الأول.",
                                        "example": [
                                            "Food",
                                            "Pizza",
                                            "Cheese"
                                        ]
                                    },
                                    "text": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 2000,
                                        "description": "ناتج قراءة النص على الجهاز، لو استخدمته. غالباً فاضي مع العربي."
                                    },
                                    "query": {
                                        "type": "string",
                                        "maxLength": 200,
                                        "nullable": true,
                                        "description": "أي كلام كتبه المستخدم جنب الصورة. بيتحط **قبل** كلمات الصورة.",
                                        "example": "اقرب واحد"
                                    },
                                    "user_lat": {
                                        "type": "number",
                                        "format": "double",
                                        "nullable": true,
                                        "example": 30.9706
                                    },
                                    "user_lng": {
                                        "type": "number",
                                        "format": "double",
                                        "nullable": true,
                                        "example": 31.1656
                                    },
                                    "limit": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 30,
                                        "default": 10
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "نتايج البحث — نفس شكل /search/ai-analyze زيادة عليه اللي اتشاف في الصورة",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/ImageSearchResult"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "إما `labels` ناقصة (خطأ تحقّق عادي)، أو مفيش ولا كلمة منها ليها معنى في الدليل وساعتها `data.code` = `nothing_recognised` → «جرب صورة أوضح».",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/ErrorResponse"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "code": {
                                                            "type": "string",
                                                            "enum": [
                                                                "nothing_recognised"
                                                            ],
                                                            "example": "nothing_recognised"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/articles/categories": {
            "get": {
                "tags": [
                    "Articles"
                ],
                "summary": "أقسام المقالات (شريط الـ chips)",
                "description": "الأقسام المتاحة فعلاً — مبنية من المقالات **المنشورة** مش من قائمة ثابتة. قسم يخترعه المحرر بيظهر لوحده، وقسم يفضى بيختفي لوحده، فمفيش chip بيفتح شاشة فاضية.\n\nاستخدم `name` كقيمة لفلتر `GET /articles?category=`.",
                "responses": {
                    "200": {
                        "description": "الأقسام مرتبة بالأكتر عدداً",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "name": {
                                                                "type": "string",
                                                                "example": "أخبار المدينة"
                                                            },
                                                            "articles_count": {
                                                                "type": "integer",
                                                                "example": 12
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/version": {
            "get": {
                "tags": [
                    "System"
                ],
                "summary": "إصدار الخادم والمزايا المتاحة فيه",
                "description": "بيقول النسخة المرفوعة فعلياً على السيرفر. مفتوح من غير توكن عشان أي حد في الفريق يقدر يتأكد إن التحديث اترفع قبل ما يفتح بلاغ على الكود.\n\n`features` بترد على الأسئلة المتكررة بالاسم — مثلاً `registration_full_payload` بتبقى `true` لما طلب تسجيل النشاط المرتجع للاستكمال يرجّع بيانات الفورم كاملة (`values` و`media` و`labels` و`completion`).",
                "responses": {
                    "200": {
                        "description": "بيانات الإصدار",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/SuccessEnvelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "version": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "example": "2026.09.19-07"
                                                        },
                                                        "title": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "built_at": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "example": "2026-09-19 22:05:48"
                                                        },
                                                        "profile": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "example": "code"
                                                        },
                                                        "file_count": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "example": 672
                                                        },
                                                        "source": {
                                                            "type": "string",
                                                            "enum": [
                                                                "manifest",
                                                                "release",
                                                                "unknown"
                                                            ],
                                                            "description": "`manifest` معناها إن السيرفر اتحدّث من باكدج مبني. `release` معناها رفع يدوي."
                                                        },
                                                        "features": {
                                                            "type": "object",
                                                            "additionalProperties": {
                                                                "type": "boolean"
                                                            },
                                                            "example": {
                                                                "registration_full_payload": true,
                                                                "registration_partial_resubmit": true
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/work-items": {
            "get": {
                "responses": {
                    "200": {
                        "description": "Active work items"
                    },
                    "403": {
                        "description": "Admin required"
                    }
                },
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "tags": [
                    "Admin"
                ],
                "summary": "Read dashboard goals, notes and tasks (admin only)"
            }
        },
        "/admin/work-items/{item}": {
            "delete": {
                "tags": ["Admin"],
                "summary": "Delete a specifically owner-authorized work item",
                "security": [{"BearerAuth": []}],
                "parameters": [{"in": "path", "required": true, "name": "item", "schema": {"type": "integer"}}],
                "responses": {"200": {"description": "Deleted"}, "403": {"description": "Not authorized"}}
            },
            "patch": {
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "evidence": {
                                        "type": "string"
                                    },
                                    "release": {
                                        "type": "string"
                                    },
                                    "operation": {
                                        "type": "string",
                                        "enum": [
                                            "claim",
                                            "stage"
                                        ]
                                    }
                                },
                                "required": [
                                    "operation"
                                ],
                                "type": "object"
                            }
                        }
                    },
                    "required": true
                },
                "summary": "Claim or stage an authorized dashboard task",
                "responses": {
                    "403": {
                        "description": "Not authorized"
                    },
                    "200": {
                        "description": "Updated task"
                    },
                    "422": {
                        "description": "Invalid transition"
                    }
                },
                "tags": [
                    "Admin"
                ],
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "in": "path",
                        "required": true,
                        "name": "item",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        }
    },
    "components": {
        "securitySchemes": {
            "BearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "description": "توكن Sanctum المرجَع من `/auth/login` أو `/auth/register`. أرسله كـ `Authorization: Bearer {token}`."
            }
        },
        "parameters": {
            "ChatId": {
                "name": "id",
                "in": "path",
                "required": true,
                "description": "`chat_1` أو `1`",
                "schema": {
                    "type": "string",
                    "example": "chat_1"
                }
            },
            "PlanId": {
                "name": "plan",
                "in": "path",
                "required": true,
                "description": "`plan_2` أو `2` أو الـ slug (`plan_premium` / `premium`)",
                "schema": {
                    "type": "string",
                    "example": "plan_premium"
                }
            },
            "SubscriptionRequestId": {
                "name": "id",
                "in": "path",
                "required": true,
                "description": "`subreq_1` أو `1`",
                "schema": {
                    "type": "string",
                    "example": "subreq_1"
                }
            },
            "PlaceId": {
                "name": "id",
                "in": "path",
                "required": true,
                "description": "`plc_101` أو `101` أو الـ slug",
                "schema": {
                    "type": "string",
                    "example": "plc_8"
                }
            },
            "CategoryId": {
                "name": "id",
                "in": "path",
                "required": true,
                "description": "`cat_17` أو `17` أو الـ slug",
                "schema": {
                    "type": "string",
                    "example": "cat_17"
                }
            },
            "ProductId": {
                "name": "id",
                "in": "path",
                "required": true,
                "description": "`prd_201` أو `201`",
                "schema": {
                    "type": "string",
                    "example": "prd_1"
                }
            },
            "OfferId": {
                "name": "id",
                "in": "path",
                "required": true,
                "description": "`off_301` أو `301`",
                "schema": {
                    "type": "string",
                    "example": "off_1"
                }
            },
            "ArticleId": {
                "name": "id",
                "in": "path",
                "required": true,
                "description": "`art_12` أو `12` أو الـ slug",
                "schema": {
                    "type": "string",
                    "example": "art_1"
                }
            },
            "NotificationId": {
                "name": "id",
                "in": "path",
                "required": true,
                "description": "`ntf_7` أو `7`",
                "schema": {
                    "type": "string",
                    "example": "ntf_1"
                }
            },
            "Page": {
                "name": "page",
                "in": "query",
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "default": 1
                }
            },
            "Limit": {
                "name": "limit",
                "in": "query",
                "description": "عدد العناصر في الصفحة",
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 50,
                    "default": 15
                }
            },
            "ListingTypeId": {
                "name": "id",
                "in": "path",
                "required": true,
                "description": "معرّف نوع النشاط: `ltype_8` أو `8` أو الـ slug.",
                "schema": {
                    "type": "string",
                    "example": "restaurant"
                }
            }
        },
        "responses": {
            "MessageOnly": {
                "description": "تمت العملية بنجاح (بدون بيانات مرجعة)",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/SuccessEnvelope"
                        }
                    }
                }
            },
            "ValidationError": {
                "description": "خطأ في التحقق من البيانات",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorResponse"
                        },
                        "example": {
                            "status": false,
                            "code": 422,
                            "message": "بيانات غير صالحة، برجاء مراجعة الحقول المطلوبة",
                            "errors": {
                                "phone": [
                                    "رقم الهاتف مسجل مسبقاً",
                                    "صيغة رقم الهاتف غير صحيحة"
                                ],
                                "password": [
                                    "كلمة المرور يجب ألا تقل عن 6 أحرف"
                                ]
                            }
                        }
                    }
                }
            },
            "Unauthenticated": {
                "description": "غير مسجّل دخول أو التوكن منتهي",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorResponse"
                        },
                        "example": {
                            "status": false,
                            "code": 401,
                            "message": "يجب تسجيل الدخول أولاً"
                        }
                    }
                }
            },
            "Forbidden": {
                "description": "مسجّل دخول لكن غير مصرّح بهذا الإجراء",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorResponse"
                        },
                        "example": {
                            "status": false,
                            "code": 403,
                            "message": "غير مصرح لك بتعديل هذا الإعلان"
                        }
                    }
                }
            },
            "NotFound": {
                "description": "المورد المطلوب غير موجود",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorResponse"
                        },
                        "example": {
                            "status": false,
                            "code": 404,
                            "message": "المورد المطلوب غير موجود"
                        }
                    }
                }
            },
            "TooManyRequests": {
                "description": "تجاوز حد المحاولات المسموح",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorResponse"
                        },
                        "example": {
                            "status": false,
                            "code": 429,
                            "message": "عدد كبير من المحاولات، برجاء المحاولة بعد قليل"
                        }
                    }
                }
            }
        },
        "schemas": {
            "FaqItem": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "faq_1"
                    },
                    "question": {
                        "type": "string",
                        "example": "ما هو تطبيق المحلة أون؟"
                    },
                    "question_en": {
                        "type": "string",
                        "nullable": true
                    },
                    "answer": {
                        "type": "string",
                        "nullable": true,
                        "description": "`null` لسؤال لم تُكتب إجابته بعد — التطبيق يعرض دعوة للتواصل بدلاً منها",
                        "example": "دليل رقمي شامل لمدينة المحلة الكبرى."
                    },
                    "answer_en": {
                        "type": "string",
                        "nullable": true
                    }
                }
            },
            "FaqCategory": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "faqcat_1"
                    },
                    "title": {
                        "type": "string",
                        "example": "عام"
                    },
                    "title_en": {
                        "type": "string",
                        "nullable": true,
                        "example": "General"
                    },
                    "icon_key": {
                        "type": "string",
                        "nullable": true,
                        "example": "info"
                    },
                    "items": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/FaqItem"
                        }
                    }
                }
            },
            "Chat": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "chat_1"
                    },
                    "name": {
                        "type": "string",
                        "description": "اسم الطرف الآخر من وجهة نظر المستخدم الحالي",
                        "example": "معرض آبل ستور المحلة"
                    },
                    "avatar_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "last_message": {
                        "type": "string",
                        "nullable": true,
                        "example": "طيب خروج الفادي"
                    },
                    "last_message_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "unread_count": {
                        "type": "integer",
                        "example": 2
                    },
                    "role": {
                        "type": "string",
                        "enum": [
                            "buyer",
                            "seller"
                        ],
                        "description": "دور المستخدم الحالي في هذه المحادثة",
                        "example": "buyer"
                    },
                    "product": {
                        "type": "object",
                        "nullable": true,
                        "description": "`null` إذا حُذف الإعلان الذي بدأت منه المحادثة",
                        "properties": {
                            "id": {
                                "type": "string",
                                "example": "prd_1"
                            },
                            "title": {
                                "type": "string",
                                "example": "آيفون 14 برو ماكس 256GB"
                            },
                            "price": {
                                "type": "number",
                                "format": "float",
                                "example": 34500
                            },
                            "image": {
                                "type": "string",
                                "nullable": true
                            }
                        }
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "ChatMessage": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "msg_10"
                    },
                    "chat_id": {
                        "type": "string",
                        "example": "chat_1"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "text",
                            "image",
                            "video",
                            "audio",
                            "file"
                        ],
                        "description": "دايماً موجود، و`text` لكل رسالة اتكتبت قبل المرفقات — فينفع تعمل switch عليه من غير null check.",
                        "example": "text"
                    },
                    "text": {
                        "type": "string",
                        "nullable": true,
                        "description": "`null` (مش \"\") للمرفق من غير تعليق، عشان ما ترسمش سطر فاضي تحت الصورة.",
                        "example": "أيوة متاح، تحب تعاين؟"
                    },
                    "attachment_url": {
                        "type": "string",
                        "nullable": true,
                        "format": "uri",
                        "example": "https://elmahalla-on.gadmotions.com/storage/chats/12/abc.jpg"
                    },
                    "attachment_mime": {
                        "type": "string",
                        "nullable": true,
                        "example": "image/jpeg"
                    },
                    "file_name": {
                        "type": "string",
                        "nullable": true,
                        "description": "للمستندات بس (`type: file`). الصور والفيديو والصوت بترجع `null` — اسم زي IMG_0421 مالوش لازمة في فقاعة الشات.",
                        "example": "العقد النهائي.pdf"
                    },
                    "file_size": {
                        "type": "integer",
                        "nullable": true,
                        "description": "بالبايت",
                        "example": 148213
                    },
                    "duration_ms": {
                        "type": "integer",
                        "nullable": true,
                        "description": "للصوت والفيديو. `null` لو العميل ما بعتهاش — المشغّل بيشتغل عادي، بس مش هيعرف يعرض المدة قبل التحميل.",
                        "example": 7400
                    },
                    "sender": {
                        "type": "string",
                        "enum": [
                            "me",
                            "them"
                        ],
                        "description": "محسوبة بالنسبة للمستخدم الحالي، فلا يحتاج التطبيق لمقارنة معرّفات المستخدمين",
                        "example": "them"
                    },
                    "is_read": {
                        "type": "boolean",
                        "example": true
                    },
                    "sent_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "Plan": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "plan_2"
                    },
                    "slug": {
                        "type": "string",
                        "example": "premium"
                    },
                    "name": {
                        "type": "string",
                        "example": "بريميوم"
                    },
                    "name_en": {
                        "type": "string",
                        "nullable": true,
                        "example": "Premium"
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "price": {
                        "type": "number",
                        "format": "float",
                        "example": 100
                    },
                    "currency": {
                        "type": "string",
                        "example": "EGP"
                    },
                    "duration_days": {
                        "type": "integer",
                        "nullable": true,
                        "description": "`null` = باقة لا تنتهي",
                        "example": 30
                    },
                    "ads_limit": {
                        "type": "integer",
                        "nullable": true,
                        "description": "`null` = غير محدود، و`0` = ممنوع النشر",
                        "example": 20
                    },
                    "features": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "20 إعلاناً شهرياً",
                            "تمييز الإعلانات"
                        ]
                    },
                    "is_free": {
                        "type": "boolean",
                        "example": false
                    },
                    "is_featured": {
                        "type": "boolean",
                        "example": true
                    },
                    "is_default": {
                        "type": "boolean",
                        "description": "الباقة التي يقع عليها حساب بلا اشتراك",
                        "example": false
                    }
                }
            },
            "PaymentMethod": {
                "type": "object",
                "properties": {
                    "key": {
                        "type": "string",
                        "description": "القيمة المرسلة في `payment_method`",
                        "example": "vodafone_cash"
                    },
                    "label": {
                        "type": "string",
                        "example": "فودافون كاش"
                    },
                    "icon_key": {
                        "type": "string",
                        "nullable": true,
                        "example": "wallet"
                    },
                    "account": {
                        "type": "string",
                        "nullable": true,
                        "description": "الرقم/الحساب المُحوَّل إليه",
                        "example": "01000000000"
                    },
                    "instructions": {
                        "type": "string",
                        "nullable": true
                    },
                    "requires_phone": {
                        "type": "boolean",
                        "description": "عندها يصبح `phone` مطلوباً عند الاشتراك",
                        "example": true
                    },
                    "is_active": {
                        "type": "boolean",
                        "example": true
                    }
                }
            },
            "CurrentSubscription": {
                "type": "object",
                "properties": {
                    "plan": {
                        "type": "object",
                        "nullable": true,
                        "properties": {
                            "id": {
                                "type": "string",
                                "example": "plan_1"
                            },
                            "slug": {
                                "type": "string",
                                "example": "free"
                            },
                            "name": {
                                "type": "string",
                                "example": "مجاني"
                            },
                            "price": {
                                "type": "number",
                                "format": "float",
                                "example": 0
                            },
                            "features": {
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "is_free": {
                        "type": "boolean",
                        "description": "لا يوجد اشتراك مدفوع فعّال",
                        "example": true
                    },
                    "status": {
                        "type": "string",
                        "example": "active"
                    },
                    "ads_used": {
                        "type": "integer",
                        "description": "الإعلانات التي تشغل حصة الآن (قيد المراجعة + منشورة)",
                        "example": 2
                    },
                    "ads_limit": {
                        "type": "integer",
                        "nullable": true,
                        "description": "`null` = غير محدود",
                        "example": 3
                    },
                    "ads_remaining": {
                        "type": "integer",
                        "nullable": true,
                        "example": 1
                    },
                    "started_on": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "expires_on": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "`null` للباقة المجانية"
                    },
                    "days_remaining": {
                        "type": "integer",
                        "nullable": true,
                        "example": 25
                    },
                    "has_pending_request": {
                        "type": "boolean",
                        "example": false
                    }
                }
            },
            "SubscriptionRequest": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "subreq_1"
                    },
                    "plan": {
                        "type": "object",
                        "nullable": true,
                        "properties": {
                            "id": {
                                "type": "string",
                                "example": "plan_2"
                            },
                            "slug": {
                                "type": "string",
                                "example": "premium"
                            },
                            "name": {
                                "type": "string",
                                "example": "بريميوم"
                            },
                            "price": {
                                "type": "number",
                                "format": "float",
                                "example": 100
                            }
                        }
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "approved",
                            "rejected",
                            "cancelled"
                        ],
                        "example": "pending"
                    },
                    "status_label": {
                        "type": "string",
                        "example": "قيد المراجعة"
                    },
                    "payment_method": {
                        "type": "string",
                        "nullable": true,
                        "example": "vodafone_cash"
                    },
                    "amount": {
                        "type": "number",
                        "format": "float",
                        "example": 100
                    },
                    "currency": {
                        "type": "string",
                        "example": "EGP"
                    },
                    "admin_note": {
                        "type": "string",
                        "nullable": true,
                        "description": "سبب الرفض عند وجوده"
                    },
                    "requested_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "reviewed_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    }
                }
            },
            "Activity": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "act_1"
                    },
                    "type": {
                        "type": "string",
                        "description": "قائمة قابلة للتوسّع — أي نوع غير معروف يجب أن يُعرض بشكل عام بدلاً من كسر الشاشة",
                        "enum": [
                            "ad_submitted",
                            "ad_approved",
                            "ad_rejected",
                            "ad_sold",
                            "ad_expired",
                            "review_submitted",
                            "subscription_requested",
                            "subscription_approved",
                            "subscription_rejected"
                        ],
                        "example": "ad_approved"
                    },
                    "title": {
                        "type": "string",
                        "example": "تم قبول إعلانك"
                    },
                    "description": {
                        "type": "string",
                        "nullable": true,
                        "example": "إعلان \"آيفون 14 برو ماكس\" أصبح ظاهراً في سوق المحلة"
                    },
                    "icon_key": {
                        "type": "string",
                        "nullable": true,
                        "example": "check"
                    },
                    "related_type": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                            "market_product",
                            "subscription_request",
                            "review"
                        ],
                        "example": "market_product"
                    },
                    "related_id": {
                        "type": "string",
                        "nullable": true,
                        "description": "المعرّف العام المسبوق",
                        "example": "prd_1"
                    },
                    "time_ago": {
                        "type": "string",
                        "nullable": true,
                        "example": "منذ ساعتين"
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "ActivitySummary": {
                "type": "object",
                "properties": {
                    "pending_count": {
                        "type": "integer",
                        "description": "إعلانات أُرسلت وما زالت تنتظر المراجعة",
                        "example": 1
                    },
                    "my_market_ads_count": {
                        "type": "integer",
                        "description": "كل إعلانات المستخدم أياً كانت حالتها",
                        "example": 4
                    },
                    "total_active_count": {
                        "type": "integer",
                        "description": "الظاهرة الآن في السوق",
                        "example": 2
                    },
                    "rejected_count": {
                        "type": "integer",
                        "example": 1
                    },
                    "sold_count": {
                        "type": "integer",
                        "example": 0
                    },
                    "expired_count": {
                        "type": "integer",
                        "example": 0
                    },
                    "total_views": {
                        "type": "integer",
                        "example": 143
                    },
                    "favorites_count": {
                        "type": "integer",
                        "example": 7
                    },
                    "reviews_count": {
                        "type": "integer",
                        "example": 3
                    },
                    "pending_subscription_requests": {
                        "type": "integer",
                        "example": 0
                    },
                    "unread_notifications": {
                        "type": "integer",
                        "example": 5
                    }
                }
            },
            "SuccessEnvelope": {
                "type": "object",
                "properties": {
                    "status": {
                        "type": "boolean",
                        "example": true
                    },
                    "code": {
                        "type": "integer",
                        "example": 200
                    },
                    "message": {
                        "type": "string",
                        "example": "تمت العملية بنجاح"
                    }
                }
            },
            "ErrorResponse": {
                "type": "object",
                "properties": {
                    "status": {
                        "type": "boolean",
                        "example": false
                    },
                    "code": {
                        "type": "integer",
                        "example": 422
                    },
                    "message": {
                        "type": "string",
                        "example": "بيانات غير صالحة، برجاء مراجعة الحقول المطلوبة"
                    },
                    "errors": {
                        "type": "object",
                        "description": "موجود فقط مع أخطاء التحقق (422). المفتاح هو اسم الحقل والقيمة مصفوفة رسائل.",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    }
                }
            },
            "Pagination": {
                "type": "object",
                "properties": {
                    "current_page": {
                        "type": "integer",
                        "example": 1
                    },
                    "per_page": {
                        "type": "integer",
                        "example": 15
                    },
                    "total": {
                        "type": "integer",
                        "example": 120
                    },
                    "total_pages": {
                        "type": "integer",
                        "example": 8
                    }
                }
            },
            "User": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "usr_5"
                    },
                    "name": {
                        "type": "string",
                        "example": "محمد علي المحلاوي"
                    },
                    "phone": {
                        "type": "string",
                        "nullable": true,
                        "example": "01012345678"
                    },
                    "is_phone_confirmed": {
                        "type": "boolean",
                        "description": "هل تم إثبات ملكية الرقم فعلياً عبر رمز SMS (وليس مجرد كتابته).",
                        "example": false
                    },
                    "email": {
                        "type": "string",
                        "example": "mohamed.ali@example.com"
                    },
                    "gender": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                            "male",
                            "female",
                            null
                        ],
                        "example": "male"
                    },
                    "area": {
                        "type": "string",
                        "nullable": true,
                        "example": "المحلة الكبرى - شارع البحر"
                    },
                    "avatar_url": {
                        "type": "string",
                        "nullable": true,
                        "example": "https://api.mahalla-on.com/storage/avatars/abc.png"
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-08-21T17:54:20+03:00"
                    }
                }
            },
            "AuthSuccessResponse": {
                "type": "object",
                "properties": {
                    "status": {
                        "type": "boolean",
                        "example": true
                    },
                    "code": {
                        "type": "integer",
                        "example": 200
                    },
                    "message": {
                        "type": "string",
                        "example": "تم تسجيل الدخول بنجاح"
                    },
                    "data": {
                        "type": "object",
                        "properties": {
                            "token": {
                                "type": "string",
                                "example": "5|Xy8kQ2mNpR7vLwT3..."
                            },
                            "token_type": {
                                "type": "string",
                                "example": "Bearer"
                            },
                            "user": {
                                "$ref": "#/components/schemas/User"
                            }
                        }
                    }
                }
            },
            "Category": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "cat_17"
                    },
                    "slug": {
                        "type": "string",
                        "example": "hospitals"
                    },
                    "title": {
                        "type": "string",
                        "example": "مستشفيات ومراكز طبية"
                    },
                    "title_en": {
                        "type": "string",
                        "nullable": true,
                        "example": "Hospitals"
                    },
                    "icon_key": {
                        "type": "string",
                        "nullable": true,
                        "description": "مفتاح ثابت تربطه بأصل محلي في التطبيق",
                        "enum": [
                            "restaurant",
                            "health",
                            "hospital",
                            "pharmacy",
                            "fashion",
                            "grocery",
                            "cafe",
                            "car",
                            "building",
                            "education",
                            "beauty",
                            "tools"
                        ],
                        "example": "hospital"
                    },
                    "color_hex": {
                        "type": "string",
                        "example": "#08214D"
                    },
                    "image_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "رابط مطلق لصورة التصنيف، أو null لو مفيش صورة — ساعتها ارسم التايل بـ icon_key + color_hex. نفس الصورة تُستخدم في الوضع الفاتح والداكن.",
                        "example": "https://elmahalla-on.gadmotions.com/storage/categories/food.png"
                    },
                    "sub_categories_count": {
                        "type": "integer",
                        "example": 3
                    },
                    "places_count": {
                        "type": "integer",
                        "example": 24
                    },
                    "icon": {
                        "type": "string",
                        "nullable": true
                    },
                    "icon_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "نفس قيمة image_url."
                    },
                    "sub_categories": {
                        "type": "array",
                        "description": "موجود فقط لما تطلبه: `/categories?with=sub_categories`، أو دايماً في `/categories/{id}`.",
                        "items": {
                            "$ref": "#/components/schemas/SubCategory"
                        }
                    }
                }
            },
            "SubCategory": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "nullable": true,
                        "example": "subcat_5"
                    },
                    "category_id": {
                        "type": "string",
                        "nullable": true,
                        "example": "cat_31"
                    },
                    "slug": {
                        "type": "string",
                        "nullable": true,
                        "example": "pizza"
                    },
                    "title": {
                        "type": "string",
                        "example": "بيتزا"
                    },
                    "name": {
                        "type": "string",
                        "nullable": true,
                        "example": "بيتزا"
                    },
                    "title_en": {
                        "type": "string",
                        "nullable": true,
                        "example": "Pizza"
                    },
                    "icon": {
                        "type": "string",
                        "nullable": true
                    },
                    "icon_key": {
                        "type": "string",
                        "nullable": true,
                        "description": "مفتاح ثابت تربطه بأصل محلي في التطبيق."
                    },
                    "color_hex": {
                        "type": "string",
                        "nullable": true,
                        "example": "#22A6DF"
                    },
                    "icon_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "رابط مطلق لصورة التخصص الفرعي، أو null فيرسم التايل بـ icon_key + color_hex."
                    },
                    "image_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "نفس قيمة icon_url."
                    },
                    "places_count": {
                        "type": "integer",
                        "example": 3
                    }
                },
                "description": "التصنيفات القديمة اللي لسه من غير تخصصات فرعية بترجع من `/categories/{id}/sub-categories` بـ `title` و`places_count` فقط، مبنية من قيم حقل `sub_category` النصي."
            },
            "Place": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "plc_7"
                    },
                    "slug": {
                        "type": "string",
                        "example": "mahalla-general-hospital"
                    },
                    "name": {
                        "type": "string",
                        "example": "مستشفى المحلة العام"
                    },
                    "category": {
                        "type": "string",
                        "nullable": true,
                        "example": "مستشفيات ومراكز طبية"
                    },
                    "category_id": {
                        "type": "string",
                        "nullable": true,
                        "example": "cat_17"
                    },
                    "sub_category": {
                        "type": "string",
                        "nullable": true,
                        "example": "مستشفيات حكومية"
                    },
                    "tagline": {
                        "type": "string",
                        "nullable": true,
                        "example": "طوارئ وعناية مركزة واستقبال 24 ساعة"
                    },
                    "brand_color_hex": {
                        "type": "string",
                        "example": "#08214D"
                    },
                    "brand_icon_key": {
                        "type": "string",
                        "nullable": true,
                        "example": "hospital"
                    },
                    "rating": {
                        "type": "number",
                        "format": "float",
                        "example": 4.8
                    },
                    "reviews_count": {
                        "type": "integer",
                        "example": 142
                    },
                    "is_verified": {
                        "type": "boolean",
                        "example": true
                    },
                    "is_featured": {
                        "type": "boolean",
                        "example": true
                    },
                    "is_open_now": {
                        "type": "boolean",
                        "nullable": true,
                        "example": true
                    },
                    "views_count": {
                        "type": "integer",
                        "example": 3200
                    },
                    "work_days": {
                        "type": "array",
                        "description": "أسماء الأيام العربية، أو `[\"يومياً\"]` عندما يكون المكان مفتوحاً 7 أيام",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "يومياً"
                        ]
                    },
                    "work_hours_from": {
                        "type": "string",
                        "nullable": true,
                        "description": "أبكر موعد فتح خلال الأسبوع",
                        "example": "00:00"
                    },
                    "work_hours_to": {
                        "type": "string",
                        "nullable": true,
                        "description": "أحدث موعد إغلاق خلال الأسبوع",
                        "example": "23:59"
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "address": {
                        "type": "string",
                        "nullable": true,
                        "example": "شارع الجيش، المحلة الكبرى"
                    },
                    "area": {
                        "type": "string",
                        "nullable": true,
                        "example": "شارع الجيش"
                    },
                    "city": {
                        "type": "string",
                        "nullable": true,
                        "example": "المحلة الكبرى"
                    },
                    "phone": {
                        "type": "string",
                        "nullable": true,
                        "example": "0402220000"
                    },
                    "whatsapp": {
                        "type": "string",
                        "nullable": true,
                        "example": "01000000001"
                    },
                    "facebook_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "instagram_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "website": {
                        "type": "string",
                        "nullable": true
                    },
                    "logo": {
                        "type": "string",
                        "nullable": true
                    },
                    "cover_image": {
                        "type": "string",
                        "nullable": true
                    },
                    "photos_count": {
                        "type": "integer",
                        "example": 12
                    },
                    "distance_km": {
                        "type": "number",
                        "format": "float",
                        "nullable": true,
                        "description": "`null` ما لم تُرسل `lat` و `lng`",
                        "example": 1.2
                    },
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "طوارئ",
                            "عناية مركزة"
                        ]
                    },
                    "latitude": {
                        "type": "number",
                        "format": "double",
                        "nullable": true,
                        "example": 30.9706
                    },
                    "longitude": {
                        "type": "number",
                        "format": "double",
                        "nullable": true,
                        "example": 31.1656
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "location_id": {
                        "type": "string",
                        "nullable": true,
                        "example": "loc_57",
                        "description": "المنطقة الجغرافية المرتبطة بالمكان. `null` للأماكن المسجلة قبل إضافة الشجرة الجغرافية."
                    },
                    "location": {
                        "type": "string",
                        "nullable": true,
                        "example": "الأنشا"
                    },
                    "location_type": {
                        "type": "string",
                        "nullable": true,
                        "example": "village"
                    },
                    "location_branch": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                            "urban",
                            "rural"
                        ],
                        "example": "rural"
                    },
                    "categories": {
                        "type": "array",
                        "description": "كل التصنيفات التي ينتمي لها المكان، الأساسي أولاً. المكان الواحد قد يكون مطعماً وكافيهاً معاً بدلاً من تكراره مرتين.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "string",
                                    "example": "cat_7"
                                },
                                "name": {
                                    "type": "string",
                                    "example": "مطاعم وأكل"
                                },
                                "slug": {
                                    "type": "string",
                                    "example": "food-restaurants"
                                },
                                "icon_key": {
                                    "type": "string",
                                    "nullable": true,
                                    "example": "restaurant"
                                },
                                "is_primary": {
                                    "type": "boolean",
                                    "example": true
                                }
                            }
                        }
                    }
                }
            },
            "PlaceDetails": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Place"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "note": {
                                "type": "string",
                                "nullable": true,
                                "example": "الاستقبال والطوارئ مجاناً على مدار 24 ساعة."
                            },
                            "phone_2": {
                                "type": "string",
                                "nullable": true
                            },
                            "email": {
                                "type": "string",
                                "nullable": true
                            },
                            "photos": {
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            },
                            "business_hours": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/BusinessHour"
                                }
                            },
                            "reviews": {
                                "type": "array",
                                "description": "أحدث 10 تقييمات معتمدة",
                                "items": {
                                    "$ref": "#/components/schemas/Review"
                                }
                            },
                            "offers": {
                                "type": "array",
                                "description": "العروض السارية لهذا المكان",
                                "items": {
                                    "$ref": "#/components/schemas/Offer"
                                }
                            },
                            "products": {
                                "type": "array",
                                "description": "عناصر المنيو أو الخدمات الخاصة بالمكان — وليست إعلانات السوق",
                                "items": {
                                    "$ref": "#/components/schemas/PlaceProduct"
                                }
                            },
                            "modules": {
                                "type": "array",
                                "description": "الأقسام التي تعرضها صفحة هذا المكان بالترتيب — يرثها من نوع النشاط ما لم يكن له إعداد خاص.",
                                "items": {
                                    "type": "string",
                                    "enum": [
                                        "gallery",
                                        "menu",
                                        "services",
                                        "products",
                                        "offers",
                                        "hours"
                                    ]
                                },
                                "example": [
                                    "gallery",
                                    "menu",
                                    "offers",
                                    "hours"
                                ]
                            },
                            "content_sections": {
                                "type": "array",
                                "description": "نفس الأقسام وقد امتلأت بمحتواها. ارسم الشاشة من هذه القائمة.",
                                "items": {
                                    "$ref": "#/components/schemas/PlaceContentSection"
                                }
                            }
                        }
                    }
                ]
            },
            "BusinessHour": {
                "type": "object",
                "properties": {
                    "day": {
                        "type": "string",
                        "enum": [
                            "saturday",
                            "sunday",
                            "monday",
                            "tuesday",
                            "wednesday",
                            "thursday",
                            "friday"
                        ],
                        "example": "sunday"
                    },
                    "open_time": {
                        "type": "string",
                        "nullable": true,
                        "example": "09:00"
                    },
                    "close_time": {
                        "type": "string",
                        "nullable": true,
                        "example": "21:00"
                    },
                    "is_closed": {
                        "type": "boolean",
                        "example": false
                    }
                }
            },
            "PlaceProduct": {
                "type": "object",
                "description": "عنصر منيو أو خدمة داخل المكان",
                "properties": {
                    "id": {
                        "type": "integer",
                        "example": 1
                    },
                    "kind": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                            "menu",
                            "service",
                            "product"
                        ],
                        "description": "القسم الذي يظهر تحته العنصر. `null` لعناصر أُضيفت قبل وجود الأقسام.",
                        "example": "menu"
                    },
                    "name": {
                        "type": "string",
                        "example": "شاورما لحمة سوري"
                    },
                    "category_name": {
                        "type": "string",
                        "nullable": true,
                        "example": "وجبات رئيسية"
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "price": {
                        "type": "number",
                        "format": "float",
                        "nullable": true,
                        "example": 95
                    },
                    "image": {
                        "type": "string",
                        "nullable": true,
                        "description": "أول صورة — الحقل القديم، ما زال يعمل كما هو."
                    },
                    "is_available": {
                        "type": "boolean",
                        "example": true
                    },
                    "images": {
                        "type": "array",
                        "description": "كل صور العنصر بالترتيب. العنصر الواحد قد يحمل أكثر من صورة.",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "Review": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "rev_4"
                    },
                    "user_name": {
                        "type": "string",
                        "nullable": true,
                        "example": "أحمد الشناوي"
                    },
                    "user_avatar": {
                        "type": "string",
                        "nullable": true
                    },
                    "rating": {
                        "type": "number",
                        "format": "float",
                        "example": 4.5
                    },
                    "comment": {
                        "type": "string",
                        "nullable": true,
                        "example": "خدمة ممتازة وأسعار مناسبة جداً."
                    },
                    "created_at": {
                        "type": "string",
                        "description": "نص جاهز للعرض مباشرة",
                        "example": "منذ يومين"
                    },
                    "created_at_iso": {
                        "type": "string",
                        "format": "date-time",
                        "example": "2026-08-21T17:54:32+03:00"
                    }
                }
            },
            "Product": {
                "type": "object",
                "description": "إعلان في سوق المحلة",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "prd_1"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "published",
                            "rejected",
                            "sold",
                            "expired"
                        ],
                        "description": "حالة الإعلان. الإعلان الجديد يبدأ `pending` إلا لو `MARKET_AUTO_PUBLISH=true`.",
                        "example": "pending"
                    },
                    "status_label": {
                        "type": "string",
                        "description": "نفس الحالة بالعربي، جاهزة للعرض في التطبيق.",
                        "example": "قيد المراجعة"
                    },
                    "rejection_reason": {
                        "type": "string",
                        "nullable": true,
                        "description": "سبب الرفض — يظهر لصاحب الإعلان في `/market/my-products` ليعرف ماذا يصلح.",
                        "example": null
                    },
                    "title": {
                        "type": "string",
                        "example": "آيفون 14 برو ماكس 256 جيجا بطارية 92%"
                    },
                    "price": {
                        "type": "number",
                        "format": "float",
                        "example": 34500
                    },
                    "old_price": {
                        "type": "number",
                        "format": "float",
                        "nullable": true,
                        "example": 37000
                    },
                    "category": {
                        "type": "string",
                        "nullable": true,
                        "example": "موبايلات وإلكترونيات"
                    },
                    "condition": {
                        "type": "string",
                        "nullable": true,
                        "example": "مستعمل بحالة ممتازة"
                    },
                    "location": {
                        "type": "string",
                        "nullable": true,
                        "example": "المحلة الكبرى - شارع البحر"
                    },
                    "is_new": {
                        "type": "boolean",
                        "example": false
                    },
                    "is_featured": {
                        "type": "boolean",
                        "example": true
                    },
                    "is_negotiable": {
                        "type": "boolean",
                        "example": true
                    },
                    "is_verified_seller": {
                        "type": "boolean",
                        "example": true
                    },
                    "seller_name": {
                        "type": "string",
                        "nullable": true,
                        "example": "معرض آبل ستور المحلة"
                    },
                    "seller_phone": {
                        "type": "string",
                        "nullable": true,
                        "example": "01011112222"
                    },
                    "seller_whatsapp": {
                        "type": "string",
                        "nullable": true,
                        "example": "01011112222"
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "time_ago": {
                        "type": "string",
                        "nullable": true,
                        "example": "منذ ساعتين"
                    },
                    "views": {
                        "type": "integer",
                        "example": 412
                    },
                    "images": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "Offer": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "off_1"
                    },
                    "place_id": {
                        "type": "string",
                        "nullable": true,
                        "description": "المكان المرتبط في الدليل، إن وُجد",
                        "example": "plc_8"
                    },
                    "business_name": {
                        "type": "string",
                        "example": "سلطان الشام للمأكولات السورية"
                    },
                    "title": {
                        "type": "string",
                        "example": "خصم 25% على جميع وجبات الشاورما العائلية"
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "discount_percent": {
                        "type": "integer",
                        "nullable": true,
                        "example": 25
                    },
                    "coupon_code": {
                        "type": "string",
                        "nullable": true,
                        "example": "MAHALLA25"
                    },
                    "image": {
                        "type": "string",
                        "nullable": true
                    },
                    "starts_on": {
                        "type": "string",
                        "format": "date",
                        "nullable": true,
                        "example": "2026-08-14"
                    },
                    "expires_on": {
                        "type": "string",
                        "format": "date",
                        "nullable": true,
                        "description": "`null` يعني عرض بلا تاريخ انتهاء",
                        "example": "2026-10-21"
                    },
                    "views": {
                        "type": "integer",
                        "example": 840
                    },
                    "terms": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "العرض ساري داخل الصالة والديليفري",
                            "لا يمكن دمج العرض مع كوبونات خصم أخرى"
                        ]
                    }
                }
            },
            "MapMarker": {
                "type": "object",
                "description": "أخف حمولة في الـ API — لا تحتوي إلا ما ترسمه النقطة على الخريطة",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "plc_8"
                    },
                    "name": {
                        "type": "string",
                        "example": "سلطان الشام للمأكولات السورية"
                    },
                    "category": {
                        "type": "string",
                        "nullable": true,
                        "example": "مطاعم ومأكولات"
                    },
                    "latitude": {
                        "type": "number",
                        "format": "double",
                        "example": 30.976
                    },
                    "longitude": {
                        "type": "number",
                        "format": "double",
                        "example": 31.169
                    },
                    "brand_icon_key": {
                        "type": "string",
                        "nullable": true,
                        "example": "restaurant"
                    },
                    "brand_color_hex": {
                        "type": "string",
                        "example": "#B54708"
                    },
                    "rating": {
                        "type": "number",
                        "format": "float",
                        "example": 4.6
                    },
                    "is_verified": {
                        "type": "boolean",
                        "example": true
                    },
                    "is_open_now": {
                        "type": "boolean",
                        "nullable": true,
                        "example": true
                    }
                }
            },
            "AiSearchResult": {
                "type": "object",
                "properties": {
                    "raw_speech": {
                        "type": "string",
                        "description": "النص كما أُرسل",
                        "example": "عايز صيدلية فاتحة دلوقتي قريبة من شارع البحر"
                    },
                    "clean_query": {
                        "type": "string",
                        "description": "النص بعد إزالة كلمات الحشو، للعرض كـ «بحثت عن …»",
                        "example": "صيدليات شارع البحر"
                    },
                    "extracted_category": {
                        "type": "string",
                        "nullable": true,
                        "example": "صيدليات"
                    },
                    "is_nearby": {
                        "type": "boolean",
                        "example": true
                    },
                    "is_open_now": {
                        "type": "boolean",
                        "example": true
                    },
                    "is_high_rating": {
                        "type": "boolean",
                        "example": false
                    },
                    "has_offer": {
                        "type": "boolean",
                        "example": false
                    },
                    "ai_summary": {
                        "type": "string",
                        "example": "تم العثور على مكان واحد ضمن صيدليات مفتوحة الآن وأقربها يبعد عنك 0.4 كم في المحلة الكبرى."
                    },
                    "places": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Place"
                        }
                    },
                    "products": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Product"
                        }
                    },
                    "offers": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Offer"
                        }
                    }
                }
            },
            "EmergencyCategory": {
                "type": "object",
                "properties": {
                    "category": {
                        "type": "string",
                        "example": "طوارئ ونجدة 🚨"
                    },
                    "items": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {
                                    "type": "string",
                                    "example": "شرطة النجدة"
                                },
                                "number": {
                                    "type": "string",
                                    "example": "122"
                                },
                                "is_hotline": {
                                    "type": "boolean",
                                    "description": "الأرقام القصيرة مثل 122 و123",
                                    "example": true
                                }
                            }
                        }
                    }
                }
            },
            "Article": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "art_1"
                    },
                    "slug": {
                        "type": "string"
                    },
                    "title": {
                        "type": "string",
                        "example": "دليلك لأفضل 10 مطاعم في المحلة الكبرى"
                    },
                    "excerpt": {
                        "type": "string",
                        "nullable": true
                    },
                    "cover_image": {
                        "type": "string",
                        "nullable": true
                    },
                    "category": {
                        "type": "string",
                        "nullable": true,
                        "example": "دليل المدينة"
                    },
                    "author_name": {
                        "type": "string",
                        "nullable": true,
                        "example": "فريق المحلة أون"
                    },
                    "reading_time_minutes": {
                        "type": "integer",
                        "minimum": 1,
                        "example": 3
                    },
                    "source": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string",
                                "nullable": true,
                                "example": "اليوم السابع"
                            },
                            "url": {
                                "type": "string",
                                "nullable": true,
                                "format": "uri"
                            }
                        }
                    },
                    "is_featured": {
                        "type": "boolean",
                        "example": true
                    },
                    "views": {
                        "type": "integer",
                        "example": 200
                    },
                    "published_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "time_ago": {
                        "type": "string",
                        "nullable": true,
                        "example": "منذ 3 أيام"
                    }
                }
            },
            "ArticleDetails": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Article"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "body": {
                                "type": "string",
                                "nullable": true,
                                "description": "محتوى المقال (HTML)"
                            },
                            "content_blocks": {
                                "type": "array",
                                "description": "أجزاء المقال مرتبة كما تظهر في الموبايل. الأنواع: paragraph, heading, quote, image.",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "id": {
                                            "type": "string",
                                            "example": "block_1"
                                        },
                                        "type": {
                                            "type": "string",
                                            "enum": [
                                                "paragraph",
                                                "heading",
                                                "quote",
                                                "image"
                                            ]
                                        },
                                        "text": {
                                            "type": "string",
                                            "nullable": true
                                        },
                                        "title": {
                                            "type": "string",
                                            "nullable": true
                                        },
                                        "author": {
                                            "type": "string",
                                            "nullable": true
                                        },
                                        "author_role": {
                                            "type": "string",
                                            "nullable": true
                                        },
                                        "image": {
                                            "type": "string",
                                            "nullable": true
                                        },
                                        "caption": {
                                            "type": "string",
                                            "nullable": true
                                        },
                                        "location": {
                                            "type": "string",
                                            "nullable": true
                                        }
                                    }
                                }
                            },
                            "share_url": {
                                "type": "string",
                                "description": "الرابط اللي زرار المشاركة بيبعته. مبني من الـ slug عشان يبقى مقروء في واتساب، وجاي من السيرفر لأن التطبيق مبيشوفش APP_URL أصلاً.",
                                "example": "https://elmahalla-on.gadmotions.com/articles/mahalla-story"
                            },
                            "related": {
                                "type": "array",
                                "description": "شريط «اقرأ كمان» في آخر الشاشة. نفس القسم الأول، وبيتكمّل من الأحدث لو القسم قليل — عشان الشريط ما يبقاش فاضي في آخر المقال. مبيرجّعش المقال نفسه ولا أي مسودة.",
                                "items": {
                                    "$ref": "#/components/schemas/Article"
                                }
                            }
                        }
                    }
                ]
            },
            "Notification": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "ntf_2"
                    },
                    "title": {
                        "type": "string",
                        "example": "عروض جديدة هذا الأسبوع 🏷️"
                    },
                    "body": {
                        "type": "string",
                        "nullable": true,
                        "example": "خصومات تصل إلى 25% لدى شركائنا في المحلة."
                    },
                    "type": {
                        "type": "string",
                        "example": "offer"
                    },
                    "icon_key": {
                        "type": "string",
                        "nullable": true,
                        "example": "tag"
                    },
                    "payload": {
                        "type": "object",
                        "description": "هدف التنقّل داخل التطبيق (deep link)",
                        "additionalProperties": true,
                        "example": {
                            "screen": "offers"
                        }
                    },
                    "is_broadcast": {
                        "type": "boolean",
                        "description": "إشعار عام يراه كل المستخدمين",
                        "example": true
                    },
                    "is_read": {
                        "type": "boolean",
                        "description": "محسوبة لكل مستخدم على حدة",
                        "example": false
                    },
                    "read_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "time_ago": {
                        "type": "string",
                        "nullable": true,
                        "example": "منذ ساعة"
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "campaign_id": {
                        "type": "string",
                        "nullable": true,
                        "example": "ncam_12",
                        "description": "الحملة اللي طلع منها السطر ده — ابعتها لـ `/notifications/campaigns/{id}/opened`. null للإشعارات القديمة أو اللي الإدارة كتبتها بإيدها."
                    },
                    "image_url": {
                        "type": "string",
                        "nullable": true
                    }
                }
            },
            "ListingType": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "ltype_8"
                    },
                    "slug": {
                        "type": "string",
                        "example": "restaurant"
                    },
                    "title": {
                        "type": "string",
                        "example": "مطعم"
                    },
                    "title_en": {
                        "type": "string",
                        "nullable": true,
                        "example": "Restaurant"
                    },
                    "icon": {
                        "type": "string",
                        "nullable": true
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "categories_count": {
                        "type": "integer",
                        "example": 2
                    },
                    "categories": {
                        "type": "array",
                        "description": "موجود فقط مع `?with=categories`.",
                        "items": {
                            "$ref": "#/components/schemas/Category"
                        }
                    }
                }
            },
            "Location": {
                "type": "object",
                "description": "عقدة في الشجرة الجغرافية للمدينة. الفرع `urban` يمثل المدينة (أحياء/شياخات/مناطق) و`rural` يمثل المركز (وحدات محلية/قرى/توابع).",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "loc_57"
                    },
                    "slug": {
                        "type": "string",
                        "example": "el-ansha"
                    },
                    "name": {
                        "type": "string",
                        "example": "الأنشا"
                    },
                    "name_en": {
                        "type": "string",
                        "nullable": true,
                        "example": "El-Ansha"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "city",
                            "markaz",
                            "district",
                            "section",
                            "shiyakha",
                            "area",
                            "local_unit",
                            "village",
                            "hamlet",
                            "kafr",
                            "nag",
                            "other"
                        ],
                        "example": "village"
                    },
                    "type_label": {
                        "type": "string",
                        "example": "قرية"
                    },
                    "branch": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                            "urban",
                            "rural"
                        ],
                        "example": "rural"
                    },
                    "branch_label": {
                        "type": "string",
                        "nullable": true,
                        "example": "المركز"
                    },
                    "parent_id": {
                        "type": "string",
                        "nullable": true,
                        "example": "loc_54"
                    },
                    "depth": {
                        "type": "integer",
                        "example": 2
                    },
                    "latitude": {
                        "type": "number",
                        "format": "float",
                        "nullable": true
                    },
                    "longitude": {
                        "type": "number",
                        "format": "float",
                        "nullable": true
                    },
                    "has_children": {
                        "type": "boolean",
                        "nullable": true
                    },
                    "listings_count": {
                        "type": "integer",
                        "nullable": true
                    },
                    "children": {
                        "type": "array",
                        "nullable": true,
                        "description": "موجود فقط عند طلب `tree=1`.",
                        "items": {
                            "$ref": "#/components/schemas/Location"
                        }
                    }
                }
            },
            "Banner": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "bnr_1"
                    },
                    "slug": {
                        "type": "string",
                        "example": "health-directory"
                    },
                    "title": {
                        "type": "string",
                        "example": "مستشفى المحلة العام والمراكز الطبية المتخصصة 🏥"
                    },
                    "subtitle": {
                        "type": "string",
                        "nullable": true,
                        "example": "دليل كامل لكافة العيادات والطوارئ والأطباء المناوبين بالمحلة"
                    },
                    "tag": {
                        "type": "string",
                        "nullable": true,
                        "example": "⭐ رعاية صحية"
                    },
                    "icon_key": {
                        "type": "string",
                        "nullable": true,
                        "example": "hospital"
                    },
                    "gradient": {
                        "type": "array",
                        "description": "لونان أو ثلاثة بصيغة ‎#RRGGBB‎ من الغامق للفاتح. لا تكون فارغة أبداً — البانر بلا ألوان يرجع بالألوان الافتراضية.",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "#0A2E5C",
                            "#147CB5",
                            "#38BDF8"
                        ]
                    },
                    "image_url": {
                        "type": "string",
                        "nullable": true,
                        "description": "صورة مرفوعة تحل محل خلفية الألوان. `null` تعني ارسم بطاقة gradient + icon_key."
                    },
                    "cta_label": {
                        "type": "string",
                        "nullable": true,
                        "example": "اكتشف المزيد"
                    },
                    "action": {
                        "type": "object",
                        "description": "وجهة الضغط على البانر — نفس شكل `payload` في الإشعارات. `{}` تعني بانر بلا وجهة.",
                        "additionalProperties": {
                            "type": "string"
                        },
                        "example": {
                            "screen": "places",
                            "category": "health-medical"
                        }
                    },
                    "placement": {
                        "type": "string",
                        "example": "home"
                    }
                }
            },
            "PlaceContentSection": {
                "type": "object",
                "description": "قسم واحد من أقسام صفحة المكان. الأقسام الفارغة لا تُرسل، فما يصل هو ما يُرسم فعلاً.",
                "properties": {
                    "key": {
                        "type": "string",
                        "enum": [
                            "gallery",
                            "menu",
                            "services",
                            "products",
                            "offers",
                            "hours"
                        ],
                        "example": "menu"
                    },
                    "title": {
                        "type": "string",
                        "example": "المنيو"
                    },
                    "title_en": {
                        "type": "string",
                        "example": "Menu"
                    },
                    "items_count": {
                        "type": "integer",
                        "description": "لأقسام العناصر فقط (menu / services / products).",
                        "example": 24
                    },
                    "groups": {
                        "type": "array",
                        "description": "العناصر مقسّمة على مجموعات المنيو — مقبلات، مشويات، حلويات.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "title": {
                                    "type": "string",
                                    "nullable": true,
                                    "example": "أطباق رئيسية"
                                },
                                "items": {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/components/schemas/PlaceProduct"
                                    }
                                }
                            }
                        }
                    },
                    "images": {
                        "type": "array",
                        "description": "ألبوم القسم نفسه — صفحات المنيو المصوّرة، لوحة الأسعار، الكتالوج. قسم بصور فقط وبدون عناصر قسم كامل.",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "AssistantReply": {
                "type": "object",
                "properties": {
                    "conversation_id": {
                        "type": "string",
                        "description": "ذاكرة المحادثة الموقعة. يجب إعادتها في الرسالة التالية.",
                        "example": "aconv_12.13a96fc11bc85c03b41a51ce9bdd7b2a"
                    },
                    "focus": {
                        "type": "object",
                        "nullable": true,
                        "description": "المكان أو الصنف المقصود حاليًا في أسئلة المتابعة.",
                        "properties": {
                            "id": {
                                "type": "string",
                                "example": "plc_42"
                            },
                            "type": {
                                "type": "string",
                                "enum": [
                                    "place",
                                    "item"
                                ]
                            },
                            "name": {
                                "type": "string"
                            },
                            "place_id": {
                                "type": "string"
                            },
                            "place_name": {
                                "type": "string"
                            }
                        }
                    },
                    "answer_type": {
                        "type": "string",
                        "nullable": true,
                        "description": "نوع سؤال المتابعة: experience, address, phone, hours, services, price, rating, specialty, details."
                    },
                    "tracking_id": {
                        "type": "string",
                        "nullable": true,
                        "description": "معرّف موقّع لإرسال open_listing / call / whatsapp إلى /assistant/outcome. يكون null إذا كان تسجيل الطلبات مغلقاً.",
                        "example": "asq_14.7f35c8d9e21a4f67b903d124"
                    },
                    "query": {
                        "type": "string",
                        "description": "نص الطلب كما أُرسل."
                    },
                    "understanding": {
                        "$ref": "#/components/schemas/AssistantUnderstanding"
                    },
                    "reply": {
                        "type": "string",
                        "description": "رد محادثي مصاغ من البيانات المسجلة فقط، مع fallback محلي عند تعطل OpenAI.",
                        "example": "لقيتلك 3 أصناف 👇"
                    },
                    "ai": {
                        "type": "object",
                        "nullable": true,
                        "description": "يظهر فقط عندما تمت صياغة الرد بواسطة OpenAI؛ عدم وجوده يعني أن المحرك الاحتياطي أجاب.",
                        "properties": {
                            "provider": {
                                "type": "string",
                                "example": "openai"
                            },
                            "model": {
                                "type": "string",
                                "example": "gpt-5.4-mini"
                            }
                        }
                    },
                    "result_type": {
                        "type": "string",
                        "enum": [
                            "item",
                            "place",
                            "answer",
                            "none"
                        ]
                    },
                    "relaxations": {
                        "type": "array",
                        "description": "الشروط التي تم التنازل عنها، بالترتيب. مصفوفة فارغة = تطابق تام.",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "مفيش حاجة في حدود 100 ج.م، فوسّعت لحد 125 ج.م"
                        ]
                    },
                    "cards": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/AssistantCard"
                        }
                    },
                    "quick_replies": {
                        "type": "array",
                        "description": "تعديلات بضغطة واحدة على نفس البحث.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "label": {
                                    "type": "string",
                                    "example": "مفتوح دلوقتي"
                                },
                                "payload": {
                                    "type": "object",
                                    "additionalProperties": true
                                }
                            }
                        }
                    },
                    "results_count": {
                        "type": "integer",
                        "example": 3
                    }
                }
            },
            "AssistantUnderstanding": {
                "type": "object",
                "description": "ما فهمه المحرك من الطلب — كما قاله المستخدم، قبل أي توسيع.",
                "properties": {
                    "intent": {
                        "type": "string",
                        "enum": [
                            "find_item",
                            "find_provider",
                            "find_place",
                            "follow_up",
                            "unknown"
                        ]
                    },
                    "summary": {
                        "type": "string",
                        "example": "بيتزا · فراخ · في حدود 150 ج.م"
                    },
                    "confidence": {
                        "type": "number",
                        "format": "float",
                        "minimum": 0,
                        "maximum": 1,
                        "example": 0.8
                    },
                    "engine": {
                        "type": "string",
                        "enum": [
                            "rules",
                            "llm",
                            "rules+llm"
                        ],
                        "description": "أي مسار أنتج الفهم. `rules` هو الافتراضي وما يعمل بدون نموذج لغوي."
                    },
                    "slots": {
                        "$ref": "#/components/schemas/AssistantSlots"
                    },
                    "unknown_terms": {
                        "type": "array",
                        "description": "كلمات لم يتعرّف عليها المحرك. تُسجّل في تقرير الطلب لإضافتها كمرادفات لاحقاً.",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "AssistantSlots": {
                "type": "object",
                "description": "الفلاتر المستخرجة من الجملة. كل المفاتيح موجودة دائماً وقيمتها null إن لم يذكرها الطلب.",
                "properties": {
                    "category_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "sub_category_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "location_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "city_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "item_term": {
                        "type": "string",
                        "nullable": true,
                        "example": "بيتزا"
                    },
                    "keywords": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "فراخ"
                        ]
                    },
                    "exclude_terms": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "زيتون"
                        ]
                    },
                    "budget_min": {
                        "type": "number",
                        "nullable": true
                    },
                    "budget_max": {
                        "type": "number",
                        "nullable": true,
                        "example": 150
                    },
                    "party_size": {
                        "type": "integer",
                        "nullable": true,
                        "example": 2
                    },
                    "budget_per_person": {
                        "type": "number",
                        "nullable": true,
                        "description": "الميزانية مقسّمة على عدد الأفراد — وهي ما يُفلتر به سعر الصنف الواحد."
                    },
                    "attributes": {
                        "type": "object",
                        "description": "خصائص مطلوبة، `المفتاح => [القيم]`.",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        },
                        "example": {
                            "subject": [
                                "arabic"
                            ],
                            "stage": [
                                "primary"
                            ],
                            "grade": [
                                "5"
                            ]
                        }
                    },
                    "exclude_attributes": {
                        "type": "object",
                        "description": "خصائص مستبعدة («مش حارة»).",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        },
                        "example": {
                            "spice": [
                                "hot"
                            ]
                        }
                    },
                    "near_me": {
                        "type": "boolean",
                        "description": "لا تكون true إلا إذا أُرسلت الإحداثيات فعلاً."
                    },
                    "open_now": {
                        "type": "boolean"
                    },
                    "min_rating": {
                        "type": "number",
                        "nullable": true
                    },
                    "has_offer": {
                        "type": "boolean"
                    }
                }
            },
            "AssistantCard": {
                "type": "object",
                "description": "نتيجة واحدة. `type` يحدد شكل الحقول: `menu_item` يحمل `item` مع ملخص المكان، و`place` يحمل المكان كاملاً.",
                "properties": {
                    "type": {
                        "type": "string",
                        "enum": [
                            "menu_item",
                            "place"
                        ]
                    },
                    "id": {
                        "type": "string",
                        "example": "itm_44"
                    },
                    "item": {
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/PlaceProduct"
                            }
                        ],
                        "nullable": true,
                        "description": "الصنف — لكروت `menu_item` فقط."
                    },
                    "place": {
                        "type": "object",
                        "nullable": true,
                        "additionalProperties": true,
                        "description": "المكان. كارت `place` يحمل شكل Place كاملاً؛ كارت `menu_item` يحمل ملخصاً (id, name, category, area, rating, is_open_now, logo, distance_km)."
                    },
                    "match_reasons": {
                        "type": "array",
                        "description": "سبب ظهور هذه النتيجة تحديداً، بالعربي، للعرض تحت الكارت.",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "جوه ميزانيتك",
                            "مفتوح دلوقتي",
                            "على بعد 1.2 كم"
                        ]
                    },
                    "score": {
                        "type": "number",
                        "format": "float",
                        "description": "درجة الترتيب 0..1."
                    },
                    "actions": {
                        "type": "array",
                        "description": "ما يمكن فعله بهذه النتيجة. يحدده الخادم لا التطبيق — لا يظهر «اتصل» لمكان بلا رقم. في V1: open_listing / call / whatsapp.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "type": {
                                    "type": "string",
                                    "enum": [
                                        "open_listing",
                                        "call",
                                        "whatsapp"
                                    ]
                                },
                                "label": {
                                    "type": "string"
                                },
                                "payload": {
                                    "type": "object",
                                    "additionalProperties": true
                                }
                            }
                        }
                    }
                }
            },
            "NotificationPermissions": {
                "type": "object",
                "description": "صلاحيات الإشعارات لنشاط واحد + عدّاد الشهر الحالي. الباك إند هو المصدر الوحيد للحقيقة — التطبيق بيرسم بيها الشاشة بس، والـ API بيرفض أي إرسال مخالف حتى لو التطبيق سمح بيه.",
                "properties": {
                    "can_send": {
                        "type": "boolean",
                        "example": true
                    },
                    "monthly_limit": {
                        "type": "integer",
                        "nullable": true,
                        "example": 10,
                        "description": "null = بلا حد"
                    },
                    "used": {
                        "type": "integer",
                        "example": 4
                    },
                    "remaining": {
                        "type": "integer",
                        "nullable": true,
                        "example": 6
                    },
                    "extra_credits": {
                        "type": "integer",
                        "example": 2
                    },
                    "billing_period": {
                        "type": "string",
                        "example": "2026-09"
                    },
                    "reset_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "max_audience": {
                        "type": "integer",
                        "nullable": true,
                        "example": 5000
                    },
                    "can_schedule": {
                        "type": "boolean"
                    },
                    "can_target_area": {
                        "type": "boolean"
                    },
                    "can_target_category": {
                        "type": "boolean"
                    },
                    "can_send_image": {
                        "type": "boolean"
                    },
                    "can_use_deep_links": {
                        "type": "boolean"
                    },
                    "can_view_analytics": {
                        "type": "boolean"
                    },
                    "extra_notification_price": {
                        "type": "number",
                        "nullable": true,
                        "example": 20
                    },
                    "is_suspended": {
                        "type": "boolean",
                        "description": "موقوف من الإدارة — الترقية مش هتحلّه"
                    },
                    "suspension_reason": {
                        "type": "string",
                        "nullable": true
                    },
                    "plan": {
                        "type": "object",
                        "nullable": true,
                        "properties": {
                            "id": {
                                "type": "string",
                                "example": "business-premium"
                            },
                            "name": {
                                "type": "string",
                                "example": "بريميوم"
                            },
                            "is_default": {
                                "type": "boolean"
                            }
                        }
                    },
                    "audiences": {
                        "type": "array",
                        "description": "أنواع الجمهور اللي باقة النشاط دي بتسمح بيها — ارسم الاختيارات من هنا.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "type": {
                                    "type": "string",
                                    "example": "listing_followers"
                                },
                                "label": {
                                    "type": "string",
                                    "example": "المتابعين للنشاط"
                                }
                            }
                        }
                    }
                }
            },
            "NotificationCampaign": {
                "type": "object",
                "description": "حملة إشعار واحدة كما يراها مُرسِلها. غير `Notification` اللي هي سطر في صندوق إشعارات القارئ.",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "ncam_12"
                    },
                    "title": {
                        "type": "string",
                        "example": "عرض النهاردة 🔥"
                    },
                    "body": {
                        "type": "string",
                        "nullable": true
                    },
                    "image_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "notification_type": {
                        "type": "string",
                        "example": "offer"
                    },
                    "notification_type_label": {
                        "type": "string",
                        "example": "عرض"
                    },
                    "source_type": {
                        "type": "string",
                        "enum": [
                            "admin",
                            "listing",
                            "system"
                        ]
                    },
                    "place_id": {
                        "type": "string",
                        "nullable": true,
                        "example": "plc_8"
                    },
                    "audience": {
                        "type": "object",
                        "properties": {
                            "type": {
                                "type": "string",
                                "example": "listing_followers"
                            },
                            "label": {
                                "type": "string"
                            }
                        }
                    },
                    "destination": {
                        "type": "object",
                        "nullable": true,
                        "description": "نفس شكل الوجهة المستخدم في البانرات والبوب أب.",
                        "properties": {
                            "screen": {
                                "type": "string",
                                "example": "offer"
                            },
                            "id": {
                                "type": "string",
                                "example": "off_12"
                            }
                        }
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "draft",
                            "scheduled",
                            "processing",
                            "sent",
                            "partial",
                            "failed",
                            "cancelled"
                        ]
                    },
                    "status_label": {
                        "type": "string",
                        "example": "تم الإرسال"
                    },
                    "is_cancellable": {
                        "type": "boolean",
                        "description": "مسودة أو مجدولة فقط — بعد بدء الإرسال بيبقى false"
                    },
                    "scheduled_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "sent_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "targeted": {
                        "type": "integer",
                        "example": 320,
                        "description": "بيظهر في كل الباقات — ده إيصال الإرسال"
                    },
                    "sent": {
                        "type": "integer",
                        "example": 298
                    },
                    "analytics": {
                        "type": "object",
                        "nullable": true,
                        "description": "موجود فقط لو الباقة بتشمل `can_view_analytics`.",
                        "properties": {
                            "delivered": {
                                "type": "integer"
                            },
                            "opened": {
                                "type": "integer"
                            },
                            "clicked": {
                                "type": "integer"
                            },
                            "failed": {
                                "type": "integer"
                            },
                            "skipped": {
                                "type": "integer"
                            },
                            "open_rate": {
                                "type": "number",
                                "nullable": true,
                                "example": 18.4
                            },
                            "click_rate": {
                                "type": "number",
                                "nullable": true
                            }
                        }
                    },
                    "failure_reason": {
                        "type": "string",
                        "nullable": true
                    }
                }
            },
            "NotificationPreferences": {
                "type": "object",
                "description": "مفاتيح المستخدم. الحساب اللي عمره ما فتح الشاشة بيرجع بكل حاجة مفعّلة — غياب الصف معناه «الكل شغال».",
                "properties": {
                    "marketing_enabled": {
                        "type": "boolean"
                    },
                    "offers_enabled": {
                        "type": "boolean"
                    },
                    "coupons_enabled": {
                        "type": "boolean"
                    },
                    "messages_enabled": {
                        "type": "boolean"
                    },
                    "reminders_enabled": {
                        "type": "boolean"
                    },
                    "updates_enabled": {
                        "type": "boolean"
                    },
                    "system_enabled": {
                        "type": "boolean"
                    },
                    "system_locked": {
                        "type": "boolean",
                        "example": true,
                        "description": "رسائل الحساب والأمان بتوصل دايماً — ارسم المفتاح ده معطّل"
                    },
                    "system_note": {
                        "type": "string"
                    },
                    "quiet_hours_enabled": {
                        "type": "boolean"
                    },
                    "quiet_hours_start": {
                        "type": "string",
                        "nullable": true,
                        "example": "22:00"
                    },
                    "quiet_hours_end": {
                        "type": "string",
                        "nullable": true,
                        "example": "08:00"
                    },
                    "quiet_hours_note": {
                        "type": "string"
                    }
                }
            },
            "ImageSearchResult": {
                "type": "object",
                "description": "كل حقول AiSearchResult (ما عدا raw_speech) زيادة عليها اللي اتشاف في الصورة. نفس الشكل بالظبط من `by-labels` ومن `by-image` — الـ parser واحد.",
                "properties": {
                    "image_query": {
                        "type": "string",
                        "description": "الجملة اللي اتبحث بيها فعلاً — كلام المستخدم لو كتب، وبعده أقوى كلمة من الصورة.",
                        "example": "مخبز الشيماء"
                    },
                    "seen": {
                        "type": "array",
                        "description": "باقي الكلمات المرشّحة من الصورة، الأقوى الأول. اعرضها كـ chips تحت النتايج عشان المستخدم يصحّح لو التخمين طلع غلط — ده مسار التصحيح اللي البحث بالصورة محتاجه والبحث الكتابي لأ.",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "حلويات",
                            "حلويات مخبوزات"
                        ]
                    },
                    "detected_text": {
                        "type": "string",
                        "nullable": true,
                        "description": "النص الخام اللي اتقرا من الصورة، أو null. مع `by-labels` غالباً null، لأن قراءة النص على الجهاز مش بتدعم العربي.",
                        "example": "مخبز الشيماء\n01000000000"
                    },
                    "clean_query": {
                        "type": "string",
                        "example": "مخبز عيش"
                    },
                    "extracted_category": {
                        "type": "string",
                        "nullable": true,
                        "example": "مخابز"
                    },
                    "is_nearby": {
                        "type": "boolean",
                        "example": false
                    },
                    "is_open_now": {
                        "type": "boolean",
                        "example": false
                    },
                    "is_high_rating": {
                        "type": "boolean",
                        "example": false
                    },
                    "has_offer": {
                        "type": "boolean",
                        "example": false
                    },
                    "ai_summary": {
                        "type": "string",
                        "example": "تم العثور على مكان واحد."
                    },
                    "places": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Place"
                        }
                    },
                    "products": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Product"
                        }
                    },
                    "offers": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Offer"
                        }
                    }
                }
            }
        }
    }
}
