Homebox Lens
Android-клиент для системы управления инвентарем Homebox. Позволяет пользователям управлять своим инвентарем, взаимодействуя с экземпляром сервера Homebox.
Библиотека логирования
В проекте используется Timber (timber.log.Timber) для всех целей логирования. Он предоставляет простой и расширяемый API для логирования.
Интернационализация (Мультиязычность)
Приложение должно поддерживать несколько языков для обеспечения доступности для глобальной аудитории.
Реализация будет основана на стандартном механизме ресурсов Android.
- Все строки, видимые пользователю, должны быть вынесены в файл `app/src/main/res/values/strings.xml`. Использование жестко закодированных строк в коде запрещено.
- Язык по умолчанию - русский (ru). Файл `strings.xml` будет содержать русские строки.
- Для поддержки других языков (например, английского - en) будут создаваться соответствующие каталоги ресурсов (например, `app/src/main/res/values-en/strings.xml`).
- В коде для доступа к строкам необходимо использовать ссылки на ресурсы (например, `R.string.app_name`).
UI Framework
Пользовательский интерфейс приложения построен с использованием Jetpack Compose, современного декларативного UI-фреймворка от Google. Это обеспечивает быстрое создание, гибкость и поддержку динамических данных.
Внедрение зависимостей (Dependency Injection)
Для управления зависимостями в проекте используется Hilt. Он интегрирован с компонентами Jetpack и упрощает внедрение зависимостей в Android-приложениях.
Навигация
Навигация между экранами (Composable-функциями) реализована с помощью библиотеки Navigation Compose, которая является частью Jetpack Navigation.
Асинхронные операции
Все асинхронные операции, такие как сетевые запросы или доступ к базе данных, выполняются с использованием Kotlin Coroutines. Это обеспечивает эффективное управление фоновыми задачами без блокировки основного потока.
Сетевое взаимодействие
Для взаимодействия с API сервера Homebox используется стек технологий: Retrofit для создания типобезопасных HTTP-клиентов, OkHttp в качестве HTTP-клиента и Moshi для парсинга JSON.
Локальное хранилище
Для кэширования данных на устройстве используется библиотека Room. Она предоставляет абстракцию над SQLite и обеспечивает надежное локальное хранение данных.
Спецификация безопасности проекта.
Все сетевые взаимодействия должны быть защищены HTTPS. Аутентификация пользователя хранится в EncryptedSharedPreferences. Обработка ошибок аутентификации должна включать logout и редирект на экран логина.
Использовать JWT или API-ключ для авторизации запросов. При истечении токена автоматически обновлять.
Локальные данные (credentials) шифровать с помощью Android KeyStore.
Спецификация обработки ошибок.
Все потенциальные ошибки (сеть, БД, валидация) должны быть обработаны с использованием sealed classes для ошибок (e.g., NetworkError, ValidationError) и отображаться пользователю через Snackbar или Dialog.
При сетевых ошибках показывать сообщение "No internet connection" и предлагать retry.
Для HTTP 4xx/5xx отображать user-friendly сообщение на основе response body.
Использовать require/check для контрактов, логировать и показывать toast.
Модель инвентарного товара.
Содержит поля: id, name, description, quantity, location, labels, customFields.
Модель метки.
Содержит поля: id, name, color.
Модель местоположения.
Содержит поля: id, name, parentLocation.
Модель статистики инвентаря.
Содержит поля: totalItems, totalValue, locationsCount, labelsCount.
Экран панели управления
Отображает сводку по инвентарю, включая статистику, такую как общее количество товаров, общая стоимость и количество по местоположениям/меткам.
Получение и отображение статистики
Получает общую статистику по инвентарю с сервера.
Пользователь аутентифицирован; сеть доступна.
Возвращает объект Statistics; данные кэшированы локально.
Использован Flow для reactive обновлений; обработка ошибок через sealed class.
Получение и отображение недавно добавленных товаров
Получает список последних N добавленных товаров из локальной базы данных.
Пользователь аутентифицирован.
Возвращает Flow со списком ItemSummary; список отсортирован по дате создания.
Данные берутся из локального кэша (Room) для быстрого отображения.
Экран списка инвентаря
Отображает список всех инвентарных позиций с возможностью поиска и фильтрации.
Поиск и фильтрация товаров
Ищет товары по строке запроса и фильтрам. Результаты разбиты на страницы.
Запрос не пустой; параметры пагинации валидны (page >= 1).
Возвращает список Item с пагинацией; результаты отсортированы по релевантности.
Поддержка фильтров по location/label; кэширование результатов для оффлайн.
Синхронизация инвентаря
Выполняет полную синхронизацию локального кэша инвентаря с сервером.
Сеть доступна; пользователь аутентифицирован.
Локальная БД обновлена; возвращает success/failure.
Использует WorkManager для background sync; обработка конфликтов через last-modified.
Экран сведений о товаре
Показывает все сведения о конкретном инвентарном товаре, включая его название, описание, изображения, вложения и настраиваемые поля.
Получение сведений о товаре
Получает полные сведения о конкретном товаре из репозитория.
Item ID валиден и существует.
Возвращает полный объект Item с attachments.
Загрузка изображений через Coil; оффлайн-поддержка из Room.
Создание/редактирование/удаление товаров
Позволяет пользователям создавать новые товары, обновлять существующие и удалять их.
Создать товар
Создает новый инвентарный товар на сервере.
Все обязательные поля (name, quantity) заполнены; данные валидны.
Новый Item сохранен на сервере; ID возвращен.
Валидация через require; sync с локальной БД.
Обновить товар
Обновляет существующий инвентарный товар на сервере.
Item ID существует; изменения валидны.
Item обновлен; версия инкрементирована.
Partial update через PATCH; обработка concurrency.
Удалить товар
Удаляет инвентарный товар с сервера.
Item ID существует; пользователь имеет права.
Item удален; связанные ресурсы (attachments) очищены.
Soft delete для восстановления; sync с локальной БД.
Управление метками и местоположениями
Позволяет пользователям просматривать списки всех доступных меток и местоположений.
Получить все метки
Получает список всех меток из репозитория.
Сеть доступна или кэш существует.
Возвращает список Label; отсортирован по name.
Кэширование в Room; reactive обновления.
Получить все местоположения
Получает список всех местоположений из репозитория.
Сеть доступна или кэш существует.
Возвращает список Location; иерархическая структура сохранена.
Поддержка nested locations; кэширование.
Экран поиска
Предоставляет специальный пользовательский интерфейс для поиска товаров.
Поиск со специального экрана
Использует ту же функцию поиска, но со специального экрана.
Запрос не пустой.
Возвращает результаты поиска; UI обновлен.
Интеграция с SearchView; debounce для запросов.
Главный экран "Панель управления"
Экран предоставляет обзорную информацию и быстрый доступ к основным функциям. Компоновка должна быть чистой и интуитивно понятной, аналогично веб-интерфейсу HomeBox.
Верхняя панель приложения. Содержит иконку навигационного меню (гамбургер), название/логотип приложения и иконку для запуска сканера (например, QR-кода).
Боковое навигационное меню. Открывается по нажатию на иконку в TopAppBar. Содержит основные разделы: Главная, Локации, Поиск, Профиль, Инструменты, а также кнопку "Выйти".
Основная область контента. Содержит несколько информационных блоков.
Сетка из 2x2 карточек, отображающих ключевые метрики.
Горизонтально прокручиваемый список карточек недавно добавленных предметов. Если предметов нет, отображается сообщение "Элементы не найдены".
Сетка или гибкий контейнер (FlowRow) с кликабельными чипами, представляющими местоположения. Нажатие на чип ведет к списку предметов в этом местоположении.
Сетка или гибкий контейнер (FlowRow) с кликабельными чипами, представляющими метки. Нажатие на чип ведет к списку предметов с этой меткой.
Вместо плавающей кнопки (FAB), в референсе используется заметная кнопка "Создать" в навигационном меню. Мы будем придерживаться этого подхода для консистентности. Эта кнопка инициирует процесс создания нового предмета.
Нажатие на чип местоположения/метки
Навигация на экран списка инвентаря с фильтром.
Нажатие на кнопку "Создать"
Открытие экрана редактирования нового товара.
Экран "Локации"
Отображает вертикальный список всех доступных местоположений. Экран должен быть интегрирован в общую структуру навигации приложения (TopAppBar, NavigationDrawer).
Общая верхняя панель приложения, аналогичная экрану "Панель управления".
Общее боковое меню навигации.
Основная область контента, занимающая все доступное пространство под TopAppBar.
Заголовок экрана, расположенный вверху основной области контента.
Вертикальный, прокручиваемый список (LazyColumn) всех местоположений.
Элемент списка, представляющий одно местоположение. Состоит из иконки (например, 'place') и названия местоположения. Весь элемент является кликабельным и ведет на экран со списком предметов в данной локации.
Плавающая кнопка действия, расположенная в правом нижнем углу. Позволяет пользователю добавить новое местоположение. В веб-версии для этого используются иконки в углу, но FAB является более нативным паттерном для Android.
Нажатие на элемент списка локаций
Осуществляется навигация на экран списка инвентаря, отфильтрованного по выбранной локации.
Нажатие на FloatingActionButton
Открывается диалоговое окно или новый экран для создания нового местоположения.
Экран "Метки"
Отображает вертикальный список всех доступных меток. Экран должен быть интегрирован в общую структуру навигации приложения.
Общая верхняя панель приложения с заголовком "Метки" и кнопкой "назад".
Основная область контента, занимающая все доступное пространство под TopAppBar.
Вертикальный, прокручиваемый список (LazyColumn) всех меток.
Элемент списка, представляющий одну метку. Состоит из иконки (например, 'label') и названия метки. Весь элемент является кликабельным и ведет на экран со списком предметов с данной меткой.
Плавающая кнопка действия, расположенная в правом нижнем углу. Позволяет пользователю добавить новую метку.
Нажатие на элемент списка меток
Осуществляется навигация на экран списка инвентаря, отфильтрованного по выбранной метке.
Нажатие на FloatingActionButton
Открывается диалоговое окно или новый экран для создания новой метки.
Экран "Список инвентаря"
Отображает список всех инвентарных позиций с возможностью поиска, фильтрации и пагинации. Интегрирован в навигацию.
Верхняя панель с поиском и фильтрами.
Прокручиваемый список товаров.
LazyColumn с карточками товаров (name, quantity, location).
Кликабельная карточка товара, ведущая на details.
Кнопка для синхронизации инвентаря.
Ввод в поиск
Обновление списка с debounce.
Нажатие на товар
Навигация на screen_item_details.
Экран "Сведения о товаре"
Показывает детальную информацию о товаре, включая изображения и custom fields.
С кнопками edit/delete.
Карусель изображений.
Текст description.
Сетка custom полей.
Нажатие edit
Навигация на screen_item_edit.
Нажатие delete
Подтверждение и вызов func_delete_item.
Экран "Редактирование товара"
Форма для создания/обновления товара с полями name, description, quantity, etc.
С кнопкой save.
Поле ввода имени.
Выбор местоположения.
Выбор меток.
Добавление изображений.
Нажатие save
Валидация и вызов func_create_item или func_update_item.
Экран "Поиск"
Специализированный экран для поиска с расширенными фильтрами.
С поисковой строкой.
Чипы для фильтров (location, label).
LazyColumn результатов.
Изменение запроса/фильтров
Обновление результатов.