# دليل الربط والتكامل البرمجي - بوابة متحف آدم حنين
## Hawas Tag Management System (TMS) & Dynamic QR/NFC API Integration Guide
**إصدار النظام:** v1.0.0 (SaaS Edition)  
**تاريخ التوثيق:** سبتمبر 2026  
**المنفذ الافتراضي للخدمة:** `5050`  

---

## 1. نظرة عامة والمعمارية العامة (Architecture Overview)

يقوم نظام **حواس لإدارة الرموز (Hawas TMS)** بربط المقتنيات والمنحوتات واللوحات المعروضة في **متحف آدم حنين** بالبوابة الإلكترونية للمتحف (`adamheneinmuseum.com`) عبر بطاقات **NFC** الذكية ولوحات رموز **QR** المطبوعة بجوار كل عمل فني.

### آلية العمل الذكية (Dynamic Redirection):
```
[ زائر المتحف يمسح QR أو يلمس NFC ]
                 │
                 ▼
[ خادم حواس TMS: http://tms.hawas-qr.com:5050/tms/m-00080 ]
                 │
                 ├─► 1. تسجيل إحصائيات المسح لحظياً في الخلفية (IP، الجهاز، المتصفح، التوقيت)
                 │
                 └─► 2. توجيه فوري مباشر (HTTP 302 Redirect) إلى صفحة العمل بالمتحف:
                         https://adamheneinmuseum.com/حاملة-الصفيحة-صغيرة
```

> [!IMPORTANT]
> **الميزة الجوهرية للمتحف:**  
> عند تغيير مسارات أو نطاقات موقع المتحف، أو تغيير ترتيب القاعات، **لا يلزم إعادة طباعة أي كود QR أو إعادة برمجة بطاقات NFC**. يتم تحديث الوجهة برمجياً عبر الـ API فورياً أو بنقرة واحدة عبر أداة تعديل النطاق الجماعي.

---

## 2. بيانات الاتصال والتوثيق (Credentials & Base URL)

* **رابط الخدمة الأساسي (Base URL):**
  * بيئة الإنتاج / الخادم المحلي: `http://localhost:5050` (أو النطاق السحابي `http://tms.hawas-qr.com:5050`)
* **بيانات حساب المتحف (VIP Museum Tier):**
  * **اسم المستخدم (Username):** `adamhenein`
  * **مستوى الصلاحية (Role):** `vip` (وصول كامل وغير محدود لتوليد الرموز، دعم NFC/RFID، بوابة API نشطة)
  * **معرف التصنيف للمتحف (CategoryId):** `2` (متحف آدم حنين)
* **طريقة المصادقة البرمجية (Authentication Header):**
  يتم تمرير مفتاح الـ API الخاص بالمتحف في ترويسة جميع الطلبات:
  ```http
  X-API-Key: hw_live_your_museum_api_key_here
  Content-Type: application/json
  ```
  أو استخدام رمز JWT عبر:
  ```http
  Authorization: Bearer <JWT_TOKEN>
  ```

---

## 3. نقاط النهاية البرمجية الأساسية (REST API Endpoints)

### 1. جلب قائمة الأعمال الفنية والرموز المسجلة (List Museum Tags)
جلب قائمة الرموز الخاصة بالمتحف مع الترقيم والبحث والفلترة.

* **المسار:** `GET /api/v1/tags`
* **المعاملات (Query Parameters):**
  * `page` (اختياري، افتراضي `1`): رقم الصفحة.
  * `pageSize` (اختياري، افتراضي `25` أو `50`): عدد العناصر في الصفحة.
  * `search` (اختياري): نص البحث (بالاسم، المعرف مثل `m-00080`، أو رابط العمل).
  * `categoryId` (اختياري): `2` لحصر النتائج على مقتنيات متحف آدم حنين فقط.
* **مثال الطلب:**
  ```http
  GET /api/v1/tags?page=1&pageSize=20&categoryId=2 HTTP/1.1
  Host: localhost:5050
  X-API-Key: hw_live_...
  ```
* **مثال الاستجابة الناجحة (HTTP 200 OK):**
  ```json
  {
    "success": true,
    "data": {
      "total": 5250,
      "page": 1,
      "pageSize": 20,
      "totalPages": 263,
      "tags": [
        {
          "ID": 80,
          "VirtualId": "m-00080",
          "Title": "حاملة الصفيحة صغيرة",
          "Description": "منحوتة برونزية نادرة من أعمال الفنان آدم حنين",
          "MapURL": "https://adamheneinmuseum.com/%D8%AD%D8%A7%D9%85%D9%84%D8%A9-%D8%A7%D9%84%D8%B5%D9%81%D9%8A%D8%AD%D8%A9-%D8%B5%D8%BA%D9%8A%D8%B1%D8%A9",
          "Hits": 42,
          "CategoryId": 2,
          "Published": true,
          "CreatedOnUtc": "2022-10-24T10:15:00.000Z"
        }
      ]
    }
  }
  ```

---

### 2. جلب تفاصيل عمل فني محدد (Get Single Tag Details)
* **المسار:** `GET /api/v1/tags/:virtualId`
* **مثال الطلب:** `GET /api/v1/tags/m-00080`
* **الاستجابة:**
  ```json
  {
    "success": true,
    "data": {
      "VirtualId": "m-00080",
      "Title": "حاملة الصفيحة صغيرة",
      "MapURL": "https://adamheneinmuseum.com/%D8%AD%D8%A7%D9%85%D9%84%D8%A9-%D8%A7%D9%84%D8%B5%D9%81%D9%8A%D8%AD%D8%A9-%D8%B5%D8%BA%D9%8A%D8%B1%D8%A9",
      "Hits": 42,
      "Published": true
    }
  }
  ```

---

### 3. إنشاء رمز جديد لعمل فني أو لوحة معروضة (Create Dynamic Tag)
عند إضافة عمل فني جديد على موقع المتحف، يمكن لبوابة المتحف استدعاء هذه النقطة لإنشاء رابط التوجيه فورياً وتوليد الـ QR المخصص له.

* **المسار:** `POST /api/v1/tags`
* **حمولة الطلب (Request Body):**
  ```json
  {
    "Title": "تمثال البومة - غرانيت أسود",
    "MapURL": "https://adamheneinmuseum.com/artworks/the-owl",
    "VirtualId": "m-05251",
    "Description": "قطعة فنية نحتية أصلية بحديقة المتحف",
    "CategoryId": 2
  }
  ```
* **الاستجابة الناجحة (HTTP 201 Created):**
  ```json
  {
    "success": true,
    "data": {
      "ID": 5329,
      "VirtualId": "m-05251",
      "Title": "تمثال البومة - غرانيت أسود",
      "MapURL": "https://adamheneinmuseum.com/artworks/the-owl",
      "Hits": 0
    }
  }
  ```

---

### 4. تحديث الرابط المستهدف لعمل فني فورياً (Update Destination URL)
لتعديل وجهة الرابط بعد إعادة تصميم صفحات المتحف أو نقل القطعة:

* **المسار:** `PUT /api/v1/tags/:virtualId`
* **مثال الطلب:** `PUT /api/v1/tags/m-00080`
* **حمولة الطلب (Request Body):**
  ```json
  {
    "MapURL": "https://adamheneinmuseum.com/exhibits/plate-bearer-new-page",
    "Title": "حاملة الصفيحة صغيرة (محدث)"
  }
  ```
* **الاستجابة:**
  ```json
  {
    "success": true,
    "data": {
      "VirtualId": "m-00080",
      "MapURL": "https://adamheneinmuseum.com/exhibits/plate-bearer-new-page",
      "Title": "حاملة الصفيحة صغيرة (محدث)"
    }
  }
  ```

---

### 5. استرجاع تحليلات زوار العمل الفني (Artwork Scan Analytics)
معرفة عدد الزيارات، ومعلومات الزوار وأجهزتهم للقطعة:

* **المسار:** `GET /api/v1/tags/:virtualId/analytics?days=30`
* **الاستجابة:**
  ```json
  {
    "success": true,
    "data": {
      "totalScans": 148,
      "last30DaysScans": 29,
      "recentLogs": [
        {
          "IpAddress": "197.38.12.45",
          "BrowserInfo": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)...",
          "CreatedOnUtc": "2026-09-22T14:20:11.000Z"
        }
      ]
    }
  }
  ```

---

### 6. استدعاء صورة الـ QR الفورية للطباعة أو العرض (Direct QR Image URL)
يمكن لمطور بوابة المتحف وضع الرمز مباشرة في صفحات موقع المتحف أو بطاقات الطباعة بدون حفظ الصورة محلياً عبر هذا الرابط المباشر:

* **الرابط المباشر:**
  `http://localhost:5050/api/v1/qr/:virtualId?format=png&size=400`
* **المعاملات:**
  * `format`: صيغة الصورة (`png` أو `svg`).
  * `size`: الحجم بالبيكسل (مثل `300` أو `500` أو `1000` للطباعة عالية الدقة).
* **مثال HTML جاهز للاستخدام في موقع المتحف:**
  ```html
  <img src="http://localhost:5050/api/v1/qr/m-00080?format=png&size=350" 
       alt="QR Code for Artwork m-00080" 
       style="width: 180px; height: 180px; border-radius: 8px; border: 1px solid #e2e8f0;" />
  ```

---

### 7. التعديل الجماعي لنطاقات الروابط (Bulk Domain Migration API)
إذا تغير نطاق خادم المتحف أو الـ IP أو تم الانتقال إلى دومين جديد، يمكن تعديل كافة الروابط (أكثر من 5,000 سجل) بطلب برمجى واحد مع الحفاظ التام على المسارات:

* **معاينة التأثير قبل التنفيذ (Preview):**  
  `POST /api/v1/tags/bulk-domain-preview`
  ```json
  {
    "oldDomain": "https://adamhenien.com",
    "newDomain": "https://adamheneinmuseum.com",
    "categoryId": 2
  }
  ```
* **تنفيذ التحديث الفوري (Execute):**  
  `POST /api/v1/tags/bulk-domain-replace`
  ```json
  {
    "oldDomain": "https://adamhenien.com",
    "newDomain": "https://adamheneinmuseum.com",
    "categoryId": 2
  }
  ```
* **الاستجابة:**
  ```json
  {
    "success": true,
    "data": {
      "updatedCount": 5250,
      "message": "Successfully updated 5,250 tags from \"https://adamhenien.com\" to \"https://adamheneinmuseum.com\"."
    }
  }
  ```

---

## 4. أمثلة برمجية متكاملة للمطورين (Code Integration Examples)

### أ) JavaScript / Node.js (أو المتصفح Fetch)
```javascript
const TMS_API_BASE = 'http://localhost:5050/api/v1';
const API_KEY = 'YOUR_MUSEUM_API_KEY';

// دالة لجلب تفاصيل رمز فني
async function getArtworkTag(virtualId) {
  const response = await fetch(`${TMS_API_BASE}/tags/${virtualId}`, {
    headers: {
      'X-API-Key': API_KEY,
      'Content-Type': 'application/json'
    }
  });
  return await response.json();
}

// دالة لتحديث رابط العمل عند تعديله في لوحة تحكم المتحف
async function updateArtworkUrl(virtualId, newUrl) {
  const response = await fetch(`${TMS_API_BASE}/tags/${virtualId}`, {
    method: 'PUT',
    headers: {
      'X-API-Key': API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ MapURL: newUrl })
  });
  return await response.json();
}
```

---

### ب) PHP / WordPress (ملف functions.php أو إضافة مخصصة)
```php
<?php
define('HAWAS_TMS_API_BASE', 'http://localhost:5050/api/v1');
define('HAWAS_TMS_API_KEY', 'YOUR_MUSEUM_API_KEY');

/**
 * دالة استدعاء API حواس لإرسال أو تحديث عمل فني
 */
function hawas_tms_update_tag($virtual_id, $new_map_url, $title = '') {
    $endpoint = HAWAS_TMS_API_BASE . '/tags/' . urlencode($virtual_id);
    
    $body = array('MapURL' => $new_map_url);
    if (!empty($title)) {
        $body['Title'] = $title;
    }

    $response = wp_remote_request($endpoint, array(
        'method'    => 'PUT',
        'headers'   => array(
            'X-API-Key'    => HAWAS_TMS_API_KEY,
            'Content-Type' => 'application/json'
        ),
        'body'      => json_encode($body),
        'timeout'   => 15
    ));

    if (is_wp_error($response)) {
        return false;
    }

    return json_decode(wp_remote_retrieve_body($response), true);
}

/**
 * شورت كود جاهز لعرض كود الـ QR الديناميكي للقطعة داخل مقال العمل الفني:
 * الاستخدام: [artwork_qr id="m-00080"]
 */
function hawas_artwork_qr_shortcode($atts) {
    $a = shortcode_atts(array(
        'id'   => 'm-00080',
        'size' => 250
    ), $atts);

    $qr_url = "http://localhost:5050/api/v1/qr/" . esc_attr($a['id']) . "?format=png&size=" . intval($a['size']);
    return '<div class="artwork-qr-box"><img src="' . esc_url($qr_url) . '" alt="NFC/QR Code" /></div>';
}
add_shortcode('artwork_qr', 'hawas_artwork_qr_shortcode');
?>
```

---

### ج) Python (Requests)
```python
import requests

TMS_URL = "http://localhost:5050/api/v1"
HEADERS = {
    "X-API-Key": "YOUR_MUSEUM_API_KEY",
    "Content-Type": "application/json"
}

# جلب أول 50 قطعة من مقتنيات المتحف
def fetch_museum_artworks():
    params = {"page": 1, "pageSize": 50, "categoryId": 2}
    r = requests.get(f"{TMS_URL}/tags", headers=HEADERS, params=params)
    if r.status_code == 200:
        data = r.json()
        print(f"Total Museum Tags: {data['data']['total']}")
        return data['data']['tags']
    return []

# تحديث رابط قطعة
def sync_artwork_destination(virtual_id, destination_url):
    payload = {"MapURL": destination_url}
    r = requests.put(f"{TMS_URL}/tags/{virtual_id}", headers=HEADERS, json=payload)
    return r.json()
```

---

## 5. ملاحظات الدعم الفني والأمان (Security & Support)

1. **حماية المفاتيح:** حافظ على سرية مفتاح الـ API (`X-API-Key`) واجعله دائماً في متغيرات البيئة (`.env`) أو داخل كود الخادم (Backend) ولا تشاركه في الأكواد العامة للمتصفح.
2. **النسخ الاحتياطي ومتابعة السجلات:** كافة طلبات المسح يتم تسجيلها فورياً ومتاحة للتحليل والفرز.
3. **الدعم الفني:** في حال وجود أي استفسار حول تكامل واجهات الـ API، يُرجى مراجعة لوحة تحكم النظام على الرابط: `http://localhost:5050/docs`.
