إنتقل إلى المحتوى الرئيسي

ترحيل المستخدمين

تنقل Locate مستخدميها ونقاطهم من نظام Shukah القديم إلى خدماتها الخاصة. توثّق هذه الوحدة، لفريق تطبيق الجوال، ما الذي حلّ محل كل واجهة Shukah يستدعيها التطبيق في مجالي المستخدمين والنقاط، حقلًا بحقل، وما الذي ما زال ناقصًا.

الخلفية​

ملاحظات مؤرَّخة عن كيفية وصول الترحيل إلى ما هو عليه. قُرئت الحقائق المتعلقة بالخدمات في 2026-10-01 وأُعيد فحصها في parity audit بتاريخ 2026-10-02؛ أما قائمة ما يستدعيه التطبيق فمن نسخة التطبيق اللحظية (snapshot) بتاريخ 2026-02-26.

  • من 2026-06-25 إلى 2026-08-04، بناء المصادقة. نسخ جماعي للمستخدمين والعناوين والـ tokens من Shukah إلى خدمة المصادقة (auth service)، ثم routes للعميل على نمط Shukah تحت /api/v1/clients/* (نُقلت من /maeda/api/* في 2026-07-10)، ثم مزامنة حية (live sync) في الاتجاهين.
  • 2026-07-06، الخطة. نقل جميع المستخدمين ونقاطهم من Shukah إلى منصة Locate (Merchant)، مع تشغيل النظامين بالتوازي ليكون الانتقال تدريجيًا وقابلًا للتراجع عنه. قدّرت الخطة المدة بين 3 و4 أسابيع.
  • من 2026-07-15 إلى 2026-09-22، بناء النقاط. نسخ السجل (ledger) والمزامنة الحية (2026-07-15)، ثم واجهات القراءة (2026-07-16)، ثم مسار كتابة طلبات النقاط على شرائح (من 2026-09-17 إلى 2026-09-22).
  • 2026-10-01، ما يستدعيه التطبيق. تستدعي النسخة اللحظية للتطبيق واجهات Shukah المدرجة في تقدّم الترحيل. لأغلبها route في Locate، ولبعضها لا، ومنها حذف الحساب (GET /maeda/client/delete) الذي يبقى على Shukah. يرجى تأكيد القائمة على التطبيق الحالي.
  • 2026-10-01، نافذة التحديث المنبثقة. يعرض التطبيق نافذة «حدّث التطبيق» اعتمادًا على أربعة headers في الاستجابة (new_version وold_version وhas_new_version وis_required_update). لا تُرسلها أي خدمة في Locate، فتتوقف النافذة عن العمل بعد التحويل، إن كانت Shukah ترسلها اليوم (غير موثّق بعد). راجع التحقق من الـ token.
  • 2026-10-01، الـ flags الاثنان الخاصان بطلبات النقاط مفعّلان على dev. دفع طلب النقاط بالنقاط وبالبطاقة يُفعَّل كلٌّ منهما بـ flag على الخادم. أجاب كلاهما بأنه مفعّل على dev؛ أما production فغير مؤكَّد، والـ flag المعطَّل يُجيب بـ 403. راجع طلبات النقاط.
  • 2026-10-01، الـ tokens. لا يستدعي التطبيق exchange-token أبدًا. المستخدم الذي يحمل token من Shukah ويستدعي verify-token في Locate يحصل على 401، فيحذف التطبيق الـ token المخزَّن ويُسجِّل خروج المستخدم. راجع الـ Tokens.
  • 2026-10-01، dev فقط هو الموثَّق. الـ hosts والعينات الملتقطة (captures) والفحوص كلها لـ dev. أما هل كل route في Locate منشور في production فسؤال منفصل؛ وأغلب الصفحات تنص على ذلك.
  • 2026-10-02، يجري نقل Shukah إلى Laravel. تجيب Shukah على dev بأجسام أخطاء من Laravel (قيم type مثل Illuminate\… وSymfony\…). ويتتبع عمود "Implemented in Laravel" في جدول حركة الإنتاج (production traffic sheet) الخاص بالفريق ذلك النقل، على الـ URLs نفسها. ولا يتتبع الانتقال إلى Locate.
  • 2026-10-02، الـ parity audit. أُرسل المُدخل نفسه إلى Shukah وإلى Locate على dev لكل route يمكن استدعاؤه بأمان. أهم النتائج: لا يوجد token واحد يعمل على الخدمتين (routes العميل في خدمة المصادقة، /api/v1/clients/*، لا تقبل إلا JWT من Locate، وroutes النقاط في order-v2 لا تقبل إلا token من Shukah، راجع الـ Tokens)؛ ونسخ العناوين بين Locate وShukah معطوب في الاتجاهين (راجع دفتر العناوين)؛ وإنشاء طلب النقاط في Locate يجيب دون معرّف الطلب الذي يحتفظ به التطبيق (أكّده استدعاء حي في اليوم نفسه)، فلا تستطيع استدعاءات الدفع إيجاد الطلب (راجع طلبات النقاط). ووجد استدعاء متابعة في اليوم نفسه أن النقاط المصروفة على جانب لا تُخصم من الآخر (خلال ثواني التشغيل؛ ولم يُفحص هل يصل لاحقًا)، لذا يجب أن يقرأ التطبيق الرصيد من الجانب الذي يُنشئ فيه الطلبات. الأرصدة على dev: في 2026-10-01 كان للعميل نفسه "514405.6788" نقطة في Locate و "128712.41" في Shukah؛ وفي 2026-10-02 كان لدى Shukah "514853.64": فقد تغيرت بيانات Shukah على dev بينهما. وكانت Locate حينها أقل بـ 447.96 نقطة، وهذا يلائم تأخر تغذية Locate من Shukah بنحو يومين (استنتاج؛ راجع محفظة النقاط). وتحمل الصفحات الآن هذه النتائج، كلٌّ بتاريخه.

من يستدعي ماذا​

Mobile app ──► Auth service ◄──────────► Shukah (legacy, /maeda/...)
│ login, token, profile, ▲ still serves delete-account,
│ address book │ restaurant orders, payments
│ │
└──────► order-v2 (/api/v2/client) ─────┤ order-v2 also calls Shukah
│ passes the point routes │ for some point calls
▼ │
Point service ◄────────────────┘ ledger sync (designed both ways; see Point orders)
(not exposed to the app)

وتستدعي الخدمات بعضها بعضًا أيضًا: يسأل order-v2 وخدمة النقاط خدمة المصادقة GET /api/v1/users عن هوية المستدعي، فلا يرسل التطبيق header لذلك. وتفاصيل عمليات المزامنة في الصفحات تحت «التفاصيل (للـ backend)».

المجالما يستدعيه التطبيقالخدمة التي تخدمهShukah سابقًا
تسجيل الدخول والتسجيلreset-otp، verify-otpAuth serviceGET /maeda/api/reset-otp، GET /maeda/api/verify-otp
الجلسة والملف الشخصيverify-token، client lookup، update profile، push setting، add deviceAuth service/maeda/api/verify-token، /maeda/client، PUT /maeda/client/{id}، /maeda/client/add-device-id
دفتر العناوينlist، get، create، update، deleteAuth service/maeda/address-book و/maeda/address-book/{id}
استبدال الـ tokenexchange-token (لا يستدعيه التطبيق بعد)Auth serviceلا شيء: endpoint موجود في Locate فقط
النقاطالرصيد، السجل، الأسئلة الشائعة، العروض، المناسباتorder-v2، الذي يمرّرها إلى خدمة النقاط/maeda/client/points، /maeda/client/point-history، /maeda/points-faq، /maeda/point-offer، /maeda/point-occasion
طلبات النقاطإنشاء، قراءة، وصف، دفع بالبطاقة أو بالجلسةorder-v2 وخدمة النقاط/maeda/point-order وroutes checkout-payment
معدلات الكسب، كود بطاقة الهديةمعدلات النقاط، كود بطاقة الهديةorder-v2 نفسه/maeda/point-rate، /maeda/giftcard-code/use
حذف الحسابلم يُستبدليبقى على ShukahGET /maeda/client/delete

تضم صفحة تقدّم الترحيل القائمة الكاملة بحالة كل route، وتقابل صفحة Shukah مقابل Locate كل واجهة من Shukah ببديلها.

عناوين URL الأساسية​

يبني التطبيق عنوان URL من عنوان أساسي (base URL) ثم / ثم الـ endpoint. وتكتب صفحات Locate أمثلة curl باستخدام $AUTH_BASE_URL و$ORDER_BASE_URL و$SHUKAH_BASE_URL، وهي الـ host فقط. أما البادئة (prefix) فتوضع في المسار: /api/v1 على host المصادقة، و/api/v2/client على host الـ order-v2، و/maeda على Shukah.

Dev​

الخدمةHostالبادئة
Auth servicehttps://dev.authentication.locate.sa/api/v1
order-v2https://dev.v2.api.order.locate.sa/api/v2/client
Point servicehttps://dev-point-api.locate.sa (لا يستدعيه التطبيق)/api/client
Shukahhttps://dev-api.shukah.com/maeda

UAT​

الخدمةHostالبادئة
Auth serviceغير موثّق بعد — اسأل فريق الـ backendغير موثّق بعد — اسأل فريق الـ backend
order-v2https://dev.v2.api.order.locate.sa (مماثل لـ dev في إعدادات UAT بالتطبيق)/api/v2/client
Point serviceغير موثّق بعد — اسأل فريق الـ backendغير موثّق بعد — اسأل فريق الـ backend
Shukahhttps://dev-api.shukah.com (مماثل لـ dev في إعدادات UAT بالتطبيق)/maeda

Production​

الخدمةHostالبادئة
Auth serviceغير موثّق بعد — اسأل فريق الـ backendغير موثّق بعد — اسأل فريق الـ backend
order-v2https://v2.api.order.locate.sa/api/v2/client
Point serviceغير موثّق بعد — اسأل فريق الـ backendغير موثّق بعد — اسأل فريق الـ backend
Shukahhttps://api.shukah.com/maeda

ليس للتطبيق اليوم base URL لخدمة المصادقة في أي من إعدادات بيئاته، لذا يحتاج إلى واحد. الـ hosts أعلاه مصدرها إعدادات التطبيق نفسه ووثائق الخدمات؛ أما hosts خدمة المصادقة في UAT وproduction فموجودة في إعدادات النشر (deployment) التي لم يطّلع عليها البحث.

الـ Tokens​

  • Token من Shukah. سلسلة معتمة (opaque). تُصدرها Shukah عند تسجيل الدخول.
  • Token من Locate. هو JWT تصدره خدمة المصادقة. لا تاريخ انتهاء له ولا شيء يُبطله.

يوضع كلاهما في Authorization: Bearer <token>. وهذه الصفحات وما تقبله:

الصفحاتالـ token
تسجيل الدخول برمز OTP، استبدال الـ token، واستدعاء add-device-id في الملف الشخصي والإعداداتلا حاجة إلى token.
التحقق من الـ token، البحث عن عميل، دفتر العناوين، وتحديث الملف الشخصي وتحديث الإعداد في الملف الشخصي والإعداداتJWT من Locate فقط. وtoken من Shukah يحصل على 401.
صفحات النقاط (محفظة النقاط، سجل النقاط، عروض النقاط، طلبات النقاط، الأسئلة الشائعة عن النقاط)token من Shukah فقط، على dev اليوم. أما JWT من Locate فيحصل على 401 Invalid or expired token (التُقط على dev، 2026-10-02؛ وفي 2026-10-01 كان لا يزال يحصل على 200). وroute معدل الكسب (earn-rate) عام. وتنص الصفحة على الحالات التي لا يحتاج فيها route إلى token.
تفاصيل المستخدممع x-auth-from: SHUKAH يمرّر dev الـ token إلى Shukah، فيعمل token من Shukah ويُتوقَّع أن يحصل JWT من Locate على 401 (استنتاج، 2026-10-02: رفضت routes النقاط التي تستدعيه الـ JWT؛ ولم يُستدعَ هذا الـ route مع x-auth-from في ذلك اليوم). وroutes النقاط تعتمد على هذا الاستدعاء، ولهذا يفشل JWT من Locate هناك.

فيحتاج التطبيق اليوم إلى الـ token كليهما: JWT من Locate لخدمة المصادقة وtoken من Shukah لـ order-v2. وتوضح Shukah مقابل Locate السبب، وأهمية ذلك عند تحوّل التطبيق.

الحصول على token تجريبي​

يحتاج قسم «جرّبه» في صفحات المصادقة إلى JWT من Locate في $TOKEN، إلا تفاصيل المستخدم التي تحتاج إلى token من Shukah. ويحتاج قسم «جرّبه» في صفحات نقاط order-v2 إلى token من Shukah في $SHUKAH_TOKEN اليوم، لأن JWT من Locate يحصل على 401 هناك (dev، 2026-10-02). استخدم dev فقط. وهناك طريقتان للحصول على JWT من Locate (أ وب أدناه)، وطريقة واحدة للحصول على token من Shukah منه (ج).

أ. تسجيل الدخول برمز OTP​

استدعاءان: reset-otp يطلب الرمز، وverify-otp يستبدل الرمز بـ token.

export AUTH_BASE_URL=https://dev.authentication.locate.sa
export PHONE='<test-mode-phone>' # placeholder: replace it with a test-mode number
curl -s -G "$AUTH_BASE_URL/api/v1/clients/reset-otp" --data-urlencode "contact_phone=$PHONE"
curl -s -G "$AUTH_BASE_URL/api/v1/clients/verify-otp" --data-urlencode "contact_phone=$PHONE" --data-urlencode "code=2022"

تحتوي الاستجابة الثانية على الـ token في access_token. احتفظ به في $TOKEN.

warning

reset-otp يرسل رسالة SMS حقيقية ما لم يكن الحساب في وضع الاختبار (account_mode: TEST). يحصل حساب وضع الاختبار على الرمز الثابت 2022 دون رسالة SMS. وليس للخدمة API لجعل الحساب في وضع الاختبار: يضبطه فريق الـ backend في قاعدة البيانات. اطلب من الـ backend رقمًا في وضع الاختبار؛ أما هل يوجد واحد على dev: غير موثّق بعد.

الرقم المضمَّن في الشيفرة +966500000000 يقبل 2022 أيضًا، لكن الخدمة ما زالت تحاول إرسال SMS إليه، فلا تستخدمه. ولا تضع أبدًا رقم شخص حقيقي في اختبار.

ملاحظات: صلاحية الرمز 3 دقائق، وما دام رمز ساريًا لا يرسل reset-otp رمزًا جديدًا (ويظل يجيب {"status":true}). ويستطيع فريق الـ backend قراءة آخر OTP عبر route تصحيح (debug) إداري محميّ بمفتاح API؛ وهو للـ backend فقط، فاسأل الـ backend. راجع تسجيل الدخول برمز OTP للقواعد الكاملة.

ب. استبدال token موجود من Shukah​

إذا كان لديك بالفعل token من Shukah لعميل على dev، فاستبدله بـ JWT من Locate. ويأتي token Shukah من تسجيل الدخول الحالي في Shukah؛ أما كيفية الحصول على واحد دون التطبيق: غير موثّق بعد.

export AUTH_BASE_URL=https://dev.authentication.locate.sa
export SHUKAH_TOKEN='<shukah-token>'
curl -s -X POST "$AUTH_BASE_URL/api/v1/clients/exchange-token" -H "Content-Type: application/json" -d "{\"token\":\"$SHUKAH_TOKEN\",\"target_platform\":\"locate\"}"

يوجد الـ JWT من Locate في data.token. احتفظ به في $TOKEN.

هذا الاستدعاء يكتب: ففي كل مرة يخزّن token جديدًا للعميل ويدفعه إلى Shukah. لا ترسل استدعاءين للعميل نفسه في الثانية نفسها. راجع استبدال الـ token.

ج. الحصول على token من Shukah انطلاقًا من JWT من Locate​

استدعاء exchange-token نفسه مع JWT من Locate الخاص بك وtarget_platform مضبوطًا على shukah يُرجع الـ token الخاص بـ Shukah المخزَّن لذلك العميل: curl -s -X POST "$AUTH_BASE_URL/api/v1/clients/exchange-token" -H "Content-Type: application/json" -d "{\"token\":\"$TOKEN\",\"target_platform\":\"shukah\"}".

يوجد الـ token الخاص بـ Shukah في data.token. احتفظ به في $SHUKAH_TOKEN. ويُفحص الـ JWT أولًا. وقد تكون الإجابة {"status":200,"data":{}} عندما لا تكون للـ token المخزَّن لـ Shukah نسخة خام؛ وحينئذٍ لا تنجح هذه الطريقة لذلك العميل (راجع استبدال الـ token).

المتغيرات التي تستخدمها الصفحات​

export AUTH_BASE_URL=https://dev.authentication.locate.sa
export ORDER_BASE_URL=https://dev.v2.api.order.locate.sa
export SHUKAH_BASE_URL=https://dev-api.shukah.com
export TOKEN='<locate-jwt>'
export SHUKAH_TOKEN='<shukah-token>'

استبدل عنصرَي الـ token النائبين (placeholders) بما يخصّك. ولا تودِع token حقيقيًا في ملف، ولا تلصقه في تذكرة (ticket) أو محادثة.

كيف تقرأ هذه الصفحات​

لصفحة الـ endpoint الشكل التالي:

  1. الخلفية والميزة: ما يفعله التطبيق اليوم على Shukah، وما هي الميزة، بكلمات بسيطة.
  2. كتلة واحدة لكل endpoint، بهذا الترتيب:
    • مربع TL;DR (عنوانه "Replaces Shukah"): واجهة Shukah التي يستبدلها وحالتها؛ والتقييم (verdict) مع عدد الفروق الكاسرة (breaking) والفروق التي تستحق المراقبة؛ وسطر لكل فرق، 🔴 للكاسر و🟡 لما يستحق المراقبة؛ والخدمة التي تخدمه، وأي الـ tokens نجحت، وكيف ومتى جرى التحقق، ورابط إلى جانب Shukah. ويشرح دليل الحالات في تقدّم الترحيل التقييمات والعلامات؛
    • الطلب (Request) والاستجابة (Response): جداول بكل حقل؛
    • الأخطاء: الـ bodies الحقيقية؛
    • جرّبه: أمر curl يستخدم المتغيرات أعلاه؛
    • الفروق عن Shukah: الفروق الحقيقية فقط، ولكل منها أثره على التطبيق. وإذا لم يكن لـ route أي فرق قال Drop-in — no differences found مع التاريخ.
  3. تنبيه: ثلاثة تحذيرات من سطر واحد على الأكثر.
  4. سطر فاصل، ثم التفاصيل (للـ backend): قواعد العمل والمخاطر والمصادر (Sources) التي تسمّي المستودع والـ commit والملف لكل حقيقة.

يستخدم مربع TL;DR وجدول التقدّم هذه الحالات:

العلامةالمعنى
✅ تم الاستبداليوجد route في Locate.
❌ لم يُستبدللا يوجد route في Locate بعد.
➖ لن يُرحَّلتبقى الواجهة على Shukah عن قصد.
🚩 flagمُنفَّذ، لكن استخدامه يتوقف على مفتاح (flag على الخادم أو إعداد في التطبيق).

تضيف تقدّم الترحيل الفحص على dev: طلب واحد إلى الـ route في Locate على dev دون token، في التاريخ المبيّن. وهو يبيّن أن الـ route منشور ويستجيب، لا أنه يعمل لعميل مسجّل الدخول.

غير موثّق بعد يعني أنه لا شيفرة ولا وثيقة ولا عيّنة ملتقطة أظهرت الجواب. وليس تخمينًا ولا «لا». تعامل معه على أنه سؤال لفريق الـ backend أو فريق الجوال.

تذكر العينات مصدرها: ملتقطة على dev في تاريخ معيّن (مع استبدال البيانات الشخصية بقيم توضيحية)، أو مأخوذة من وثيقة خدمة، مع مسارها وتاريخها. وتشير أسماء ملفات الالتقاط (capture) تحت Sources إلى مجموعة التقاط dev بتاريخ 2026-10-01 غير المودَعة (uncommitted) وإلى مجموعة التقاط parity-audit بتاريخ 2026-10-02 (بأسماء مثل points--shukah)، ويحتفظ بهما كاتب الوثائق؛ وهما ليستا في هذا المستودع.

استثناء من الوحدات الأخرى. أغلب الوحدات لا تعيد ذكر أسماء الحقول أو أشكال الاستجابات، لأن OpenAPI المعروضة للخدمة هي مصدر الحقيقة. أما الخدمات هنا فلا تنشر أي OpenAPI، لذا توثّق هذه الصفحات الحقول بنفسها، من الشيفرة. ولذلك قد تتقادم جداول الحقول: افحص الـ commit المذكور تحت Sources، وعند اختلاف الصفحة عن الخدمة، فالقول للخدمة.

الوسوم​

تحمل الصفحات وسومًا (tags). يرتبط كل وسم بكل صفحة تحمله.

الوسمالمعنى
auth-serviceتخدمه خدمة المصادقة. يستدعيه التطبيق مباشرة.
order-v2يُوصَل إليه عبر client API الخاصة بـ order-v2.
point-serviceتخدمه خدمة النقاط، خلف order-v2.
authenticationتسجيل الدخول والـ tokens والجلسات.
profileالملف الشخصي للعميل وإعداداته وأجهزته.
address-bookعناوين التوصيل المحفوظة للعميل.
pointsالرصيد والسجل والعروض والمناسبات والأسئلة الشائعة.
point-ordersشراء النقاط أو إهداؤها، ودفع ثمنها.
shukah-replacementendpoint في Locate يحل محل واجهة Shukah.
new-endpointendpoint في Locate لا يقابله شيء في Shukah.
overviewصفحات على مستوى الوحدة: الخلفية والتقدّم والمقارنة.
mobileمكتوب لفريق تطبيق الجوال.
backendتستدعيه خدمات الـ backend، أو مكتوب لمهندسي الـ backend.
clientيستدعيه تطبيق العميل باستخدام الـ token الخاص بالعميل نفسه.
adminيُستدعى من أداة إدارية، وليس من تطبيق العميل. ولا توجد صفحة تحمل هذا الوسم بعد.
server-to-serverتستدعيه خدمة backend أخرى، وليس تطبيقًا.

الحالة ليست وسمًا، بل توجد في تقدّم الترحيل.

الصفحات​

ابدأ من هنا إذا كنت تحوّل التطبيق: قائمة التحويل.

Auth service​

النقاط​