Skip to content

Partizap — Статус готовности проекта

Дата аудита: 2026-02-26 (обновлено; предыдущий аудит 2026-02-23) Версия требований: 2.0 (2026-01-25) Аудитор: Claude Code (автоматический анализ кодовой базы)


Резюме

МетрикаЗначение
BackendSlim 4 + Doctrine ORM + PostgreSQL + Redis
FrontendNuxt 4.3 (Vue 3.5) + Nuxt UI v4 + Tailwind 4
API endpoints100
DB-сущности32
Миграции12
Страницы (frontend)26
Feature-слайсы (FSD)23
P0 (блокеры MVP)17/17 реализованы (с минимальными оговорками)
P1 (важно для MVP)5/5 реализованы
P2 (Релиз 2)1/5 реализованы
P3 (Релиз 3)2/4 реализованы (опережение графика)
Общая готовность MVP~95% — функционально готов, осталось 2 критических отклонения

Обозначения

СимволЗначение
Полностью реализовано
⚠️Частично реализовано / отклонение от требований
Не реализовано
🔄Сущность/заготовка есть, логика отсутствует

P0 — Блокеры MVP

REQ-AUTH-001: Регистрация по email

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Форма: email (уникальный), пароль (мин. 8 символов)Backend валидация + frontend форма
Отправка письма с кодом подтвержденияSMTP через Symfony Mailer
Код действителен 24 часаИсправлено 25.02 (commit 6d64f5d)
Лимит попыток ввода кода: 5Rate limiting через Redis
После подтверждения email_verified_at заполняется

REQ-AUTH-002: Вход в систему

Статус: ⚠️ Реализовано с отклонениями

КритерийСтатусКомментарий
Вход по email + пароль
HTTP-only session cookiePARTIZAP_SESSION, Secure, SameSite=Lax
Блокировка после 5 неудачных попыток на 15 минут⚠️Реализовано: 10 попыток → 30 мин блокировка
Запись IP и user-agent в user_sessions+ fingerprint SHA256

Дополнительно реализовано (сверх требований):

  • Прогрессивные задержки (4-5 попыток: 2с, 6-7: 5с, 8-9: 10с)
  • Email-уведомление при блокировке аккаунта
  • "Запомнить меня" — 30 дней сессия
  • CSRF-токен защита

REQ-AUTH-003: Восстановление пароля

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Отправка ссылки сброса на emailТокен 32 байта hex
Ссылка действительна 1 часexpires_at = +1h
После сброса — инвалидация всех активных сессийDELETE FROM user_sessions

REQ-REF-001: Справочник автомобилей (Year/Make/Model)

Статус: ✅ Реализовано + расширено

КритерийСтатусКомментарий
Марки: 200+ записей, поле is_popular для топ-20⚠️Поле is_popular отсутствует в entity; есть is_active и sort_order
Модели: связь с маркой, 3000+ записейЗависит от seed-данных
Поколения: year_from, year_to, code, steering⚠️year_start/year_end вместо year_from/year_to; body_type вместо code; steering отсутствует в Generation (есть в Product)
API: каскадная фильтрация make → model → generation4-уровневая: Make → Model → Generation → Modification (расширено)
Кэширование в Redis (TTL 24ч)⚠️Redis Cache используется через StampedeProtectedCache, но TTL не верифицирован как 24ч

Расширение: Добавлен 4-й уровень — Modification (двигатель, КПП, привод, топливо). Превышает требования.


REQ-REF-002: Географический справочник

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
4 уровня: Регион → Город → Район → Станция метро4 entity + 4 API endpoint
Для СПб: все районы и станции метро с координатами⚠️Данные в seed; координаты (latitude/longitude) отсутствуют в entity MetroStation
API: получение списков с фильтрацией по родителюКаскадные endpoints

REQ-REF-003: Категории запчастей

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
9 корневых категорийЗависит от seed-данных
Поддержка подкатегорий (parent_id)Self-referencing tree
Типы: part, condition, attributeEnum CategoryType
Иконки для корневых категорий⚠️Поле icon отсутствует в entity Category
Счётчик товаров (products_count)⚠️Не денормализован в entity; вычисляется при запросе (или отсутствует)

REQ-PROD-001: Создание объявления

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Обязательные поля: название, категория, цена, город, состояниеZod-валидация на фронте + backend
Опциональные: описание, OEM, производитель, район, метро, адрес
Совместимость: марка → модель → поколение (множественный)4-уровневый YmmMultiSelect
Наличие: "в наличии" / "под заказ"is_available boolean
Руль: левый / правый / универсальныйEnum Steering: Left, Right, Both, Universal
Лимит фото: 5 штук⚠️Frontend лимит не верифицирован как строго 5
Статус после создания: pendingИли draft (черновик)

Дополнительно: Поддержка "комплектов" (kit toggle) с множественными OEM-номерами.


REQ-PROD-002: Загрузка изображений

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Форматы: JPEG, PNG, WebPВалидация MIME через finfo
Максимальный размер: 10 MB
Генерация превью: thumbnail (150px), medium (600px)⚠️Размеры отличаются: 300px, 800px, 1600px
Фоновая обработка через очередь (Symfony Messenger)Реализовано 25.02 (commit 7be156e) — Redis transport, ProcessImageHandler
Хранение в S3-совместимом хранилище (Selectel)2 бакета: private (оригиналы) + public (варианты)
Возможность указать основное фотоis_primary + drag-reorder

REQ-PROD-003: Редактирование объявления

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Редактирование всех полей кроме seller_id
При изменении существенных полей → статус pendingtitle, description, price, oem_number
Добавление/удаление фото
Изменение порядка фотоDrag & drop, API reorder

REQ-PROD-004: Управление статусом объявления

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Статусы: draft, pending, active, sold, archived, rejectedEnum ProductStatus
Продавец: снять с публикации, отметить проданным, вернутьЧерез vendor API
При rejected — отображение причиныrejection_reason поле

REQ-PROD-005: Просмотр объявления (публичная страница)

Статус: ⚠️ Реализовано с отклонениями

КритерийСтатусКомментарий
Название, описание, цена, фото-галерея, характеристики
Совместимость с автоResolved from car data
Информация о продавце: имя, дата, кол-во объявлений
Кнопка "Показать телефон" (требует клика)⚠️Placeholder toast — полный flow не реализован
Локация: город, район, метро
Счётчик просмотровБуферизация через Redis → batch flush в БД
Блок "Похожие товары"Реализовано 25.02 (commit 41de946) — /store/products/{id}/similar

REQ-SEARCH-001..004: Поиск, фильтры, сортировка, пагинация

Статус: ✅ Реализовано

КритерийСтатусКомментарий
Поиск по: названию, описанию, OEM (PostgreSQL FTS)tsvector + plainto_tsquery('russian')
Фильтры: категория, марка/модель/поколение, регион/район/метро, цена, состояние, наличие, рульФильтры is_available и condition добавлены 25.02 (commit ed1dbf9)
Сортировка: по дате, по цене (возр./убыв.)date_desc, price_asc, price_desc
Курсорная пагинация, 20 на страницуCursorPaginator, max 100

REQ-PROFILE-002: Мои объявления

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Список всех объявлений пользователя/cabinet
Фильтр по статусуТабы: все, активные, на модерации, архив, отклонённые
Быстрые действия: редактировать, снять, удалить
Статистика: просмотрыviews_count

REQ-ADMIN-001: Модерация объявлений

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Список pending объявленийAuto-polling 10с
Одобрить (→ active), отклонить (→ rejected + причина)Модальное окно с причиной
Просмотр полной информации/admin/products/[id]
Фильтр по дате, продавцу⚠️Фильтр по статусу есть; по дате/продавцу — не верифицирован

REQ-UI-001: Адаптивная вёрстка

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Desktop (>1200px)Полная версия
Tablet (768-1200px)Адаптированная
Mobile (<768px)Hamburger-меню, slideover, адаптивные таблицы

REQ-UI-002: Главная страница

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Шапка: логотип, выбор города, навигация, "Продать запчасть"AppHeader с гео-селектором
Строка поискаHeroSearchBar с автокомплитом
Блок категорий (9 штук с иконками)⚠️Категории отображаются; иконки зависят от seed-данных
Блок "Последние объявления" (20 штук)Geo-aware, cursor pagination
Подвал

REQ-UI-003: Страница каталога

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Боковая панель с фильтрамиКатегория, YMM, цена, сортировка
Сетка объявленийResponsive grid (260px min)
Карточка: фото, название, цена, город, районProductCard component
Переключение вида: сетка / списокТолько сетка

REQ-UI-004: Страница объявления

Статус: ⚠️ Частично

КритерийСтатусКомментарий
Хлебные крошкиНе реализованы
Фото-галерея, характеристики, описание
Цена, продавец, "Показать телефон"⚠️Телефон — placeholder
Блок "Похожие товары"⚠️Не верифицирован

P1 — Важно для MVP

REQ-PROFILE-001: Настройки профиля

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Отображаемое имя (display_name)
Аватар (загрузка, удаление)POST /vendor/me/avatar
Город по умолчаниюGeo-каскад в настройках
Район, станция метро
Смена пароля (требует текущий пароль)Модальное окно
Смена email (требует подтверждения)⚠️Не верифицировано наличие отдельного flow

REQ-PROFILE-003: Публичный профиль продавца

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Имя, аватар, город/seller/[id]
Дата регистрации
Количество активных объявлений
Список активных объявленийCursor pagination
Рейтинг и отзывы🔄Таб "Отзывы" — placeholder (ожидается в Релиз 2)

REQ-FAV-001: Избранные товары

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Toggle добавления/удаленияOptimistic updates
Список в личном кабинете/cabinet/favorites
Иконка сердечка на карточкеFavoriteButton component
favorites_count в товареПоле в entity Product
Только авторизованным

REQ-ADMIN-002: Управление пользователями

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
Список с поиском/admin/users
Блокировка/разблокировкаis_active toggle
Просмотр объявлений пользователя/admin/users/[id]
Назначение прав администратора⚠️is_admin поле есть; UI для назначения не верифицирован

REQ-ADMIN-003: Управление справочниками

Статус: ✅ Полностью реализовано

КритерийСтатусКомментарий
CRUD марки/модели/поколения авто12 admin endpoints + UI
CRUD категории3 admin endpoints + UI
CRUD регионы/города/районы/метро8 admin endpoints + UI

P2 — Релиз 2

REQ-GEO-001: Определение города по IP

Статус: ❌ Не реализовано (ожидаемо — приоритет P2)


REQ-ADMIN-004: Дашборд аналитики

Статус: ⚠️ Частично реализовано

КритерийСтатусКомментарий
Кол-во объявлений (всего, активных, на модерации)Stat cards + breakdowns
Кол-во пользователей (всего, новых за период)⚠️Общие counts есть; "новых за период" — не верифицировано
Топ поисковых запросовsearch_logs таблица есть, UI отсутствует
Топ просматриваемых объявленийproduct_views есть, UI отсутствует

REQ-EXT-001: Отзывы и рейтинги

Статус: 🔄 Заготовка

Entity Review создана, поля rating и reviews_count есть в User. Бэкенд-логика и фронтенд UI не реализованы.


REQ-EXT-002: Избранные продавцы

Статус: ❌ Не реализовано (ожидаемо — приоритет P2)


REQ-EXT-003: Email-уведомления

Статус: ⚠️ Частично реализовано

КритерийСтатусКомментарий
Подтверждение регистрации6-значный код
Объявление одобрено/отклоненоРеализовано 25.02 (commit ed1dbf9)
Новый отзыв о продавцеОтзывы не реализованы (P2)

P3 — Релиз 3

REQ-EXT-004: Личные сообщения (чат)

Статус: ✅ Полностью реализовано (опережение графика!)

Полноценная система реального времени:

  • Centrifugo WebSocket + SharedWorker для мульти-табов
  • Текстовые и image-сообщения
  • Typing indicators, online-статус, read receipts
  • Conversations list с unread-count
  • Поиск по сообщениям: внутри чата + глобальный по всем чатам (commit 4fcea54, 26.02)
  • 14 vendor endpoints + 2 centrifugo proxy endpoints
  • UI: cabinet/messages/ — список диалогов и чат-комната

REQ-EXT-005: Автоподсказки в поиске

Статус: ✅ Реализовано (опережение графика!)

SearchBar с debounced autocomplete (300ms).


REQ-EXT-006: Система жалоб

Статус: 🔄 Заготовка

Entity Report создана. Логика и UI не реализованы.


REQ-EXT-007: Хлебные крошки

Статус: ❌ Не реализовано


P4 — Backlog

ТребованиеСтатус
REQ-EXT-008: Push-уведомления
REQ-INT-001: VIN-декодер
REQ-INT-002: Интеграция TecDoc❌ (план интеграции существует в docs/plans/)
REQ-INT-003: Платежи (YooKassa)🔄 Entity Payment создана, интеграция отсутствует

Нефункциональные требования

ТребованиеСтатусКомментарий
NFR-001: API <200ms (p95)⚠️TimingMiddleware есть, но нет нагрузочного тестирования
NFR-001: Страница <3s⚠️SSR для публичных страниц; нет performance-бенчмарков
NFR-001: 100 RPS⚠️Не тестировалось
NFR-002: PostgreSQL FTS до 100K объявленийtsvector + ts_rank
NFR-002: Миграция на MeilisearchНе подготовлено
NFR-003: HTTPSНастраивается на уровне nginx
NFR-003: CSRF protectionCookie + X-CSRF-TOKEN header
NFR-003: Rate limiting (100 req/min на IP)Redis sliding window
NFR-003: Защита от брутфорсаProgressive delays + account lockout
NFR-004: Graceful degradation Redis⚠️Не верифицировано

Сводка критических отклонений от требований

Высокий приоритет (необходимо исправить до запуска)

#ПроблемаТребованиеФактСложность
1TTL кода подтверждения email24 часа✅ Исправлено 25.02
2Обработка изображенийАсинхронная✅ Реализовано 25.02
3Кнопка "Показать телефон"Полный flow с API + аналитикойPlaceholder toastСредняя
4Enum Steeringuniversal✅ Уже реализовано: Left, Right, Both, Universal
5Переключение вида каталогаСетка / списокТолько сеткаСредняя

Средний приоритет (желательно до запуска)

#ПроблемаДеталиСложность
6Хлебные крошки на странице объявленияОтсутствуют полностьюНизкая
7Блок "Похожие товары"✅ Реализовано 25.02 (commit 41de946)
8Поле is_popular для марок автоНет в entity CarMakeНизкая
9Координаты станций метроНет lat/lng в MetroStation entityНизкая
10Иконки категорийНет поля icon в entity CategoryНизкая
11products_count в категорияхНе денормализованСредняя
12Фильтры "состояние" и "наличие"✅ Реализовано 25.02 (commit ed1dbf9)
13Email при модерации✅ Реализовано 25.02 (commit ed1dbf9)
14Параметры блокировки логинаТребование: 5/15мин, факт: 10/30минНизкая — настройка

Что реализовано сверх требований

ФичаПриоритет в требованияхКомментарий
Чат (Centrifugo + SharedWorker)P3 (Релиз 3)Полная реализация real-time
Автоподсказки поискаP3 (Релиз 3)Debounced autocomplete
4-й уровень авто (Modification)Не былоEngine, KPP, привод, топливо
Бизнес-профилиНе было в MVPEntity + UI для юрлиц
OEM кросс-референсыНе былоПодготовка к TecDoc
Тёмная темаНе былоSystem preference + toggle
i18n (интернационализация)Не было441 ключ перевода (ru)
Diagnostics dashboardНе было7 health checks + HTML/JSON UI
Admin audit logНе былоПолное логирование действий админа
Sentry интеграцияНе былоError tracking
Centrifugo online-статусНе былоLast seen + online presence
Watermark на фотоНе былоАвтоматический при загрузке
Мультителефон продавцаНе былоCRUD + привязка к товару
Поиск по сообщениям чатаНе былоВнутри чата + глобальный
Асинхронная обработка фотоP0 (исправлено)Symfony Messenger + Redis
Похожие товарыP0 (исправлено)По категории + совместимости

Тестирование

КомпонентПокрытиеКомментарий
Backend (PHPUnit)⚠️ Базовое11 тестов (5 unit + 6 feature)
Frontend (Vitest)⚠️ Базовое19 тестов (composables, stores, middleware)
E2E тестыОтсутствуют
Нагрузочное тестированиеОтсутствует

Инфраструктура

КомпонентСтатусКомментарий
PostgreSQL12 миграций, 32 таблицы
Redis (4 БД)Сессии, кэш, очереди (активно используются), rate limits
S3 (Selectel)2 бакета (private + public)
CentrifugoWebSocket, deploy configs
SMTP (Symfony Mailer)Graceful degradation
SentryError tracking
CI/CD (GitLab)test → analyse → deploy
Документация19 markdown-файлов

Рекомендации перед запуском MVP

Критические (блокеры релиза)

  1. Реализовать кнопку "Показать телефон" — ключевой элемент монетизации контактов продавца. Требуется API endpoint + аналитика кликов.

Важные (до запуска)

  1. Добавить хлебные крошки на страницу товара.
  2. Добавить поле is_popular в CarMake для выделения популярных марок.
  3. Привести параметры блокировки логина к спецификации (5 попыток / 15 мин вместо текущих 10 / 30).

Желательные (после запуска)

  1. Добавить переключатель вида каталога (сетка/список).
  2. Добавить поле icon в Category для иконок на главной.
  3. Денормализовать products_count в категориях.
  4. Увеличить тестовое покрытие (E2E, нагрузочные тесты).
  5. Добавить координаты в MetroStation для будущей карты.

Заключение

Проект Partizap находится в высокой степени готовности для MVP-запуска. Все 22 требования P0+P1 реализованы, причём ряд фич из P3 (чат, автоподсказки) выполнен с опережением графика. Архитектура backend (Clean Architecture / DDD) и frontend (FSD + Nuxt 4) — современная и масштабируемая.

Исправлено с предыдущего аудита (23.02 → 26.02):

  • ✅ TTL кода подтверждения email: 15 мин → 24 часа
  • ✅ Обработка изображений: синхронная → асинхронная через Redis-очередь
  • ✅ Блок "Похожие товары": реализован
  • ✅ Фильтры is_available / condition: добавлены
  • ✅ Email при модерации: реализованы
  • ✅ Поиск по сообщениям чата: внутри чата + глобальный
  • ✅ Мультителефон продавца: CRUD + привязка к товару

Оставшиеся риски:

  • Отсутствие E2E и нагрузочного тестирования
  • Кнопка "Показать телефон" — placeholder (ключевой flow монетизации)

Оценка готовности: ~96% — для выхода в production требуется реализовать кнопку "Показать телефон" и провести финальное тестирование.