No description
Find a file
2026-10-11 19:07:53 +03:00
README.md Обновить README.md 2026-10-11 19:07:53 +03:00

АСО-Контроль — Mobile

Мобильное приложение инспектора: с ним человек выходит на борт, считывает RFID-метки аварийно-спасательного оборудования и сразу видит, чего не хватает, что просрочено и что неисправно.

Приложение — тонкий клиент. Вся бизнес-логика (сравнение факта с эталоном, расчёт статусов, отправка заявок инженерам) живёт на бэкенде. Задача мобилки — собрать коды меток из доступного источника, отправить их и понятно показать ответ сервера.

Платформа и фреймворк не зафиксированы. Нужно: работа с NFC телефона, работа с внешним ридером по Bluetooth LE, HTTP-клиент, локальное хранение токена. Это умеют и нативные Android/iOS, и кроссплатформенные решения. Выбирайте по тому, с чем справится команда, и фиксируйте выбор в этом README. Основная целевая платформа — Android (внешние UHF-ридеры в практике почти всегда Android).


Решения, принятые по проекту

Вопрос Решение
Источники меток Три: NFC телефона, внешний ридер по BLE, ручной ввод кода. За одним общим интерфейсом + мок-источник для демо.
Офлайн-режим Нет. Приложение работает только при наличии сети. Без связи осмотр не начинается — это должно быть честно показано пользователю, а не выглядеть как зависание.
Роли Инспектор и Администратор. Инженеров в приложении нет — заявка уходит им через бэкенд во внешнюю систему.
Админские функции Приложение показывает админу расширенные экраны (справочники, привязка меток, пользователи), но полноценное управление парком — задача будущей веб-панели.

Что означает «только онлайн» на практике

Это главный риск сценария: в самолёте сети может не быть. Поэтому:

  • состояние сети видно в интерфейсе постоянно, а не только в момент ошибки;
  • при обрыве связи во время осмотра приложение не теряет контекст: сессия осмотра живёт на сервере, после восстановления сети экран продолжается с того же места;
  • отправка считываний идёт батчами с ретраями, с показом «не отправлено: N»;
  • все изменяющие запросы уходят с Idempotency-Key, чтобы повтор после обрыва не создал дубль осмотра или заявки.

Что должно делать приложение

1. Вход и сессия

  • Экран входа по логину/паролю, токен в защищённом хранилище устройства (Keystore / Keychain), не в обычных настройках.
  • Автопродление токена, выход по истечении, кнопка «Выйти».
  • Интерфейс подстраивается под роль, пришедшую с сервера. Роль не хранится локально как источник правды — проверка прав всё равно на бэкенде.

2. Слой источников метки — ключевая абстракция

Один интерфейс TagSource с четырьмя реализациями:

Источник Назначение
NfcTagSource встроенный NFC телефона. Дистанция сантиметры — подходит для точечной проверки единицы, не для обхода салона.
BleReaderTagSource внешний UHF-ридер по Bluetooth LE: сопряжение, подключение, поток считываний, уровень заряда, отключение. Основной режим для массового осмотра.
ManualTagSource ручной ввод кода метки: метка не читается, оторвана, повреждена.
MockTagSource генерирует коды из заранее заданного набора. Нужен обязательно — чтобы разрабатывать и показывать приложение без железа.

Требования к слою:

  • Экраны осмотра работают с интерфейсом, а не с конкретным ридером: смена модели ридера не должна затрагивать UI.
  • Переключение источника на ходу, без перезапуска осмотра.
  • Дедупликация: одна и та же метка, прочитанная ридером десять раз за секунду, — это одно считывание.
  • Каждое считывание несёт source (nfc / ble_reader / manual / mock) — сервер сохраняет это для аудита.
  • Выбор мок-источника — через настройки сборки или скрытый экран отладки, а не доступной кнопкой в боевом интерфейсе.

3. Процесс осмотра — главный сценарий

  1. Инспектор выбирает борт.
  2. Приложение начинает осмотр на сервере и получает эталонный перечень.
  3. Экран осмотра показывает перечень: что ещё не найдено, что найдено, что проблемное. Прогресс виден цифрой и полосой.
  4. Инспектор обходит салон, метки считываются и уходят батчами на сервер.
  5. Каждое считывание отражается в списке: найдено / не из перечня / просрочено / неисправно / метка неизвестна.
  6. Чего ридер не нашёл — инспектор помечает вручную: отсутствует или неисправно, с комментарием и фото.
  7. По неисправному или отсутствующему можно создать заявку инженерам.
  8. Закрытие осмотра → итоговый отчёт на экране.

4. Фото и комментарии

  • Фото проблемной единицы с камеры, сжатие перед отправкой.
  • Комментарий текстом. Голосовой ввод — опционально, если останется время.

5. Разбор и история

  • История осмотров: свои и (для админа) все, с фильтрами.
  • Карточка единицы оборудования: тип, место, сроки, статус, история.
  • Список проблемных единиц по борту.

6. Экраны администратора

  • Привязка RFID-метки к единице: считать метку → выбрать единицу → привязать.
  • Справочники: типы АСО, борта, места установки — просмотр и базовое редактирование.
  • Пользователи: создание, смена роли.
  • Просмотр отправленных заявок инженерам и их статуса доставки.

Views (экраны)

Экран Что показывает / делает Роль
Splash проверка токена, проверка доступности сервера, маршрутизация —
Login логин, пароль, ошибки входа, адрес сервера (для dev) —
Home / Борты список ВС с бортовым номером и сводным статусом готовности, поиск, индикатор сети И, А
Карточка борта данные ВС, сводка проблем, кнопка «Начать осмотр», история осмотров И, А
Выбор источника метки NFC / внешний ридер / ручной ввод; статус подключения ридера, заряд И, А
Сопряжение ридера поиск BLE-устройств, подключение, проверка связи, переподключение И, А
Осмотр: прогресс перечень борта по местам установки, найдено/осталось, прогресс, индикатор неотправленных считываний И, А
Осмотр: поток считываний лента последних меток с вердиктом сервера, цветовая маркировка И, А
Осмотр: карточка единицы тип, серийный номер, место, сроки, статус; действия: отметить вручную, фото, комментарий, создать заявку И, А
Осмотр: ручной ввод кода ввод кода метки с клавиатуры, подсказка о формате, проверка через сервер И, А
Осмотр: подтверждение закрытия сводка перед закрытием: найдено N из M, проблемных K, что отсутствует И, А
Итоговый отчёт осмотра результат закрытого осмотра, список расхождений, поделиться/сохранить И, А
Создание заявки единица, причина, приоритет, комментарий, фото; подтверждение отправки И, А
Заявки список созданных заявок и статус доставки во внешнюю систему И, А
История осмотров список осмотров с фильтрами по борту, дате, инспектору И, А
Карточка оборудования полные данные единицы и её история: осмотры, обслуживание, смены метки И, А
Поиск по метке считать метку вне осмотра и узнать, что это и в каком состоянии И, А
Срок истекает список единиц с истекающими сроками, фильтр по дням И, А
Админ: привязка меток считать метку → выбрать единицу → привязать / отвязать А
Админ: справочники типы АСО, борта, места установки А
Админ: эталонный перечень борта просмотр и правка состава оборудования борта А
Админ: пользователи список, создание, смена роли, сброс пароля А
Настройки адрес сервера, язык, о приложении, выход И, А
Отладка (dev-сборка) включение мок-источника метки, лог запросов, набор тестовых меток —
Нет сети понятное состояние: что недоступно, кнопка «Повторить». Не экран-заглушка на весь экран, если осмотр уже идёт —

И — инспектор, А — администратор.

Требования к интерфейсу

  • Приложением пользуются стоя, в салоне, иногда в перчатках: крупные элементы управления, минимум ввода текста, цель нажатия не меньше 48 dp.
  • Статус единицы читается цветом и подписью/иконкой — не только цветом.
  • Ни одно сетевое ожидание не выглядит как зависание: везде явная индикация.
  • Ошибка сервера показывается человеческим текстом, а не кодом ответа.
  • Весь интерфейс на русском; строки вынесены в ресурсы, а не вшиты в код.

Структура проекта

Ориентир. Смысл — чтобы работа с ридером, работа с API и экраны не были перемешаны: ридер должен подменяться моком, API — заглушкой, экраны — собираться без железа.

mobile/
├── README.md
├── .env.example                # адрес API, флаги сборки
└── src/ (или app/, lib/)
    ├── app/                    # точка входа, навигация, тема, DI
    ├── core/
    │   ├── network/            # HTTP-клиент, токен, ретраи, Idempotency-Key
    │   ├── storage/            # защищённое хранение токена
    │   ├── connectivity/       # отслеживание сети
    │   └── errors/             # маппинг ошибок сервера в сообщения
    ├── api/                    # клиент бэкенда: модели и методы по эндпоинтам
    ├── tagsource/              # ⬅ ключевой модуль
    │   ├── TagSource           # общий интерфейс
    │   ├── nfc/
    │   ├── ble/                # драйвер внешнего ридера
    │   ├── manual/
    │   └── mock/
    ├── features/
    │   ├── auth/
    │   ├── aircraft/
    │   ├── inspection/         # самый большой модуль: сессия, прогресс, лента
    │   ├── equipment/
    │   ├── requests/           # заявки инженерам
    │   ├── reports/
    │   └── admin/
    ├── ui/                     # общие компоненты, цвета статусов, типографика
    └── l10n/                   # строки интерфейса

Тесты:

test/
├── unit/           # дедупликация считываний, маппинг ответов, состояние осмотра
└── integration/    # сценарий осмотра целиком на MockTagSource + заглушке API

Взаимодействие с бэкендом

Контракт — backend/openapi.json. Основные вызовы в порядке сценария:

Шаг Запрос
Вход POST /auth/login, затем GET /auth/me
Список бортов GET /aircraft
Карточка борта GET /aircraft/{id}, GET /aircraft/{id}/status
Начать осмотр POST /inspections → id сессии
Состояние осмотра GET /inspections/{id}
Закрыть осмотр POST /inspections/{id}/close
Отчёт GET /inspections/{id}/report
Заявка инженерам POST /maintenance-requests
Метка вне осмотра GET /tags/lookup?code=...
Привязка метки (админ) POST /tags/bind

Правила:

  • Приложение ничего не решает само: «просрочено», «не из перечня», «готовность борта» — всё это приходит с сервера. Дублировать правила на клиенте нельзя, иначе клиент и сервер разойдутся.
  • Считывания отправляются батчами (по размеру или по таймеру, ~1–2 с), а не по одной метке на запрос.
  • Изменяющие запросы — с Idempotency-Key.
  • Адрес API — из конфигурации сборки, не вшит в код.

Задачи на разработку

Этап 1. Каркас

  • Выбрать платформу и стек, зафиксировать в этом README.
  • Создать проект, навигацию, тему, базовые компоненты.
  • HTTP-клиент: базовый адрес из конфига, токен, обработка ошибок, ретраи.
  • Отслеживание сети и единый индикатор состояния связи.
  • Экран входа, защищённое хранение токена, выход.

Этап 2. Слой источников метки

  • Интерфейс TagSource и общая модель считывания.
  • MockTagSource — первым, чтобы дальше работать без железа.
  • ManualTagSource и экран ввода кода.
  • NfcTagSource на встроенном NFC.
  • BleReaderTagSource: сопряжение, подключение, поток считываний, заряд, переподключение после разрыва.
  • Дедупликация и буферизация считываний, юнит-тесты.
  • Экран выбора источника и экран сопряжения ридера.

Этап 3. Основной сценарий

  • Список бортов и карточка борта.
  • Старт осмотра, получение и отображение эталонного перечня.
  • Экран прогресса: сгруппировано по местам установки, найдено/осталось.
  • Лента считываний с вердиктами сервера.
  • Отправка батчей, счётчик неотправленного, ретраи.
  • Ручная отметка единицы: отсутствует / неисправно, комментарий.
  • Фото проблемной единицы, сжатие и отправка.
  • Закрытие осмотра и экран итогового отчёта.
  • Поведение при потере сети посреди осмотра — отдельно проверить и отладить.

Этап 4. Заявки и история

  • Создание заявки инженерам из осмотра и из карточки единицы.
  • Список заявок и статус доставки.
  • История осмотров с фильтрами.
  • Карточка оборудования с историей.
  • Поиск по метке вне осмотра.
  • Список истекающих сроков.

Этап 5. Администратор

  • Привязка и отвязка меток.
  • Просмотр и правка справочников.
  • Эталонный перечень борта.
  • Пользователи и роли.

Этап 6. Качество и демо

  • Экран отладки: включение мок-источника, набор тестовых меток.
  • Юнит-тесты на состояние осмотра и дедупликацию.
  • Интеграционный прогон сценария на моке.
  • Проверка на реальном устройстве с реальным ридером.
  • Сборка демо-APK, прогнанный сценарий для демо-дня: вход → борт → осмотр → нехватка → заявка → отчёт.
  • README обновлён под фактическую реализацию.

Известные риски

Риск Что делаем
На борту нет сети, а приложение только онлайн честная индикация, сессия на сервере, ретраи батчей; если станет блокером — обсуждать офлайн-режим как отдельное решение, а не допиливать на ходу
Внешний ридер недоступен к нужной дате весь UI разрабатывается на MockTagSource, железо подключается последним
UHF-ридер ловит метки соседнего борта или склада фильтрация по перечню борта на сервере, «лишние» метки показываются отдельной категорией, а не как ошибка
Метки на металле и в тесных отсеках читаются плохо ручной ввод кода как полноценный путь, а не затычка
Контракт API меняется по ходу openapi.yaml — единственный источник правды, изменения проговариваются с бэкендом до реализации

Правила работы с репозиторием

  • Ветки: main защищена, работа в feature/<кратко>, fix/<кратко>.
  • Merge в main только через PR и ревью.
  • Секреты и ключи подписи — не в репозиторий. .env в .gitignore.
  • Новый экран — сразу со состояниями загрузки, ошибки и пустого списка.
  • Меняется поведение — обновляется вики проекта.