إبقاء سياسة الخصوصية متوافقة مع البناء (build) الخاص بك
تُكتب سياسة الخصوصية مرة واحدة وتتقادم يوم يضيف طلب دمج SDK جديدة. كيف تلاحظ ذلك في طلب الدمج نفسه، بفحص مجاني لا يقرأ إلا ملفات البناء.
سجّل الـ SDK وأنواع البيانات والأذونات التي كُتبت صفحاتك على أساسها، ثم قارن ملفات البناء في كل طلب دمج (pull request) بذلك السجل. عندما تظهر اعتمادية أو إذن ليس في السجل، يُظهره طلب الدمج قبل أن يظهر في الإصدار، بينما لا يزال تحديث سياسة الخصوصية ونماذج المتجر سهلًا.
أنجز هذا في دقائق بدلًا من ذلك
تستضيف AppFoyer الصفحات التي يتناولها هذا الدليل — سياسة الخصوصية والشروط والدعم وحذف الحساب وapp-ads.txt — على نطاق فرعي خاص بها، دون نطاق أو خادم خاص بك. تطبيق واحد مجاني، ولا شيء يشترطه المتجر يكون خلف جدار دفع أبدًا.
تمت المراجعة في 30 سبتمبر 2026. تتغير سياسات المتاجر، أحيانًا دون إشعار. كل ما يلي يربط بالتوثيق الرسمي، وتلك الصفحة — لا هذه — هي المرجع. إذا تعارضتا، فالمتجر هو المحق. هذا الدليل مترجم من الإنجليزية؛ والاقتباسات من توثيق المتاجر محفوظة بالإنجليزية الأصلية.
كتابة سياسة الخصوصية مهمة تُنجز مرة واحدة. أما إبقاؤها صحيحة فليس كذلك: فالسياسة تصف البناء الذي كان لديك حين كتبتها، والبناء يظل يتغيّر. يضيف طلب دمج أداة للإبلاغ عن الأعطال، أو مكتبة اشتراكات، أو إذن موقع، ويُطلق التطبيق، بينما لا تزال السياسة ونموذج Data safety وتفاصيل App Privacy تصف التطبيق القديم.
يعدّ كلا المتجرين ذلك مشكلتك أنت، لا مشكلتهما. يقول Google Play إن إجاباتك في Data safety يجب أن تظل دقيقة وكاملة في جميع الأوقات، وإن البيانات التي تجمعها المكتبات والـ SDK التابعة لأطراف ثالثة في تطبيقك عليك أنت الإعلان عنها. وتقول Apple الشيء نفسه عن تفاصيل App Privacy، وتضيف أنك تستطيع تغيير الإجابات في App Store Connect في أي وقت دون إرسال تحديث.
من أين يأتي الانحراف فعلًا
لا يأتي تقريبًا أبدًا من قرار «جمع مزيد من البيانات». بل يأتي من العمل الهندسي العادي:
- اعتمادية جديدة. إبلاغ عن الأعطال، أو تحليلات، أو SDK لجدار الدفع، أو مكتبة خرائط.
- إذن جديد. الموقع لميزة واحدة، أو الكاميرا لماسح ضوئي، أو التتبّع للإعلانات.
- نكهة (flavor) أو هدف (target). بناء مجاني يكتسب SDK إعلانات ليست في البناء المدفوع.
- إزالة. وهذا انحراف أيضًا: فالسياسة الآن تعلن أكثر من اللازم، وهو الخطأ الأكثر أمانًا لكنه يظل خطأ.
كل واحد من هذه ينتهي في ملف بناء: build.gradle، وAndroidManifest.xml، وPodfile، وPackage.swift،
وInfo.plist، وpubspec.yaml، وpackage.json. وهذا ما يجعله قابلًا للفحص.
المنهج: سجلّ، وفحص في كل طلب دمج
- عندما تُكتب صفحاتك، سجّل ما كُتبت على أساسه: الـ SDK وأنواع البيانات والأذونات الموجودة في البناء في تلك اللحظة.
- في كل طلب دمج، اقرأ ملفات البناء مجددًا وقارن.
- عندما يختلف شيء، قل ما هو، وأين (الملف والسطر)، وأي صفحة أو نموذج قد يتأثر.
خاصيتان مهمتان. يجب أن يقرأ الفحص ملفات البناء فقط، لا الشيفرة المصدرية أبدًا ولا الأسرار أبدًا، حتى يكون آمنًا تشغيله على أي مستودع. ويجب أن يقول «قد يكون قديمًا»، لا «مخالفة»: فوجود مكتبة في ملف بناء ليس دليلًا على أن التطبيق يستخدمها، ووحدك تعرف ما إذا كانت تغيّر ما يجمعه تطبيقك.
إعداده مع AppFoyer
الفحص مجاني في كل الخطط. يقرأ ملفات البناء فقط، ولا يحتاج إلى مفتاح أو سرّ، ولا يرسل شيئًا إلى أي مكان، ولا يغيّر أي صفحة أبدًا.
مع إضافة Claude Code
- قل “make this app store-ready”. إلى جانب صياغة مسودات الصفحات، تكتب الإضافة
appfoyer.jsonفي جذر مستودعك: سجلّ ما كُتبت الصفحات على أساسه. - قل “add the AppFoyer drift check”. تعرض عليك سير عمل GitHub وتكتب
.github/workflows/appfoyer.ymlعندما توافق. - أودِع (commit) الملفين. الإضافة لا تودِع ولا تدفع (push) نيابةً عنك أبدًا.
من دون الإضافة
أضف سير العمل بنفسك:
name: AppFoyer drift check
on: pull_request
permissions:
contents: read
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: appfoyer/check-action@v1
افتح طلب دمج. ما دام لا يوجد appfoyer.json في المستودع بعد، يعرض ملخّص المهمة (job summary) الملف الذي
سيكتبه من البناء الخاص بك. قارنه بصفحاتك المنشورة وأودِعه.
أو أنشئه محليًا، بالماسح نفسه المنشور على npm:
npx @appfoyer/check init
على نظام CI آخر
تعمل حزمة npm في أي مكان يعمل فيه Node 20 أو أحدث. في GitLab، مثلًا:
appfoyer-drift-check:
image: node:22
script:
- npx -y @appfoyer/check --fail-on-drift
يعطي --format markdown التقرير نفسه الذي يعرضه ملخّص مهمة GitHub؛ و--format json مخصّص للسكربتات.
كيف تبدو النتيجة
طلب دمج يضيف RevenueCat إلى تطبيق كُتبت صفحاته من دونها:
"Trail Notes": 2 changes
+ In-app purchases / subscriptions (data collected) app/build.gradle.kts:28
→ Privacy policy may not declare "In-app purchases / subscriptions"
→ Google Play Data safety and Apple App Privacy answers may be outdated
→ Terms may not cover purchases and subscriptions
+ RevenueCat (SDK) app/build.gradle.kts:28
→ Store forms: RevenueCat is not in the app's SDK list
→ Privacy policy may not name this SDK
افتراضيًا، تُبلغ المهمة وتنجح. أضف fail-on-drift: "true" تحت with: لتجعلها تفشل إلى أن يُحدَّث السجل.
عندما يُبلغ عن تغيير
- حدّث ما يؤثر فيه التغيير. قل “make this app store-ready” مجددًا على الفرع نفسه: تقرأ الإضافة
البناء مجددًا، وتحدّث حقائق التطبيق، وتعيد صياغة الصفحات التي يمسّها التغيير، وتعيد كتابة
appfoyer.json. أو عدّل الصفحات وتبويب Store forms في لوحة التحكم بنفسك. - حدّث السجل. الإضافة فعلت ذلك بالفعل. بعد تعديل في لوحة التحكم، شغّل
npx @appfoyer/check update، أو انسخ الملف المحدّث من ملخّص المهمة، حيث يوجد تحت النتائج. - أودِعه في طلب الدمج نفسه. لن يُظهر التشغيل التالي أي تغييرات، وسيُظهر السجل التاريخي وصول الاعتمادية وتغيير الإفصاح معًا.
- حدّث نماذج المتجر في وحدات التحكم. لا يستطيع الفحص ولا AppFoyer الوصول إلى Play Console أو App Store Connect. ومسودات الإجابات موجودة في تبويب Store forms في لوحة التحكم.
- انشر المسودات المحدّثة من شاشة المراجعة.
عدة تطبيقات في مستودع واحد
يحتوي appfoyer.json على إدخال واحد لكل صفحة تطبيق في المتجر. ونكهة المنتج (product flavor) التي لها معرّف
تطبيق خاص بها تحصل على إدخال خاص بها، فتُقارَن SDK الإعلانات المستخدمة في النكهة المجانية فقط بصفحات النكهة
المجانية لا بصفحات النكهة المدفوعة. تكتب الإضافة إدخالًا واحدًا لكل نكهة جعلتها جاهزة للمتجر. ويدويًا، يأخذ
الإدخال قائمة sourceSets (مثل ["free"]، أو في بناء متعدد الأبعاد كل نكهة في التركيبة إضافةً إلى التركيبة
نفسها) ومجلد root عندما يكون التطبيق داخل مستودع أحادي (monorepo).
ما لا يستطيع رؤيته
- اعتماديات الاعتماديات، إلا على iOS، حيث يسردها
Podfile.lock. فالـ SDK التي تجلبها مكتبة أخرى لا تظهر في ملف البناء لديك، لذا لا تظهر هنا أيضًا. - الإعدادات المكتوبة كشيفرة فقط.
app.config.js/app.config.tsفي Expo هي JavaScript ولا تُقرأ؛ أماapp.jsonوpackage.jsonفتُقرآن. - ما إذا كنت تستخدم ما تعلنه. الاعتمادية الموجودة لكن غير المستخدمة يُبلَّغ عنها مع ذلك.
- الواجهة الخلفية لديك. لا شيء في ملف بناء يقول ما يخزّنه خادمك أو لأي مدة.
إنه تذكير في اللحظة التي يكون فيها الإفصاح عن التغيير أرخص ما يكون، وليس حكمًا على الامتثال وليس استشارة قانونية.
المصادر الرسمية
- Provide information for Google Play’s Data safety section — مساعدة Google Play Console: إبقاء النموذج دقيقًا، وبيانات الـ SDK التابعة لأطراف ثالثة
- App privacy details on the App Store — Apple: إبقاء الإجابات محدّثة، وتحديثها دون تحديث التطبيق
appfoyer/check-actionو@appfoyer/check— الـ Action وحزمة npm، مع ما تقرآنه