Files
gnezim 5d512e146e
CI / ci (push) Failing after 37s
Deploy / build-and-deploy (push) Failing after 6s
Add image/font assets from Angular and fix CSS url() resolution
- Copy 134 image files and 28 font files from ClientApp/src/assets/
  to public/assets/ for browser-side serving
- Set tools.cssLoader.url=false in modern.config.ts so the CSS loader
  leaves url() references as-is instead of trying to resolve them as
  webpack modules
- Add .playwright-mcp/, coverage/, and screenshot artifacts to .gitignore
2026-04-15 19:01:56 +03:00

316 lines
35 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
**ФУНКЦИОНАЛЬНЫЕ ТРЕБОВАНИЯ**
Раздел «Карта полетов» в системе «Онлайн-Табло и Расписание
**1.**       **Термины и** **определения**
| | |
|---|---|
|**Сокращение**|**Определение**|
|Заказчик|ПАО «Аэрофлот»|
|Исполнитель|ООО «ТИМ»|
|Категория города|Классификация городов по определённым признакам, используемая для их отображения на карте в зависимости от масштаба|
|ОС|Операционная система|
|ПАО «Аэрофлот»|Публичное акционерное общество «Аэрофлот – российские авиалинии», он же Заказчик|
|ПО|Программное обеспечение|
|Пользователь|Физическое лицо, осуществляющее бронирование авиабилета и дополнительных услуг через основной сайт|
|Сайт|Основной сайт ПАО «Аэрофлот» http://www.aeroflot.ru|
|Система|Система сбора, обработки и предоставления актуальной информации о фактическом выполнении рейсов ПАО «Аэрофлот» в режиме реального времени, а также представление информации о движении (расписание) рейсов ПАО «Аэрофлот».|
|Тайл|Квадратный фрагмент цифровой карты фиксированного масштаба|
|ФТ|Функциональные требования|
|API|Интерфейс программирования приложений, интерфейс прикладного программирования) — набор готовых классов, процедур, функций, структур и констант, предоставляемых приложением (библиотекой, сервисом) или операционной системой для использования во внешних программных продуктах|
|IATA|Международная ассоциация воздушного транспорта (International Air Transport Association)|
|QGIS|Геоинформационная система для подготовки картографических тайлов|
|S3 (Simple Storage Service)|Сервис, где хранятся цифровые данные большого объема. Работает по одноименному протоколу. S3 – это вариант «плоского» (не иерархического) хранилища. С точки зрения системы все объекты равнозначны, поэтому в S3-хранилище удобно долго хранить разнородную информацию и быстро получать к ней доступ|
**2.**       **Основные положения**
**Цель изменений**
Карта полетов предназначена для наглядного отображения маршрутной сети авиакомпании ПАО «Аэрофлот». С её помощью пользователи смогут визуально оценить географическое покрытие рейсов, узнать, какие города доступны для вылета и прилёта, а также перейти к бронированию на интересующее направление.
Внедрение интерактивной карты полётов на сайте авиакомпании повысит прозрачность маршрутной сети для клиентов, улучшит взаимодействие с пользователями и станет дополнительным элементом продвижения доступных направлений.
В рамках задачи будет разработан и добавлен новый раздел «Карта полетов» в Систему «Онлайн-Табло и Расписание».
## Описание целевых бизнес-процессов
## Бизнес-процесс «Первое открытие раздела»
Пользователь открывает раздел «Карта полетов».
Система запрашивает разрешение на определение местоположения.
Пользователь разрешает определить свое местоположение:
Система автоматически определяет ближайший к пользователю аэропорт, из которого выполняются рейсы авиакомпании Аэрофлот, и заполняет поле «Город вылета».
На карте строятся дуги маршрутов. Поле «Город прилета» заполнено плейсхолдером «Куда».
Переключатели «Внутренние рейсы» и «Международные внутренние рейсы» не выбраны.
Переключатель «Показать только рейсы с пересадкой» заблокирован.
Поле «Дата рейса» заполняется ближайшим днем выполнения рейсов, начиная с текущей даты.
Пользователь запрещает определить свое местоположение:
Поля «Город вылета» и «Город прилета» заполнены плейсхолдерами «Откуда» и «Куда» соответственно.
Переключатели «Внутренние рейсы», «Международные регулярные рейсы» и «Показать только рейсы с пересадкой» заблокированы.
Поле «Дата рейса» заполнено плейсхолдером «ДД.ММ.ГГГГ».
## Бизнес-процесс «Выбор маршрута с помощью карты»
Пользователь открывает раздел «Карта полетов». Поля «Город вылета» и «Город прилета» пусты.
Первый клик: Пользователь нажимает на город на карте (например, Москва). Система заполняет поле «Город вылета» значением «Москва», выделяет город на карте оранжевой точкой, отображая дуги ко всем доступным для прилета городам. Переключатели «Внутренние рейсы» и «Международные регулярные рейсы» становятся доступны. Поле «Дата рейса» заполняется ближайшим днем выполнения рейсов из города вылета, начиная с текущей даты.
Второй клик: Пользователь нажимает на другой город на карте (например, Самара). Система заполняет поле «Город прилета» значением «Самара», строит дугу маршрута «Москва - Самара», переключатель «Показать только рейсы с пересадкой» становится доступен, поле «Дата рейса» заполняется ближайшим днем выполнения рейсов по выбранному маршруту, начиная с текущей даты. Над городом прилета отображает окно с кнопкой «Купить билет».
Третий клик: Пользователь нажимает на город на карте (например, Санкт-Петербург). Система очищает поля «Город вылета» и «Город прилета», после чего заполняет поле «Город вылета» значением «Санкт-Петербург» и снова отображает дуги ко всем доступным городам. Переключатели «Внутренние рейсы» и «Международные регулярные рейсы» становятся доступны, переключатель «Показать только рейсы с пересадкой» блокируется. Поле «Дата рейса» заполняется ближайшим днем выполнения рейсов для заданного города вылета, начиная с текущей даты.
## Бизнес-процесс «Масштабирование и навигация»
Пользователь открывает раздел «Карта полетов».
Пользователь масштабирует карту колесом мыши, кнопками «+» и «-», расположенными в левом верхнем углу карты или жестами на мобильном устройстве.
При изменении масштаба система отображает города в соответствии с их категорией (см. Раздел 3.2 Требования к визуальной интерактивной карте).
## Бизнес-процесс «Фильтрация рейсов»
Пользователь открывает раздел «Карта полетов».
Пользователь заполняет поле «Город вылета».
Становятся доступны переключатели:
«Внутренние рейсы» – при активации отображаются только маршруты, выполняемые внутри территории России. Международные направления скрываются.
«Международные регулярные рейсы» – отображаются маршруты, имеющие в качестве одного из пунктов за пределами России. Внутренние направления скрываются.
Пользователь заполняет поле «Город прилета».
Становится доступен переключатель:
«Показать только рейсы с пересадкой» – система скрывает прямые маршруты и показывает рейсы с возможной стыковкой, отображая такие рейсы на карте пунктирными линиями.
Если между городами нет прямых рейсов, то переключатель «Показать только рейсы с пересадкой» включается автоматически.
## Бизнес-процесс «Выбор даты рейса»
Пользователь открывает раздел «Карта полетов». Поля «Город вылета» и «Город прилета» пусты, поле «Дата рейса» заполнено плейсхолдером «ДД.ММ.ГГГГ», выбор дней в календаре заблокирован.
Пользователь заполняет поле «Город вылета» или выбирает маршрут. Поле «Дата рейса» заполняется ближайшим днем выполнения рейсов. Выбор дней в календаре становится доступен.
Пользователь может изменить автоматически подставленную дату, выбрав другую из календаря или введя её вручную. В календаре недоступны для выбора дни, в которые не выполняются рейсы (см. Раздел Ограничения для задачи).
Система отображает выбранную дату в формате ДД.ММ.ГГГГ.
Если дата совпадает с текущей – поле «Дата рейса» заполняется значением «Сегодня»; если с завтрашней – «Завтра».
Пользователь может очистить поле посимвольно или целиком (нажатие на крестик).
## Ограничения для задачи:   
Дни в календаре атрибута «Дата вылета» не должны быть доступны для выбора пока пользователь не заполнит атрибут «Город вылета» или маршрут полностью.
Если пользователь сменил местами значение «Город вылета» и «Горд прилета» и при этом значение «Город вылета» стало не заполнено – то дни в календаре атрибута «Дата вылета» не должны быть доступны для выбора. Аналогичное поведение должно распространятся на кнопки-дни «Сегодня», «Завтра», «Послезавтра» мобильной версии.
Диапазон дат для выбора в календаре в поле «Дата вылета» ограничен от -1 дня до +6 месяцев от текущей даты.
На календаре в поле «Дата вылета» дни, в которых не выполняются рейсы из заданного города вылета или маршрута, блокируются.
Фильтры «Внутренние рейсы» и «Международные регулярные рейсы» взаимоисключающие.
Фильтр «Показать только рейсы с пересадкой» активируется только после выбора городов вылета и прилета.
Фильтр «Показать только рейсы с пересадкой» должен отображать только рейсы с пересадкой, прямые рейсы при этом перестают отображаться на карте.
Города на карте должны отображаться в зависимости от категории города и уровня масштабирования (см. Раздел 3.2 Требования к визуальной интерактивной карте).
При выборе маршрута на карте остаются видны только названия городов вылета, прилета и города с возможной стыковкой, остальные названия городов скрываются.
## Направления работ:
Дополнение Системы «Онлайн-Табло и Расписание» новым разделом «Карта полетов» согласно целевым бизнес-процессам и требованиям к их реализации, описанным в соответствующих пунктах данного документа.
**3.**       **Требования**
## 3.1 Требования к API
Сервис будет работать на основе внутреннего API с архитектурным стилем REST. Вызов сервисов будет осуществляться с помощью GET запросов по протоколу HTTPS, необходимые параметры передаются в строке запроса. Для работы раздела будет использовано несколько сервисов: API тайлов, API для получения координат городов, API маршрутов и API календаря.
·       API тайлов карты.
Сервис, который отдает изображения карты с помощью метода GET /map/api/tiles/{z}/{x}/{y}.jpg, где z, x, y это координаты и уровень масштабирования тайла. Данный сервис кэширует тайлы на 6 часов для ускорения повторной отдачи.
·       API координат городов.
Отдельный внутренний API, из которого фронтенд получает координаты городов по их IATA-коду для отрисовки точек на карте.
·       API маршрутов.
Для работы данного сервиса будет переиспользоваться существующее API от «Онлайн-Табло и Расписание». Метод GET /api/flights/1/ru/destinations возвращает список доступных направлений из указанного города вылета, выполняет проверку наличия прямых рейсов между городами вылета и прилета, а также возвращает список маршрутов при поиске рейсов с пересадкой.
В качестве параметров запроса передаются:
-      departure IATA-код города или аэропорта вылета;
-      arrival – IATA-код города или аэропорта прилета;
-      dateFrom/dateTo – Диапазон дат для поиска маршрутов в формате yyyy-MM-dd, где yyyy - год, MM – месяц, dd – день. Даты заполняются от -1 дня до +6 месяцев от текущей даты;
-      connections – количество пересадок.
В качестве ответа поступает массив routes, содержащий проверку наличия прямых рейсов и IATA-коды аэропортов городов маршрута.
·       API календаря.
Для работы данного сервиса будет переиспользоваться существующее API от «Онлайн-Табло и Расписание». Метод GET /api/flights/v1/ru/days возвращает список дней выполнения рейсов для заданного города вылета или маршрута.
В запросе передается дата для поиска в формате от -1 дня до +6 месяцев от текущей даты, а также параметры:
-      departure IATA-код города или аэропорта вылета (когда заполнено только поле «Город вылета»);
-      route – IATA- коды городов или аэропортов заданного маршрута.
В качестве ответа поступает строка, отражающая наличие рейсов на полгода вперёд, где каждый символ соответствует дню: «1» - рейсы есть, «0» - рейсов нет.
**3.2** **Требования к визуальной интерактивной карте**
 
Для выбора города вылета или прилета должна быть реализована возможность выбора необходимого города как на карте, так и в специальных полях «Город вылета» и «Город прилета» в интерфейсе раздела, доступного рядом с картой. На карте предусмотрена цветовая дифференциация выбранных и доступных направлений:
·               Оранжевый – выбранный на карте или в поле «Город вылета».
·               Синий – доступный для выбора на карте или в поле «Город прилета».
Дуги, показывающие маршрут между городами, бывают двух видов: сплошные – для прямых рейсов (многоплечевые рейсы также отображаются прямыми) и пунктирные – для стыковочных рейсов.
При первом открытии раздела «Карта полетов» в рамках одной сессии и после подтверждения разрешения на определение местоположения, система должна автоматически определить город пользователя и заполнить поле «Город вылета». Город пользователя определяется на основе ближайшего аэропорта, из которого выполняются рейсы авиакомпании Аэрофлот.
Тайлы для карты должны подготавливаться с помощью сервиса QGIS, в который будут загружены данные из открытых источников. Для отображения карты на фронтенде и обеспечения её интерактивности будет использована библиотека Leaflet.js. Сами тайлы загружены в хранилище S3 и берутся оттуда для отображения карты. Для изменения тайлов необходимо произвести повторную их подготовку через сервис QGIS и загрузку в S3. Для их удаления требуется произвести ручное удаление тайлов из S3 и повторно загрузить при необходимости. Поверх карты будут наложены города по координатам, полученным через внутреннее API.
**Логика отображения городов по уровням масштабирования**
Города разделены на категории и отображаются на карте в зависимости от текущего уровня масштабирования и категории.
Категории городов:
·      Города-миллионники.
·      Города с населением от 500 тысяч до 1 миллиона.
·      Города с населением менее 500 тысяч.
·      Популярные курорты.
Правила отображения:
·      Минимальное приближение – отображаются города-миллионники и популярные курорты
·      Среднее приближение – дополнительно появляются города с населением от 500 тысяч до 1 миллиона.
·      Максимальное приближение – отображаются все категории городов.
**Интерактивные возможности карты:**
·               При клике на город вылета на карте, поле «Город вылета» автоматически заполняется этим городом.
·               После выбора города вылета на карте отображаются дуги маршрута, указывающие на доступные города прилета. Количество направлений ограничено категориями городов в зависимости от масштаба карты.
·               При нажатии на город на карте, когда поле «Город вылета» уже заполнено, поле «Город прилета» будет заполнено выбранным городом. Между городами будет построена дуга маршрута: сплошная, если рейс прямой или пунктирная, если рейс со стыковкой.
·               После выбора города прилета над ним на карте появится всплывающее окно с названием города и кнопкой покупки билета. По нажатию кнопки «Купить билет» в систему бронирования передаются город вылета и прилёта. Если поле «Дата рейса» заполнено, оно также передаётся в систему бронирования, если пустое – не передаётся.
·               После выбора городов вылета и прилёта названия остальных городов на карте скрываются для упрощения восприятия маршрута.
·               Если маршрут включает пересадку, то название города, в котором происходит стыковка, также остаётся видимым на карте.
·               При нажатии на город на карте, когда поля «Город вылета» и «Город прилета» заполнены конкретными значениями, данные поля будут очищены и поле «Город вылета» будет заполнено выбранным городом. Из этого города будут отображены дуги маршрута, указывающие на доступные города прилета.
**3.3 Требования к реализации работы фильтров**
Для упрощения поиска маршрутов и повышения удобства взаимодействия пользователя с разделом «Карта полетов» реализуется блок фильтров с возможностью настройки параметров отображения направлений. Фильтры расположены в интерфейсе рядом картой.
·      Поля выбора городов вылета и прилета.
Данные фильтры представлены в виде полей с возможностью ручного ввода названия города, а также выпадающего списка городов, взятых из справочника. Поле также заполняется при выборе города на карте. Между полями есть кнопка, при нажатии которой города вылета и прилета меняются местами.
По умолчанию поля «Город вылета» и «Город прилета» содержат плейсхолдеры с текстом «Откуда» и «Куда» соответственно. После заполнения данных полей значениями в каждом из них должна появиться возможность удаления текста посимвольно или целиком (нажатие на крестик).
Для выбора типа рейса предусмотрены три переключателя:
·      Внутренние рейсы.
При активации отображаются только маршруты, выполняемые внутри территории России. Международные направления скрываются.
·      Международные регулярные рейсы.
Отображаются маршруты, имеющие в качестве одного из пунктов за пределами России. Внутренние направления при этом скрываются.
·      Показать только рейсы с пересадкой.
Активация этого фильтра заменяет отображение прямых маршрутов на рейсы с возможной стыковкой. Фильтр становится доступен после выбора городов вылета и прилета. Визуально такие маршруты представлены пунктирной дугой. Если между городами вылета и прилета нет прямого маршрута для диапазона дат от -1 дня до +6 месяцев от текущей даты, то данный фильтр активируется автоматически.
Фильтр «Показать только рейсы с пересадкой» можно комбинировать с другими: например, можно одновременно включить «Международные регулярные рейсы» и «Показать только рейсы с пересадкой», чтобы отобразить только международные маршруты с пересадками.
Фильтры «Внутренние рейсы» и «Международные регулярные рейсы» являются взаимоисключающими, то есть возможно выбрать только один из них.
Также доступен фильтр «Дата рейса».
Допускается выбор даты из календаря или ручной ввод даты в формате ДД.ММ.ГГГГ. В мобильной версии сайта доступны кнопки-дни «Сегодня», «Завтра» и «Послезавтра», по нажатию которых, поле «Дата рейса» заполняется датой, соответствующей данным значениям.
При заполнении поля значениями должен появиться крестик.
Должна предусматриваться возможность очищения введённых значений посимвольно или сразу всего значения (нажатие на крестик).
Работа календаря должна соответствовать следующим правилам:
·      Диапазон дат для выбора в календаре от -1 дня до +6 месяцев от текущей даты;
·      Если выбрана дата текущего дня, то заполнять атрибут «Дата рейса» значением «Сегодня».
·      Если выбрана дата завтрашнего дня, то заполнять атрибут «Дата рейса» значением «Завтра».
·      На календаре дни, в которых не выполняются рейсы для заданного города вылета или маршрута, блокируются. Блокировка происходит в два этапа: сперва после выбора города вылета, а затем дополнительно после выбора города прилёта.
·      Дни в календаре атрибута «Дата вылета» не должны быть доступны для выбора пока пользователь не заполнит атрибут «Город вылета» или маршрут полностью. Если пользователь сменил местами значение «Город вылета» и «Город прилета» и при этом значение «Город вылета» стало не заполнено – то дни в календаре атрибута «Дата вылета» не должны быть доступны для выбора. Аналогичное поведение должно распространятся на кнопки–дни «Сегодня», «Завтра», «Послезавтра» мобильной версии
·      Логика работы календаря должна быть идентичной вне зависимости от способа выбора городов: кликом на карте, ручным вводом в поле или выбором из справочника.
**3.4 Требования к микроразметке раздела «Карта полетов»**
На странице раздела «Карта полетов» должна присутствовать следующая информация в разметке страниц:
·      Title: Карта полетов авиакомпании Аэрофлот.
·      Description: Карта полетов авиакомпании "Аэрофлот". Информация о направлениях рейсов.
В файле Robot.txt будет содержаться перечень агентов и разрешения для них по контенту раздела «Карта полетов», см. Таблица 1.
Таблица 1
| | | |
|---|---|---|
|**Агент**|**Страница**<br><br>**Контент**|**Разрешено/**<br><br>**Не разрешено**|
|User-agent: Yandex|Канонические страницы Карты полетов|allow|
|User-agent: Googlebot|Канонические страницы Карты полетов|allow|
|User-agent: *|Канонические страницы Карты полетов|allow|
Пример канонических страниц для титульной страницы на русском:
<link rel="canonical" href="https://flights.aeroflot.ru/ru-ru/flights-map"/>
**3.5 Требования к сбору статистики**
Добавление параметров для возможности сбора статистики в «Яндекс.Метрика» по разделу «Карта полетов» будет работать аналогично всей Системе «Онлайн-Табло и Расписание».
**3.6 Требования к макетам и верстке**
Выполняемая в рамках задачи работа отразится на внешнем виде сайта ПАО «Аэрофлот». Макеты планируемых изменений представлены заказчиком для десктопной (рисунок 1), планшетной (рисунок 2) и мобильной версии сайта (рисунок 3).