Перейти к содержимому
AppFoyer
Начать

Руководства После запуска

Как поддерживать политику конфиденциальности в соответствии со сборкой

Политику пишут один раз, а устаревает она, когда pull request добавляет SDK. Как заметить это в самом pull request бесплатной проверкой, читающей только файлы сборки.

Зафиксируйте, по каким SDK, типам данных и разрешениям были написаны ваши страницы, а затем сравнивайте с этой записью файлы сборки в каждом pull request. Когда появляется зависимость или разрешение, которых в записи нет, pull request покажет это раньше релиза — пока политику конфиденциальности и формы магазинов ещё легко обновить.

Сделайте это за несколько минут

AppFoyer размещает страницы, о которых это руководство, — политику конфиденциальности, условия использования, поддержку, удаление аккаунта и app-ads.txt — на отдельном поддомене, без собственного домена и сервера. Одно приложение — бесплатно, и ничто из того, что требует магазин, никогда не бывает платным.

Проверено 30 сентября 2026 г. Правила магазинов меняются, иногда без предупреждения. Всё ниже ссылается на официальную документацию, и авторитетна именно она, а не эта страница. Если они расходятся, прав магазин. Это руководство переведено с английского; цитаты из документации магазинов приведены в оригинале на английском.

Написать политику конфиденциальности — разовая работа. Поддерживать её правдивой — нет: политика описывает сборку, которая была у вас в момент написания, а сборка продолжает меняться. Pull request добавляет crash reporting, библиотеку подписок или разрешение на геолокацию, приложение выходит, а политика, форма Data safety и сведения App Privacy всё ещё описывают старое приложение.

Оба магазина считают это вашей проблемой, а не своей. Google Play говорит, что ваши ответы в Data safety должны всегда оставаться точными и полными и что данные, собираемые сторонними библиотеками и SDK в вашем приложении, декларируете вы. Apple говорит то же самое о сведениях App Privacy и добавляет, что ответы в App Store Connect можно изменить в любой момент без отправки обновления.

Откуда на самом деле берётся расхождение

Почти никогда — из решения «собирать больше данных». Оно возникает из обычной инженерной работы:

  • Новая зависимость. Crash reporting, аналитика, SDK paywall, библиотека карт.
  • Новое разрешение. Геолокация для одной функции, камера для сканера, отслеживание для рекламы.
  • Flavor или target. Бесплатная сборка получает рекламный SDK, которого нет в платной.
  • Удаление. Это тоже расхождение: политика теперь декларирует лишнее — более безопасная ошибка, но всё же ошибка.

Каждое из этих изменений попадает в файл сборки — build.gradle, AndroidManifest.xml, Podfile, Package.swift, Info.plist, pubspec.yaml, package.json. Именно это и делает его проверяемым.

Подход: запись и проверка в каждом pull request

  1. Когда страницы написаны, зафиксируйте, по чему они написаны: SDK, типы данных и разрешения, которые были в сборке в тот момент.
  2. В каждом pull request снова читайте файлы сборки и сравнивайте.
  3. Если что-то отличается, сообщайте, что именно, где (файл и строка) и на какую страницу или форму это может повлиять.

Важны два свойства. Проверка должна читать только файлы сборки — никогда исходный код, никогда секреты, — чтобы её можно было безопасно запускать на любом репозитории. И она должна говорить «может быть устаревшим», а не «нарушение»: библиотека в файле сборки не доказывает, что приложение её использует, и только вы знаете, меняет ли она то, что собирает ваше приложение.

Настройка с AppFoyer

Проверка бесплатна на любом тарифе. Она читает только файлы сборки, не требует ключа или секрета, ничего никуда не отправляет и никогда не меняет страницу.

С плагином Claude Code

  1. Скажите “make this app store-ready”. Помимо черновиков страниц, плагин записывает appfoyer.json в корень репозитория: запись о том, по чему были написаны страницы.
  2. Скажите “add the AppFoyer drift check”. Он покажет вам GitHub workflow и запишет .github/workflows/appfoyer.yml, когда вы согласитесь.
  3. Закоммитьте оба файла. Плагин никогда не делает commit или push за вас.

Без плагина

Добавьте workflow сами:

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

Откройте pull request. Пока в репозитории нет 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 job summary; --format json — для скриптов.

Как выглядит находка

Pull request, который добавляет 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

По умолчанию job сообщает о находках и проходит успешно. Добавьте fail-on-drift: "true" в with:, чтобы он падал, пока запись не обновлена.

Когда проверка сообщает об изменении

  1. Обновите то, на что влияет изменение. Снова скажите “make this app store-ready” в той же ветке: плагин заново прочитает сборку, обновит факты о приложении, перепишет черновики затронутых страниц и перезапишет appfoyer.json. Или отредактируйте страницы и вкладку Store forms в дашборде сами.
  2. Обновите запись. Плагин уже сделал это. После правки в дашборде выполните npx @appfoyer/check update или скопируйте обновлённый файл из job summary, где он находится под находками.
  3. Закоммитьте её в том же pull request. Следующий запуск не покажет изменений, а в истории зависимость и изменение раскрытия появятся вместе.
  4. Обновите формы магазинов в консолях. Ни проверка, ни AppFoyer не имеют доступа к Play Console или App Store Connect. Черновики ответов находятся на вкладке Store forms в дашборде.
  5. Опубликуйте обновлённые черновики с экрана проверки.

Несколько приложений в одном репозитории

appfoyer.json содержит одну запись на каждую страницу приложения в магазине. Product flavor с собственным application id получает собственную запись, поэтому рекламный SDK, используемый только бесплатным flavor, сравнивается со страницами бесплатного flavor, а не платного. Плагин записывает по одной записи на каждый flavor, который он подготовил к магазину. Вручную запись принимает список sourceSets — ["free"], а для сборки с несколькими измерениями — каждый flavor в комбинации плюс саму комбинацию — и папку root, если приложение находится внутри monorepo.

Чего она не видит

  • Зависимости зависимостей, кроме iOS, где их перечисляет Podfile.lock. SDK, подтянутый другой библиотекой, не появляется в вашем файле сборки, поэтому не появляется и здесь.
  • Конфигурацию только в коде. app.config.js / app.config.ts в Expo — это JavaScript, и он не читается; app.json и package.json — читаются.
  • Используете ли вы то, что объявили. Зависимость, которая присутствует, но не используется, всё равно попадает в отчёт.
  • Ваш бэкенд. Ничто в файле сборки не говорит, что хранит ваш сервер и как долго.

Это напоминание в тот момент, когда раскрыть изменение дешевле всего, а не вердикт о соответствии и не юридическая консультация.

Официальные источники