ТЗ на Android-приложение для Ильи К.
1. Цель продукта
Нужно разработать мобильное приложение ParkTrack под Android, которое помогает пользователю:
- видеть парковки на карте;
- понимать текущую, историческую и прогнозную занятость парковок;
- искать парковку рядом с собой или рядом с выбранной точкой назначения;
- получать ранжированный список подходящих парковок;
- строить маршрут до выбранной парковки;
- в ранних версиях открывать внешний навигатор через deeplink;
- в следующих версиях использовать встроенный навигатор внутри приложения;
- получать обновления и перестроение маршрута при изменении ситуации с парковками.
Приложение должно быть полноценным пользовательским продуктом, соответствующим современным стандартам Android-разработки, UX, производительности и надёжности.
2. Роль мобильного приложения в системе
Мобильное приложение — это отдельный клиент ParkTrack для конечного пользователя.
В приложение входят:
- авторизация;
- пользовательская карта;
- работа с парковками;
- поиск парковки;
- маршрут;
- навигационный сценарий;
- уведомления.
В приложение не входят:
- админ-панель;
- управление камерами;
- управление парковочными зонами;
- управление источниками данных;
- управление пользователями;
- партнёрские кабинеты;
- аналитические кабинеты.
Эти части остаются только в веб-версии.
3. Этапность разработки
Разработка должна вестись поэтапно.
3.1 Этап 1 — базовый MVP приложения
На первом этапе обязательно реализовать:
- авторизацию;
- карту парковок;
- отображение текущей занятости;
- отображение истории и прогноза через селектор времени;
- фильтры парковок;
- карточку парковки;
- поиск по адресу / месту назначения;
- сценарий «Где припарковаться?»;
- ранжированный список парковок;
- построение маршрута до выбранной парковки;
- deeplink во внешний навигатор.
3.2 Этап 2 — расширенный мобильный сценарий
На следующем этапе реализовать:
- хранение активного маршрута;
- отслеживание маршрута в приложении;
- получение обновлений по маршруту;
- автоматическое перестроение маршрута;
- уведомления о смене парковки;
- встроенный навигатор внутри приложения.
3.3 Этап 3 — polished product
На финальном этапе:
- улучшение UX навигации;
- стабильная работа в фоне;
- тонкая работа с уведомлениями;
- восстановление маршрута после перезапуска приложения;
- дополнительная оптимизация производительности и энергопотребления.
4. Основные пользовательские сценарии
Пользователь должен иметь возможность:
- зарегистрироваться;
- войти в приложение;
- остаться авторизованным между запусками;
- открыть карту;
- увидеть парковки;
- понять их состояние по цвету и карточке;
- выбрать время: прошлое, настоящее, будущее;
- отфильтровать парковки;
- найти точку назначения;
- получить ранжированный список оптимальных парковок рядом с точкой;
- выбрать парковку;
- увидеть маршрут до неё;
- в ранней версии перейти во внешний навигатор;
- в последующих версиях ехать по встроенному маршруту;
- получать перестроение маршрута, если ситуация изменилась;
- получить уведомление о смене парковки.
5. Авторизация
Так как мобильное приложение разрабатывается отдельно, авторизация входит в функционал приложения.
5.1 Что нужно реализовать
Нужно реализовать:
- экран регистрации;
- экран логина;
- экран выхода из аккаунта;
- автоматическую проверку текущей сессии;
- сохранение сессии между запусками;
- защиту приватных экранов от неавторизованного доступа.
5.2 Поддерживаемые сценарии
Пользователь должен иметь возможность:
- зарегистрироваться по email и паролю;
- войти по email и паролю;
- после успешного входа попасть в приложение без повторного логина;
- после перезапуска приложения остаться авторизованным;
- выйти из аккаунта вручную;
- быть разлогинен или инвалидировании сессии.
5.3 Технические требования к auth
Нужно использовать backend-контур авторизации ParkTrack API.
Приложение должно уметь:
- получить токены/сессию;
- безопасно хранить access/refresh данные;
- автоматически обновлять access-токен;
- корректно обрабатывать
401; - переводить пользователя на экран логина, если сессия больше невалидна.
5.4 Хранение токенов
Обязательно:
- хранить чувствительные данные безопасно;
- использовать защищённое хранилище Android;
- не хранить токены в открытом SharedPreferences;
- не логировать токены;
- не показывать их в UI.
6. Карта
Нужно реализовать основной экран приложения — карту парковок.
Для мобильного клиента необходимо использовать Yandex MapKit.
На карте должны отображаться:
- базовая карта;
- пользовательское местоположение;
- парковочные зоны из нашего API;
- при наличии — дополнительные объекты UI, связанные с поиском и маршрутом.
Важно: источником истины о парковках остаётся наш backend, а не картографический SDK.
7. Отображение парковок
На карте должны отображаться парковочные зоны, полученные из нашего API.
7.1 Семантическая раскраска
Парковки должны отображаться цветом по смыслу.
Минимальные состояния:
- мест нет;
- свободно 1 место;
- свободных мест больше 1;
- данные низкой достоверности;
- зона неактивна / данных нет.
Базовая логика:
- красный — мест нет;
- жёлтый — свободно 1 место;
- светло-зелёный — свободных мест больше 1, но уверенность ниже порога;
- тёмно-зелёный — свободных мест больше 1 и уверенность выше порога;
- серый — нет данных / зона неактивна.
Порог уверенности должен быть вынесен в константу или конфигурацию клиента.
7.2 Различение типов парковок
Нужно визуально различать:
parallelstandard
Логика отображения:
parallel— как линия/полоса по центрам коротких сторон;standard— как полигон по геометрии зоны.
Также желательно уметь визуально различать:
- платная / бесплатная парковка;
- парковка для инвалидов;
- частная парковка;
location_type, если поле есть в API.
7.3 Производительность на карте
Нужно обеспечить:
- корректную работу при большом числе объектов;
- подгрузку по viewport через
bbox; - debounce на движение карты;
- минимизацию лишних перерисовок;
- отказ от постоянного полного пересоздания всех map objects.
8. Карточка парковки
При нажатии на парковку должна открываться карточка.
Карточка должна содержать:
- идентификатор или название парковки
- количество свободных мест и общую вместимость;
- уровень достоверности данных;
- дата и время последнего обновления информации;
- индикатор частной парковки, если применимо;
- индикатор инвалидной парковки, если применимо;
- тип парковки по способу постановки авто (parallel, standard);
- тип расположения;
- цену за час, либо зелёное "бесплатно"
На мобильном устройстве карточку лучше делать как bottom sheet.
9. Селектор времени
Нужен селектор времени с выбором времени как в прошлом, так и в будущем, отдельно выделить "Сейчас". Для отображения прошлого и будущего использовать разделы Occupancy и Forecasts нашего API соответственно. Для отображения настоящего использовать раздел Parking Zones нашего API.
Что должно меняться при выборе времени
- раскраска парковок;
- значения свободных и занятых мест, уверенности, времени обновления в карточках;
- список подходящих парковок и автоматически выбранная самая оптимальная парковка;
- ранжирование результатов.
UX
Должно быть всегда явно видно:
- какое точное время применено;
- как вернуться к режиму «сейчас».
10. Фильтры парковок
Нужно реализовать фильтры отображения парковок.
Должна быть возможность скрывать/показывать:
- парковки без свободных мест и настраивать минимальную степень уверенности в данных (достоверности)
- парковки дороже определённой цены за час (0 = бесплатно)
- частные парковки
- парковки по типу (уличные, дворовые, подземные и т.д.) -> чекбоксы
- парковки для инвалидов
- неактивные парковки (по умолчанию скрывать)
Требования:
- фильтры применяются без перезагрузки;
- влияют и на карту, и на результаты поиска;
- удобны для использования на мобильном устройстве;
- не мешают просмотру карты и взаимодействию с ней;
- должны открываться через отдельную панель / modal sheet;
- должны быть понятные активные состояния фильтров;
- в рамках текущего запуска приложения их состояние не должно теряться.
11. Поиск по адресу / месту назначения
Нужно реализовать поиск точки назначения через Yandex Search API.
Пользователь должен иметь возможность:
- ввести адрес или место;
- получить подсказки;
- выбрать результат;
- центрировать карту;
- использовать точку как
destinationдля сценария подбора парковки.
На мобильном устройстве важно:
- быстрый отклик;
- нормальная работа клавиатуры;
- понятный empty state;
- закрытие клавиатуры при выборе результата;
- удобный UX результатов поиска.
12. Сценарий «Где припарковаться?»
В приложении должна быть заметная функция «Где припарковаться?».
12.1 Логика
- берётся текущее местоположение пользователя;
- система получает оптимальные парковки рядом;
- пользователь видит ранжированный список;
- лучший вариант выделяется сразу;
- пользователь может переключиться на другой вариант;
- может открыть карточку;
- над предложенными вариантами должна быть панель фильтров с тем же набором, что и на основной карте, фильтры должны влиять на предложенные варианты парковок.
- при нажатии "Построить маршрут" пользователю предлагаются маршруты на выбор как в Яндекс Навигаторе, оптимальный должен быть выбран по умолчанию;
- может запустить навигацию (кнопка "В путь").
12.2 Поведение при отказе в геолокации
Если пользователь не дал доступ к геолокации:
- нужно показать понятное сообщение;
- объяснить, зачем нужен доступ;
- предложить вручную выбрать стартовую точку;
- предложить перейти в системные настройки разрешений.
13. Сценарий поиска парковки около точки назначения
Пользователь выбирает точку назначения.
После этого приложение должно:
- подобрать подходящие парковки рядом;
- применить фильтры;
- учесть текущее состояние, историю или прогноз;
- показать ранжированный список;
- выделить лучший вариант;
- подсветить варианты на карте;
- дать выбрать нужную парковку;
- построить маршрут до выбранной парковки.
13.1 Что учитывается при ранжировании
- расстояние от парковки до точки назначения;
- текущее количество свободных мест;
- прогноз на время прибытия;
- стоимость;
- confidence;
- фильтры пользователя.
13.2 Что должен видеть пользователь
- лучший вариант;
- альтернативы;
- текущие свободные места;
- прогноз свободных мест;
- стоимость;
- расстояние до точки назначения;
- оценку уверенности.
14. Построение маршрута
Маршрут в мобильном приложении нужен.
Но реализация может быть поэтапной.
14.1 Этап 1
Нужно реализовать:
- выбор парковки;
- запрос маршрута;
- отображение маршрута на карте;
- показ ETA и расстояния;
- deeplink во внешний навигатор.
На этом этапе встроенной навигации ещё нет.
14.2 Этап 2
Нужно реализовать встроенный навигатор внутри приложения.
Функционал:
- отображение текущей позиции пользователя;
- ведение по маршруту;
- обновление положения в реальном времени;
- отображение ETA;
- отображение расстояния до парковки;
- индикация схода с маршрута;
- пересчёт маршрута;
- смена целевой парковки при необходимости.
14.3 Требования к route preview
Даже до встроенного навигатора приложение должно уметь:
- выделить выбранную парковку;
- показать маршрут на карте;
- показать старт, цель и геометрию маршрута;
- показать ETA;
- показать расстояние.
15. Deeplink в навигатор
В первых версиях приложения нужно поддержать deeplink во внешний навигатор.
Требования:
- deeplink должен открываться из приложения по явной кнопке;
- пользователю должно быть понятно, что он переходит во внешний навигатор;
- нужно предусмотреть fallback, если навигатор не установлен;
- желательно поддержать приоритетно Яндекс Навигатор.
16. Встроенная навигация
Это функционал более позднего этапа, но он должен быть предусмотрен архитектурно уже сейчас.
Нужно проектировать приложение так, чтобы потом можно было встроить навигатор без полного переписывания клиента.
16.1 Что должна делать встроенная навигация
- вести пользователя по маршруту на автомобиле;
- обновлять маршрут при отклонении;
- следить за ETA;
- учитывать изменение парковочной ситуации;
- давать возможность завершить или отменить поездку;
- корректно работать при сворачивании и возврате в приложение.
17. Перестроение маршрута
В отличие от веб-карты, в мобильном приложении это обязательный функционал расширенной версии.
Если серверные данные показывают, что парковка назначения к моменту прибытия, вероятно, будет занята, приложение должно:
- получить обновлённые данные;
- пересчитать лучший вариант;
- перестроить маршрут;
- показать уведомление;
- объяснить пользователю, что парковка изменена.
17.1 Когда это должно происходить
Минимальные триггеры:
predicted_free_countстановится слишком низким;- вероятность наличия свободного места падает ниже порога;
- парковка становится неактивной;
- появляется явно более подходящая альтернатива.
17.2 Техническая реализация
Предпочтительно:
- push-обновления через WebSocket / SSE / push-сигнал от backend.
Допустимо на раннем этапе:
- polling по активному маршруту.
18. Уведомления
Мобильное приложение должно уметь показывать уведомления.
Минимально нужны уведомления:
- маршрут перестроен;
- парковка назначения изменилась;
- сессия истекла;
- не удалось получить геолокацию;
- нет связи с сервером;
- не удалось получить маршрут.
В расширенной версии:
- системные push-уведомления при смене маршрута, даже если приложение не на переднем плане.
19. Интеграция с API
Нужно использовать следующие разделы API:
Авторизация
POST /auth/registerPOST /auth/loginPOST /auth/logoutGET /auth/mePOST /auth/refresh, если refresh используется в финальной схеме
Пользователь
GET /users/me
Парковки
GET /zones?bbox=...&view=mapGET /zones/<zone_id>
История
GET /occupancy?...&view=mapGET /occupancy?...&view=series
Прогноз
GET /forecasts?...&view=mapGET /forecasts?...&view=series
Маршруты
POST /routing/searchPOST /routing/newGET /routing/<route_id>PUT /routing/<route_id>
Если для мобильного приложения не хватает каких-либо эндпоинтов или данных, необходимо зафиксировать это и инициировать изменение API.
20. Состояние приложения
Нужно централизованно управлять как минимум следующими состояниями:
- auth/session state;
- current user state;
- permissions state;
- map viewport state;
- user location state;
- selected time state;
- filters state;
- selected zone state;
- destination search state;
- ranked results state;
- selected route candidate state;
- route preview state;
- active navigation state;
- rerouting state;
- notifications state.
Логика состояния должна быть предсказуемой и тестируемой.
21. UX и feedback интерфейса
Интерфейс обязан давать понятную обратную связь на все действия.
Обязательные состояния:
- загрузка карты;
- загрузка зон;
- загрузка карточки;
- загрузка истории;
- загрузка прогноза;
- поиск адреса;
- применение фильтров;
- построение маршрута;
- перестроение маршрута;
- пустой результат;
- ошибка;
- успех.
Обязательно:
- skeleton/spinner;
- понятные empty states;
- тосты и баннеры;
- отсутствие “тихих” зависаний;
- понятные подписи кнопок и состояний;
- быстрый и современный UX.
22. Навигация по приложению
Нужно продумать понятную мобильную структуру экранов.
Минимально:
- splash / launch;
- login;
- registration;
- карта;
- экран/панель фильтров;
- экран/панель результатов;
- экран карточки парковки;
- экран preview маршрута;
- экран активной навигации;
- экран профиля / выхода;
- экран системных ошибок / состояния сети, если нужен отдельный UX.
Навигация по приложению должна быть согласованной с системной кнопкой Back и с жизненным циклом Android.
23. Android-специфичные требования
23.1 Платформа
Нужно разрабатывать нативное Android-приложение.
Предпочтительно:
- Kotlin;
- современный Android stack;
- актуальные практики lifecycle-aware разработки;
- современная архитектура, пригодная для масштабирования.
23.2 Работа с разрешениями
Обязательно корректно обрабатывать:
- доступ к геолокации;
- поведение при отказе;
- повторный запрос;
- переход в настройки;
- поведение в фоне, если будет нужна фоновая навигация.
23.3 Работа в фоне
На раннем этапе фоновые сценарии могут быть ограниченными.
На этапе встроенной навигации надо предусмотреть:
- корректную работу при сворачивании;
- foreground service, если это потребуется;
- отсутствие внезапных остановок критичных сценариев системой.
23.4 Работа при плохой сети
Нужно корректно обрабатывать:
- медленный интернет;
- обрыв сети;
- временную недоступность API;
- повторные запросы;
- сохранение последнего валидного состояния экрана.
24. Архитектурные требования
Приложение должно быть построено так, чтобы его можно было расширять без переписывания.
Обязательно:
- чистое разделение UI, domain и data логики;
- отдельный слой API;
- отдельный слой auth/session;
- отдельный слой картографической логики;
- отдельный слой маршрутизации и навигации;
- типизированные модели;
- явные состояния экрана;
- предсказуемая обработка ошибок.
25. Требования к качеству кода
Код должен быть:
- типизированным;
- модульным;
- читаемым;
- расширяемым;
- покрытым тестами там, где это разумно;
- без сильной связки между экранами и сетевым слоем;
- без бизнес-логики, размазанной по UI-компонентам.
26. Производительность
Нужно обеспечить:
- плавную работу карты;
- экономную работу с сетью;
- минимизацию лишних запросов;
- разумную работу с большим количеством зон;
- отсутствие тяжёлых полных перерисовок;
- быструю загрузку основных экранов;
- приемлемое энергопотребление.
27. Надёжность
Приложение должно корректно обрабатывать:
- отсутствие сети;
- недоступность API;
- таймауты;
- ошибки авторизации;
- отсутствие геолокации;
- пустые ответы;
- отсутствие результатов поиска;
- конфликты состояния при одновременной смене времени, фильтров и парковки;
- потерю маршрута;
- смену парковки назначения;
- возврат пользователя в приложение после сворачивания.
28. Безопасность
Нужно обеспечить:
- безопасное хранение токенов;
- корректную работу logout;
- невозможность случайной утечки чувствительных данных в логи;
- корректную обработку авторизации при истечении токенов;
- безопасную работу с deeplink и внешними интентами.
29. Нефункциональные требования
Согласованность с другими клиентами
- приложение должно визуально выглядеть схоже с веб-версией карты (которую делает Илья Р.);
- стиль приложения должен соответствовать общей стилистике ParkTrack;
- приложение должно использовать единую цветовую тему, характерную для ParkTrack (нейтральные цвета + оттенки зелёного);
- иконки должны быть в одном стиле с веб-версией;
- шрифты и визуальная иерархия должны быть согласованы с другими клиентами системы;
- взаимодействия должны быть похожими на другие клиенты ParkTrack, насколько это разумно для мобильной платформы;
- все элементы интерфейса должны быть адаптированы под общую стилистику продукта и не выглядеть чужеродно.
Требования к качеству продукта
- приложение должно выглядеть как готовый коммерческий продукт, а не как технический прототип;
- все основные пользовательские сценарии должны быть интуитивно понятными без дополнительного обучения;
- интерфейс должен соответствовать современным стандартам Android UX;
- визуальные состояния loading / success / error / empty должны быть оформлены последовательно и единообразно;
- приложение должно быть устойчиво к неидеальным условиям эксплуатации: плохой интернет, временные ошибки API, смена ориентации, сворачивание и возврат в приложение;
- ключевые пользовательские действия должны сопровождаться понятным и своевременным feedback.
30. Что считается готовым продуктом
Приложение можно считать готовым поэтапно.
Готовность первого этапа
Пользователь может:
- зарегистрироваться и войти;
- открыть карту;
- увидеть парковки;
- применить фильтры;
- выбрать время;
- искать точку назначения;
- получить ранжированные парковки;
- выбрать парковку;
- увидеть маршрут до неё;
- перейти во внешний навигатор.
Готовность второго этапа
Пользователь может:
- использовать встроенную навигацию;
- ехать по маршруту внутри приложения;
- получить автоматическое перестроение;
- получить уведомление о смене парковки;
- завершить поездку.
31. Ожидаемый результат
На выходе должен получиться полноценный Android-продукт, который:
- соответствует современным стандартам мобильной разработки;
- удобен для реального использования;
- интегрирован с ParkTrack API;
- позволяет искать парковки и ехать к ним;
- сначала поддерживает deeplink во внешний навигатор;
- затем эволюционирует во встроенный мобильный навигатор;
- устойчиво работает в реальных условиях сети и движения пользователя.