Files
evening_detective_server/docs/COMPLIANCE.md
T
2026-08-19 23:31:37 +07:00

18 KiB
Raw Blame History

ЧЕК-ЛИСТ COMPLIANCE: ПРИВЕДЕНИЕ СЕРВИСА В СООТВЕТСТВИЕ С ДОКУМЕНТАМИ

Сервис «Вечерний детектив» · Обновлено: 18.08.2026

Сопутствующие документы: docs/TERMS.md (Пользовательское соглашение), docs/PRIVACY.md (Политика конфиденциальности), docs/CONSENT.md (Согласие на обработку ПДн).

Легенда: — реализовано, 🟡 — частично / требует решения владельца, — осталось сделать.


1. Юридические документы

Задача Статус Примечание
1.1 Пользовательское соглашение (оферта) docs/TERMS.md — заполнить плейсхолдеры, утвердить у юриста
1.2 Политика конфиденциальности (152-ФЗ) docs/PRIVACY.md — заполнить плейсхолдеры, утвердить у юриста
1.3 Текст согласия на обработку ПДн docs/CONSENT.md — встроить в форму регистрации
1.4 Публикация документов на сайте по постоянным URL RPC GetTerms/GetPrivacy/GetConsent (api/main.proto, пути /api/terms, /api/privacy, /api/consent); текст встраивается из docs/embed.go; подставить реальные домены в тексты документов

2. Акцепт соглашений при регистрации (ст. 428 ГК РФ, ст. 9 152-ФЗ)

Задача Статус Где
2.1 Поля accept_terms / accept_privacy в запросе регистрации api/main.proto (SignupReq), перегенерирован proto/
2.2 Серверная проверка: регистрация без акцепта отклоняется (ErrTermsNotAccepted) internal/services/users_service/service.goAddUser; internal/app/server.goSignup
2.3 Таблица user_agreements (user_id, тип, версия, дата, IP, user-agent) migrations/20260818231943_create_user_agreements_table.sql
2.4 Фиксация акцепта при регистрации (terms + privacy), атомарно с созданием пользователя users_repo.AddUserWithAgreements (одна транзакция: пользователь не существует без записей о согласиях)
2.5 Версии документов как константы (termsVersion, privacyVersion) users_service/service.go — при новой редакции документов поднять версию
2.6 Чекбоксы в форме регистрации (не предустановленные!) + блокировка отправки Фронтенд (репозиторий фронта)
2.7 Возраст 18+ (текст + проверка) 🟡 В документах и коде — запрет; проверить, что форма запрашивает подтверждение возраста
2.8 Фиксация IP и user-agent клиента при акцепте (ст. 9 ч. 3 152-ФЗ) clientInfoFromContext: X-Real-IP от доверенного прокси (матчер в cmd/evening_detective_server/main.go), иначе последний элемент X-Forwarded-For; UA — grpcgateway-user-agent

3. Удаление аккаунта и данных (ст. 14, 21 152-ФЗ)

Задача Статус Где
3.1 Эндпоинт DELETE /api/auth/delete-account (авторизован JWT) api/main.proto (DeleteAccount), internal/app/server.go
3.2 Удаление аккаунта: ПДн удаляются (refresh-токены, учётная запись); записи об акцептах СОХРАНЯЮТСЯ обезличенными (факт/версия/время; user_id отвязывается через FK ON DELETE SET NULL, ip/user_agent обнуляются — бремя доказывания согласия на операторе, ст. 9 ч. 4 152-ФЗ) internal/repos/users_repo/repo.goDeleteUser (транзакция); миграции 20260818231943_create_user_agreements_table.sql, 20260818232725_keep_content_on_user_delete.sql
3.2а Подтверждение паролем при удалении аккаунта (защита от удаления чужим обладателем украденного access-токена) HTTP-заголовок X-Password (матчер в cmd/evening_detective_server/main.go) → users_service.DeleteAccount (bcrypt-сверка); пароль не попадает в URL/query
3.3 Судьба контента при удалении аккаунта Выбран вариант «отчуждение исключительного права на опубликованные Сценарии»: контент сохраняется, автор не вправе требовать удаления (п. 7.2, 7.6, 7.8 TERMS; ст. 1234, 1269 ГК РФ)
3.4 NULL-safe чтение сценариев с обезличенным автором scenarios_repo (scan через указатели), mapUser возвращает nil → author: null в API (клиент показывает «Автор удалён»)
3.5 Удаление файлов из S3 при удалении аккаунта Сейчас удаляются только записи в БД; файлы пользователя в S3 (file_service) остаются — добавить вызов fileStorage.Delete для файлов автора
3.6 UI-кнопка «Удалить аккаунт» + подтверждение Фронтенд
3.7 Отзыв согласия без удаления аккаунта (ст. 9 ч. 2, 152-ФЗ) Опционально: отдельный эндпоинт «отозвать согласие» → прекращение обработки, блокировка аккаунта
3.8 Инвалидация выданных access-токенов после удаления аккаунта 🟡 JWT без revoke-листа: refresh-токен удаляется сразу, access-токен действует до истечения TTL (3 ч, processor_jwt); запросы с устаревшим токеном после удаления получат ошибку FK/«Пользователь не найден». Защита: короткий TTL; при необходимости — версия токена/чёрный список

Примечание по акцептам (п. 3.2): решение владельца — хранить записи об акцептах обезличенными после удаления аккаунта (факт/версия/время без user_id/ip/user_agent): ст. 9 ч. 4 152-ФЗ возлагает на оператора бремя доказывания получения согласия. Альтернатива, если позже решат уничтожать и их (ст. 21 152-ФЗ): вернуть FK ON DELETE CASCADE в миграции 20260818231943 и DELETE FROM user_agreements WHERE user_id = $1 в DeleteUser.

3а. Отчуждение исключительных прав на сценарии (ст. 1234, 1269 ГК РФ)

Задача Статус Где
3а.1 Пункт TERMS об отчуждении исключительного права при публикации (безвозмездно, в полном объёме) docs/TERMS.md п. 7.27.4
3а.2 Запрет автору удалять / снимать с публикации опубликованный сценарий (ErrScenarioPublished); ПРАВКА КОНТЕНТА опубликованного сценария РАЗРЕШЕНА владельцу (решение владельца продукта) internal/services/scenarios_service/service.go; админ — исключение; guard в SQL от гонки «чтение → запись» для status/delete
3а.3 Проверка владельца сценария при всех изменениях (public/draft/delete/update/места) (ErrScenarioNotOwner) internal/services/scenarios_service/service.gogetScenarioForChange
3а.4 Право на отзыв ограничено моментом обнародования (ст. 1269 ГК РФ) docs/TERMS.md п. 7.6
3а.5 Отдельный чекбокс «передаю исключительные права» при первой публикации + серверная проверка Фронтенд + бэкенд (сейчас публикация доступна владельцу без доп. подтверждения; добавить confirm_transfer в PublicScenarioReq при необходимости)
3а.6 Проверка владельца при редактировании сценария (UpdateScenario, AddScenarioPlace и др.) getScenarioForChange в internal/services/scenarios_service/service.go; правка опубликованного разрешена (решение владельца, см. 3а.2)
3а.7 Оценка рисков ЗоЗПП (ст. 16) для безвозмездного отчуждения в договоре присоединения 🟡 См. «Риски» ниже; при запуске для широкой аудитории — консультация юриста и судебная практика

Риски отчуждения прав в договоре присоединения:

  • ЗоЗПП, ст. 16: безвозмездное отчуждение исключительного права на пользовательский контент в оферте для потребителя может быть оспорено как условие, ущемляющее права потребителя. Снижение риска: отдельное явное подтверждение при публикации, возможность отозвать Сценарий до публикации (черновики не отчуждаются), прозрачное выделение условия.
  • Личные неимущественные права (ст. 1265 ГК РФ) не отчуждаются: автор сохраняет право авторства и может требовать его признания — отчуждается только имущественное (исключительное) право.
  • Право на отзыв (ст. 1269 ГК РФ) действует только до обнародования — после публикации требования автора об удалении не подлежат удовлетворению (кроме случаев, предусмотренных законом, напр. признание сценария нарушающим права третьих лиц).
  • Коммерческие организации: п. 3.1 ст. 1234 ГК РФ запрещает безвозмездное отчуждение исключительного права между коммерческими организациями — не применяется, т.к. пользователи — физические лица.

4. Регистрация в Роскомнадзоре (ст. 22 152-ФЗ)

Задача Статус Примечание
4.1 Оценить необходимость уведомления РКН о начале обработки ПДн 🟡 Интернет-сервис с автоматизированной обработкой обычно требует уведомления; исключения ч. 2 ст. 22 вряд ли применимы. Подать до запуска в прод
4.2 Подать уведомление (портал РКН, форма «оператор ПДн») Внешняя процедура; оператор — физлицо
4.3 Получить и хранить номер уведомления / решение Приложить к документации

5. Локализация баз данных (ст. 18 ч. 5 152-ФЗ)

Задача Статус Где
5.1 PostgreSQL в РФ docker-compose-db.yml / прод-конфигурация — проверить, что БД в РФ
5.2 S3 (RustFS) — файлы пользователей 🟡 Проверить, где физически находится S3_HOST в проде
5.3 SMTP-логи переписки 🟡 Проверить, не сохраняются ли письма/логи за пределами РФ

6. Безопасность (ст. 19 152-ФЗ)

Задача Статус Где
6.1 Хеширование паролей (bcrypt) users_service/service.go
6.2 JWT access (3 ч) + refresh (7 дн) с ротацией processor_jwt
6.3 HTTPS на проде 🟡 Через обратный прокси (не в репозитории)
6.4 Назначить ответственного за обработку ПДн (ст. 22.1) Организационный шаг (для физлица-оператора — сам владелец)
6.5 Внутренний документ: сроки хранения логов, порядок реагирования на утечки (ст. 21 ч. 3.1 — уведомление РКН за 24 ч) Организационный шаг
6.6 Gateway только за доверенным обратным прокси, перезаписывающим X-Real-IP (иначе клиент спуфит IP при акцепте; значения валидируются netip.ParseAddr) 🟡 Требование к прод-развёртыванию: nginx/Caddy перед :8090; настройка не в репозитории

7. Права субъекта (ст. 14, 17, 20 152-ФЗ)

Задача Статус Где
7.1 Эндпоинт «получить свои данные» (GDPR-стиль / ст. 14) 🟡 Частично есть GET /api/users/me; полная выгрузка ПДн (все таблицы) — добавить
7.2 Эндпоинт «изменить email/ник» Сейчас нет; без него нельзя исполнить «уточнение ПДн»
7.3 Эндпоинт «удалить аккаунт» П. 3.1
7.4 Процедура ответа на запросы (10 раб. дней, ст. 20) Организационный шаг + адрес [email] из документов

8. Прочее

Задача Статус Примечание
8.1 Обновление swagger (cmd/evening_detective_server/main.swagger.json) Перегенерирован make generate
8.2 Прогон миграции на реальной БД (goose up) Выполнить на staging перед продом
8.3 Интеграционный тест: signup без акцепта → ошибка; delete-account → данные удалены go test (сейчас тестов нет)
8.4 Обновить README: новые эндпоинты, документы
8.5 GDPR (если появятся пользователи из ЕС) Политика + DPA + механизмы прав субъекта — отдельный этап

Порядок действий перед запуском в прод

  1. Заполнить плейсхолдеры в docs/TERMS.md, docs/PRIVACY.md, docs/CONSENT.md и утвердить у юриста.
  2. Вставить в тексты документов реальные домены (/api/terms, /api/privacy, /api/consent); вставить чекбоксы акцепта, подтверждение отчуждения прав при публикации сценария и кнопку «Удалить аккаунт» во фронтенд.
  3. Подать уведомление в Роскомнадзор (п. 4.2) до начала обработки.
  4. Проверить локализацию: БД, S3, SMTP — в РФ.
  5. Прогнать goose up на staging; добавить интеграционный тест (п. 8.3) — включая сценарий: публикация → удаление запрещено; удаление аккаунта → сценарий остаётся с author: null.
  6. Решить задачу удаления файлов из S3 (п. 3.5) и «изменить email/ник» (п. 7.2) — по остаточному принципу после запуска.