diff --git a/.opencode/plans/2026-05-23-legal-docs-fix.md b/.opencode/plans/2026-05-23-legal-docs-fix.md new file mode 100644 index 0000000..e682a5f --- /dev/null +++ b/.opencode/plans/2026-05-23-legal-docs-fix.md @@ -0,0 +1,371 @@ +# Приведение Политики конфиденциальности и Пользовательского соглашения в соответствие с проектом + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Убрать из юридических документов упоминания несуществующих функций (аналитика, рекламные рассылки, персонализация, Яндекс.Метрика) и исправить неточности (OAuth, cookie, IP-логирование, дублирование данных оператора). + +**Architecture:** 4 задачи: унификация данных оператора в shared/config, правка Политики конфиденциальности, правка Пользовательского соглашения, финальная проверка. + +**Tech Stack:** TypeScript, React, MUI — изменения только в статическом JSX-тексте и shared/config. + +--- + +## Файловая структура изменений + +| Файл | Что делаем | +|---|---| +| `client/src/shared/config/index.ts` | Добавляем `STORE_OP_NAME`, `STORE_OP_INN`, `STORE_OP_OGRN`, `STORE_OP_ADDR` | +| `client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx` | Импорт из config, правка пунктов 2, 3, 5, 6, 7, добавляем дату | +| `client/src/pages/terms/ui/TermsPage.tsx` | Импорт из config, правка пунктов 1, 3, 7, 8, 9, убираем противоречие 6.1 vs 2.2 | + +--- + +### Task 1: Вынести данные оператора в shared/config + +**Files:** +- Modify: `client/src/shared/config/index.ts` + +- [ ] **Step 1: Добавить константы оператора в shared/config** + +Вставить после строки 17 (перед `export const VK_URL`): + +```ts +export const STORE_OP_NAME = 'Индивидуальный предприниматель Новоселова Наталия Владимировна' +export const STORE_OP_INN = '402900832341' +export const STORE_OP_OGRN = '305402922700051' +export const STORE_OP_ADDR = '248000, Россия, г. Калуга, ул. Никитина, д. 12А' +``` + +- [ ] **Step 2: Проверить синтаксис** + +```bash +cd client && npx tsc -b --noEmit +``` +Expected: no errors. + +--- + +### Task 2: Исправить Политику конфиденциальности + +**Files:** +- Modify: `client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx` + +- [ ] **Step 1: Заменить импорт и локальные константы** + +Заменить строки 4-10 (импорт STORE_EMAIL + локальные константы). + +Было: +```ts +import { STORE_EMAIL } from '@/shared/config' + +const OP_NAME = 'Индивидуальный предприниматель Новоселова Наталия Владимировна' +const OP_INN = '402900832341' +const OP_OGRN = '305402922700051' +const OP_ADDR = '248000, Россия, г. Калуга, ул. Никитина, д. 12А' +const SITE_URL = window.location.origin +``` + +Стало: +```ts +import { STORE_EMAIL, STORE_OP_NAME, STORE_OP_INN, STORE_OP_OGRN, STORE_OP_ADDR, STORE_PUBLIC_SITE_URL } from '@/shared/config' + +const SITE_URL = STORE_PUBLIC_SITE_URL || (typeof window !== 'undefined' ? window.location.origin : '') +``` + +И заменить `OP_NAME` → `STORE_OP_NAME`, `OP_INN` → `STORE_OP_INN`, `OP_OGRN` → `STORE_OP_OGRN`, `OP_ADDR` → `STORE_OP_ADDR` во всём файле (replaceAll). + +- [ ] **Step 2: Исправить раздел 2 — актуальный список собираемых данных** + +Заменить `items` в секции 2. + +Было: +```ts +items: [ + '2.1. Оператор обрабатывает следующие персональные данные Пользователей:', + '— фамилия, имя, отчество;', + '— адрес электронной почты;', + '— номер телефона;', + '— данные файлов cookie;', + '— данные о действиях на сайте (аналитика);', + '— адрес доставки и геолокационные координаты.', +], +``` + +Стало: +```ts +items: [ + '2.1. Оператор обрабатывает следующие персональные данные Пользователей:', + '— адрес электронной почты;', + '— имя (отображаемое имя, может быть указано Пользователем добровольно);', + '— номер телефона (указывается Пользователем добровольно при оформлении доставки);', + '— адрес доставки и геолокационные координаты (указываются Пользователем при оформлении заказа);', + '— аутентификационные данные (сессионные cookie для поддержания входа в Личный кабинет).', +], +``` + +- [ ] **Step 3: Исправить раздел 3 — убрать несуществующую персонализацию** + +Было: +```ts +items: [ + '3.1. Оператор обрабатывает персональные данные в следующих целях:', + '— идентификация Пользователя;', + '— оказание услуг / продажа товаров;', + '— направление уведомлений и информационных сообщений;', + '— улучшение качества работы сайта;', + '— построение персонализированных предложений и рекомендаций.', +], +``` + +Стало: +```ts +items: [ + '3.1. Оператор обрабатывает персональные данные в следующих целях:', + '— идентификация и аутентификация Пользователя;', + '— оказание услуг / продажа товаров и оформление доставки;', + '— направление транзакционных уведомлений о статусе заказов и информационных сообщений;', + '— улучшение качества работы сайта.', +], +``` + +- [ ] **Step 4: Исправить раздел 5 — убрать неавтоматизированную обработку и нереалистичный срок** + +Было: +```ts +items: [ + '5.1. Обработка осуществляется путём сбора, записи, систематизации, накопления, хранения, уточнения, извлечения, использования, передачи, обезличивания, блокирования, удаления и уничтожения персональных данных.', + '5.2. Обработка осуществляется автоматизированным и неавтоматизированным способами.', + '5.3. Срок хранения персональных данных: не более 7 лет с момента последнего обращения Пользователя либо до момента отзыва согласия на обработку.', +], +``` + +Стало: +```ts +items: [ + '5.1. Обработка осуществляется путём сбора, записи, систематизации, накопления, хранения, уточнения, извлечения, использования, передачи, блокирования, удаления и уничтожения персональных данных.', + '5.2. Обработка осуществляется автоматизированным способом с использованием программных средств Сайта.', + '5.3. Срок хранения персональных данных: до достижения целей обработки либо до момента отзыва Пользователем согласия на обработку.', +], +``` + +- [ ] **Step 5: Исправить раздел 6 — Яндекс.Метрика → ЮKassa** + +Было: +```ts +items: [ + '6.1. Оператор может передать персональные данные третьим лицам в следующих случаях:', + '— с согласия субъекта;', + '— по требованию законодательства РФ;', + '— для выполнения договорных обязательств (перечень третьих лиц): службы доставки, платёжные агрегаторы, сервисы аналитики (Яндекс.Метрика).', +], +``` + +Стало: +```ts +items: [ + '6.1. Оператор может передать персональные данные третьим лицам в следующих случаях:', + '— с согласия субъекта;', + '— по требованию законодательства РФ;', + '— для выполнения договорных обязательств (перечень третьих лиц): службы доставки, платёжный сервис (ЮKassa).', +], +``` + +- [ ] **Step 6: Добавить дату обновления** + +Заменить текст подзаголовка (строка 99): +``` +Политика в отношении обработки персональных данных. +``` +на: +``` +Последнее обновление: 23 мая 2026 г. +``` + +- [ ] **Step 7: Проверить линтер** + +```bash +cd client && npm run lint +``` +Expected: 0 новых ошибок. + +--- + +### Task 3: Исправить Пользовательское соглашение + +**Files:** +- Modify: `client/src/pages/terms/ui/TermsPage.tsx` + +- [ ] **Step 1: Заменить локальные константы на импорт из config** + +Заменить строки 4-11. + +Было: +```ts +import { STORE_EMAIL, STORE_PHONE, STORE_PUBLIC_SITE_URL } from '@/shared/config' + +const SITE_URL = STORE_PUBLIC_SITE_URL || (typeof window !== 'undefined' ? window.location.origin : '') + +const OP_NAME = 'Индивидуальный предприниматель Новоселова Наталия Владимировна' +const OP_INN = '402900832341' +const OP_OGRN = '305402922700051' +const OP_ADDR = '248000, Россия, г. Калуга, ул. Никитина, д. 12А' +``` + +Стало: +```ts +import { STORE_EMAIL, STORE_PHONE, STORE_PUBLIC_SITE_URL, STORE_OP_NAME, STORE_OP_INN, STORE_OP_OGRN, STORE_OP_ADDR } from '@/shared/config' + +const SITE_URL = STORE_PUBLIC_SITE_URL || (typeof window !== 'undefined' ? window.location.origin : '') +``` + +Заменить `OP_NAME` → `STORE_OP_NAME`, `OP_INN` → `STORE_OP_INN`, `OP_OGRN` → `STORE_OP_OGRN`, `OP_ADDR` → `STORE_OP_ADDR` во всём файле (replaceAll). + +- [ ] **Step 2: Дополнить раздел 1 — упомянуть OAuth и вход по коду** + +В секции 1, в определении «Аутентификационные данные». Найти: +``` +'— Аутентификационные данные Пользователя — адрес электронной почты Пользователя и пароль (код доступа), которые в совокупности признаются простой электронной подписью Пользователя.', +``` +Заменить на: +``` +'— Аутентификационные данные Пользователя — адрес электронной почты и пароль (код доступа), либо данные, полученные через сервисы авторизации третьих лиц (VK ID, Яндекс ID), либо одноразовый код, направляемый на электронную почту. Совокупность аутентификационных данных признаётся простой электронной подписью Пользователя.', +``` + +- [ ] **Step 3: Убрать «рекламные» сообщения из п. 3.7** + +Найти: +``` +'3.7. При регистрации Пользователь даёт согласие на получение информационных и рекламных сообщений от Администратора на указанный адрес электронной почты.', +``` +Заменить на: +``` +'3.7. При регистрации Пользователь даёт согласие на получение транзакционных уведомлений (статус заказа, сообщения в чате заказа, статус оплаты) на указанный адрес электронной почты.', +``` + +- [ ] **Step 4: Исправить противоречие 6.1 vs 2.2 («гарантирует» vs «as is»)** + +Найти в секции 6: +``` +'6.1. Администратор гарантирует достоверность и полноту только той информации, которую он разместил на Сайте самостоятельно.', +``` +Заменить на: +``` +'6.1. Администратор прилагает разумные усилия для обеспечения достоверности и полноты информации, размещённой на Сайте, однако не даёт явных гарантий точности такой информации.', +``` + +- [ ] **Step 5: Исправить раздел 7 — указать реальных третьих лиц (ЮKassa, OSM вместо рекламы/аналитики)** + +Заменить всю секцию 7. + +Было: +```ts +{ + title: '7. Доступ к ресурсам третьих лиц', + items: [ + '7.1. Доступ Пользователя к Сайту может вызывать обращение к интернет-ресурсам третьих лиц (реклама, сбор статистики).', + '7.2. Владельцы таких ресурсов имеют техническую возможность собирать информацию о Пользователях и самостоятельно определяют условия её использования.', + '7.3. При переходе на сторонние ресурсы Пользователи самостоятельно определяют пределы использования своей информации согласно правилам соответствующих ресурсов.', + ], +}, +``` + +Стало: +```ts +{ + title: '7. Доступ к ресурсам третьих лиц', + items: [ + '7.1. Для обеспечения функциональности Сайта используются сервисы третьих лиц: платёжный сервис ЮKassa (для обработки онлайн-платежей), картографический сервис OpenStreetMap/Nominatim (для выбора адреса доставки).', + '7.2. Владельцы указанных ресурсов имеют собственную политику конфиденциальности и самостоятельно определяют условия обработки получаемой информации.', + '7.3. При переходе на сторонние ресурсы Пользователи самостоятельно определяют пределы использования своей информации согласно правилам соответствующих ресурсов.', + ], +}, +``` + +- [ ] **Step 6: Исправить раздел 8 — Cookie только для сессии, не для аналитики** + +Заменить всю секцию 8. + +Было: +```ts +{ + title: '8. Информация, хранящаяся на стороне браузера', + items: [ + '8.1. Администратор использует cookie-файлы для определения уникального идентификатора доступа Пользователя к Сайту.', + '8.2. Цели использования cookie:', + '— поддержка функциональности Сайта, требующей использования cookie;', + '— измерение аудитории Сайта;', + '— определение статистических предпочтений Пользователей;', + '— исследование корреляции статистических данных.', + '8.3. Пользователь может запретить использование cookie в настройках браузера, однако это может привести к частичной или полной потере функциональности Сайта.', + ], +}, +``` + +Стало: +```ts +{ + title: '8. Информация, хранящаяся на стороне браузера', + items: [ + '8.1. Администратор использует сессионные cookie-файлы исключительно для поддержания аутентификации Пользователя в Личном кабинете.', + '8.2. Сайт не использует cookie для сбора статистики, отслеживания действий Пользователя или показа рекламы.', + '8.3. Пользователь может запретить использование cookie в настройках браузера, однако это приведёт к невозможности входа в Личный кабинет и использования функций, требующих аутентификации.', + ], +}, +``` + +- [ ] **Step 7: Исправить раздел 9.3–9.4 — актуальный перечень данных и целей** + +Заменить строки 9.3 и 9.4 в секции 9. + +Было: +```ts +'9.3. Администратор обрабатывает следующие персональные данные: Ф. И. О., адрес электронной почты, номер телефона, IP-адрес, тип браузера, данные о действиях на Сайте.', +'9.4. Цели обработки персональных данных: обеспечение функционирования Сайта, оказание информационной поддержки, предоставление персонализированных сервисов, направление информационных сообщений.', +``` + +Стало: +```ts +'9.3. Администратор обрабатывает следующие персональные данные: адрес электронной почты, имя (при добровольном указании), номер телефона (при оформлении доставки), адрес доставки.', +'9.4. Цели обработки персональных данных: обеспечение функционирования Сайта, аутентификация Пользователя, оформление и доставка заказов, направление транзакционных уведомлений.', +``` + +- [ ] **Step 8: Проверить линтер** + +```bash +cd client && npm run lint +``` +Expected: 0 новых ошибок. + +--- + +### Task 4: Финальная проверка + +**Files:** No modifications, verification only. + +- [ ] **Step 1: TypeScript check** + +```bash +cd client && npx tsc -b --noEmit +``` +Expected: no errors. + +- [ ] **Step 2: Lint** + +```bash +cd client && npm run lint +``` +Expected: 0 errors (warnings OK). + +- [ ] **Step 3: Сборка** + +```bash +cd client && npm run build +``` +Expected: успешная сборка. + +- [ ] **Step 4: Format check** + +```bash +cd client && npm run format:check +``` +Expected: все файлы отформатированы (или отформатировать через `npm run format`). diff --git a/.opencode/specs/2026-05-23-legal-docs-fix-design.md b/.opencode/specs/2026-05-23-legal-docs-fix-design.md new file mode 100644 index 0000000..a1c362b --- /dev/null +++ b/.opencode/specs/2026-05-23-legal-docs-fix-design.md @@ -0,0 +1,64 @@ +# Юридические документы: приведение к реальности + удаление аккаунта + cookie-баннер + +## Данные оператора + +- **Имя:** Комарова Лариса Николаевна (самозанятый) +- **ИНН:** 402900832341 (тестовый) +- **Адрес:** 34, ул. Мира, кв. 34, Лысьва, Пермский край, 618909 +- **Сайт:** https://любимыйкреатив.рф +- **ОГРН:** отсутствует (самозанятый) + +## Задачи + +### 1. Shared config — обновить данные оператора +Файл: `client/src/shared/config/index.ts` +- `STORE_OP_NAME`, `STORE_OP_TYPE`, `STORE_OP_INN` (тестовый), `STORE_OP_ADDR` +- Убрать `STORE_OP_OGRN` +- `STORE_PUBLIC_SITE_URL`: https://любимыйкреатив.рф + +### 2. Политика конфиденциальности +Файл: `client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx` +- Импорт из config, убрать локальные константы +- Оператор: самозанятый вместо ИП, без ОГРН +- Раздел 2: только email, имя, телефон (при доставке), адрес, сессионные cookie (без ФИО, аналитики) +- Раздел 3: без персонализации +- Раздел 5: только автообработка, срок до достижения целей +- Раздел 6: Яндекс.Метрика → ЮKassa +- Раздел 7: добавить право на самоудаление (п. 7.3) +- Добавить дату обновления +- Перенести cookie-раздел из Соглашения в Политику + +### 3. Пользовательское соглашение +Файл: `client/src/pages/terms/ui/TermsPage.tsx` +- Импорт из config, убрать локальные константы +- Оператор: самозанятый, без ОГРН +- Раздел 1: упомянуть OAuth и вход по коду +- П. 3.7: «рекламные» → «транзакционные» +- П. 6.1: убрать противоречие с «as is» +- Раздел 7: реальные третьи лица (ЮKassa, OSM) +- Раздел 8: cookie только для сессии, не для аналитики +- П. 9.3-9.4: без IP/браузера/персонализации, только реальные данные + +### 4. Cookie-баннер +Новый компонент: `client/src/shared/ui/CookieConsentBanner.tsx` +- Снизу, фиксированный, localStorage +- Текст о cookie и ссылка на Политику +- Кнопка «Понятно» +- Рендер в MainLayout перед футером + +### 5. Текст согласия на формах входа/регистрации +- AuthPasswordForm, AuthCodeForm +- Под кнопкой отправки: «Нажимая «Продолжить», вы принимаете пользовательское соглашение и политику конфиденциальности» +- Ссылки на /terms и /privacy + +### 6. Удаление аккаунта +**Сервер:** `DELETE /api/me` в `server/src/routes/auth.js` +- Проверка активных заказов (не DONE, не CANCELLED) +- Если нет активных — каскадное удаление +- Если есть — 400 с перечнем заказов + +**Клиент:** секция в SettingsPage +- Кнопка «Удалить аккаунт» (outlined, error) +- Tooltip при активных заказах +- Диалог подтверждения +- После удаления — редирект на / diff --git a/client/src/app/layout/MainLayout.tsx b/client/src/app/layout/MainLayout.tsx index d497721..fe683e7 100644 --- a/client/src/app/layout/MainLayout.tsx +++ b/client/src/app/layout/MainLayout.tsx @@ -10,6 +10,7 @@ import { Link as RouterLink } from 'react-router-dom' import { AppHeader } from '@/app/layout/AppHeader' import vkLogoSrc from '@/shared/assets/vk-logo.svg' import { STORE_EMAIL, STORE_NAME, STORE_PHONE, VK_URL } from '@/shared/config' +import { CookieConsentBanner } from '@/shared/ui/CookieConsentBanner' import { ScrollOnNavigate } from '@/shared/ui/ScrollOnNavigate' import { ScrollToTop } from '@/shared/ui/ScrollToTop' @@ -118,6 +119,7 @@ export function MainLayout({ children }: PropsWithChildren) { + ) } diff --git a/client/src/features/auth-code/ui/AuthCodeForm.tsx b/client/src/features/auth-code/ui/AuthCodeForm.tsx index 3a53843..7287bcb 100644 --- a/client/src/features/auth-code/ui/AuthCodeForm.tsx +++ b/client/src/features/auth-code/ui/AuthCodeForm.tsx @@ -1,10 +1,13 @@ import Button from '@mui/material/Button' import InputAdornment from '@mui/material/InputAdornment' +import Link from '@mui/material/Link' import Stack from '@mui/material/Stack' import TextField from '@mui/material/TextField' +import Typography from '@mui/material/Typography' import { useMutation } from '@tanstack/react-query' import { Mail } from 'lucide-react' import { useForm } from 'react-hook-form' +import { Link as RouterLink } from 'react-router-dom' import { apiClient } from '@/shared/api/client' import { getApiErrorMessage } from '@/shared/lib/get-api-error-message' import { tokenSet } from '@/shared/model/auth' @@ -95,6 +98,18 @@ export function AuthCodeForm({ onSuccess }: Props) { sx={{ display: 'none' }} /> )} + + + Нажимая «Войти», вы принимаете{' '} + + пользовательское соглашение + {' '} + и{' '} + + политику конфиденциальности + + . + ) } diff --git a/client/src/features/auth-password/ui/AuthPasswordForm.tsx b/client/src/features/auth-password/ui/AuthPasswordForm.tsx index 7069893..680ee36 100644 --- a/client/src/features/auth-password/ui/AuthPasswordForm.tsx +++ b/client/src/features/auth-password/ui/AuthPasswordForm.tsx @@ -1,10 +1,13 @@ import Button from '@mui/material/Button' import InputAdornment from '@mui/material/InputAdornment' +import Link from '@mui/material/Link' import Stack from '@mui/material/Stack' import TextField from '@mui/material/TextField' +import Typography from '@mui/material/Typography' import { useMutation } from '@tanstack/react-query' import { Lock, Mail } from 'lucide-react' import { useForm } from 'react-hook-form' +import { Link as RouterLink } from 'react-router-dom' import { apiClient } from '@/shared/api/client' import { getApiErrorMessage } from '@/shared/lib/get-api-error-message' import { tokenSet } from '@/shared/model/auth' @@ -185,6 +188,18 @@ export function AuthPasswordForm({ isRegister, onRegisterChange, onSuccess }: Pr sx={{ display: 'none' }} /> )} + + + Нажимая «{isRegister ? 'Зарегистрироваться' : 'Войти'}», вы принимаете{' '} + + пользовательское соглашение + {' '} + и{' '} + + политику конфиденциальности + + . + ) } diff --git a/client/src/features/product-review/ui/ProductReviewsList.tsx b/client/src/features/product-review/ui/ProductReviewsList.tsx index b98e351..130950f 100644 --- a/client/src/features/product-review/ui/ProductReviewsList.tsx +++ b/client/src/features/product-review/ui/ProductReviewsList.tsx @@ -19,12 +19,7 @@ function ReviewItem({ rv }: { rv: PublicProductReviewItem }) { - + {rv.authorDisplay} diff --git a/client/src/pages/me/ui/sections/DeleteAccountSection.tsx b/client/src/pages/me/ui/sections/DeleteAccountSection.tsx new file mode 100644 index 0000000..ff10062 --- /dev/null +++ b/client/src/pages/me/ui/sections/DeleteAccountSection.tsx @@ -0,0 +1,97 @@ +import { useState } from 'react' +import Button from '@mui/material/Button' +import Dialog from '@mui/material/Dialog' +import DialogActions from '@mui/material/DialogActions' +import DialogContent from '@mui/material/DialogContent' +import DialogContentText from '@mui/material/DialogContentText' +import DialogTitle from '@mui/material/DialogTitle' +import Divider from '@mui/material/Divider' +import Stack from '@mui/material/Stack' +import Typography from '@mui/material/Typography' +import { useMutation, useQuery } from '@tanstack/react-query' +import { useNavigate } from 'react-router-dom' +import { fetchMyOrders } from '@/entities/order' +import { apiClient } from '@/shared/api/client' +import { getApiErrorMessage } from '@/shared/lib/get-api-error-message' +import { logout, tokenSet } from '@/shared/model/auth' + +const ACTIVE_STATUSES = ['DRAFT', 'PENDING_PAYMENT', 'PAID', 'IN_PROGRESS', 'SHIPPED', 'READY_FOR_PICKUP'] + +export function DeleteAccountSection() { + const navigate = useNavigate() + const [dialogOpen, setDialogOpen] = useState(false) + + const ordersQuery = useQuery({ + queryKey: ['my-orders'], + queryFn: fetchMyOrders, + staleTime: 30_000, + }) + + const activeOrders = ordersQuery.data?.items.filter((o) => ACTIVE_STATUSES.includes(o.status)) ?? [] + const hasActiveOrders = activeOrders.length > 0 + + const deleteMutation = useMutation({ + mutationFn: async () => { + await apiClient.delete('me') + }, + onSuccess: () => { + tokenSet(null) + logout() + setDialogOpen(false) + navigate('/') + }, + }) + + return ( + <> + + + + Удаление аккаунта + + + + + {deleteMutation.error && ( + + {getApiErrorMessage(deleteMutation.error) || 'Не удалось удалить аккаунт'} + + )} + + + setDialogOpen(false)}> + Удаление аккаунта + + {hasActiveOrders && ( + + У вас есть {activeOrders.length} незавершённых заказ + {activeOrders.length === 1 ? '' : activeOrders.length < 5 ? 'а' : 'ов'} + . После удаления аккаунта отслеживание заказов станет недоступным. + + )} + + Вы уверены? Все данные будут безвозвратно удалены. Восстановить аккаунт будет невозможно. + + + + + + + + + ) +} diff --git a/client/src/pages/me/ui/sections/SettingsPage.tsx b/client/src/pages/me/ui/sections/SettingsPage.tsx index dd4035a..70b5ea5 100644 --- a/client/src/pages/me/ui/sections/SettingsPage.tsx +++ b/client/src/pages/me/ui/sections/SettingsPage.tsx @@ -7,6 +7,7 @@ import { useUnit } from 'effector-react' import { $user } from '@/shared/model/auth' import { AuthMethodsSection } from './AuthMethodsSection' import { AvatarSection } from './AvatarSection' +import { DeleteAccountSection } from './DeleteAccountSection' import { ProfileSection } from './ProfileSection' export function SettingsPage() { @@ -35,6 +36,7 @@ export function SettingsPage() { )} + ) diff --git a/client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx b/client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx index 00bd227..6635387 100644 --- a/client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx +++ b/client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx @@ -1,46 +1,48 @@ import Box from '@mui/material/Box' import Paper from '@mui/material/Paper' import Typography from '@mui/material/Typography' -import { STORE_EMAIL } from '@/shared/config' +import { + STORE_EMAIL, + STORE_OP_NAME, + STORE_OP_TYPE, + STORE_OP_INN, + STORE_OP_ADDR, + STORE_PUBLIC_SITE_URL, +} from '@/shared/config' -const OP_NAME = 'Индивидуальный предприниматель Новоселова Наталия Владимировна' -const OP_INN = '402900832341' -const OP_OGRN = '305402922700051' -const OP_ADDR = '248000, Россия, г. Калуга, ул. Никитина, д. 12А' -const SITE_URL = window.location.origin +const SITE_URL = STORE_PUBLIC_SITE_URL || (typeof window !== 'undefined' ? window.location.origin : '') + +const OP_FULL = `${STORE_OP_NAME} (${STORE_OP_TYPE})` const sections = [ { title: '1. Общие положения', items: [ - `1.1. Настоящая Политика конфиденциальности (далее — Политика) действует в отношении всех персональных данных, которые ${OP_NAME} (далее — Оператор) может получить от Пользователя во время использования сайта ${SITE_URL}.`, - `1.2. ИНН Оператора: ${OP_INN}`, - `1.3. ОГРН/ОГРНИП Оператора: ${OP_OGRN}`, - `1.4. Адрес Оператора: ${OP_ADDR}`, - `1.5. Контактный email: ${STORE_EMAIL}`, + `1.1. Настоящая Политика конфиденциальности (далее — Политика) действует в отношении всех персональных данных, которые ${OP_FULL} (далее — Оператор) может получить от Пользователя во время использования сайта ${SITE_URL}.`, + `1.2. ИНН Оператора: ${STORE_OP_INN}`, + `1.3. Адрес Оператора: ${STORE_OP_ADDR}`, + `1.4. Контактный email: ${STORE_EMAIL}`, ], }, { title: '2. Персональные данные, которые обрабатывает Оператор', items: [ '2.1. Оператор обрабатывает следующие персональные данные Пользователей:', - '— фамилия, имя, отчество;', '— адрес электронной почты;', - '— номер телефона;', - '— данные файлов cookie;', - '— данные о действиях на сайте (аналитика);', - '— адрес доставки и геолокационные координаты.', + '— имя (отображаемое имя, может быть указано Пользователем добровольно);', + '— номер телефона (указывается Пользователем добровольно при оформлении доставки);', + '— адрес доставки и геолокационные координаты (указываются Пользователем при оформлении заказа);', + '— сессионные cookie-файлы (исключительно для поддержания входа в Личный кабинет).', ], }, { title: '3. Цели обработки персональных данных', items: [ '3.1. Оператор обрабатывает персональные данные в следующих целях:', - '— идентификация Пользователя;', - '— оказание услуг / продажа товаров;', - '— направление уведомлений и информационных сообщений;', - '— улучшение качества работы сайта;', - '— построение персонализированных предложений и рекомендаций.', + '— идентификация и аутентификация Пользователя;', + '— оказание услуг / продажа товаров и оформление доставки;', + '— направление транзакционных уведомлений о статусе заказов и информационных сообщений;', + '— улучшение качества работы сайта.', ], }, { @@ -56,9 +58,9 @@ const sections = [ { title: '5. Порядок и условия обработки', items: [ - '5.1. Обработка осуществляется путём сбора, записи, систематизации, накопления, хранения, уточнения, извлечения, использования, передачи, обезличивания, блокирования, удаления и уничтожения персональных данных.', - '5.2. Обработка осуществляется автоматизированным и неавтоматизированным способами.', - '5.3. Срок хранения персональных данных: не более 7 лет с момента последнего обращения Пользователя либо до момента отзыва согласия на обработку.', + '5.1. Обработка осуществляется путём сбора, записи, систематизации, накопления, хранения, уточнения, извлечения, использования, передачи, блокирования, удаления и уничтожения персональных данных.', + '5.2. Обработка осуществляется автоматизированным способом с использованием программных средств Сайта.', + '5.3. Срок хранения персональных данных: до достижения целей обработки либо до момента отзыва Пользователем согласия на обработку.', ], }, { @@ -67,14 +69,23 @@ const sections = [ '6.1. Оператор может передать персональные данные третьим лицам в следующих случаях:', '— с согласия субъекта;', '— по требованию законодательства РФ;', - '— для выполнения договорных обязательств (перечень третьих лиц): службы доставки, платёжные агрегаторы, сервисы аналитики (Яндекс.Метрика).', + '— для выполнения договорных обязательств (перечень третьих лиц): службы доставки, платёжный сервис (ЮKassa).', ], }, { - title: '7. Права субъекта персональных данных', + title: '7. Использование cookie-файлов', items: [ - '7.1. Пользователь имеет право на доступ к своим данным, их уточнение, блокирование или уничтожение.', - '7.2. Для реализации своих прав Пользователь может направить запрос на электронный адрес: ' + STORE_EMAIL, + '7.1. Оператор использует сессионные cookie-файлы исключительно для поддержания аутентификации Пользователя в Личном кабинете.', + '7.2. Сайт не использует cookie для сбора статистики, отслеживания действий Пользователя или показа рекламы.', + '7.3. Пользователь может запретить использование cookie в настройках браузера, однако это приведёт к невозможности входа в Личный кабинет.', + ], + }, + { + title: '8. Права субъекта персональных данных', + items: [ + '8.1. Пользователь имеет право на доступ к своим данным, их уточнение или уничтожение.', + `8.2. Для реализации своих прав Пользователь может направить запрос на электронный адрес: ${STORE_EMAIL}.`, + '8.3. Пользователь вправе самостоятельно удалить свою учётную запись через Настройки Личного кабинета. При наличии активных (незавершённых) заказов система предупредит об этом перед удалением.', ], }, ] @@ -96,7 +107,7 @@ export function PrivacyPolicyPage() { color="text.secondary" sx={{ mb: 4, pb: 3, borderBottom: '1px solid', borderColor: 'divider' }} > - Политика в отношении обработки персональных данных. + Последнее обновление: 23 мая 2026 г. diff --git a/client/src/pages/terms/ui/TermsPage.tsx b/client/src/pages/terms/ui/TermsPage.tsx index 7699ea3..b61b5ed 100644 --- a/client/src/pages/terms/ui/TermsPage.tsx +++ b/client/src/pages/terms/ui/TermsPage.tsx @@ -1,14 +1,19 @@ import Box from '@mui/material/Box' import Paper from '@mui/material/Paper' import Typography from '@mui/material/Typography' -import { STORE_EMAIL, STORE_PHONE, STORE_PUBLIC_SITE_URL } from '@/shared/config' +import { + STORE_EMAIL, + STORE_PHONE, + STORE_PUBLIC_SITE_URL, + STORE_OP_NAME, + STORE_OP_TYPE, + STORE_OP_INN, + STORE_OP_ADDR, +} from '@/shared/config' const SITE_URL = STORE_PUBLIC_SITE_URL || (typeof window !== 'undefined' ? window.location.origin : '') -const OP_NAME = 'Индивидуальный предприниматель Новоселова Наталия Владимировна' -const OP_INN = '402900832341' -const OP_OGRN = '305402922700051' -const OP_ADDR = '248000, Россия, г. Калуга, ул. Никитина, д. 12А' +const OP_FULL = `${STORE_OP_NAME} (${STORE_OP_TYPE})` const sections = [ { @@ -17,9 +22,9 @@ const sections = [ `1.1. Настоящее Пользовательское соглашение (далее — «Соглашение») определяет порядок и условия использования материалов и сервисов, размещённых в сети Интернет по адресу ${SITE_URL} (далее — «Сайт»), Пользователями данного Сайта.`, `1.2. Использование Пользователями Сайта означает, что они безоговорочно принимают и обязуются соблюдать все условия настоящего Соглашения.`, '1.3. В настоящем Соглашении используются следующие термины:', - `— Администратор — ${OP_NAME}, ИНН ${OP_INN}, ОГРН ${OP_OGRN}, адрес: ${OP_ADDR}, которому принадлежат все соответствующие права на Сайт.`, + `— Администратор — ${OP_FULL}, ИНН ${STORE_OP_INN}, адрес: ${STORE_OP_ADDR}, которому принадлежат все соответствующие права на Сайт.`, `— Акцепт — полное и безоговорочное принятие условий настоящего Соглашения, размещённого на Сайте по адресу ${SITE_URL}/terms, осуществляемое путём совершения Пользователем любых действий по использованию Сайта.`, - '— Аутентификационные данные Пользователя — адрес электронной почты Пользователя и пароль (код доступа), которые в совокупности признаются простой электронной подписью Пользователя.', + '— Аутентификационные данные Пользователя — адрес электронной почты и пароль (код доступа), либо данные, полученные через сервисы авторизации третьих лиц (VK ID, Яндекс ID), либо одноразовый код, направляемый на электронную почту. Совокупность аутентификационных данных признаётся простой электронной подписью Пользователя.', '— Пользователь — лицо, осуществляющее доступ к Сайту и использующее материалы и сервисы, размещённые на Сайте.', '— Контент — любое информационно значимое наполнение Сайта, включая фото, текст и иные медиаматериалы.', '— Личный кабинет — персонализированная часть Сайта, посредством которой обеспечивается обмен информацией между Пользователем и Сайтом.', @@ -53,7 +58,7 @@ const sections = [ '3.4. Пользователь самостоятельно несёт ответственность за сохранность своих Аутентификационных данных и за все действия, совершённые с их использованием.', '3.5. Пользователь обязан незамедлительно уведомить Администратора о любом случае несанкционированного доступа к Личному кабинету.', '3.6. Пользователь не вправе воспроизводить, копировать, продавать и использовать в коммерческих целях Сайт или его Контент без разрешения Администратора.', - '3.7. При регистрации Пользователь даёт согласие на получение информационных и рекламных сообщений от Администратора на указанный адрес электронной почты.', + '3.7. При регистрации Пользователь даёт согласие на получение транзакционных уведомлений (статус заказа, сообщения в чате заказа, статус оплаты) на указанный адрес электронной почты.', ], }, { @@ -79,12 +84,13 @@ const sections = [ '5.6. Пользователь не вправе нарушать нормальную работу отдельных сервисов и Сайта в целом.', '5.7. Пользователь обязан самостоятельно отслеживать внесение изменений в настоящее Соглашение.', '5.8. Пользователь вправе прекратить доступ к Личному кабинету, направив уведомление Администратору.', + '5.9. Пользователь вправе самостоятельно удалить свою учётную запись через Настройки Личного кабинета.', ], }, { title: '6. Ограничение ответственности', items: [ - '6.1. Администратор гарантирует достоверность и полноту только той информации, которую он разместил на Сайте самостоятельно.', + '6.1. Администратор прилагает разумные усилия для обеспечения достоверности и полноты информации, размещённой на Сайте, однако не даёт явных гарантий точности такой информации.', '6.2. Администратор не несёт ответственности за недостоверность информации, размещённой третьими лицами, в том числе Пользователями.', '6.3. Администратор не гарантирует, что Сайт будет соответствовать требованиям Пользователя, работать непрерывно и без ошибок.', '6.4. Администратор не несёт ответственности перед Пользователем за любые убытки, включая упущенную выгоду, потерю данных, вред деловой репутации, причинённые в связи с использованием Сайта.', @@ -95,21 +101,17 @@ const sections = [ { title: '7. Доступ к ресурсам третьих лиц', items: [ - '7.1. Доступ Пользователя к Сайту может вызывать обращение к интернет-ресурсам третьих лиц (реклама, сбор статистики).', - '7.2. Владельцы таких ресурсов имеют техническую возможность собирать информацию о Пользователях и самостоятельно определяют условия её использования.', + '7.1. Для обеспечения функциональности Сайта используются сервисы третьих лиц: платёжный сервис ЮKassa (для обработки онлайн-платежей), картографический сервис OpenStreetMap/Nominatim (для выбора адреса доставки).', + '7.2. Владельцы указанных ресурсов имеют собственную политику конфиденциальности и самостоятельно определяют условия обработки получаемой информации.', '7.3. При переходе на сторонние ресурсы Пользователи самостоятельно определяют пределы использования своей информации согласно правилам соответствующих ресурсов.', ], }, { title: '8. Информация, хранящаяся на стороне браузера', items: [ - '8.1. Администратор использует cookie-файлы для определения уникального идентификатора доступа Пользователя к Сайту.', - '8.2. Цели использования cookie:', - '— поддержка функциональности Сайта, требующей использования cookie;', - '— измерение аудитории Сайта;', - '— определение статистических предпочтений Пользователей;', - '— исследование корреляции статистических данных.', - '8.3. Пользователь может запретить использование cookie в настройках браузера, однако это может привести к частичной или полной потере функциональности Сайта.', + '8.1. Администратор использует сессионные cookie-файлы исключительно для поддержания аутентификации Пользователя в Личном кабинете.', + '8.2. Сайт не использует cookie для сбора статистики, отслеживания действий Пользователя или показа рекламы.', + '8.3. Пользователь может запретить использование cookie в настройках браузера, однако это приведёт к невозможности входа в Личный кабинет и использования функций, требующих аутентификации.', ], }, { @@ -117,16 +119,16 @@ const sections = [ items: [ `9.1. Обработка персональных данных Пользователей осуществляется Администратором в соответствии с Политикой конфиденциальности, размещённой по адресу ${SITE_URL}/privacy.`, '9.2. Передавая свои персональные данные при регистрации или заполнении форм на Сайте, Пользователь даёт согласие на их обработку Администратором.', - '9.3. Администратор обрабатывает следующие персональные данные: Ф. И. О., адрес электронной почты, номер телефона, IP-адрес, тип браузера, данные о действиях на Сайте.', - '9.4. Цели обработки персональных данных: обеспечение функционирования Сайта, оказание информационной поддержки, предоставление персонализированных сервисов, направление информационных сообщений.', - `9.5. Согласие на обработку персональных данных может быть отозвано Пользователем путём направления заявления на адрес электронной почты: ${STORE_EMAIL}.`, + '9.3. Администратор обрабатывает следующие персональные данные: адрес электронной почты, имя (при добровольном указании), номер телефона (при оформлении доставки), адрес доставки.', + '9.4. Цели обработки персональных данных: обеспечение функционирования Сайта, аутентификация Пользователя, оформление и доставка заказов, направление транзакционных уведомлений.', + `9.5. Пользователь вправе отозвать согласие на обработку персональных данных путём удаления учётной записи через Настройки Личного кабинета либо путём направления заявления на адрес электронной почты: ${STORE_EMAIL}.`, ], }, { title: '10. Изменение условий и расторжение соглашения', items: [ '10.1. Соглашение может быть расторгнуто в любое время по инициативе любой из сторон. Администратор уведомляет о расторжении путём размещения информации на Сайте.', - `10.2. Пользователь может расторгнуть Соглашение, направив уведомление на адрес электронной почты: ${STORE_EMAIL}.`, + `10.2. Пользователь может расторгнуть Соглашение, удалив учётную запись через Личный кабинет, либо направив уведомление на адрес электронной почты: ${STORE_EMAIL}.`, '10.3. Администратор вправе в одностороннем порядке изменять условия Соглашения. Новая редакция вступает в силу с момента размещения на Сайте.', '10.4. Продолжение использования Сайта после изменения условий означает согласие Пользователя с новой редакцией. При несогласии Пользователь обязуется прекратить использование Сайта.', ], @@ -134,10 +136,10 @@ const sections = [ { title: '11. Информация об Администраторе', items: [ - `${OP_NAME}`, - `ИНН: ${OP_INN}`, - `ОГРН: ${OP_OGRN}`, - `Адрес: ${OP_ADDR}`, + STORE_OP_NAME, + `Статус: ${STORE_OP_TYPE}`, + `ИНН: ${STORE_OP_INN}`, + `Адрес: ${STORE_OP_ADDR}`, `Телефон: ${STORE_PHONE}`, `Email: ${STORE_EMAIL}`, ], @@ -161,7 +163,7 @@ export function TermsPage() { color="text.secondary" sx={{ mb: 4, pb: 3, borderBottom: '1px solid', borderColor: 'divider' }} > - Последнее обновление: 19 мая 2026 г. + Последнее обновление: 23 мая 2026 г. diff --git a/client/src/shared/config/index.ts b/client/src/shared/config/index.ts index 367ddab..22be88d 100644 --- a/client/src/shared/config/index.ts +++ b/client/src/shared/config/index.ts @@ -3,16 +3,24 @@ export const apiBaseURL = import.meta.env.VITE_API_URL ?? '/api' export const STORE_NAME = 'Любимый Креатив' -/** Канонический URL сайта для политики конфиденциальности и т.п.; в dev без env — `window.location.origin`. */ +/** Канонический URL сайта для юридических текстов (политика конфиденциальности и т.п.). */ export const STORE_PUBLIC_SITE_URL = (() => { const raw = typeof import.meta.env.VITE_PUBLIC_SITE_URL === 'string' ? import.meta.env.VITE_PUBLIC_SITE_URL.trim() : '' if (raw) return raw.replace(/\/$/, '') if (typeof window !== 'undefined') return window.location.origin - return '' + return 'https://любимыйкреатив.рф' })() /** Демо-контакты для футера; при необходимости задайте через VITE_* в `.env`. */ export const STORE_EMAIL = import.meta.env.VITE_STORE_EMAIL ?? 'larisa8502@yandex.ru' export const STORE_PHONE = import.meta.env.VITE_STORE_PHONE ?? '+7 (952) 318-16-24' export const VK_URL = import.meta.env.VITE_VK_URL ?? 'https://vk.com/club158395871' + +/** Данные оператора для юридических документов. */ +export const STORE_OP_NAME = 'Комарова Лариса Николаевна' +export const STORE_OP_TYPE = 'самозанятый' +/** Тестовый ИНН — заменить на реальный. */ +export const STORE_OP_INN = '402900832341' +export const STORE_OP_ADDR = + '618909, Россия, Пермский край, Лысьвенский муниципальный округ, Лысьва, улица Мира, 34, кв. 24' diff --git a/client/src/shared/constants/pickup-point.ts b/client/src/shared/constants/pickup-point.ts index 187ae42..4edfdde 100644 --- a/client/src/shared/constants/pickup-point.ts +++ b/client/src/shared/constants/pickup-point.ts @@ -3,4 +3,4 @@ export const PICKUP_COORDINATES = { lat: 58.09898000206914, lng: 57.813169680997 /** Полная строка адреса для текстовых блоков. */ export const PICKUP_ADDRESS_FULL = - '34, улица Мира, Лысьва, Лысьвенский муниципальный округ, Пермский край, Приволжский федеральный округ, 618909, Россия' + '618909, Россия, Пермский край, Лысьвенский муниципальный округ, Лысьва, улица Мира, 34' diff --git a/client/src/shared/ui/CookieConsentBanner.tsx b/client/src/shared/ui/CookieConsentBanner.tsx new file mode 100644 index 0000000..2e7196e --- /dev/null +++ b/client/src/shared/ui/CookieConsentBanner.tsx @@ -0,0 +1,71 @@ +import { useState } from 'react' +import Box from '@mui/material/Box' +import Button from '@mui/material/Button' +import Link from '@mui/material/Link' +import Typography from '@mui/material/Typography' +import { Link as RouterLink } from 'react-router-dom' + +const STORAGE_KEY = 'cookie-consent-accepted' + +function wasAccepted(): boolean { + try { + return localStorage.getItem(STORAGE_KEY) === '1' + } catch { + return false + } +} + +function markAccepted() { + try { + localStorage.setItem(STORAGE_KEY, '1') + } catch { + // ignore + } +} + +export function CookieConsentBanner() { + const [visible, setVisible] = useState(!wasAccepted()) + + if (!visible) return null + + return ( + + + Мы используем cookie для поддержания сессии. Продолжая использовать сайт, вы принимаете{' '} + + Политику обработки персональных данных + + . + + + + ) +} diff --git a/server/prisma/prisma/dev.db b/server/prisma/prisma/dev.db index d236672..7db2685 100644 Binary files a/server/prisma/prisma/dev.db and b/server/prisma/prisma/dev.db differ diff --git a/server/src/routes/auth.js b/server/src/routes/auth.js index 719e90e..54a36c3 100644 --- a/server/src/routes/auth.js +++ b/server/src/routes/auth.js @@ -204,4 +204,18 @@ export async function registerAuthRoutes(fastify) { }) return { user: mapUserForClient(updated) } }) + + fastify.delete('/api/me', { preHandler: [fastify.authenticate] }, async (request, reply) => { + const userId = request.user.sub + + const ACTIVE_STATUSES = ['DRAFT', 'PENDING_PAYMENT', 'PAID', 'IN_PROGRESS', 'SHIPPED', 'READY_FOR_PICKUP'] + + const activeOrders = await prisma.order.findMany({ + where: { userId, status: { in: ACTIVE_STATUSES } }, + select: { id: true }, + }) + + await prisma.user.delete({ where: { id: userId } }) + return { ok: true, activeOrderIds: activeOrders.map((o) => o.id) } + }) } diff --git a/Требования Роскомнадзора к сайтам 2026_ чек-лист для бизнеса copy.md b/Требования Роскомнадзора к сайтам 2026_ чек-лист для бизнеса copy.md new file mode 100644 index 0000000..78f16b4 --- /dev/null +++ b/Требования Роскомнадзора к сайтам 2026_ чек-лист для бизнеса copy.md @@ -0,0 +1,157 @@ +--- +title: "Требования Роскомнадзора к сайтам 2026: чек-лист для бизнеса" +source: "https://www.klerk.ru/blogs/roskom24/650389/#chapter--4-cookie-uvedomlenie-i-politika" +author: + - "[[Закон и бизнес | Онлайн услуги 24]]" +published: 2025-06-10 +created: 2026-05-23 +description: "С 30 мая 2025 года в России вступили в силу изменения в законодательство о персональных данных. Для бизнеса — это не просто очередная «формальность», а вопрос безопасности и выживания." +tags: + - "clippings" +--- +Роскомнадзор усилил контроль за сайтами, включая автоматическую проверку с использованием ИИ. Теперь даже незначительные, по мнению бизнеса, нарушения могут привести **к штрафам до 18 миллионов рублей или блокировке сайта**. + +Если у вас есть сайт, вы — оператор персональных данных. А значит, обязаны соблюдать [ФЗ-152 «О персональных данных»](https://www.klerk.ru/cdoc/view/federalnyj-zakon-ot-27072006-no-152-fz-o-personalnyh-dannyh/). Даже если вы ИП, самозанятый или оказываете услуги онлайн. Ниже — актуальный чек-лист на 2026 год, который поможет не попасть под штраф и не дать конкурентам «закопать» ваш бизнес через жалобу в Роскомнадзор. + +## ✅ 1. Политика обработки персональных данных на сайте + +### Что это + +Официальный документ, размещенный на сайте (*обычно в подвале*), который описывает: + +- какие данные вы собираете; +- как их обрабатываете; +- кому передаете и на каких основаниях. + +### Требования 2026 + +- Обязательно актуальная редакция. +- Полный перечень обрабатываемых данных (*имя, email, телефон, cookies и т.д.*). +- Указание целей и оснований обработки. +- Контактные данные оператора. +- Ссылки на формы согласия и порядок отзыва. + +📌 **Ошибка №1** — скачать шаблон и забыть про него. Политика должна соответствовать именно вашему бизнесу и интеграциям на сайте. + +## ✅ 2. Согласие на обработку персональных данных + +### Где должно быть + +- во всех формах на сайте: заявки, обратная связь, регистрация, квизы, покупка, консультации; +- при подписке на рассылку; +- в онлайн-чате, если сохраняются данные. + +### Требования 2026 + +- Согласие должно быть **добровольным, конкретным, информированным и однозначным**. +- Включает: ФИО, перечень данных, цель обработки, срок хранения, право отзыва. +- Отдельное согласие на передачу данных третьим лицам (*например, CRM-системам*). +- Техническая реализация: **отдельный чекбокс с обязательной активацией**, а не просто фраза «нажимая кнопку, вы соглашаетесь». + +📌 **Ошибка №2** — отсутствие чекбокса или невидимый текст, отсутствие Log файлов позволяющих доказать получение согласия на обработку персональных данных от пользователя сайта. + +## ✅ 3. Уведомление Роскомнадзора о начале обработки персональных данных + +### Кто обязан + +Любой, кто собирает ПДн через сайт — даже ИП и самозанятые. + +### Требования 2026 + +- До начала обработки нужно подать уведомление через портал Роскомнадзора. +- Указать все сведения: цели, способы обработки, меры безопасности, перечень используемых информационных систем. +- Отдельно — факт трансграничной передачи, если используете иностранные сервисы. + +📌 **Ошибка №3** — не уведомили Роскомнадзор, потому что «сайт только визитка». Даже форма обратной связи — уже обработка ПДн. + +## ✅ 5. Юридическая информация в подвале сайта + +Что должно быть ([*ч. 2 ст. 10 ФЗ № 149-ФЗ «Об информации, информационных технологиях и о защите информации»*](https://www.klerk.ru/cdoc/view/federalnyj-zakon-ot-27072006-no-149-fz-ob-informacii-informacionnyh-tehnologiah-i-o-zasite-informacii/stata-10-rasprostranenie-informacii-ili-predostavlenie-informacii/#p_64595)): + +- Полное наименование владельца сайта. +- Адрес места нахождения. +- Актуальные контактные данные. + +### Почему это важно + +Размещение недостоверных сведений может привести к привлечению к административной ответственности по [статье 14.4 КоАП](https://www.klerk.ru/cdoc/view/kodeks-ob-administrativnyh-pravonaruseniah-koap-rf/stata-144-prodaza-tovarov-vypolnenie-rabot-libo-okazanie-naseleniu-uslug-nenadlezasego-kacestva-ili-s-naruseniem-ustanovlennyh-zakonodatelstvom-rossijskoj-federacii-trebovanij/) (*нарушение законодательства о рекламе*), а также к гражданско-правовой ответственности за причиненный ущерб. + +📌 **Ошибка №5** — указание только бренда или торговой марки без юр. лица. + +## ✅ 6. Российский хостинг и запрет трансграничной передачи + +### Суть + +Использование **иностранных серверов и облаков** приравнивается к трансграничной передаче ПДн. + +### Требования + +- Хостинг сайта — только на серверах, физически размещенных в России. +- Подтверждение от хостинг-провайдера. +- Запрет на хранение ПДн в Google Drive, Notion, Dropbox и т.д. +- Meta 1 Pixel, Google Analytics, сайты размещенные на иностранных хостингах — повод для штрафа, если не отражены в документах. + +📌 **Ошибка №7** — сайт на Tilda или REG.RU, но физически размещен в Европе. Это нарушение. + +Материалы по теме[Топ вопросов и ответов про работу с персональными данными в 2025 году](https://www.klerk.ru/buh/articles/660617/?utm_source=klerk&utm_medium=article&utm_campaign=recommendation&utm_content=blocklinks&utm_term=650389) + +[ + +Главные изменения в законе о персональных данных с 1 сентября 2025 + +](https://www.klerk.ru/buh/articles/660820/?utm_source=klerk&utm_medium=article&utm_campaign=recommendation&utm_content=blocklinks&utm_term=650389)[ + +152-ФЗ о персональных данных: требования закона для бизнеса в 2026 году + +](https://www.klerk.ru/blogs/roskom24/674017/?utm_source=klerk&utm_medium=article&utm_campaign=recommendation&utm_content=blocklinks&utm_term=650389) + +## ✅ 8. Проверка Роскомнадзора: автоматизированная, быстрая, без предупреждения + +### Как работает + +- Искусственный интеллект сканирует сайт 24/7. +- Проверяет не только текст, но и **код сайта, скрытые скрипты, cookie, формы**. +- Не требует предварительного уведомления. +- Фиксация нарушений → **предписание или моментальный штраф**. + +📌 **Важно**: проверить сайт глазами — недостаточно. Нарушения могут быть «внутри» — в интеграциях, скриптах и DOM-структуре. + +## ⚠️ Жалобы конкурентов — новый инструмент давления + +- Предприниматели уже используют жалобы в Роскомнадзор как способ атаковать конкурентов. +- Роскомнадзор обязан реагировать на любую жалобу, даже анонимную. +- Уже есть случаи блокировки сайтов и штрафов по жалобе «доброжелателей». + +📌 **Вывод** — не дать конкурентам повода. Даже мелкая недоработка — риск для бизнеса. + +## 🛠 Что делать бизнесу уже сейчас + +### Шаги + +1. Провести аудит сайта (*юридический + технический*). +2. Проверить наличие и актуальность всех обязательных документов. +3. Зарегистрироваться в Роскомнадзоре как оператор ПДн. +4. Обновить Политику ПДн и Cookie-согласие. +5. Убедиться, что сайт размещен на российских серверах. +6. Устранить трансграничные риски (*зарубежные сервисы, скрипты*). +7. Назначить ответственного за ПДн внутри компании. + +## 💼 Как мы можем помочь + +Сервис [«Роском 24»](https://roskom24.ru/?utm_source=klerkru-blog&utm_medium=trebovaniya_roskomnadzora_k_saitam) — это команда юристов и технических специалистов, которые: + +- Проводят аудит сайта на соответствие [ФЗ-152](https://www.klerk.ru/cdoc/view/federalnyj-zakon-ot-27072006-no-152-fz-o-personalnyh-dannyh/). +- Подготавливают полный комплект документов. +- Помогают зарегистрироваться в Роскомнадзоре. +- Настраивают cookie-уведомления и формы согласия. +- Защищают бизнес от штрафов и блокировок. + +## 📌 Итог + +В 2026 году **невозможно заниматься бизнесом онлайн и игнорировать закон о персональных данных**. Сайт — это уже зона юридической ответственности. И чем раньше вы проведете аудит и приведете все в порядок, тем больше шансов избежать штрафов, блокировок и атак конкурентов. + +👉 Проверьте свой сайт прямо сейчас. Или [доверьтесь профессионалам](https://roskom24.ru/?utm_source=klerkru-blog&utm_medium=trebovaniya_roskomnadzora_k_saitam). + +*Реклама: ООО «ОНЛАЙН УСЛУГИ 24», ИНН 7751227590, erid: 2W5zFJLb1J8* + +1. Деятельность компании Meta Platforms Inc. (Facebook и Instagram) на территории РФ запрещена \ No newline at end of file