diff --git a/_blueprint/plan-draft.md b/_blueprint/plan-draft.md index eb2f213..d625793 100644 --- a/_blueprint/plan-draft.md +++ b/_blueprint/plan-draft.md @@ -329,12 +329,15 @@ HTMX: форма с `hx-post`, `hx-encoding="multipart/form-data"` → SVG вс ### 4. Политика хранения, приватность и модели -#### 4.1. Принципы приватности и Zero-PII (Без регистрации) +#### 4.1. Принципы приватности, Zero-PII и учет голосов - **Полное отсутствие регистрации для посетителей:** Пользователи не создают аккаунты, не вводят email, пароли или личные данные. Единственный пользователь в `auth.User` — администратор сайта для входа в Django Admin. - **Исходные растровые изображения (JPG/PNG/WEBP):** Обрабатываются исключительно в оперативной памяти (через буфер `BytesIO`) и **не сохраняются на диск сервера вообще**. +- **Куки-согласие и идентификация устройства (Cookie-токен):** + - При согласии с правилами («Подчиниться Гипножабе!» в `allow-tracking.html`) клиенту выставляется долгоживущая анонимная кука устройства `hypn0_vid` со случайным UUID (`Max-Age=2 года`, `SameSite=Lax`, `HttpOnly`). + - **Голосование доступно только при наличии согласия на куки:** Если посетитель не принял соглашение (кука отсутствует), голосование заблокировано интерфейсом и отклоняется бэкендом (с требованием подчиниться Гипножабе). - **Лайки и учет голосов:** - - **Бэкенд:** Голоса учитываются анонимно через связку `(item_id, fingerprint)`. Поле `fingerprint` формируется как необратимый SHA-256 хэш: `sha256(IP + User-Agent + SECRET_KEY)`. Это защищает от примитивной накрутки через очистку кук или инкогнито и не сохраняет персональные данные (Zero-PII). - - **Фронтенд:** Для исключения переполнения cookies и сетевого оверхеда список лайкнутых картин хранится локально на клиенте в **`localStorage`** (до 5–10 МБ). На базе Alpine.js выполняется мгновенная индикация проголосованных работ. + - **Бэкенд:** Голоса учитываются анонимно через связку `(item_id, fingerprint)`. Поле `fingerprint` формируется как необратимый хэш: `sha256(visitor_uuid + SECRET_KEY)`. Это надежно разделяет разные компьютеры в одной корпоративной сети/NAT и не содержит открытых ПДн (Zero-PII). + - **Фронтенд:** Для быстродействия UI и исключения лишней нагрузки список лайкнутых картин дублируется локально на клиенте в **`localStorage`** (`hypn0_votes`). На базе Alpine.js выполняется мгновенная индикация проголосованных работ. - **Соответствие GDPR / 152-ФЗ:** Персональные данные не собираются и не хранятся. #### 4.2. Генерация названий (AI & Fallback Title) @@ -402,7 +405,7 @@ class HalftoneVote(models.Model): fingerprint = models.CharField( max_length=64, db_index=True, - help_text="SHA256(IP + User-Agent + SECRET_KEY) для базовой защиты от накрутки" + help_text="SHA256(visitor_uuid + SECRET_KEY) для защиты от накрутки и разделения устройств" ) created_at = models.DateTimeField(auto_now_add=True)