Настоящий документ является внутренней технической спецификацией для разработчиков платформы 4×4×. Он определяет, каким образом требования российского законодательства (152-ФЗ, ГК РФ, ЗоЗПП) транслируются в конкретные элементы пользовательского интерфейса, схемы базы данных и алгоритмы серверной логики. Документ не является публичной офертой или политикой конфиденциальности.
Данная спецификация определяет архитектуру юридических UX-элементов для всех поддоменов платформы 4×4× и служит единым источником истины для:
Настоящий документ распространяется на следующие доменные зоны и поддомены:
| Домен | Тип сервиса | Основная целевая аудитория |
|---|---|---|
4x4x.ru |
Главный сайт-агрегатор | Пользователи (заказчики услуг) |
evac.4x4x.ru |
Эвакуация внедорожников | Пользователи, исполнители-эвакуаторщики |
taxi.4x4x.ru |
Внедорожное такси | Пользователи, водители-исполнители |
event.4x4x.ru |
Внедорожные мероприятия | Участники, организаторы |
Платформа 4×4× обрабатывает ПДн физических лиц (имя, телефон, геолокация). На основании постановления Правительства № 1119 установлен уровень защищённости УЗ-3 (до 100 000 субъектов, актуальные угрозы 3-го типа). Все технические меры защиты должны соответствовать требованиям УЗ-3 согласно Приказу ФСТЭК № 21.
Раздел 2Страница /legal/ является центральным узлом всех правовых документов платформы. Она должна быть доступна с любой страницы сайта через ссылку в футере. Структура хаба делится на пять блоков.
| Идентификатор | Название документа | URL | Обязателен в форме |
|---|---|---|---|
user-agreement |
Пользовательское соглашение | /legal/user-agreement.html |
Да (все формы) |
service-rules |
Правила сервиса | /legal/service-rules.html |
Ссылка в футере |
privacy-policy |
Политика конфиденциальности | /legal/privacy-policy.html |
Ссылка в футере |
pd-consent |
Согласие на обработку персональных данных | /legal/pd-consent.html |
Да (все формы) |
cookie-policy |
Политика использования cookie | /legal/cookie-policy.html |
Cookie-баннер |
| Идентификатор | Название документа | URL | Обязателен при |
|---|---|---|---|
contractor-offer |
Оферта для исполнителей | /legal/contractor-offer.html |
Регистрация исполнителя |
executor-rules |
Правила работы исполнителей | /legal/executor-rules.html |
Регистрация исполнителя |
| Идентификатор | Название документа | URL | Обязателен при |
|---|---|---|---|
offroad-event-waiver |
Информированное согласие с рисками участия | /legal/offroad-event-waiver.html |
Регистрация на мероприятие |
offroad-event-rules |
Правила безопасности на мероприятии | /legal/offroad-event-rules.html |
Регистрация на мероприятие |
offroad-event-organizer-policy |
Политика для организаторов мероприятий | /legal/offroad-event-organizer-policy.html |
Регистрация организатора |
| Идентификатор | Название документа | URL |
|---|---|---|
consent-log-policy |
Политика журналирования согласий | /legal/consent-log-policy.html |
document-versioning-policy |
Политика версионирования документов | /legal/document-versioning-policy.html |
incident-management-policy |
Политика управления инцидентами | /legal/incident-management-policy.html |
| Идентификатор | Название документа | Примечание |
|---|---|---|
internal-pd-regulation |
Положение об обработке персональных данных | Внутренний документ, не публикуется на сайте |
data-retention-policy |
Политика хранения и удаления данных | Внутренний документ, не публикуется на сайте |
Согласно принципу минимизации персональных данных, платформа вправе собирать только те ПДн, которые необходимы и достаточны для выполнения конкретной услуги. Сбор избыточных данных является нарушением 152-ФЗ и влечёт административную ответственность.
| Поле | HTML-тип | Обязательное | Максимальная длина | Примечание |
|---|---|---|---|---|
| Имя | text |
Да | 100 символов | Только имя. Паспортные данные, фамилия — ЗАПРЕЩЕНЫ |
| Телефон | tel |
Да | 20 символов | Для связи исполнителя. Формат: +7XXXXXXXXXX |
| Тип услуги | select |
Да | — | Значения: taxi / evac / event |
| Локация (точка подачи) | text или map-picker |
Да | 500 символов | Адрес или координаты. Хранить как text, не как PostGIS без явного согласия |
| Комментарий | textarea |
Нет | 1000 символов | Дополнительные сведения. Не запрашивать ПДн в этом поле |
Запрещено собирать без специального правового основания: паспортные данные (серия, номер, дата выдачи), дата рождения, СНИЛС, ИНН физического лица, адрес проживания/регистрации, email-адрес (если не требуется для функционала и не указан в политике), фото/видеоматериалы пользователя (без явного согласия).
Email может быть добавлен в форму только при наличии соответствующей функциональной необходимости (например, отправка квитанции). При добавлении email поле должно быть отражено в Политике конфиденциальности.
Все поля формы ОБЯЗАНЫ проходить серверную валидацию независимо от клиентской. Клиентская валидация является вспомогательной мерой UX, но не является достаточным механизмом защиты. Backend должен:
Акцепт документов посредством чекбоксов является допустимой формой выражения согласия согласно ГК РФ ст. 434 (договор в электронной форме) и 152-ФЗ ст. 9 (согласие на обработку ПДн). Каждый чекбокс фиксируется в журнале согласий (consent_logs) с отметкой времени и версией документа.
Для стандартной формы заявки требуются два обязательных чекбокса:
<!-- Чекбокс 1 — Пользовательское соглашение -->
<label class="consent-checkbox">
<input type="checkbox" name="consent_ua" required data-doc="user-agreement" data-version="1.0">
<span>Я принимаю условия
<a href="/legal/user-agreement.html" target="_blank" rel="noopener">
Пользовательского соглашения
</a>
</span>
</label>
<!-- Чекбокс 2 — Согласие на обработку ПДн -->
<label class="consent-checkbox">
<input type="checkbox" name="consent_pd" required data-doc="pd-consent" data-version="1.0">
<span>Я даю согласие на
<a href="/legal/pd-consent.html" target="_blank" rel="noopener">
обработку персональных данных
</a>
</span>
</label>
Для форм регистрации на внедорожные мероприятия добавляется третий обязательный чекбокс — информированное согласие с рисками:
<!-- Чекбокс 1 — Пользовательское соглашение -->
<label class="consent-checkbox">
<input type="checkbox" name="consent_ua" required data-doc="user-agreement" data-version="1.0">
<span>Я принимаю условия
<a href="/legal/user-agreement.html" target="_blank" rel="noopener">
Пользовательского соглашения
</a>
</span>
</label>
<!-- Чекбокс 2 — Согласие на обработку ПДн -->
<label class="consent-checkbox">
<input type="checkbox" name="consent_pd" required data-doc="pd-consent" data-version="1.0">
<span>Я даю согласие на
<a href="/legal/pd-consent.html" target="_blank" rel="noopener">
обработку персональных данных
</a>
</span>
</label>
<!-- Чекбокс 3 — Согласие с рисками (только для мероприятий) -->
<label class="consent-checkbox">
<input type="checkbox" name="consent_waiver" required data-doc="offroad-event-waiver" data-version="1.0">
<span>Я ознакомлен с рисками участия и принимаю
<a href="/legal/offroad-event-waiver.html" target="_blank" rel="noopener">
правила безопасности
</a>
</span>
</label>
type="submit") должна оставаться недоступной (disabled) до тех пор, пока все обязательные чекбоксы не отмечены. Блокировка реализуется как на клиенте (JS), так и на сервере.target="_blank" rel="noopener noreferrer").data-doc и data-version используются frontend-скриптом для формирования payload согласий, передаваемого на сервер вместе с формой.POST /api/v1/request/submit
Content-Type: application/json
{
"name": "Иван",
"phone": "+79001234567",
"service_type": "taxi",
"location": "Санкт-Петербург, ул. Ленина, 1",
"comment": "",
"consents": [
{ "document": "user-agreement", "version": "1.0", "accepted": true },
{ "document": "pd-consent", "version": "1.0", "accepted": true }
]
}
Сервер обязан проверить, что для данного типа заявки (service_type) переданы все требуемые документы с accepted: true. При несоответствии — вернуть HTTP 422 с описанием отсутствующего согласия.
Cookie-баннер отображается при первом визите пользователя на сайт (определяется по отсутствию cookie 4x4x-cookie-consent). Баннер не должен блокировать основной контент страницы, однако обязан быть хорошо заметен.
Мы используем файлы cookie для обеспечения работы сайта и улучшения
пользовательского опыта. Подробнее в
<a href="/legal/cookie-policy.html">Политике cookie</a>.
| Кнопка | Стиль | Действие |
|---|---|---|
| Принять | Primary (выделена) | Устанавливает 4x4x-cookie-consent=accepted, скрывает баннер, логирует событие |
| Настроить | Secondary (нейтральная) | Открывает модальное окно настройки категорий cookie |
Модальное окно открывается по нажатию «Настроить» и содержит следующие категории:
| Категория | Описание | Состояние по умолчанию | Может быть отключена |
|---|---|---|---|
| Необходимые | Обеспечивают работу сайта (сессия, тема, язык) | Включены | Нет (toggle disabled) |
| Аналитические | Статистика посещений (без передачи 3-м лицам) | Отключены | Да |
После сохранения настроек устанавливается cookie 4x4x-cookie-consent=customized и дополнительные cookie с выбором категорий: 4x4x-cookie-analytics=0|1.
// Принятие всех категорий
document.cookie = "4x4x-cookie-consent=accepted" +
";path=/" +
";domain=.4x4x.ru" +
";max-age=31536000" + // 1 год
";SameSite=Lax" +
";Secure";
// Кастомизированный выбор
document.cookie = "4x4x-cookie-consent=customized;path=/;domain=.4x4x.ru;max-age=31536000;SameSite=Lax;Secure";
document.cookie = "4x4x-cookie-analytics=1;path=/;domain=.4x4x.ru;max-age=31536000;SameSite=Lax;Secure";
При любом действии пользователя с cookie-баннером (принятие, настройка, отклонение) выполняется POST-запрос на сервер для фиксации события в таблице consent_logs:
POST /api/v1/consent/cookie
Content-Type: application/json
{
"event_type": "cookie_accept",
"choices": {
"necessary": true,
"analytics": false
}
}
Сервер добавляет к записи IP-адрес, User-Agent и временную метку UTC автоматически. Сами cookie-значения в лог не записываются.
Раздел 6| event_type | Описание события | Таблица |
|---|---|---|
consent_accept |
Принятие пользователем юридических документов при подаче заявки | consent_logs |
cookie_accept |
Принятие или настройка cookie-политики | consent_logs |
request_submit |
Успешная подача заявки пользователем | consent_logs |
request_transfer |
Передача заявки исполнителю (раскрытие ПДн третьему лицу) | request_transfers |
waiver_sign |
Подпись информированного согласия с рисками мероприятия | consent_logs |
executor_onboard |
Принятие оферты исполнителем при регистрации | consent_logs |
data_subject_request |
Запрос субъекта ПДн на доступ, исправление или удаление данных | consent_logs |
{
"event_type": "consent_accept | request_submit | request_transfer | waiver_sign | executor_onboard | cookie_accept | data_subject_request",
"user_ip": "203.0.113.42",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0...)...",
"timestamp": "2026-03-19T10:30:00Z",
"document_versions": {
"user_agreement": "1.0",
"privacy_policy": "1.0",
"pd_consent": "1.0",
"event_waiver": "1.0" // только для мероприятий
},
"user_id": "uuid-or-null",
"session_id": "sess_a1b2c3d4e5f6",
"request_id": "req_0000000001", // только для request_submit/transfer
"metadata": {} // дополнительные данные события
}
consent_logs.consent_logs не должны обновляться или удаляться штатным образом. Исправления вносятся исключительно через создание новой корректирующей записи.Для снижения рисков при утечке логов рекомендуется хранить IP в виде SHA-256 хэша с постоянной солью (pepper), известной только серверу. Это позволяет верифицировать IP при необходимости, но делает его нечитаемым без ключа:
import hashlib, hmac
PEPPER = os.environ["CONSENT_LOG_IP_PEPPER"]
def hash_ip(ip: str) -> str:
return hmac.new(PEPPER.encode(), ip.encode(), hashlib.sha256).hexdigest()
Pepper хранится в переменных окружения, не в коде и не в базе данных.
Раздел 7Футер каждой страницы всех поддоменов платформы 4×4× должен содержать следующие ссылки и сведения о юридическом лице. Отсутствие сведений о юрлице в публичном доступе является нарушением ст. 9 149-ФЗ и требований Роспотребнадзора к интернет-магазинам и агрегаторам.
| Текст ссылки | URL |
|---|---|
| Пользовательское соглашение | /legal/user-agreement.html |
| Политика персональных данных | /legal/privacy-policy.html |
| Согласие на обработку ПДн | /legal/pd-consent.html |
| Политика cookie | /legal/cookie-policy.html |
| Правила сервиса | /legal/service-rules.html |
В футере каждой страницы должны отображаться следующие реквизиты:
<footer class="footer">
<div class="footer-legal-links">
<a href="/legal/user-agreement.html">Пользовательское соглашение</a>
<a href="/legal/privacy-policy.html">Политика конфиденциальности</a>
<a href="/legal/pd-consent.html">Согласие на обработку ПДн</a>
<a href="/legal/cookie-policy.html">Политика cookie</a>
<a href="/legal/service-rules.html">Правила сервиса</a>
</div>
<div class="footer-entity">
<p>[LEGAL_ENTITY_NAME] · [LEGAL_ENTITY_ADDRESS]</p>
<p>ОГРН: [OGRN] · ИНН: [INN] · [EMAIL]</p>
</div>
<p class="footer-copy">© 2025–2026 4×4× · Внедорожные приключения. Санкт-Петербург.</p>
</footer>
Раздел 8
Страница /contacts/ или аналогичная должна содержать следующие сведения. Их наличие обязательно согласно требованиям к агрегаторам услуг (Постановление Правительства РФ № 481 от 28.03.2022 о маркетплейсах) и ЗоЗПП:
| Элемент | Обязательность | Примечание |
|---|---|---|
| Полное наименование юридического лица | Обязательно | Как в ЕГРЮЛ/ЕГРИП |
| Юридический / почтовый адрес | Обязательно | Адрес для корреспонденции |
| Электронная почта | Обязательно | Для обращений по ПДн и потребителей |
| Телефон | Рекомендовано | Не требуется по закону, но улучшает доверие |
| ОГРН / ОГРНИП | Обязательно | Основной государственный регистрационный номер |
| ИНН | Обязательно | Идентификационный номер налогоплательщика |
Страница контактов должна содержать отдельную форму или явно указанный email для направления запросов субъектов ПДн (право на доступ, исправление, удаление, ограничение обработки — 152-ФЗ гл. 3). Срок ответа — 30 календарных дней (ст. 20 152-ФЗ).
Раздел 9Каждая страница юридического документа обязана отображать:
Версия 1.0) — в верхней части страницы;/legal/archive/ (если существуют archived-версии).<!-- data-атрибуты для машиночитаемой идентификации -->
<article
data-doc-id="privacy-policy"
data-doc-version="1.0"
data-effective-from="2026-03-19"
>
...
</article>
Эти атрибуты используются JavaScript-кодом форм для формирования payload document_versions при логировании согласий.
Таблица document_versions (описана в разделе 11) отслеживает полную историю версий всех юридических документов. При публикации новой версии документа:
effective_to для предыдущей версии (timestamp момента замены).effective_from = NOW() и effective_to = NULL.content_hash (SHA-256 от HTML-содержимого документа без навигации)./legal/archive/.<!-- Вставляется на страницу документа при наличии архивных версий -->
<a href="/legal/archive/?doc=privacy-policy" class="archive-link">
Предыдущие версии документа
</a>
Раздел 10
URL: /executors/join или /drivers.html. Данная страница является точкой акцепта оферты для исполнителей — физических лиц (ИП, самозанятые) и юридических лиц.
| Поле | HTML-тип | Обязательное | Примечание |
|---|---|---|---|
| ФИО | text |
Да | Полные ФИО — необходимы для заключения договора |
| ИНН | text (12 цифр для ФЛ, 10 для ЮЛ) |
Да | Для идентификации налогоплательщика |
| Правовой статус | select |
Да | Значения: ip (ИП) / self_employed (самозанятый) / legal_entity (юрлицо) |
| Номер водительского удостоверения | text |
Да (для водителей такси/эвакуации) | Серия и номер ВУ. Не для организаторов мероприятий. |
| Телефон | tel |
Да | Рабочий контакт |
email |
Да | Для направления договора и уведомлений |
<!-- Чекбокс 1 — Оферта для исполнителей -->
<label class="consent-checkbox">
<input type="checkbox" name="consent_offer" required data-doc="contractor-offer" data-version="1.0">
<span>Я принимаю условия
<a href="/legal/contractor-offer.html" target="_blank" rel="noopener">
Оферты для исполнителей
</a>
</span>
</label>
<!-- Чекбокс 2 — Правила работы исполнителей -->
<label class="consent-checkbox">
<input type="checkbox" name="consent_rules" required data-doc="executor-rules" data-version="1.0">
<span>Я ознакомлен с
<a href="/legal/executor-rules.html" target="_blank" rel="noopener">
Правилами работы исполнителей
</a>
</span>
</label>
<!-- Чекбокс 3 — Согласие на обработку ПДн -->
<label class="consent-checkbox">
<input type="checkbox" name="consent_pd" required data-doc="pd-consent" data-version="1.0">
<span>Я даю согласие на
<a href="/legal/pd-consent.html" target="_blank" rel="noopener">
обработку персональных данных
</a>
</span>
</label>
Акцепт оферты исполнителем логируется в consent_logs с event_type = "executor_onboard". Дополнительно создаётся запись в таблице executor_verifications с фиксацией предоставленных идентификаторов (ИНН, номер ВУ) для последующей верификации.
CREATE TABLE consent_logs (
id BIGSERIAL PRIMARY KEY,
event_type VARCHAR(64) NOT NULL,
-- Возможные значения:
-- 'consent_accept', 'cookie_accept', 'request_submit',
-- 'request_transfer', 'waiver_sign', 'executor_onboard',
-- 'data_subject_request'
-- Идентификация субъекта (хранить минимум)
user_id UUID NULL, -- NULL для анонимных действий
session_id VARCHAR(128) NOT NULL,
user_ip_hash VARCHAR(64) NOT NULL, -- SHA-256 + HMAC pepper
user_agent TEXT NOT NULL,
-- Временная метка
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- Версии принятых документов (JSONB для гибкости)
document_versions JSONB NOT NULL DEFAULT '{}',
-- Пример: {"user_agreement": "1.0", "pd_consent": "1.0"}
-- Привязка к заявке (если применимо)
request_id BIGINT NULL REFERENCES service_requests(id),
-- Дополнительный контекст
metadata JSONB NOT NULL DEFAULT '{}',
-- Мягкое удаление (реальное удаление запрещено для событий согласий)
-- Записи никогда не удаляются физически
CONSTRAINT chk_event_type CHECK (event_type IN (
'consent_accept', 'cookie_accept', 'request_submit',
'request_transfer', 'waiver_sign', 'executor_onboard',
'data_subject_request'
))
);
-- Индексы
CREATE INDEX idx_consent_logs_user_id ON consent_logs(user_id) WHERE user_id IS NOT NULL;
CREATE INDEX idx_consent_logs_session ON consent_logs(session_id);
CREATE INDEX idx_consent_logs_created ON consent_logs(created_at);
CREATE INDEX idx_consent_logs_event ON consent_logs(event_type);
CREATE INDEX idx_consent_logs_request ON consent_logs(request_id) WHERE request_id IS NOT NULL;
-- Политика хранения (исполняется cron-задачей)
-- DELETE FROM consent_logs WHERE created_at < NOW() - INTERVAL '3 years';
-- ВАЖНО: удаление выполняется только по истечении законного срока хранения.
CREATE TABLE document_versions (
id BIGSERIAL PRIMARY KEY,
document_id VARCHAR(128) NOT NULL,
-- Примеры: 'user-agreement', 'privacy-policy', 'pd-consent',
-- 'contractor-offer', 'offroad-event-waiver', 'cookie-policy'
version VARCHAR(20) NOT NULL, -- Например: '1.0', '1.1', '2.0'
title VARCHAR(512) NOT NULL, -- Заголовок документа
html_file_path VARCHAR(512) NOT NULL, -- Путь к HTML-файлу на диске
-- Хэш содержимого для верификации целостности
content_hash VARCHAR(64) NOT NULL, -- SHA-256 от HTML-содержимого
published_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
effective_from TIMESTAMPTZ NOT NULL,
effective_to TIMESTAMPTZ NULL, -- NULL = текущая активная версия
-- Кто опубликовал
published_by VARCHAR(256) NOT NULL, -- email/username администратора
CONSTRAINT uq_document_version UNIQUE (document_id, version)
);
-- Индексы
CREATE INDEX idx_docver_document_id ON document_versions(document_id);
CREATE INDEX idx_docver_effective ON document_versions(document_id, effective_from);
-- Получить актуальную версию документа:
-- SELECT * FROM document_versions
-- WHERE document_id = 'privacy-policy' AND effective_to IS NULL
-- LIMIT 1;
CREATE TABLE incidents (
id BIGSERIAL PRIMARY KEY,
incident_type VARCHAR(64) NOT NULL,
-- Типы: 'security_breach', 'data_leak', 'unauthorized_access',
-- 'service_outage', 'user_complaint', 'legal_request'
severity VARCHAR(16) NOT NULL DEFAULT 'medium',
-- Уровни: 'low', 'medium', 'high', 'critical'
status VARCHAR(32) NOT NULL DEFAULT 'open',
-- Статусы: 'open', 'investigating', 'resolved', 'closed'
title VARCHAR(512) NOT NULL,
description TEXT NOT NULL,
-- Связанный пользователь (если применимо)
affected_user_id UUID NULL,
affected_count INTEGER NULL, -- Количество затронутых субъектов ПДн
-- Уведомление Роскомнадзора (152-ФЗ ст. 21.1)
-- При утечке ПДн оператор обязан уведомить РКН в течение 24 часов
rkn_notified_at TIMESTAMPTZ NULL,
rkn_ticket_id VARCHAR(256) NULL,
-- Временные метки
detected_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
resolved_at TIMESTAMPTZ NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- Ответственный сотрудник
assigned_to VARCHAR(256) NULL,
-- Внутренние заметки (не для публичного доступа)
internal_notes TEXT NULL,
CONSTRAINT chk_severity CHECK (severity IN ('low', 'medium', 'high', 'critical')),
CONSTRAINT chk_status CHECK (status IN ('open', 'investigating', 'resolved', 'closed'))
);
-- Индексы
CREATE INDEX idx_incidents_status ON incidents(status);
CREATE INDEX idx_incidents_severity ON incidents(severity);
CREATE INDEX idx_incidents_created ON incidents(created_at);
CREATE INDEX idx_incidents_user ON incidents(affected_user_id) WHERE affected_user_id IS NOT NULL;
-- Каждая передача ПДн пользователя исполнителю (третьему лицу)
-- является юридически значимым действием и должна быть зафиксирована
-- (152-ФЗ ст. 6 — обработка ПДн с передачей третьим лицам)
CREATE TABLE request_transfers (
id BIGSERIAL PRIMARY KEY,
request_id BIGINT NOT NULL REFERENCES service_requests(id),
executor_id BIGINT NOT NULL REFERENCES executors(id),
-- Какие категории ПДн были переданы
transferred_fields JSONB NOT NULL DEFAULT '["name", "phone", "location"]',
-- Правовое основание передачи (ГК РФ + 152-ФЗ)
legal_basis VARCHAR(256) NOT NULL DEFAULT 'Исполнение договора (ГК РФ ст. 307)',
transferred_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- Подтверждение получения исполнителем
executor_ack_at TIMESTAMPTZ NULL,
-- IP-адрес и сессия при передаче (хэшированные)
operator_ip_hash VARCHAR(64) NULL,
session_id VARCHAR(128) NULL
);
-- Индексы
CREATE INDEX idx_rqtrans_request_id ON request_transfers(request_id);
CREATE INDEX idx_rqtrans_executor_id ON request_transfers(executor_id);
CREATE INDEX idx_rqtrans_transferred ON request_transfers(transferred_at);
CREATE TABLE executor_verifications (
id BIGSERIAL PRIMARY KEY,
executor_id BIGINT NOT NULL REFERENCES executors(id),
-- Статус верификации
status VARCHAR(32) NOT NULL DEFAULT 'pending',
-- Статусы: 'pending', 'verified', 'rejected', 'suspended'
-- Идентификаторы, предоставленные исполнителем
inn VARCHAR(12) NOT NULL, -- ИНН (хранить в зашифрованном виде)
legal_status VARCHAR(32) NOT NULL, -- 'ip', 'self_employed', 'legal_entity'
driver_license_no VARCHAR(32) NULL, -- Номер ВУ (зашифрованный)
license_expiry DATE NULL,
-- ФНС верификация
fns_check_at TIMESTAMPTZ NULL, -- Дата проверки ИНН через API ФНС
fns_status VARCHAR(32) NULL, -- 'active', 'inactive', 'not_found'
fns_raw_response JSONB NULL,
-- ГИБДД верификация водительского удостоверения
gibdd_check_at TIMESTAMPTZ NULL,
gibdd_status VARCHAR(32) NULL, -- 'valid', 'invalid', 'expired'
-- Кто верифицировал (оператор-человек)
verified_by VARCHAR(256) NULL,
verified_at TIMESTAMPTZ NULL,
rejection_reason TEXT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- Согласие на проверку данных (отдельное согласие)
consent_log_id BIGINT NULL REFERENCES consent_logs(id),
CONSTRAINT chk_ev_status CHECK (status IN ('pending', 'verified', 'rejected', 'suspended')),
CONSTRAINT chk_ev_legal_status CHECK (legal_status IN ('ip', 'self_employed', 'legal_entity'))
);
-- Индексы
CREATE INDEX idx_execverif_executor_id ON executor_verifications(executor_id);
CREATE INDEX idx_execverif_status ON executor_verifications(status);
CREATE INDEX idx_execverif_inn ON executor_verifications(inn);
Следующие поля таблицы executor_verifications содержат чувствительные ПДн и должны храниться в зашифрованном виде с использованием расширения pgcrypto или прикладного шифрования на уровне приложения (AES-256-GCM):
inn — ИНН физического лица является ПДн согласно позиции Роскомнадзора (письмо от 07.07.2017);driver_license_no — паспортоподобный документ, категория специальных ПДн;fns_raw_response — может содержать расширенные данные из реестров ФНС.-- Пример шифрования на уровне PG (pgcrypto):
-- INSERT INTO executor_verifications (inn, ...)
-- VALUES (
-- pgp_sym_encrypt('770123456789', current_setting('app.encryption_key')),
-- ...
-- );
-- Расшифровка:
-- SELECT pgp_sym_decrypt(inn::bytea, current_setting('app.encryption_key'))
-- FROM executor_verifications WHERE id = $1;
-- ПРЕДПОЧТИТЕЛЬНЫЙ способ: шифрование на уровне приложения (Python)
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os, base64
def encrypt_field(plaintext: str, key_b64: str) -> str:
key = base64.b64decode(key_b64)
nonce = os.urandom(12)
ct = AESGCM(key).encrypt(nonce, plaintext.encode(), None)
return base64.b64encode(nonce + ct).decode()
def decrypt_field(ciphertext_b64: str, key_b64: str) -> str:
key = base64.b64decode(key_b64)
data = base64.b64decode(ciphertext_b64)
nonce, ct = data[:12], data[12:]
return AESGCM(key).decrypt(nonce, ct, None).decode()
| Таблица | Назначение | Срок хранения | Может удаляться |
|---|---|---|---|
consent_logs |
Все события согласий и акцептов | 3 года | Только по истечении срока |
document_versions |
История версий юр. документов | Бессрочно | Нет |
incidents |
Журнал инцидентов ИБ и ПДн | 5 лет | Только по истечении срока |
request_transfers |
Журнал передачи ПДн исполнителям | 3 года | Только по истечении срока |
executor_verifications |
Верификация документов исполнителей | 5 лет после прекращения | Нет (архивирование) |
Важно: Настоящий документ является технической спецификацией. Его реализация должна быть проверена юридической службой перед запуском сервиса в коммерческую эксплуатацию. Все поля с плейсхолдерами ([LEGAL_ENTITY_NAME], [OGRN], [INN], [EMAIL]) должны быть заполнены реальными данными юридического лица оператора до публикации любого публичного документа.
Оператор персональных данных
[LEGAL_ENTITY_NAME]
[LEGAL_ENTITY_ADDRESS]
ОГРН: [OGRN] · ИНН: [INN]
Email: [EMAIL]