ТЗ на MVP веб-карты парковок для Ильи Р.
1. Цель MVP
Нужно реализовать пользовательскую часть сайта с картой парковок, где пользователь может:
- открыть карту;
- увидеть парковочные зоны;
- понять, где есть свободные места;
- выбрать время просмотра: прошлое, настоящее, будущее;
- отфильтровать парковки;
- найти адрес или точку назначения;
- получить ранжированный список оптимальных парковок рядом с выбранной точкой или рядом с собой;
- увидеть маршрут до выбранной парковки и получить deeplink в навигатор;
- открыть карточку парковки и посмотреть подробную информацию.
В рамках MVP веб-карты не нужно реализовывать:
- встроенную навигацию;
- автоматическое перестроение;
- уведомления о смене парковки по маршруту;
- хранение активного маршрута;
- turn-by-turn сценарии.
2. Границы задачи
Нужно реализовать:
- главную карту парковок;
- отображение парковок и их занятости;
- фильтры парковок;
- карточку парковки;
- селектор времени;
- поиск точки назначения по тексту;
- кнопку «Где припарковаться?» для поиска ближайших к пользователю оптимальных парковок;
- подбор подходящих парковок около точки назначения (при построении маршрута куда-либо), ранжированный список;
- единый с другими разделами сайта UI и корректный UX;
- интеграцию с общей авторизацией и общей сессией сайта.
Не входит в задачу:
- логин/регистрация;
- управление пользователями;
- управление камерами;
- управление зонами;
- управление источниками данных;
- личные кабинеты;
- административные разделы;
- аналитические кабинеты;
- навигация.
3. Общие требования к интеграции в сайт
Эта часть должна быть частью единого сайта.
Обязательные требования:
- один домен parktrack.live;
- одна пользовательская сессия;
- после логина пользователь не должен заново входить в раздел карты;
- нужно использовать общий auth/session механизм сайта;
- внешний вид должен совпадать с остальным продуктом.
Нужно использовать общие:
- layout;
- header/navigation;
- UI-компоненты;
- стили;
- API client;
- типы и DTO;
- обработку ошибок;
- систему уведомлений.
Для выполнения этих условий будет необходимо провзаимодействовать с Мишей и разработать общие UI компоненты, договориться о формате авторизации и создании сессий, создать единую точку входа для запуска сайта.
4. Основной сценарий пользователя в MVP
Пользователь открывает карту и должен иметь возможность:
- увидеть парковки на карте;
- понять текущую ситуацию с занятостью;
- выбрать интересующее время (как в прошлом, так и в будущем);
- применить фильтры
- нажать на парковку;
- посмотреть её карточку
- найти адрес/место назначения, введя текст в строку поиска;
- получить подходящие парковки рядом с этой точкой;
- увидеть ранжированный список вариантов;
- выбрать наиболее интересующую парковку;
- построить маршрут до выбранной парковки и получить deeplink в навигатор.
5. Карта
Нужно реализовать карту на основе Yandex Maps API.
На карте должны использоваться:
- базовая карта Яндекса;
- парковочный слой Яндекса;
- собственные парковочные зоны из нашего API;
- построение маршрута до выбранной парковки.
Важно:
- бизнес-истина по занятости, прогнозам, фильтрам и доступности парковок приходит из нашего API;
- слой Яндекса используется как картографическая основа и дополнительный визуальный слой;
- логика продукта должна строиться вокруг данных ParkTrack API.
6. Загрузка данных на карте
Нужно загружать зоны не все сразу, а по текущему viewport карты.
Для этого:
- вычисляется
bbox; - выполняется запрос в API с
bbox; - используется режим ответа
view=map; - на карте отображаются только объекты, попадающие в текущую область.
Обязательные требования:
- debounce на перемещение карты;
- отсутствие лишних повторных запросов;
- отсутствие полного сброса карты при каждом изменении.
7. Отображение парковок
На карте должны отображаться парковочные зоны из нашего API.
7.1 Семантическая раскраска
Парковки должны быть раскрашены по смыслу.
Минимальные состояния:
- мест нет;
- свободно 1 место;
- места есть;
- данные низкой достоверности;
- зона неактивна или нет данных.
Базовая логика цветов:
- красный — мест нет;
- жёлтый — свободно 1 место;
- светло-зелёный — свободно >2 мест, но confidence < CONFIDENCE_THRESHOLD (например, 0.75);
- тёмно-зелёный — свободно >2 мест и confidence >= CONFIDENCE_THRESHOLD;
- серый — нет данных / зона неактивна.
7.2 Различие типов парковок
Нужно визуально различать:
parallel- отрисовывается полосой, соединяющей центры коротких сторон четырехугольника, указанного в API;standard- отрисовывается четырехугольником по точкам указанным в API
Также желательно настроить разное визуальное отображение для следующего:
- платная / бесплатная парковка;
- парковка для инвалидов;
- частная парковка;
location_type, если поле есть в API.
8. Карточка парковки
При нажатии на парковку должна открываться карточка.
В карточке нужно показывать:
- идентификатор или название парковки
- количество свободных мест и общую вместимость;
- уровень достоверности данных;
- дата и время последнего обновления информации;
- индикатор частной парковки, если применимо;
- индикатор инвалидной парковки, если применимо;
- тип парковки по способу постановки авто (parallel, standard);
- тип расположения;
- цену за час, либо зелёное "бесплатно"
9. Селектор времени
Нужен селектор времени с выбором времени как в прошлом, так и в будущем, отдельно выделить "Сейчас". Для отображения прошлого и будущего использовать разделы Occupancy и Forecasts нашего API соответственно. Для отображения настоящего использовать раздел Parking Zones нашего API.
Что должно меняться при выборе времени
- раскраска парковок;
- значения свободных и занятых мест, уверенности, времени обновления в карточках;
- список подходящих парковок и автоматически выбранная самая оптимальная парковка;
- ранжирование результатов.
UX
Должно быть всегда явно видно:
- какое точное время применено;
- как вернуться к режиму «сейчас».
10. Фильтры парковок
Нужно реализовать фильтры отображения парковок.
Должна быть возможность скрывать/показывать:
- парковки без свободных мест и настраивать минимальную степень уверенности в данных (достоверности)
- парковки дороже определённой цены за час (0 = бесплатно)
- частные парковки
- парковки по типу (уличные, дворовые, подземные и т.д.) -> чекбоксы
- парковки для инвалидов
- неактивные парковки (по умолчанию скрывать)
Требования к фильтрам:
- работают без перезагрузки страницы;
- влияют и на карту, и на список результатов;
- визуально понятно, какие фильтры активны;
- не мешают просмотру карты и взаимодействию с ней;
- фильтры удобно найти, открыть и использовать на любом устройстве;
- состояние фильтров не теряется в рамках текущего сеанса страницы.
11. Поиск по адресу / месту назначения
Нужно реализовать строку поиска с использованием Yandex Search API.
Пользователь должен иметь возможность:
- ввести адрес или название места;
- получить подсказки;
- выбрать нужный результат;
- центрировать карту на выбранной точке;
- использовать эту точку как основу для поиска парковок рядом.
В MVP это не маршрутная точка, а просто целевая точка поиска парковки.
12. Сценарий «Где припарковаться?»
На карте нужна отдельная функция «Где припарковаться?». Стоит сделать отдельную кнопку с этой или похожей надписью/иконкой, которую можно нажать первым кликом.
Логика
- берётся текущее местоположение пользователя;
- система подбирает ближайшие подходящие парковки;
- пользователь получает ранжированный список вариантов;
- может выбрать один из них;
- наиболее оптимальный вариант уже выбран автоматически, но его можно менять;
- можно открыть карточку парковки каждого варианта и посмотреть подробности;
- над предложенными вариантами должна быть панель фильтров с тем же набором, что и на основной карте, фильтры должны влиять на предложенные варианты парковок.
- 2 или 3 кликом должна быть кнопка "Построить маршрут";
- при нажатии "Построить маршрут" пользователю предлагаются маршруты на выбор как в Яндекс Навигаторе, оптимальный должен быть выбран по умолчанию;
- при выборе маршрута пользователь получает deeplink в навигатор (кнопка "В путь").
При отказе в геолокации
Нужно:
- показать понятное сообщение;
- предложить вручную указать стартовую точку;
- не ломать интерфейс.
13. Сценарий поиска парковки около точки назначения
Пользователь выбирает точку назначения через поиск или по карте.
После этого система должна:
- подобрать подходящие парковки рядом с точкой;
- применить фильтры;
- учитывать текущее состояние, историю или прогноз в зависимости от выбранного времени;
- показать ранжированный список парковок;
- выделить лучший вариант;
- подсветить варианты на карте.
Для поиска оптимальной парковки используется API.
Что учитывается при ранжировании
- расстояние от парковки до точки назначения;
- число свободных мест;
- прогноз свободных мест на выбранное время;
- стоимость;
- confidence;
- фильтры пользователя.
Что пользователь должен увидеть
- лучший вариант;
- альтернативные варианты;
- расстояние до точки назначения;
- текущие свободные места;
- прогноз на выбранное время;
- стоимость;
- confidence.
14. Список результатов
Результаты поиска парковок должны отображаться отдельным списком/панелью.
Для каждой парковки в списке нужно показывать:
- тип/название;
- стоимость;
- текущее количество свободных мест;
- прогноз на выбранное время, если применимо;
- расстояние до точки назначения;
- confidence;
- метку лучшего варианта.
При выборе элемента списка:
- объект подсвечивается на карте;
- карта центрируется на нём;
- открывается карточка парковки.
15. Что должно происходить при смене времени
Нужно жёстко разделять режимы данных.
Если выбрано прошлое время:
- отображаются только исторические данные;
- нельзя продолжать показывать текущее состояние как будто это история.
Если выбрано будущее время:
- отображаются прогнозные данные;
- карточки и списки должны тоже перейти в прогнозный режим.
Нельзя смешивать текущие, исторические и прогнозные данные в одном пользовательском состоянии.
16. Интеграция с API
Нужно использовать следующие разделы API.
Для карты парковок
GET /zones?bbox=...&view=mapGET /zones/<zone_id>
Для исторических данных
GET /occupancy?...&view=mapGET /occupancy?...&view=series
Для прогнозных данных
GET /forecasts?...&view=mapGET /forecasts?...&view=series
Для авторизации и сессии
GET /auth/meGET /users/me
Список неполный и документация API может дополняться, если сейчас не хватает данных для реализации чего-либо. Если нужно что-то добавить в API, обращаться к Никите.
17. Состояние приложения
Нужно централизованно хранить как минимум:
- auth/session state;
- current user state;
- map viewport state;
- selected time state;
- filters state;
- selected zone state;
- destination search state;
- ranked results state;
- selected_route_candidate;
- route_preview_state.
Состояния не должны быть хаотично распределены по компонентам.
18. UX и feedback интерфейса
Интерфейс должен всегда давать пользователю понятный feedback.
Обязательные состояния:
- загрузка карты;
- загрузка парковок;
- загрузка карточки;
- загрузка исторических данных;
- загрузка прогноза;
- поиск адреса;
- применение фильтров;
- пустой результат;
- ошибка API;
- успешная загрузка данных.
Что обязательно:
- skeleton/spinner при загрузке;
- empty-state при отсутствии результатов;
- тост/баннер при ошибках;
- понятные подписи и названия действий;
- отсутствие «тихих» зависаний.
19. Desktop и mobile
Интерфейс должен быть адаптивным.
Desktop
- карта;
- панель фильтров;
- панель результатов;
- карточка парковки.
Mobile
- карта как основной слой;
- фильтры и результаты через drawer/bottom sheet/overlay;
- удобные тапы;
- без перегруженности интерфейса.
20. Нефункциональные требования
Качество кода
Код должен быть:
- типизированным;
- модульным;
- расширяемым;
- читаемым;
- без жёсткой связки UI и API-логики.
Производительность
Нужно:
- не рендерить лишние объекты;
- не перегружать карту лишними данными;
- минимизировать ненужные запросы;
- не делать тяжёлых полных перерисовок без необходимости.
Надёжность
Нужно корректно обрабатывать:
- пустые ответы API;
- отсутствие геолокации;
- ошибки карты;
- ошибки API;
- отсутствие результатов поиска;
- конфликты состояний при одновременной смене времени, поиска и фильтров.
Согласованность с другими клиентами
- интерфейс должен визуально выглядеть схоже с мобильным приложением (которое делает Илья Киселев);
- стиль сайта должен быть единым как для карты, так и для личных кабинетов (которые делает Миша)
- сайт должен использовать единую цветовую тему, характерную для ParkTrack (нейтральные цвета + оттенки зелёного);
- иконки должны быть в одном стиле с остальным сайтом;
- шрифты должны быть такими же, как на остальном сайте;
- взаимодействия должны быть похожими на остальной сайт (например, открытие карточки парковки должно работать так же, как открытие карточки камеры в другом разделе сайта).
- все элементы интерфейса должны быть адаптированы под общую стилистику сайта и не выделяться как чужеродные.
21. Что считается готовым MVP
MVP считается готовым, если пользователь может:
- открыть карту;
- увидеть парковки из нашего API;
- увидеть семантическую раскраску парковок;
- применять фильтры;
- выбирать время в прошлом, настоящем и будущем;
- видеть корректные данные для каждого режима времени;
- искать точку назначения по тексту;
- получать подбор парковок рядом с точкой назначения;
- использовать сценарий «Где припарковаться?»;
- видеть ранжированный список парковок;
- строить маршрут до выбранной парковки и получать deeplink в навигатор;
- открывать карточку парковки;
- пользоваться всем этим как частью единого сайта без повторного логина.
22. Что не входит в MVP
В MVP не нужно реализовывать:
- встроенную навигацию;
- автоматическое перестроение;
- уведомления о смене маршрута;
- хранение активного маршрута;
- пошаговую навигацию;
23. Ожидаемый результат
На выходе должна быть готова frontend-часть единого сайта, которая:
- визуально выглядит как часть одного продукта;
- использует общую авторизацию;
- работает в рамках общей сессии;
- отображает парковки на карте;
- поддерживает текущее, историческое и прогнозное отображение;
- умеет фильтровать парковки;
- умеет искать адрес и подбирать парковки рядом;
- показывает ранжированные результаты и строит маршрут до выбранной парковки;
- даёт понятный и современный пользовательский опыт.