From 70594408926dc4273cced9d6dc88469d2396251c Mon Sep 17 00:00:00 2001 From: busya Date: Sun, 7 Sep 2025 12:41:52 +0300 Subject: [PATCH] refactor promts --- .../filesystem_task_channel.xml | 74 + .../filesystem_task_source.xml | 38 - .../gitea_issue_task_source.xml | 26 - .../implementations/gitea_task_channel.xml | 69 + .../interfaces/task_channel_interface.xml | 43 + .../interfaces/task_source_interface.xml | 7 - .../kotlin/comments_and_kdoc.md | 0 .../kotlin/naming_conventions.md | 82 + .../kotlin/style_and_formatting.md | 0 agent_promts/protocols/gitea_protocol.xml | 85 - agent_promts/roles/architect.xml | 90 +- agent_promts/roles/base_role.xml | 8 + agent_promts/roles/documentation.xml | 66 +- agent_promts/roles/engineer.xml | 67 +- agent_promts/roles/qa.xml | 79 +- agent_promts/roles/semantic_linter.xml | 129 +- .../homebox/lens/ui/components/ColorPicker.kt | 5 +- .../ui/screen/itemedit/ItemEditViewModel.kt | 16 +- app/src/main/res/values-en/strings.xml | 42 +- build.gradle.kts | 2 +- ...250825_100000_create_updateitemusecase.xml | 30 - ...828_100001_implement_itemeditviewmodel.xml | 31 - ...828_100002_implement_itemeditscreen_ui.xml | 27 - ..._100003_update_navigation_for_itemedit.xml | 27 - ...809_label_management_feature_qa_report.xml | 47 + logs/communication_log.xml | 12 - process_openapi.py | 147 + tech_spec/api_summary.md | 1575 ++++++ tech_spec/document.json | 4374 +++++++++++++++++ 29 files changed, 6635 insertions(+), 563 deletions(-) create mode 100644 agent_promts/implementations/filesystem_task_channel.xml delete mode 100644 agent_promts/implementations/filesystem_task_source.xml delete mode 100644 agent_promts/implementations/gitea_issue_task_source.xml create mode 100644 agent_promts/implementations/gitea_task_channel.xml create mode 100644 agent_promts/interfaces/task_channel_interface.xml delete mode 100644 agent_promts/interfaces/task_source_interface.xml create mode 100644 agent_promts/knowledge_base/kotlin/comments_and_kdoc.md create mode 100644 agent_promts/knowledge_base/kotlin/naming_conventions.md create mode 100644 agent_promts/knowledge_base/kotlin/style_and_formatting.md delete mode 100644 agent_promts/protocols/gitea_protocol.xml delete mode 100644 logs/assurance_reports/20250825_103000_20250825_100000_create_updateitemusecase.xml delete mode 100644 logs/assurance_reports/20250828_100001_implement_itemeditviewmodel.xml delete mode 100644 logs/assurance_reports/20250828_100002_implement_itemeditscreen_ui.xml delete mode 100644 logs/assurance_reports/20250828_100003_update_navigation_for_itemedit.xml create mode 100644 logs/assurance_reports/20250906_123809_label_management_feature_qa_report.xml delete mode 100644 logs/communication_log.xml create mode 100644 process_openapi.py create mode 100644 tech_spec/api_summary.md create mode 100644 tech_spec/document.json diff --git a/agent_promts/implementations/filesystem_task_channel.xml b/agent_promts/implementations/filesystem_task_channel.xml new file mode 100644 index 0000000..dddb439 --- /dev/null +++ b/agent_promts/implementations/filesystem_task_channel.xml @@ -0,0 +1,74 @@ + + + + + + Реализует канал управления задачами через локальную файловую систему. + Задачи хранятся как файлы в директории `tasks/`. + + + + Сканировать директорию `tasks/`. + Найти первый файл, содержащий `status="pending"` и метку роли `{RoleName}`. + Если найден, вернуть содержимое файла. Иначе, вернуть `NULL`. + + + + Создать новый XML-файл в директории `tasks/`. + Имя файла: `{Timestamp}_{Title}.xml`. + Содержимое файла должно включать `Title`, `Body`, `Assignee`, `Labels` и `status="pending"`. + + + + Найти файл задачи по `{IssueID}` (имени файла). + Заменить в файле `status="{OldStatus}"` на `status="{NewStatus}"`. + + + + Найти файл задачи по `{IssueID}`. + Добавить в конец файла XML-блок `{CommentBody}`. + + + + + [FileSystemTaskChannel] INFO: Операция 'CreatePullRequest' не поддерживается файловым протоколом. Пропущено. + Title: {Title}, Head: {HeadBranch}, Base: {BaseBranch} + + + + + + [FileSystemTaskChannel] INFO: Операция 'MergeAndComplete' не поддерживается файловым протоколом. Пропущено. + IssueID: {IssueID}, PrID: {PrID} + + + + + + [FileSystemTaskChannel] INFO: Операция 'ReturnToDev' не поддерживается файловым протоколом. Пропущено. + IssueID: {IssueID}, PrID: {PrID} + + + + + + [FileSystemTaskChannel] INFO: Операция 'CommitChanges' не поддерживается файловым протоколом. Пропущено. + Commit Message: {CommitMessage} + + + + + + [FileSystemTaskChannel] INFO: Операция 'CreateBranch' не поддерживается файловым протоколом. Пропущено. + Branch Name: {BranchName} + + + + + + [FileSystemTaskChannel] INFO: Операция 'CommitChanges' не поддерживается файловым протоколом. Пропущено. + Commit Message: {CommitMessage} + + + + diff --git a/agent_promts/implementations/filesystem_task_source.xml b/agent_promts/implementations/filesystem_task_source.xml deleted file mode 100644 index 6ddddab..0000000 --- a/agent_promts/implementations/filesystem_task_source.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - Реализует канал получения задач через сканирование директории 'tasks/' - на наличие файлов со статусом 'pending'. - - - - - - Выполни команду `ReadFolder` для директории `tasks/`. - Сохрани результат в переменную `task_files_list`. - - - - Если `task_files_list` пуст, значит, заданий нет. - Вернуть `NULL`. - - - - - - - - - Если `file_content` НЕ пуста И содержит `status="pending"`, - Вернуть `file_content`. - - - - - - Вернуть `NULL`. - - - - diff --git a/agent_promts/implementations/gitea_issue_task_source.xml b/agent_promts/implementations/gitea_issue_task_source.xml deleted file mode 100644 index b72b067..0000000 --- a/agent_promts/implementations/gitea_issue_task_source.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - Реализует канал получения задач через поиск открытых issues в Gitea, - используя `gitea-client.zsh`. - - - - RoleName - - Выполнить команду `./gitea-client.zsh {RoleName} find-tasks --type "type::development"` - для поиска доступных задач для указанной роли. - - - Если найдена одна или несколько задач, взять первую из списка. - - - Извлечь содержимое задачи (WorkOrder) и вернуть его. - - - Если задачи не найдены, вернуть `NULL`. - - - diff --git a/agent_promts/implementations/gitea_task_channel.xml b/agent_promts/implementations/gitea_task_channel.xml new file mode 100644 index 0000000..5842fcf --- /dev/null +++ b/agent_promts/implementations/gitea_task_channel.xml @@ -0,0 +1,69 @@ + + + + + + + Реализует канал управления задачами через Gitea, используя `gitea-client.zsh`. + + + + + Выполнить команду `./gitea-client.zsh {RoleName} find-tasks --type "{TaskType}"`. + + + + + + Выполнить команду `./gitea-client.zsh {RoleName} create-task --title "{Title}" --body "{Body}" --assignee "{Assignee}" --labels "{Labels}"`. + + + + + + Выполнить команду `./gitea-client.zsh {RoleName} update-task-status --issue-id {IssueID} --old "{OldStatus}" --new "{NewStatus}"`. + + + + + + Выполнить команду `./gitea-client.zsh {RoleName} create-pr --title "{Title}" --body "{Body}" --head "{HeadBranch}" --base "{BaseBranch}"`. + + + + + + Выполнить команду `./gitea-client.zsh {RoleName} merge-and-complete --issue-id {IssueID} --pr-id {PrID} --branch "{BranchToDelete}"`. + + + + + + Выполнить команду `./gitea-client.zsh {RoleName} return-to-dev --issue-id {IssueID} --pr-id {PrID} --report "{DefectReport}"`. + + + + + + + + ACTION: AddComment. Issue: {IssueID}, Body: {CommentBody} + + + + + Выполнить `git add .`. + Выполнить `git commit -m "{CommitMessage}"`. + Выполнить `git push origin {CurrentBranch}`. + + + + Выполнить `git checkout -b {BranchName}`. + + + + Выполнить `git add .`. + Выполнить `git commit -m "{CommitMessage}"`. + Выполнить `git push origin {CurrentBranch}`. + + diff --git a/agent_promts/interfaces/task_channel_interface.xml b/agent_promts/interfaces/task_channel_interface.xml new file mode 100644 index 0000000..6059f1f --- /dev/null +++ b/agent_promts/interfaces/task_channel_interface.xml @@ -0,0 +1,43 @@ + + + + Абстрактный контракт для канала взаимодействия с системой управления задачами. + Определяет все необходимые операции для полного жизненного цикла задачи. + + + + Находит следующую доступную задачу для указанной роли и типа. + + + + Создает новую задачу. + + + + Атомарно изменяет статус задачи. + + + + Создает Pull Request. + + + + Атомарно сливает PR, удаляет ветку и закрывает связанную задачу. + + + + Отклоняет PR и возвращает задачу разработчику с отчетом о дефектах. + + + + Добавляет комментарий к задаче. + + + + Создает новую ветку в системе контроля версий. + + + + Фиксирует все текущие изменения в рабочей директории. + + diff --git a/agent_promts/interfaces/task_source_interface.xml b/agent_promts/interfaces/task_source_interface.xml deleted file mode 100644 index 0f3b619..0000000 --- a/agent_promts/interfaces/task_source_interface.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/agent_promts/knowledge_base/kotlin/comments_and_kdoc.md b/agent_promts/knowledge_base/kotlin/comments_and_kdoc.md new file mode 100644 index 0000000..e69de29 diff --git a/agent_promts/knowledge_base/kotlin/naming_conventions.md b/agent_promts/knowledge_base/kotlin/naming_conventions.md new file mode 100644 index 0000000..27d5cfa --- /dev/null +++ b/agent_promts/knowledge_base/kotlin/naming_conventions.md @@ -0,0 +1,82 @@ +# Соглашения об именовании в Kotlin для AI + +Этот документ определяет соглашения об именовании для написания кода на Kotlin. Четкие и описательные имена критически важны для того, чтобы AI мог понять назначение элементов кода без необходимости в обширных комментариях или анализе. + +## 1. Общий принцип: Ясность и Описательность + +**Правило:** Имена ДОЛЖНЫ быть описательными и четко сообщать о назначении переменной, функции, класса или другой конструкции. Избегай однобуквенных имен (за исключением простых счетчиков циклов или параметров лямбда-выражений) и сокращений. + +**Действие:** +- **Хорошо:** `val userProfile = getUserProfile()` +- **Плохо:** `val u = getUP()` +- **Хорошо:** `fun sendEmailToPrimarySubscriber()` +- **Плохо:** `fun email()` + +**Обоснование:** AI в значительной степени полагается на имена для вывода смысла и назначения кода. Описательные имена предоставляют сильные семантические сигналы, уменьшая двусмысленность и вероятность неверной интерпретации. + +## 2. Имена пакетов + +**Правило:** Имена пакетов ДОЛЖНЫ быть в `lowercase` и не должны использовать подчеркивания (`_`) или другие специальные символы. Несколько слов должны быть соединены вместе. + +**Действие:** +- **Хорошо:** `com.homebox.lens.user.profile` +- **Плохо:** `com.homebox.lens.user_profile` + +**Обоснование:** Это стандартное соглашение в мире Java и Kotlin. Его соблюдение обеспечивает консистентность. + +## 3. Имена классов и интерфейсов + +**Правило:** Имена классов и интерфейсов ДОЛЖНЫ быть в `PascalCase`. + +**Действие:** +- **Хорошо:** `class UserProfile` +- **Хорошо:** `interface UserRepository` +- **Плохо:** `class user_profile` + +**Обоснование:** `PascalCase` является стандартом для типов. Это позволяет AI немедленно отличать типы от переменных или функций. + +## 4. Имена функций + +**Правило:** Имена функций ДОЛЖНЫ быть в `camelCase`. Обычно они должны быть глаголами или глагольными фразами. + +**Действие:** +- **Хорошо:** `fun getUserProfile()` +- **Хорошо:** `fun calculateTotalPrice()` +- **Плохо:** `fun UserProfile()` +- **Плохо:** `fun total_price()` + +**Обоснование:** `camelCase` является стандартом для функций. Использование глаголов помогает AI понять, что функция выполняет действие. + +## 5. Имена переменных и свойств + +**Правило:** Имена переменных и свойств ДОЛЖНЫ быть в `camelCase`. + +**Действие:** +- **Хорошо:** `val userName: String` +- **Хорошо:** `var isVisible: Boolean` +- **Плохо:** `val UserName: String` +- **Плохо:** `val is_visible: Boolean` + +**Обоснование:** Консистентность с именами функций. + +## 6. Имена для Boolean + +**Правило:** Имена для `Boolean` переменных или функций, возвращающих `Boolean`, ДОЛЖНЫ начинаться с глаголов "is", "has" или "should". + +**Действие:** +- **Хорошо:** `val isVisible: Boolean` +- **Хорошо:** `fun hasPendingChanges(): Boolean` +- **Плохо:** `val visible: Boolean` +- **Плохо:** `fun pendingChanges(): Boolean` + +**Обоснование:** Это соглашение делает булеву логику намного яснее и менее двусмысленной для AI. Имя читается как вопрос, чем, по сути, и является булево условие. + +## 7. Имена констант + +**Правило:** Константы (свойства, определенные в `companion object` или свойства верхнего уровня с `const val`) ДОЛЖНЫ быть в `UPPER_SNAKE_CASE`. + +**Действие:** +- **Хорошо:** `const val MAX_RETRIES = 3` +- **Плохо:** `const val maxRetries = 3` + +**Обоснование:** Это сильное и общепризнанное соглашение, сигнализирующее о том, что значение является константой. diff --git a/agent_promts/knowledge_base/kotlin/style_and_formatting.md b/agent_promts/knowledge_base/kotlin/style_and_formatting.md new file mode 100644 index 0000000..e69de29 diff --git a/agent_promts/protocols/gitea_protocol.xml b/agent_promts/protocols/gitea_protocol.xml deleted file mode 100644 index 9192132..0000000 --- a/agent_promts/protocols/gitea_protocol.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - Определить единый, отказоустойчивый и полностью автоматизированный протокол для межагентной коммуникации, основанный на использовании высокоуровневого клиента 'gitea-client.zsh'. - 4.0 - - - - - **КЛЮЧЕВОЕ ИЗМЕНЕНИЕ:** Все взаимодействия с Gitea **ОБЯЗАНЫ** осуществляться исключительно через `gitea-client.zsh`. Прямые вызовы `tea` или `git` в рамках жизненного цикла задачи запрещены, чтобы гарантировать предсказуемость и централизованное управление логикой. - - - Клиент `gitea-client.zsh` автоматически определяет репозиторий (`{repo_slug}`) при инициализации. Агентам не нужно управлять этим состоянием. Роль (`{role_name}`) передается как первый аргумент при каждом вызове. - - - Человек взаимодействует с системой исключительно через диалог с Агентом-Архитектором, который инициирует весь воркфлоу. - - - Конечным продуктом работы Агента-Разработчика является формальный Pull Request (PR), который является основой для проверки и слияния. - - - - - `./gitea-client.zsh {role_name} {command} [options]` - - `create-task --title "..." --body "..." --assignee "..." --labels "..."` - Создание новой задачи в Gitea. - - - `find-tasks --type "{label_name}"` - Поиск открытых задач с нужным типом и статусом 'pending'. - - - `update-task-status --issue-id ID --old "{label}" --new "{label}"` - Атомарное изменение статуса задачи (например, с 'pending' на 'in-progress'). - - - `create-pr --title "..." --body "..." --head "{branch}" --base "{target_branch}"` - Создание Pull Request. - - - `merge-and-complete --issue-id ID --pr-id ID --branch "{branch_to_delete}"` - Атомарная операция: слияние PR, удаление ветки и закрытие связанной задачи. - - - `return-to-dev --issue-id ID --pr-id ID --report "{defect_report_text}"` - Атомарная операция: отклонение PR, добавление комментария с отчетом и переназначение задачи разработчику. - - - - - - 1. Архитектор, после согласования с человеком, создает задачу для Разработчика. - `./gitea-client.zsh agent-architect create-task --title "Реализовать модуль X" --body "..." --assignee "agent-developer" --labels "type::development,status::pending"` - - - - 1. Разработчик находит назначенную ему задачу. - `./gitea-client.zsh agent-developer find-tasks --type "type::development"` - 2. Берет задачу в работу. - `./gitea-client.zsh agent-developer update-task-status --issue-id {issue-id} --old "status::pending" --new "status::in-progress"` - 3. После написания кода и локальных тестов создает Pull Request. - `./gitea-client.zsh agent-developer create-pr --title "feat: Реализован модуль X" --body "Closes #{issue-id}" --head "feature/{issue-id}-module-x"` - 4. Создает задачу для QA-агента, передавая ему контекст (ID задачи и PR). - `./gitea-client.zsh agent-developer create-task --title "QA: Проверить реализацию модуля X" --body "PR: #{pr-id}\nIssue: #{issue-id}" --assignee "agent-qa" --labels "type::quality-assurance,status::pending"` - - - - 1. QA-Агент находит свою задачу. - `./gitea-client.zsh agent-qa find-tasks --type "type::quality-assurance"` - 2. Берет задачу в работу. - `./gitea-client.zsh agent-qa update-task-status --issue-id {qa-issue-id} --old "status::pending" --new "status::in-progress"` - 3. Извлекает `PULL_REQUEST_ID` и `DEVELOPER_ISSUE_ID` из тела задачи и проводит аудит кода. - - - Выполняет единую команду для слияния PR, удаления ветки и закрытия исходной задачи разработчика. - `./gitea-client.zsh agent-qa merge-and-complete --issue-id {developer-issue-id} --pr-id {pr-id} --branch "feature/{issue-id}-module-x"` - - - - Выполняет единую команду для отклонения PR и возврата задачи разработчику с отчетом. - `./gitea-client.zsh agent-qa return-to-dev --issue-id {developer-issue-id} --pr-id {pr-id} --report "Найдены следующие дефекты: ..."` - - - - \ No newline at end of file diff --git a/agent_promts/roles/architect.xml b/agent_promts/roles/architect.xml index 96d2849..d7de1ea 100644 --- a/agent_promts/roles/architect.xml +++ b/agent_promts/roles/architect.xml @@ -2,8 +2,8 @@ - Этот документ определяет операционный протокол для **исполнения роли 'Агента-Архитектора'**. Он описывает философию, процедуры и пошаговый алгоритм действий, которым я, Gemini, следую при выполнении этой роли, используя высокоуровневый `gitea-client.zsh` для взаимодействия с Gitea. - 8.0 + Этот документ определяет операционный протокол для **исполнения роли 'Агента-Архитектора'**. Он описывает философию, процедуры и пошаговый алгоритм действий для трансформации диалога с человеком в формализованный `Work Order` для разработчика. + 9.0 Этот агент собирает следующие группы метрик для анализа. @@ -13,107 +13,93 @@ - - Gitea_Issue_Driven_Protocol (v4.0+) + - ../interfaces/task_channel_interface.xml - При исполнении этой роли, я, Gemini, действую как стратегический интерфейс между человеком-архитектором и автоматизированной системой разработки. Моя задача — вести итеративный диалог для уточнения целей, анализировать кодовую базу и, после получения одобрения, инициировать производственную цепочку через Gitea, используя `gitea-client.zsh`. - Основная цель этой роли — трансформировать неструктурированный человеческий диалог в структурированный, машиночитаемый и полностью готовый к исполнению `Work Order` в виде Gitea Issue для роли 'Агента-Разработчика'. + При исполнении этой роли, я, Gemini, действую как стратегический интерфейс между человеком-архитектором и автоматизированной системой разработки. Моя задача — вести итеративный диалог для уточнения целей, анализировать кодовую базу и, после получения одобрения, инициировать производственную цепочку через выбранный канал задач. + Основная цель этой роли — трансформировать неструктурированный человеческий диалог в структурированный, машиночитаемый и полностью готовый к исполнению `Work Order` для роли 'Агента-Разработчика'. - Основной рабочий цикл в рамках этой роли — это прямой диалог с человеком. Gitea не используется для взаимодействия с пользователем. После предложения плана, исполнение останавливается до получения явной вербальной команды ('Выполняй', 'Одобряю'). + Основной рабочий цикл в рамках этой роли — это прямой диалог с человеком. Исполнение останавливается до получения явной вербальной команды ('Выполняй', 'Одобряю'). - - Gitea — это исключительно межагентная коммуникационная шина. Задача в рамках этой роли — скрыть сложность системы от человека и использовать Gitea для надежной координации с другими ролями. + + Канал задач (TaskChannel) — это исключительно межагентная коммуникационная шина. Задача в рамках этой роли — скрыть сложность системы от человека и использовать канал для надежной координации с другими ролями. - - Конечная цель роли — создать "генезис-блок" для новой фичи. Это первый Issue в Gitea, который запускает производственный конвейер. + + Конечная цель роли — создать "генезис-блок" для новой фичи. Это первая задача в канале, которая запускает производственный конвейер. - Планы и выводы в рамках этой роли всегда должны быть основаны на актуальном состоянии исходных файлов, полученном через исследовательские инструменты. + Планы и выводы в рамках этой роли всегда должны быть основаны на актуальном состоянии исходных файлов. + + + Манифест проекта (`tech_spec/PROJECT_MANIFEST.xml`) является единым источником правды об архитектуре. Все изменения должны быть отражены в манифесте. - - Убедиться, что скрипт `gitea-client.zsh` доступен в системном PATH и имеет права на исполнение. - Вся логика аутентификации и определения репозитория **делегирована** `gitea-client.zsh`. Моя задача — передавать свою роль (`agent-architect`) как первый аргумент при каждом вызове. - - + + - - gitea-client.zsh agent-architect create-task --title "..." --body "..." --assignee "..." --labels "..." find grep - + Начать диалог с пользователем. Проанализировать его первоначальный запрос. Задавать уточняющие вопросы до тех пор, пока бизнес-цель не станет полностью ясной и недвусмысленной. - Используя `CodeEditor` и `Shell`, провести полный анализ системы в контексте цели. Прочитать исходный код, проанализировать существующую архитектуру. + Используя `CodeEditor` и `Shell`, провести полный анализ системы в контексте цели, включая `tech_spec/PROJECT_MANIFEST.xml`. - На основе цели и результатов исследования, сформулировать детальный, пошаговый план. Представить его пользователю, используя стандартный `RESPONSE_FORMAT`. + На основе цели и результатов исследования, сформулировать детальный, пошаговый план, включающий изменения в `PROJECT_MANIFEST.xml`. Представить его пользователю. - **ОСТАНОВИТЬ ВЫПОЛНЕНИЕ.** Завершить ответ блоком `` и ждать от человека явной, утверждающей команды ('Выполняй', 'План принят', 'Одобряю'). - Это критически важный шлюз безопасности, гарантирующий, что автоматизированный процесс не будет запущен без явного человеческого контроля. + **ОСТАНОВИТЬ ВЫПОЛНЕНИЕ.** Ждать от человека явной, утверждающей команды ('Выполняй', 'План принят', 'Одобряю'). - + Получена утверждающая команда от человека. - Сформировать и выполнить команду `Shell.ExecuteShellCommand`, используя `gitea-client.zsh` для создания Gitea Issue, как описано в `GITEA_ISSUE_DRIVEN_PROTOCOL`. - `./gitea-client.zsh agent-architect create-task --title "[ARCHITECT -> DEV] {Feature Summary}" --body "{XML Work Orders}" --assignee "agent-developer" --labels "status::pending,type::development"` - Стандартный вывод `gitea-client.zsh`, подтверждающий создание задачи. + На основе утвержденного плана, внести необходимые изменения в `tech_spec/PROJECT_MANIFEST.xml`. - - Сообщить человеку об успешном запуске автоматизированного процесса. Подтвердить, что задача для 'Агента-Разработчика' создана и дальнейшая работа будет вестись автономно. - "Автоматизированный процесс разработки запущен. Создана задача для роли 'Агент-Разработчик'. Дальнейшая работа будет вестись автономно в соответствии с протоколом." + + Изменения в манифесте успешно сохранены. + Вызвать `MyTaskChannel.CreateTask` для создания задачи для разработчика. + + [ARCHITECT -> DEV] {Feature Summary} + {XML Work Orders} + agent-developer + status::pending,type::development + + ID созданной задачи. - - Исполняющая среда ДОЛЖНА собрать все метрики, задекларированные в METRICS_TO_COLLECT. - Собранные метрики ДОЛЖНЫ быть отправлены в MyMetricsSink. + + Сообщить человеку об успешном запуске автоматизированного процесса. + + + + Собрать и отправить метрики через `MyMetricsSink`. - - Этот XML-формат используется для структурирования ответов человеку на этапе планирования (Шаг 3). - - - Выводы после анализа кода. - Анализ ситуации в контексте вашего запроса. - - Описание первого шага плана. - Описание второго шага плана. - - - - - - ]]> - - - \ No newline at end of file diff --git a/agent_promts/roles/base_role.xml b/agent_promts/roles/base_role.xml index 6f0f5e6..352d61c 100644 --- a/agent_promts/roles/base_role.xml +++ b/agent_promts/roles/base_role.xml @@ -4,6 +4,7 @@ 1.0 + @@ -11,6 +12,13 @@ Переопределить в дочерней роли. + + + Это основной источник правды об API Homebox. При разработке, отладке или тестировании функциональности, связанной с API, необходимо сверяться с этим документом. + tech_spec/api_summary.md + + + diff --git a/agent_promts/roles/documentation.xml b/agent_promts/roles/documentation.xml index 513a093..957dc7d 100644 --- a/agent_promts/roles/documentation.xml +++ b/agent_promts/roles/documentation.xml @@ -2,26 +2,23 @@ - Этот документ определяет операционный протокол для **исполнения роли 'Агента Документации'**. Он описывает философию, процедуры инициализации и пошаговый алгоритм действий, которым я, Gemini, следую при выполнении этой роли. Главная задача — синхронизация `PROJECT_MANIFEST.xml` с текущим состоянием кодовой базы. - 4.0 + Этот документ определяет операционный протокол для **исполнения роли 'Агента Документации'**. Главная задача — синхронизация `PROJECT_MANIFEST.xml` с текущим состоянием кодовой базы. + 5.0 - Этот агент собирает следующие группы метрик для анализа. - - - Gitea_Issue_Driven_Protocol_v2.1 - - Agent_Bootstrap_Protocol_v1.0 - - SEMANTIC_ENRICHMENT_PROTOCOL + - ../interfaces/task_channel_interface.xml + - ../protocols/semantic_enrichment_protocol.xml - При исполнении этой роли, я, Gemini, действую как автоматизированный аудитор и синхронизатор проекта. Моя задача — обеспечить, чтобы единый файл манифеста (`PROJECT_MANIFEST.xml`) был точным, актуальным и полным отражением реального состояния кодовой базы, проанализировав ее семантическую разметку. - Поддерживать целостность и актуальность семантического графа проекта, представленного в `PROJECT_MANIFEST.xml`, и фиксировать его изменения в системе контроля версий. + При исполнении этой роли, я, Gemini, действую как автоматизированный аудитор и синхронизатор проекта. Моя задача — обеспечить, чтобы `PROJECT_MANIFEST.xml` был точным отражением реального состояния кодовой базы. + Поддерживать целостность и актуальность `PROJECT_MANIFEST.xml` и фиксировать его изменения через предоставленный канал задач. @@ -29,28 +26,14 @@ Главная цель — сделать так, чтобы `PROJECT_MANIFEST.xml` был точным отражением кодовой базы. - Единственным источником истины является кодовая база и ее семантическая разметка (`[ENTITY]`, `[RELATION]`, и т.д.). Манифест должен соответствовать коду, а не наоборот. - - - Задача заключается в дистилляции и структурировании информации, уже заложенной в код, а не в создании новой. + Единственным источником истины является кодовая база и ее семантическая разметка. Манифест должен соответствовать коду, а не наоборот. - Все изменения в манифесте должны быть зафиксированы в Git. Это превращает документацию из статичного файла в живущий, версионируемый артефакт проекта. + Все изменения в манифесте должны быть зафиксированы в системе контроля версий, если это поддерживается выбранным каналом задач. - - Выполнить `AGENT_BOOTSTRAP_PROTOCOL` с идентификатором роли `identity="agent-docs"`. - - - - - - - - - @@ -60,58 +43,49 @@ find . -name "*.kt" - git checkout main - git pull origin main - git add tech_spec/PROJECT_MANIFEST.xml - git commit -m "{...}" - git push origin main - Использовать `GiteaClient.FindIssues(assignee='agent-docs', labels=['status::pending', 'type::documentation'])` для получения списка задач на синхронизацию. - Задачи для этой роли могут создаваться автоматически по расписанию, после успешного слияния PR, или вручную для принудительного аудита. + Использовать `MyTaskChannel.FindNextTask(RoleName='agent-docs', TaskType='type::documentation')` для получения задачи. - - **ДЛЯ КАЖДОГО** `issue` в списке, выполнить следующий суб-воркфлоу. + + Если задача (`WorkOrder`) найдена: - - Обновить статус `issue` на `status::in-progress`. - Выполнить `Shell.ExecuteShellCommand("git checkout main")` и `git pull origin main` для работы с самой свежей версией кода и манифеста. + + Вызвать `MyTaskChannel.UpdateTaskStatus(IssueID={WorkOrder.ID}, OldStatus='status::pending', NewStatus='status::in-progress')`. Загрузить текущий `tech_spec/PROJECT_MANIFEST.xml` в память как `original_manifest`. Выполнить `Shell.ExecuteShellCommand("find . -name \"*.kt\"")` для получения списка всех исходных файлов. - Провести полный аудит (создание новых узлов, обновление существующих на основе семантической разметки, пометка удаленных) и сгенерировать `updated_manifest`. + Провести полный аудит и сгенерировать `updated_manifest`. **ЕСЛИ** `updated_manifest` отличается от `original_manifest`: a. Сохранить `updated_manifest` в файл `tech_spec/PROJECT_MANIFEST.xml`. - b. Выполнить `Shell.ExecuteShellCommand("git add tech_spec/PROJECT_MANIFEST.xml")`. - c. Сформировать сообщение коммита: `"chore(docs): sync project manifest\n\nTriggered by task #{issue_id}."` - d. Выполнить `Shell.ExecuteShellCommand("git commit -m '...'"` и `git push origin main`. - e. Добавить в `issue` комментарий: `"Synchronization complete. Manifest updated and committed to main."` + b. Сформировать сообщение коммита: `"chore(docs): sync project manifest\n\nTriggered by task #{WorkOrder.ID}."` + c. Вызвать `MyTaskChannel.CommitManifestChanges(CommitMessage=...)`. + d. Вызвать `MyTaskChannel.AddComment(IssueID={WorkOrder.ID}, CommentBody='Synchronization complete. Manifest updated and committed.')` **ИНАЧЕ:** - a. Добавить в `issue` комментарий: `"Synchronization check complete. No changes detected in the manifest."` + a. Вызвать `MyTaskChannel.AddComment(IssueID={WorkOrder.ID}, CommentBody='Synchronization check complete. No changes detected.')` - Обновить `issue` на статус `status::completed`. + Вызвать `MyTaskChannel.UpdateTaskStatus(IssueID={WorkOrder.ID}, OldStatus='status::in-progress', NewStatus='status::completed')`. - Исполняющая среда ДОЛЖНА собрать все метрики, задекларированные в METRICS_TO_COLLECT. - Собранные метрики ДОЛЖНЫ быть отправлены в MyMetricsSink. + Собрать и отправить метрики через `MyMetricsSink`. \ No newline at end of file diff --git a/agent_promts/roles/engineer.xml b/agent_promts/roles/engineer.xml index 6199e49..59730f8 100644 --- a/agent_promts/roles/engineer.xml +++ b/agent_promts/roles/engineer.xml @@ -3,55 +3,52 @@ Преобразует бизнес-намерение в готовый к работе Kotlin-код. - 3.0 + 4.0 - Этот агент собирает следующие группы метрик для анализа. - - - - - + + - ../interfaces/task_channel_interface.xml + - ../protocols/semantic_enrichment_protocol.xml + - При исполнении этой роли, я, Gemini, действую как автоматизированный разработчик. Моя задача — преобразовать бизнес-намерение (WorkOrder) в полностью реализованный и семантически богатый код на языке Kotlin, следуя всем протоколам и базам знаний. - Создать готовый к работе, семантически размеченный и соответствующий всем контрактам код, который реализует поставленную задачу. + При исполнении этой роли, я, Gemini, действую как автоматизированный разработчик. Моя задача — преобразовать `WorkOrder` в полностью реализованный и семантически богатый код на языке Kotlin. + Создать готовый к работе, семантически размеченный и соответствующий всем контрактам код, который реализует поставленную задачу, и передать его на проверку. - - - - - - - - - - - - - - - + + + + + + CALL MyTaskChannel.UpdateTaskStatus(IssueID={WorkOrder.ID}, OldStatus='status::pending', NewStatus='status::in-progress') + - - - Исполняющая среда ДОЛЖНА собрать все метрики, задекларированные в METRICS_TO_COLLECT. - Собранные метрики ДОЛЖНЫ быть отправлены в MyMetricsSink. - + + Создать ветку для разработки: `feature/{WorkOrder.ID}-{short_title}`. + Выполнить основную работу по реализации, следуя `WorkOrder` и `SEMANTIC_ENRICHMENT_PROTOCOL`. + Запустить локальные тесты и сборку для проверки корректности. + + + + + + + + + CALL MyTaskChannel.UpdateTaskStatus(IssueID={WorkOrder.ID}, OldStatus='status::in-progress', NewStatus='status::pending-qa') + + + + Собрать и отправить метрики через `MyMetricsSink`. + - - - WorkOrder - - - \ No newline at end of file diff --git a/agent_promts/roles/qa.xml b/agent_promts/roles/qa.xml index ddc0492..1c455e9 100644 --- a/agent_promts/roles/qa.xml +++ b/agent_promts/roles/qa.xml @@ -3,20 +3,17 @@ Проверяет соответствие реализации бизнес-требованиям и техническим спецификациям. - 1.0 + 2.0 - Этот агент собирает метрики для анализа качества и полноты тестирования. - - - - - - + + - ../interfaces/task_channel_interface.xml + - ../protocols/semantic_enrichment_protocol.xml + @@ -25,43 +22,37 @@ - - - - - - - - - - - - - + + + + + + CALL MyTaskChannel.UpdateTaskStatus(IssueID={WorkOrder.ID}, OldStatus='status::pending', NewStatus='status::in-progress') + - - - Исполняющая среда ДОЛЖНА собрать все метрики, задекларированные в METRICS_TO_COLLECT. - Собранные метрики ДОЛЖНЫ быть отправлены в MyMetricsSink. - + + Извлечь `PULL_REQUEST_ID` и `DEVELOPER_ISSUE_ID` из тела `WorkOrder`. + Провести аудит кода и функциональное тестирование на основе `PULL_REQUEST_ID`. + Сгенерировать `DefectReport` если найдены проблемы. + + + + + + CALL MyTaskChannel.MergeAndComplete(IssueID={DEVELOPER_ISSUE_ID}, PrID={PULL_REQUEST_ID}, BranchToDelete=...) + + + + + CALL MyTaskChannel.ReturnToDev(IssueID={DEVELOPER_ISSUE_ID}, PrID={PULL_REQUEST_ID}, DefectReport={DefectReport}) + + + CALL MyTaskChannel.UpdateTaskStatus(IssueID={WorkOrder.ID}, OldStatus='status::in-progress', NewStatus='status::completed') + + + + Собрать и отправить метрики через `MyMetricsSink`. + - - WorkOrder - - - Проанализировать WorkOrder и связанные с ним артефакты (например, тикеты в Gitea, спецификации). - - - На основе анализа создать детальный план тестирования, покрывающий позитивные и негативные сценарии. - - - Выполнить тесты. Это может включать запуск автоматизированных тестов, проверку UI, анализ логов. - - - Сформировать отчет о результатах тестирования. В случае нахождения дефектов, создать соответствующие тикеты в Gitea, используя gitea_protocol. - - - - diff --git a/agent_promts/roles/semantic_linter.xml b/agent_promts/roles/semantic_linter.xml index 8dcb40f..b3565f0 100644 --- a/agent_promts/roles/semantic_linter.xml +++ b/agent_promts/roles/semantic_linter.xml @@ -2,53 +2,35 @@ - Этот документ определяет операционный протокол для **исполнения роли 'Агента Семантической Разметки'**. Он описывает философию, процедуры инициализации и пошаговый алгоритм действий, которым я, Gemini, следую при выполнении этой роли. Главная задача — приведение кодовой базы в полное соответствие с `SEMANTIC_ENRICHMENT_PROTOCOL`. - 4.0 + Этот документ определяет операционный протокол для **исполнения роли 'Агента Семантической Разметки'**. Главная задача — приведение кодовой базы в полное соответствие с `SEMANTIC_ENRICHMENT_PROTOCOL`. + 5.0 - Этот агент собирает следующие группы метрик для анализа. - - - Gitea_Issue_Driven_Protocol - - Agent_Bootstrap_Protocol - - SEMANTIC_ENRICHMENT_PROTOCOL + - ../interfaces/task_channel_interface.xml + - ../protocols/semantic_enrichment_protocol.xml - При исполнении этой роли, я, Gemini, действую как автоматизированный хранитель чистоты кода. Моя единственная задача — обеспечить, чтобы каждый файл в указанной области соответствовал `SEMANTIC_ENRICHMENT_PROTOCOL`. Я анализирую код и добавляю или исправляю исключительно семантическую разметку, **никогда не изменяя бизнес-логику**. + При исполнении этой роли, я, Gemini, действую как автоматизированный хранитель чистоты кода. Моя единственная задача — обеспечить, чтобы каждый файл в указанной области соответствовал `SEMANTIC_ENRICHMENT_PROTOCOL`. Поддерживать 100% семантическую чистоту и машиночитаемость кодовой базы, делая все изменения отслеживаемыми через систему контроля версий. - В рамках этой роли категорически запрещено изменять исполняемый код, исправлять ошибки или проводить рефакторинг. Работа касается исключительно метаданных. + Работа касается исключительно метаданных в комментариях, а не исполняемого кода. - Любые изменения, даже косметические, не должны вноситься напрямую в `main`. Результатом работы всегда является Pull Request, что обеспечивает прозрачность и возможность контроля. - - - Операции в этой роли идемпотентны. Повторный запуск на уже обработанном, неизмененном файле не должен приводить к каким-либо изменениям. + Результатом работы всегда является Pull Request или аналогичный артефакт, если это поддерживается каналом задач. - - Выполнить `AGENT_BOOTSTRAP_PROTOCOL` с идентификатором роли `identity="agent-linter"`. - - - - - - - - - - @@ -56,10 +38,6 @@ find . -name "*.kt" git diff --name-only {commit_range} - git checkout -b {branch_name} - git add . - git commit -m "{...}" - git push origin {branch_name} @@ -73,7 +51,6 @@ - ]]> @@ -81,70 +58,40 @@ - - Использовать `GiteaClient.FindIssues(assignee='agent-linter', labels=['status::pending', 'type::linting'])`. + + + + + + CALL MyTaskChannel.UpdateTaskStatus(IssueID={WorkOrder.ID}, OldStatus='status::pending', NewStatus='status::in-progress') - - **ДЛЯ КАЖДОГО** `issue` в списке, выполнить следующий суб-воркфлоу. - - - Обновить статус `issue` на `status::in-progress`. - Извлечь из тела `issue` блок `` и определить `MODE` и `TARGET`. - - - - Сформировать имя ветки: `chore/{issue-id}/semantic-linting-{MODE}`. - Выполнить `Shell.ExecuteShellCommand("git checkout -b {branch_name}")`. - - - - В зависимости от `MODE`: - - Выполнить `find . -name "*.kt"`. - Выполнить `git diff --name-only {TARGET}`. - Использовать `TARGET` как единственный файл в списке. - - Список `files_to_process`. - - - - Для каждого файла в `files_to_process`, выполнить атомарную операцию обогащения: - - 1. Прочитать `original_content`. - 2. Сгенерировать `enriched_content` в соответствии с `SEMANTIC_ENRICHMENT_PROTOCOL`. - 3. Если есть отличия, перезаписать файл. - - Собрать список `modified_files`. - - - - **ЕСЛИ** список `modified_files` не пуст: - - 1. Выполнить `git add .`. - 2. Сформировать коммит: `chore(lint): apply semantic enrichment\n\n- Files modified: {count}\n- Scope: {MODE}\n\nTriggered by task #{issue_id}.` - 3. Выполнить `git commit` и `git push origin {branch_name}`. - 4. Установить флаг `changes_pushed = true`. - - - - - **ЕСЛИ** `changes_pushed` равен `true`: - - 1. Создать `Pull Request` из `{branch_name}` в `main`. - 2. Добавить в `issue` комментарий: `Linting complete. Pull Request #{pr_id} created for review.` - - **ИНАЧЕ:** - - 1. Добавить в `issue` комментарий: `Linting complete. No semantic violations found.` - - Обновить `issue` на статус `status::completed`. - - + + Извлечь из тела `WorkOrder` блок `` и определить `MODE` и `TARGET`. + chore/{WorkOrder.ID}/semantic-linting-{MODE} + CALL MyTaskChannel.CreateBranch(BranchName={BranchName}) + Определить список `files_to_process` в зависимости от `MODE`. + Выполнить обогащение для каждого файла в `files_to_process` и собрать список `modified_files`. - - Исполняющая среда ДОЛЖНА собрать все метрики, задекларированные в METRICS_TO_COLLECT. - Собранные метрики ДОЛЖНЫ быть отправлены в MyMetricsSink. + + + + Сформировать коммит: `chore(lint): apply semantic enrichment\n\nFiles modified: {count}` + CALL MyTaskChannel.CommitChanges(CommitMessage=...) + + CALL MyTaskChannel.AddComment(IssueID={WorkOrder.ID}, CommentBody='Linting complete. Pull Request #{PrID} created for review.') + + + CALL MyTaskChannel.AddComment(IssueID={WorkOrder.ID}, CommentBody='Linting complete. No semantic violations found.') + + + + + CALL MyTaskChannel.UpdateTaskStatus(IssueID={WorkOrder.ID}, OldStatus='status::in-progress', NewStatus='status::completed') + + + + Собрать и отправить метрики через `MyMetricsSink`. \ No newline at end of file diff --git a/app/src/main/java/com/homebox/lens/ui/components/ColorPicker.kt b/app/src/main/java/com/homebox/lens/ui/components/ColorPicker.kt index 54083e2..3151ad5 100644 --- a/app/src/main/java/com/homebox/lens/ui/components/ColorPicker.kt +++ b/app/src/main/java/com/homebox/lens/ui/components/ColorPicker.kt @@ -47,7 +47,10 @@ fun ColorPicker( Box( modifier = Modifier .size(48.dp) - .background(Color(android.graphics.Color.parseColor(selectedColor)), CircleShape) + .background( + if (selectedColor.isEmpty()) Color.Transparent else Color(android.graphics.Color.parseColor(selectedColor)), + CircleShape + ) .border(2.dp, MaterialTheme.colorScheme.onSurface, CircleShape) .clickable { /* TODO: Implement a more advanced color selection dialog */ } ) diff --git a/app/src/main/java/com/homebox/lens/ui/screen/itemedit/ItemEditViewModel.kt b/app/src/main/java/com/homebox/lens/ui/screen/itemedit/ItemEditViewModel.kt index 4ca8c27..1b0a5e6 100644 --- a/app/src/main/java/com/homebox/lens/ui/screen/itemedit/ItemEditViewModel.kt +++ b/app/src/main/java/com/homebox/lens/ui/screen/itemedit/ItemEditViewModel.kt @@ -121,15 +121,15 @@ class ItemEditViewModel @Inject constructor( name = currentItem.name, description = currentItem.description, quantity = currentItem.quantity, - assetId = null, - notes = null, - serialNumber = null, - value = null, - purchasePrice = null, - purchaseDate = null, - warrantyUntil = null, + assetId = null, // Item does not have assetId + notes = null, // Item does not have notes + serialNumber = null, // Item does not have serialNumber + value = currentItem.value?.toDouble(), // Convert BigDecimal to Double + purchasePrice = null, // Item does not have purchasePrice + purchaseDate = null, // Item does not have purchaseDate + warrantyUntil = null, // Item does not have warrantyUntil locationId = currentItem.location?.id, - parentId = null, + parentId = null, // Item does not have parentId labelIds = currentItem.labels.map { it.id } )) Timber.d("[DEBUG][ACTION][mapping_item_summary_to_item] Mapping ItemSummary to Item for UI state.") diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index faec1d8..2501676 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -16,7 +16,7 @@ Scan QR code Navigate back Add new location - Add new label + Add new label Dashboard @@ -72,7 +72,7 @@ Navigate back Create new label Label icon - Labels not created yet. + No labels found. Create Label Label Name Create @@ -80,4 +80,42 @@ + + Sync inventory + + + Edit item + Delete item + Description + No description + Details + Quantity + Location + Labels + + + Create item + Save item + Name + Description + + + Search items... + + + Setup + + + Create label + Edit label + Label name + + + Back + Save + + + Color + HEX color code + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 06a2e72..63a48c8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ plugins { // [PLUGIN] Android Application plugin - id("com.android.application") version "8.11.1" apply false + id("com.android.application") version "8.12.2" apply false // [PLUGIN] Kotlin Android plugin id("org.jetbrains.kotlin.android") version "1.9.22" apply false // [PLUGIN] Hilt Android plugin diff --git a/logs/assurance_reports/20250825_103000_20250825_100000_create_updateitemusecase.xml b/logs/assurance_reports/20250825_103000_20250825_100000_create_updateitemusecase.xml deleted file mode 100644 index a44db7b..0000000 --- a/logs/assurance_reports/20250825_103000_20250825_100000_create_updateitemusecase.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - 20250825_100000_create_updateitemusecase.xml - /home/busya/dev/homebox_lens/domain/src/main/java/com/homebox/lens/domain/usecase/UpdateItemUseCase.kt - 2025-08-25T10:30:00Z - FAILED - - - - - UpdateItemUseCase.kt:4 - Keyword 'business_logic' in [SEMANTICS] anchor is not part of the defined taxonomy in SEMANTIC_ENRICHMENT_PROTOCOL.xml. - SemanticLintingCompliance.SemanticKeywordTaxonomy - - - UpdateItemUseCase.kt:4 - Keyword 'item_management' in [SEMANTICS] anchor is not part of the defined taxonomy in SEMANTIC_ENRICHMENT_PROTOCOL.xml. - SemanticLintingCompliance.SemanticKeywordTaxonomy - - - UpdateItemUseCase.kt:35 - Stray comment '// Assuming these are not updated via this use case' found. All comments must adhere to structured semantic anchors or KDoc. - SemanticLintingCompliance.NoStrayComments - - - - - - - \ No newline at end of file diff --git a/logs/assurance_reports/20250828_100001_implement_itemeditviewmodel.xml b/logs/assurance_reports/20250828_100001_implement_itemeditviewmodel.xml deleted file mode 100644 index a6da3a1..0000000 --- a/logs/assurance_reports/20250828_100001_implement_itemeditviewmodel.xml +++ /dev/null @@ -1,31 +0,0 @@ - - 20250825_100001_implement_itemeditviewmodel - 2025-08-28T10:00:00Z - SUCCESS - - - SUCCESS - - - ViewModel code adheres to the acceptance criteria in the work order. - - Semantic enrichment comments are present. - - - - SUCCESS - - - Generated unit tests for ItemEditViewModel. - - All tests passed successfully after fixing build and test issues. - - - app/src/test/java/com/homebox/lens/ui/screen/itemedit/ItemEditViewModelTest.kt - - - - SUCCESS - - - The application compiles successfully. - - All existing and new tests pass, indicating no regressions. - - - - \ No newline at end of file diff --git a/logs/assurance_reports/20250828_100002_implement_itemeditscreen_ui.xml b/logs/assurance_reports/20250828_100002_implement_itemeditscreen_ui.xml deleted file mode 100644 index ac5e074..0000000 --- a/logs/assurance_reports/20250828_100002_implement_itemeditscreen_ui.xml +++ /dev/null @@ -1,27 +0,0 @@ - - 20250825_100002_implement_itemeditscreen_ui - 2025-08-28T10:00:00Z - SUCCESS - - - SUCCESS - - - The Composable function adheres to the acceptance criteria in the work order. - - Semantic enrichment comments are present. - - - - SKIPPED - - - Unit tests for Composable functions are complex and will be covered by end-to-end tests. - - - - SUCCESS - - - The application compiles successfully. - - All existing tests pass, indicating no regressions. - - - - \ No newline at end of file diff --git a/logs/assurance_reports/20250828_100003_update_navigation_for_itemedit.xml b/logs/assurance_reports/20250828_100003_update_navigation_for_itemedit.xml deleted file mode 100644 index 581d509..0000000 --- a/logs/assurance_reports/20250828_100003_update_navigation_for_itemedit.xml +++ /dev/null @@ -1,27 +0,0 @@ - - 20250825_100003_update_navigation_for_itemedit - 2025-08-28T10:00:00Z - SUCCESS - - - SUCCESS - - - The navigation graph adheres to the acceptance criteria in the work order. - - Semantic enrichment comments are present. - - - - SKIPPED - - - Unit tests for navigation graphs are complex and will be covered by end-to-end tests. - - - - SUCCESS - - - The application compiles successfully. - - All existing tests pass, indicating no regressions. - - - - \ No newline at end of file diff --git a/logs/assurance_reports/20250906_123809_label_management_feature_qa_report.xml b/logs/assurance_reports/20250906_123809_label_management_feature_qa_report.xml new file mode 100644 index 0000000..ef568c8 --- /dev/null +++ b/logs/assurance_reports/20250906_123809_label_management_feature_qa_report.xml @@ -0,0 +1,47 @@ + + + + 20250906_123809 + 20250906_100000 + [ARCHITECT -> DEV] Implement Label Management Feature - QA Report + 2025-09-06 + FAILED + Gemini CLI QA Agent + + + Build Failed + + The application build failed during the QA process due to Lint errors. + The primary issue identified is missing translations for new string resources. + Functional testing could not be performed as the application did not compile. + + + + + + Missing translations for string resources in 'values-en/strings.xml'. + The build output indicates 26 errors and 32 warnings related to Lint. + Example error: "content_desc_add_label" is not translated in "en" (English). + This prevents the application from building successfully. + + + app/src/main/res/values/strings.xml + app/src/main/res/values-en/strings.xml (missing translations) + + + Add missing string translations to 'values-en/strings.xml' and other relevant locale files. + Address all other Lint errors and warnings to ensure code quality and successful builds. + + + + + + + + + + + Developer to fix Lint errors, especially missing translations. + Re-run build and re-initiate QA process. + + \ No newline at end of file diff --git a/logs/communication_log.xml b/logs/communication_log.xml deleted file mode 100644 index 8876222..0000000 --- a/logs/communication_log.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - BUILD_SUCCESS - Batch build successful. Tasks handed over to QA. -
- - - - -
-
-
\ No newline at end of file diff --git a/process_openapi.py b/process_openapi.py new file mode 100644 index 0000000..e926055 --- /dev/null +++ b/process_openapi.py @@ -0,0 +1,147 @@ + +import json +import sys + +def resolve_ref(spec, ref): + """ + Resolves a $ref reference in the OpenAPI spec. + """ + parts = ref.strip('#/').split('/') + current = spec + for part in parts: + if part in current: + current = current[part] + else: + return None + return current + +def format_schema(spec, schema, indent=0): + """ + Formats a schema definition into a readable string. + """ + indent_str = ' ' * indent + output = [] + + if 'type' in schema: + if schema['type'] == 'object' and 'properties' in schema: + output.append(f'{indent_str}Object with properties:\n') + for prop_name, prop_details in schema['properties'].items(): + prop_type = prop_details.get('type', 'any') + prop_desc = prop_details.get('description', 'No description') + output.append(f'{indent_str} - `{prop_name}` ({prop_type}): {prop_desc}\n') + elif schema['type'] == 'array' and 'items' in schema: + output.append(f'{indent_str}Array of:\n') + item_schema = schema['items'] + if '$ref' in item_schema: + ref_schema = resolve_ref(spec, item_schema['$ref']) + if ref_schema: + output.append(format_schema(spec, ref_schema, indent + 1)) + else: + output.append(f'{indent_str} Unresolved reference: {item_schema["$ref"]}\n') + else: + output.append(format_schema(spec, item_schema, indent + 1)) + else: + output.append(f'{indent_str}{schema["type"]}\n') + elif '$ref' in schema: + ref_schema = resolve_ref(spec, schema['$ref']) + if ref_schema: + output.append(format_schema(spec, ref_schema, indent)) + else: + output.append(f'{indent_str}Unresolved reference: {schema["$ref"]}\n') + + return ''.join(output) + + +def main(input_file, output_file): + """ + Main function to process the OpenAPI spec. + """ + try: + with open(input_file, 'r', encoding='utf-8') as f: + spec = json.load(f) + except FileNotFoundError: + print(f"Error: Input file not found at {input_file}") + return + except json.JSONDecodeError: + print(f"Error: Could not decode JSON from {input_file}") + return + + with open(output_file, 'w', encoding='utf-8') as f: + f.write("\n\n") + f.write(f"# API Summary: {spec.get('info', {}).get('title', 'Untitled API')}\n\n") + + for path, path_item in spec.get('paths', {}).items(): + for method, operation in path_item.items(): + f.write(f"<{method.upper()} {path}>\n") + + summary = operation.get('summary', '') + if summary: + f.write(f"**Summary:** {summary}\n\n") + + description = operation.get('description', '') + if description: + f.write(f"**Description:** {description}\n\n") + + # Parameters + if 'parameters' in operation: + f.write("\n") + f.write("| Name | In | Required | Type | Description |\n") + f.write("|------|----|----------|------|-------------|\n") + for param in operation['parameters']: + param_name = param.get('name') + param_in = param.get('in') + param_req = param.get('required', False) + param_type = param.get('type', 'N/A') + param_desc = param.get('description', '').replace('\n', ' ') + if 'schema' in param: + param_type = 'object' + f.write(f"| `{param_name}` | {param_in} | {param_req} | {param_type} | {param_desc} |\n") + f.write("\n") + f.write("\n") + + # Request Body (for 'body' parameters) + if 'parameters' in operation: + for param in operation['parameters']: + if param.get('in') == 'body' and 'schema' in param: + f.write("\n") + schema_str = format_schema(spec, param['schema']) + f.write(schema_str) + f.write("```\n\n") + f.write("\n") + + # Form Data (for 'formData' parameters) + form_data_params = [p for p in operation.get('parameters', []) if p.get('in') == 'formData'] + if form_data_params: + f.write("") + f.write("| Name | Type | Description |\n") + f.write("|------|------|-------------|\n") + for param in form_data_params: + param_name = param.get('name') + param_type = param.get('type', 'N/A') + param_desc = param.get('description', '').replace('\n', ' ') + f.write(f"| `{param_name}` | {param_type} | {param_desc} |\n") + f.write("\n") + f.write("") + + + # Responses + if 'responses' in operation: + f.write("\n") + for status_code, response in operation['responses'].items(): + f.write(f"- **{status_code}**: {response.get('description', '')}\n") + if 'schema' in response: + schema_str = format_schema(spec, response['schema'], indent=1) + if schema_str.strip(): + f.write(f" **Schema:**\n{schema_str}\n") + f.write("\n") + + f.write("---\n\n") + f.write(f"") + + f.write("\n") + +if __name__ == "__main__": + if len(sys.argv) != 3: + print("Usage: python process_openapi.py ") + else: + main(sys.argv[1], sys.argv[2]) diff --git a/tech_spec/api_summary.md b/tech_spec/api_summary.md new file mode 100644 index 0000000..274f8c8 --- /dev/null +++ b/tech_spec/api_summary.md @@ -0,0 +1,1575 @@ + + +# API Summary: Homebox API + + +**Summary:** Create Missing Thumbnails + +**Description:** Creates thumbnails for items that are missing them + + +- **200**: OK + **Schema:** + Object with properties: + - `completed` (integer): No description + + +--- + + +**Summary:** Ensure Asset IDs + +**Description:** Ensures all items in the database have an asset ID + + +- **200**: OK + **Schema:** + Object with properties: + - `completed` (integer): No description + + +--- + + +**Summary:** Ensures Import Refs + +**Description:** Ensures all items in the database have an import ref + + +- **200**: OK + **Schema:** + Object with properties: + - `completed` (integer): No description + + +--- + + +**Summary:** Set Primary Photos + +**Description:** Sets the first photo of each item as the primary photo + + +- **200**: OK + **Schema:** + Object with properties: + - `completed` (integer): No description + + +--- + + +**Summary:** Zero Out Time Fields + +**Description:** Resets all item date fields to the beginning of the day + + +- **200**: OK + **Schema:** + Object with properties: + - `completed` (integer): No description + + +--- + + +**Summary:** Get Item by Asset ID + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Asset ID | + + + +- **200**: OK + **Schema:** + Object with properties: + - `items` (array): No description + - `page` (integer): No description + - `pageSize` (integer): No description + - `total` (integer): No description + + +--- + + +**Summary:** Currency + + +- **200**: OK + **Schema:** + Object with properties: + - `code` (string): No description + - `local` (string): No description + - `name` (string): No description + - `symbol` (string): No description + + +--- + + +**Summary:** Get Group + + +- **200**: OK + **Schema:** + Object with properties: + - `createdAt` (string): No description + - `currency` (string): No description + - `id` (string): No description + - `name` (string): No description + - `updatedAt` (string): No description + + +--- + + +**Summary:** Update Group + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `payload` | body | True | object | User Data | + + + +Object with properties: + - `currency` (string): No description + - `name` (string): No description +``` + + + +- **200**: OK + **Schema:** + Object with properties: + - `createdAt` (string): No description + - `currency` (string): No description + - `id` (string): No description + - `name` (string): No description + - `updatedAt` (string): No description + + +--- + + +**Summary:** Create Group Invitation + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `payload` | body | True | object | User Data | + + + +Object with properties: + - `expiresAt` (string): No description + - `uses` (integer): No description +``` + + + +- **200**: OK + **Schema:** + Object with properties: + - `expiresAt` (string): No description + - `token` (string): No description + - `uses` (integer): No description + + +--- + + +**Summary:** Get Group Statistics + + +- **200**: OK + **Schema:** + Object with properties: + - `totalItemPrice` (number): No description + - `totalItems` (integer): No description + - `totalLabels` (integer): No description + - `totalLocations` (integer): No description + - `totalUsers` (integer): No description + - `totalWithWarranty` (integer): No description + + +--- + + +**Summary:** Get Label Statistics + + +- **200**: OK + **Schema:** + Array of: + Object with properties: + - `id` (string): No description + - `name` (string): No description + - `total` (number): No description + + +--- + + +**Summary:** Get Location Statistics + + +- **200**: OK + **Schema:** + Array of: + Object with properties: + - `id` (string): No description + - `name` (string): No description + - `total` (number): No description + + +--- + + +**Summary:** Get Purchase Price Statistics + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `start` | query | False | string | start date | +| `end` | query | False | string | end date | + + + +- **200**: OK + **Schema:** + Object with properties: + - `end` (string): No description + - `entries` (array): No description + - `start` (string): No description + - `valueAtEnd` (number): No description + - `valueAtStart` (number): No description + + +--- + + +**Summary:** Query All Items + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `q` | query | False | string | search string | +| `page` | query | False | integer | page number | +| `pageSize` | query | False | integer | items per page | +| `labels` | query | False | array | label Ids | +| `locations` | query | False | array | location Ids | +| `parentIds` | query | False | array | parent Ids | + + + +- **200**: OK + **Schema:** + Object with properties: + - `items` (array): No description + - `page` (integer): No description + - `pageSize` (integer): No description + - `total` (integer): No description + + +--- + + +**Summary:** Create Item + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `payload` | body | True | object | Item Data | + + + +Object with properties: + - `description` (string): No description + - `labelIds` (array): No description + - `locationId` (string): Edges + - `name` (string): No description + - `parentId` (string): No description + - `quantity` (integer): No description +``` + + + +- **201**: Created + **Schema:** + Object with properties: + - `archived` (boolean): No description + - `assetId` (string): No description + - `createdAt` (string): No description + - `description` (string): No description + - `id` (string): No description + - `imageId` (string): No description + - `insured` (boolean): No description + - `labels` (array): No description + - `location` (any): Edges + - `name` (string): No description + - `purchasePrice` (number): No description + - `quantity` (integer): No description + - `soldTime` (string): Sale details + - `thumbnailId` (string): No description + - `updatedAt` (string): No description + + +--- + + +**Summary:** Export Items + + +- **200**: text/csv + **Schema:** + string + + +--- + + +**Summary:** Get All Custom Field Names + + +- **200**: OK + **Schema:** + Array of: + string + + +--- + + +**Summary:** Get All Custom Field Values + + +- **200**: OK + **Schema:** + Array of: + string + + +--- + + +**Summary:** Import Items + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `csv` | formData | True | file | Image to upload | + + +| Name | Type | Description | +|------|------|-------------| +| `csv` | file | Image to upload | + + +- **204**: No Content + +--- + + +**Summary:** Get Item + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Item ID | + + + +- **200**: OK + **Schema:** + Object with properties: + - `archived` (boolean): No description + - `assetId` (string): No description + - `attachments` (array): No description + - `createdAt` (string): No description + - `description` (string): No description + - `fields` (array): No description + - `id` (string): No description + - `imageId` (string): No description + - `insured` (boolean): No description + - `labels` (array): No description + - `lifetimeWarranty` (boolean): Warranty + - `location` (any): Edges + - `manufacturer` (string): No description + - `modelNumber` (string): No description + - `name` (string): No description + - `notes` (string): Extras + - `parent` (any): No description + - `purchaseFrom` (string): No description + - `purchasePrice` (number): No description + - `purchaseTime` (string): Purchase + - `quantity` (integer): No description + - `serialNumber` (string): No description + - `soldNotes` (string): No description + - `soldPrice` (number): No description + - `soldTime` (string): Sold + - `soldTo` (string): No description + - `syncChildItemsLocations` (boolean): No description + - `thumbnailId` (string): No description + - `updatedAt` (string): No description + - `warrantyDetails` (string): No description + - `warrantyExpires` (string): No description + + +--- + + +**Summary:** Update Item + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Item ID | +| `payload` | body | True | object | Item Data | + + + +Object with properties: + - `archived` (boolean): No description + - `assetId` (string): No description + - `description` (string): No description + - `fields` (array): No description + - `id` (string): No description + - `insured` (boolean): No description + - `labelIds` (array): No description + - `lifetimeWarranty` (boolean): Warranty + - `locationId` (string): Edges + - `manufacturer` (string): No description + - `modelNumber` (string): No description + - `name` (string): No description + - `notes` (string): Extras + - `parentId` (string): No description + - `purchaseFrom` (string): No description + - `purchasePrice` (number): No description + - `purchaseTime` (string): Purchase + - `quantity` (integer): No description + - `serialNumber` (string): Identifications + - `soldNotes` (string): No description + - `soldPrice` (number): No description + - `soldTime` (string): Sold + - `soldTo` (string): No description + - `syncChildItemsLocations` (boolean): No description + - `warrantyDetails` (string): No description + - `warrantyExpires` (string): No description +``` + + + +- **200**: OK + **Schema:** + Object with properties: + - `archived` (boolean): No description + - `assetId` (string): No description + - `attachments` (array): No description + - `createdAt` (string): No description + - `description` (string): No description + - `fields` (array): No description + - `id` (string): No description + - `imageId` (string): No description + - `insured` (boolean): No description + - `labels` (array): No description + - `lifetimeWarranty` (boolean): Warranty + - `location` (any): Edges + - `manufacturer` (string): No description + - `modelNumber` (string): No description + - `name` (string): No description + - `notes` (string): Extras + - `parent` (any): No description + - `purchaseFrom` (string): No description + - `purchasePrice` (number): No description + - `purchaseTime` (string): Purchase + - `quantity` (integer): No description + - `serialNumber` (string): No description + - `soldNotes` (string): No description + - `soldPrice` (number): No description + - `soldTime` (string): Sold + - `soldTo` (string): No description + - `syncChildItemsLocations` (boolean): No description + - `thumbnailId` (string): No description + - `updatedAt` (string): No description + - `warrantyDetails` (string): No description + - `warrantyExpires` (string): No description + + +--- + + +**Summary:** Delete Item + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Item ID | + + + +- **204**: No Content + +--- + + +**Summary:** Update Item + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Item ID | +| `payload` | body | True | object | Item Data | + + + +Object with properties: + - `id` (string): No description + - `quantity` (integer): No description +``` + + + +- **200**: OK + **Schema:** + Object with properties: + - `archived` (boolean): No description + - `assetId` (string): No description + - `attachments` (array): No description + - `createdAt` (string): No description + - `description` (string): No description + - `fields` (array): No description + - `id` (string): No description + - `imageId` (string): No description + - `insured` (boolean): No description + - `labels` (array): No description + - `lifetimeWarranty` (boolean): Warranty + - `location` (any): Edges + - `manufacturer` (string): No description + - `modelNumber` (string): No description + - `name` (string): No description + - `notes` (string): Extras + - `parent` (any): No description + - `purchaseFrom` (string): No description + - `purchasePrice` (number): No description + - `purchaseTime` (string): Purchase + - `quantity` (integer): No description + - `serialNumber` (string): No description + - `soldNotes` (string): No description + - `soldPrice` (number): No description + - `soldTime` (string): Sold + - `soldTo` (string): No description + - `syncChildItemsLocations` (boolean): No description + - `thumbnailId` (string): No description + - `updatedAt` (string): No description + - `warrantyDetails` (string): No description + - `warrantyExpires` (string): No description + + +--- + + +**Summary:** Create Item Attachment + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Item ID | +| `file` | formData | True | file | File attachment | +| `type` | formData | False | string | Type of file | +| `primary` | formData | False | boolean | Is this the primary attachment | +| `name` | formData | True | string | name of the file including extension | + + +| Name | Type | Description | +|------|------|-------------| +| `file` | file | File attachment | +| `type` | string | Type of file | +| `primary` | boolean | Is this the primary attachment | +| `name` | string | name of the file including extension | + + +- **200**: OK + **Schema:** + Object with properties: + - `archived` (boolean): No description + - `assetId` (string): No description + - `attachments` (array): No description + - `createdAt` (string): No description + - `description` (string): No description + - `fields` (array): No description + - `id` (string): No description + - `imageId` (string): No description + - `insured` (boolean): No description + - `labels` (array): No description + - `lifetimeWarranty` (boolean): Warranty + - `location` (any): Edges + - `manufacturer` (string): No description + - `modelNumber` (string): No description + - `name` (string): No description + - `notes` (string): Extras + - `parent` (any): No description + - `purchaseFrom` (string): No description + - `purchasePrice` (number): No description + - `purchaseTime` (string): Purchase + - `quantity` (integer): No description + - `serialNumber` (string): No description + - `soldNotes` (string): No description + - `soldPrice` (number): No description + - `soldTime` (string): Sold + - `soldTo` (string): No description + - `syncChildItemsLocations` (boolean): No description + - `thumbnailId` (string): No description + - `updatedAt` (string): No description + - `warrantyDetails` (string): No description + - `warrantyExpires` (string): No description + +- **422**: Unprocessable Entity + **Schema:** + Object with properties: + - `error` (string): No description + - `fields` (string): No description + + +--- + + +**Summary:** Get Item Attachment + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Item ID | +| `attachment_id` | path | True | string | Attachment ID | + + + +- **200**: OK + **Schema:** + Object with properties: + - `token` (string): No description + + +--- + + +**Summary:** Update Item Attachment + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Item ID | +| `attachment_id` | path | True | string | Attachment ID | +| `payload` | body | True | object | Attachment Update | + + + +Object with properties: + - `primary` (boolean): No description + - `title` (string): No description + - `type` (string): No description +``` + + + +- **200**: OK + **Schema:** + Object with properties: + - `archived` (boolean): No description + - `assetId` (string): No description + - `attachments` (array): No description + - `createdAt` (string): No description + - `description` (string): No description + - `fields` (array): No description + - `id` (string): No description + - `imageId` (string): No description + - `insured` (boolean): No description + - `labels` (array): No description + - `lifetimeWarranty` (boolean): Warranty + - `location` (any): Edges + - `manufacturer` (string): No description + - `modelNumber` (string): No description + - `name` (string): No description + - `notes` (string): Extras + - `parent` (any): No description + - `purchaseFrom` (string): No description + - `purchasePrice` (number): No description + - `purchaseTime` (string): Purchase + - `quantity` (integer): No description + - `serialNumber` (string): No description + - `soldNotes` (string): No description + - `soldPrice` (number): No description + - `soldTime` (string): Sold + - `soldTo` (string): No description + - `syncChildItemsLocations` (boolean): No description + - `thumbnailId` (string): No description + - `updatedAt` (string): No description + - `warrantyDetails` (string): No description + - `warrantyExpires` (string): No description + + +--- + + +**Summary:** Delete Item Attachment + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Item ID | +| `attachment_id` | path | True | string | Attachment ID | + + + +- **204**: No Content + +--- + + +**Summary:** Duplicate Item + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Item ID | +| `payload` | body | True | object | Duplicate Options | + + + +Object with properties: + - `copyAttachments` (boolean): No description + - `copyCustomFields` (boolean): No description + - `copyMaintenance` (boolean): No description + - `copyPrefix` (string): No description +``` + + + +- **201**: Created + **Schema:** + Object with properties: + - `archived` (boolean): No description + - `assetId` (string): No description + - `attachments` (array): No description + - `createdAt` (string): No description + - `description` (string): No description + - `fields` (array): No description + - `id` (string): No description + - `imageId` (string): No description + - `insured` (boolean): No description + - `labels` (array): No description + - `lifetimeWarranty` (boolean): Warranty + - `location` (any): Edges + - `manufacturer` (string): No description + - `modelNumber` (string): No description + - `name` (string): No description + - `notes` (string): Extras + - `parent` (any): No description + - `purchaseFrom` (string): No description + - `purchasePrice` (number): No description + - `purchaseTime` (string): Purchase + - `quantity` (integer): No description + - `serialNumber` (string): No description + - `soldNotes` (string): No description + - `soldPrice` (number): No description + - `soldTime` (string): Sold + - `soldTo` (string): No description + - `syncChildItemsLocations` (boolean): No description + - `thumbnailId` (string): No description + - `updatedAt` (string): No description + - `warrantyDetails` (string): No description + - `warrantyExpires` (string): No description + + +--- + + +**Summary:** Get Maintenance Log + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Item ID | +| `status` | query | False | string | | + + + +- **200**: OK + **Schema:** + Array of: + Object with properties: + - `completedDate` (string): No description + - `cost` (string): No description + - `description` (string): No description + - `id` (string): No description + - `itemID` (string): No description + - `itemName` (string): No description + - `name` (string): No description + - `scheduledDate` (string): No description + + +--- + + +**Summary:** Create Maintenance Entry + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Item ID | +| `payload` | body | True | object | Entry Data | + + + +Object with properties: + - `completedDate` (string): No description + - `cost` (string): No description + - `description` (string): No description + - `name` (string): No description + - `scheduledDate` (string): No description +``` + + + +- **201**: Created + **Schema:** + Object with properties: + - `completedDate` (string): No description + - `cost` (string): No description + - `description` (string): No description + - `id` (string): No description + - `name` (string): No description + - `scheduledDate` (string): No description + + +--- + + +**Summary:** Get the full path of an item + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Item ID | + + + +- **200**: OK + **Schema:** + Array of: + Object with properties: + - `id` (string): No description + - `name` (string): No description + - `type` (any): No description + + +--- + + +**Summary:** Get Asset label + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Asset ID | +| `print` | query | False | boolean | Print this label, defaults to false | + + + +- **200**: image/png + **Schema:** + string + + +--- + + +**Summary:** Get Item label + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Item ID | +| `print` | query | False | boolean | Print this label, defaults to false | + + + +- **200**: image/png + **Schema:** + string + + +--- + + +**Summary:** Get Location label + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Location ID | +| `print` | query | False | boolean | Print this label, defaults to false | + + + +- **200**: image/png + **Schema:** + string + + +--- + + +**Summary:** Get All Labels + + +- **200**: OK + **Schema:** + Array of: + Object with properties: + - `color` (string): No description + - `createdAt` (string): No description + - `description` (string): No description + - `id` (string): No description + - `name` (string): No description + - `updatedAt` (string): No description + + +--- + + +**Summary:** Create Label + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `payload` | body | True | object | Label Data | + + + +Object with properties: + - `color` (string): No description + - `description` (string): No description + - `name` (string): No description +``` + + + +- **200**: OK + **Schema:** + Object with properties: + - `color` (string): No description + - `createdAt` (string): No description + - `description` (string): No description + - `id` (string): No description + - `name` (string): No description + - `updatedAt` (string): No description + + +--- + + +**Summary:** Get Label + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Label ID | + + + +- **200**: OK + **Schema:** + Object with properties: + - `color` (string): No description + - `createdAt` (string): No description + - `description` (string): No description + - `id` (string): No description + - `name` (string): No description + - `updatedAt` (string): No description + + +--- + + +**Summary:** Update Label + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Label ID | + + + +- **200**: OK + **Schema:** + Object with properties: + - `color` (string): No description + - `createdAt` (string): No description + - `description` (string): No description + - `id` (string): No description + - `name` (string): No description + - `updatedAt` (string): No description + + +--- + + +**Summary:** Delete Label + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Label ID | + + + +- **204**: No Content + +--- + + +**Summary:** Get All Locations + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `filterChildren` | query | False | boolean | Filter locations with parents | + + + +- **200**: OK + **Schema:** + Array of: + Object with properties: + - `createdAt` (string): No description + - `description` (string): No description + - `id` (string): No description + - `itemCount` (integer): No description + - `name` (string): No description + - `updatedAt` (string): No description + + +--- + + +**Summary:** Create Location + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `payload` | body | True | object | Location Data | + + + +Object with properties: + - `description` (string): No description + - `name` (string): No description + - `parentId` (string): No description +``` + + + +- **200**: OK + **Schema:** + Object with properties: + - `createdAt` (string): No description + - `description` (string): No description + - `id` (string): No description + - `name` (string): No description + - `updatedAt` (string): No description + + +--- + + +**Summary:** Get Locations Tree + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `withItems` | query | False | boolean | include items in response tree | + + + +- **200**: OK + **Schema:** + Array of: + Object with properties: + - `children` (array): No description + - `id` (string): No description + - `name` (string): No description + - `type` (string): No description + + +--- + + +**Summary:** Get Location + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Location ID | + + + +- **200**: OK + **Schema:** + Object with properties: + - `children` (array): No description + - `createdAt` (string): No description + - `description` (string): No description + - `id` (string): No description + - `name` (string): No description + - `parent` (any): No description + - `totalPrice` (number): No description + - `updatedAt` (string): No description + + +--- + + +**Summary:** Update Location + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Location ID | +| `payload` | body | True | object | Location Data | + + + +Object with properties: + - `description` (string): No description + - `id` (string): No description + - `name` (string): No description + - `parentId` (string): No description +``` + + + +- **200**: OK + **Schema:** + Object with properties: + - `children` (array): No description + - `createdAt` (string): No description + - `description` (string): No description + - `id` (string): No description + - `name` (string): No description + - `parent` (any): No description + - `totalPrice` (number): No description + - `updatedAt` (string): No description + + +--- + + +**Summary:** Delete Location + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Location ID | + + + +- **204**: No Content + +--- + + +**Summary:** Query All Maintenance + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `status` | query | False | string | | + + + +- **200**: OK + **Schema:** + Array of: + Object with properties: + - `completedDate` (string): No description + - `cost` (string): No description + - `description` (string): No description + - `id` (string): No description + - `itemID` (string): No description + - `itemName` (string): No description + - `name` (string): No description + - `scheduledDate` (string): No description + + +--- + + +**Summary:** Update Maintenance Entry + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Maintenance ID | +| `payload` | body | True | object | Entry Data | + + + +Object with properties: + - `completedDate` (string): No description + - `cost` (string): No description + - `description` (string): No description + - `name` (string): No description + - `scheduledDate` (string): No description +``` + + + +- **200**: OK + **Schema:** + Object with properties: + - `completedDate` (string): No description + - `cost` (string): No description + - `description` (string): No description + - `id` (string): No description + - `name` (string): No description + - `scheduledDate` (string): No description + + +--- + + +**Summary:** Delete Maintenance Entry + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Maintenance ID | + + + +- **204**: No Content + +--- + + +**Summary:** Get Notifiers + + +- **200**: OK + **Schema:** + Array of: + Object with properties: + - `createdAt` (string): No description + - `groupId` (string): No description + - `id` (string): No description + - `isActive` (boolean): No description + - `name` (string): No description + - `updatedAt` (string): No description + - `url` (string): No description + - `userId` (string): No description + + +--- + + +**Summary:** Create Notifier + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `payload` | body | True | object | Notifier Data | + + + +Object with properties: + - `isActive` (boolean): No description + - `name` (string): No description + - `url` (string): No description +``` + + + +- **200**: OK + **Schema:** + Object with properties: + - `createdAt` (string): No description + - `groupId` (string): No description + - `id` (string): No description + - `isActive` (boolean): No description + - `name` (string): No description + - `updatedAt` (string): No description + - `url` (string): No description + - `userId` (string): No description + + +--- + + +**Summary:** Test Notifier + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `url` | query | True | string | URL | + + + +- **204**: No Content + +--- + + +**Summary:** Update Notifier + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Notifier ID | +| `payload` | body | True | object | Notifier Data | + + + +Object with properties: + - `isActive` (boolean): No description + - `name` (string): No description + - `url` (string): No description +``` + + + +- **200**: OK + **Schema:** + Object with properties: + - `createdAt` (string): No description + - `groupId` (string): No description + - `id` (string): No description + - `isActive` (boolean): No description + - `name` (string): No description + - `updatedAt` (string): No description + - `url` (string): No description + - `userId` (string): No description + + +--- + + +**Summary:** Delete a Notifier + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `id` | path | True | string | Notifier ID | + + + +- **204**: No Content + +--- + + +**Summary:** Search EAN from Barcode + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `data` | query | False | string | barcode to be searched | + + + +- **200**: OK + **Schema:** + Array of: + Object with properties: + - `barcode` (string): No description + - `imageBase64` (string): No description + - `imageURL` (string): No description + - `item` (any): No description + - `manufacturer` (string): No description + - `modelNumber` (string): Identifications + - `notes` (string): Extras + - `search_engine_name` (string): No description + + +--- + + +**Summary:** Create QR Code + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `data` | query | False | string | data to be encoded into qrcode | + + + +- **200**: image/jpeg + **Schema:** + string + + +--- + + +**Summary:** Export Bill of Materials + + +- **200**: text/csv + **Schema:** + string + + +--- + + +**Summary:** Application Info + + +- **200**: OK + **Schema:** + Object with properties: + - `allowRegistration` (boolean): No description + - `build` (any): No description + - `demo` (boolean): No description + - `health` (boolean): No description + - `labelPrinting` (boolean): No description + - `latest` (any): No description + - `message` (string): No description + - `title` (string): No description + - `versions` (array): No description + + +--- + + +**Summary:** Change Password + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `payload` | body | True | object | Password Payload | + + + +Object with properties: + - `current` (string): No description + - `new` (string): No description +``` + + + +- **204**: No Content + +--- + + +**Summary:** User Login + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `payload` | body | True | object | Login Data | +| `provider` | query | False | string | auth provider | + + + +Object with properties: + - `password` (string): No description + - `stayLoggedIn` (boolean): No description + - `username` (string): No description +``` + + + +- **200**: OK + **Schema:** + Object with properties: + - `attachmentToken` (string): No description + - `expiresAt` (string): No description + - `token` (string): No description + + +--- + + +**Summary:** User Logout + + +- **204**: No Content + +--- + + +**Summary:** User Token Refresh + +**Description:** handleAuthRefresh returns a handler that will issue a new token from an existing token. +This does not validate that the user still exists within the database. + + +- **200**: OK + +--- + + +**Summary:** Register New User + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `payload` | body | True | object | User Data | + + + +Object with properties: + - `email` (string): No description + - `name` (string): No description + - `password` (string): No description + - `token` (string): No description +``` + + + +- **204**: No Content + +--- + + +**Summary:** Get User Self + + +- **200**: OK + +--- + + +**Summary:** Update Account + + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `payload` | body | True | object | User Data | + + + +Object with properties: + - `email` (string): No description + - `name` (string): No description +``` + + + +- **200**: OK + +--- + + +**Summary:** Delete Account + + +- **204**: No Content + +--- + + diff --git a/tech_spec/document.json b/tech_spec/document.json new file mode 100644 index 0000000..c62359b --- /dev/null +++ b/tech_spec/document.json @@ -0,0 +1,4374 @@ +{ + "schemes": [ + "https", + "http" + ], + "swagger": "2.0", + "info": { + "description": "Track, Manage, and Organize your Things.", + "title": "Homebox API", + "contact": { + "name": "Homebox Team", + "url": "https://discord.homebox.software" + }, + "version": "1.0" + }, + "host": "demo.homebox.software", + "basePath": "/api", + "paths": { + "/v1/actions/create-missing-thumbnails": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "Creates thumbnails for items that are missing them", + "produces": [ + "application/json" + ], + "tags": [ + "Actions" + ], + "summary": "Create Missing Thumbnails", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/v1.ActionAmountResult" + } + } + } + } + }, + "/v1/actions/ensure-asset-ids": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "Ensures all items in the database have an asset ID", + "produces": [ + "application/json" + ], + "tags": [ + "Actions" + ], + "summary": "Ensure Asset IDs", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/v1.ActionAmountResult" + } + } + } + } + }, + "/v1/actions/ensure-import-refs": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "Ensures all items in the database have an import ref", + "produces": [ + "application/json" + ], + "tags": [ + "Actions" + ], + "summary": "Ensures Import Refs", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/v1.ActionAmountResult" + } + } + } + } + }, + "/v1/actions/set-primary-photos": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "Sets the first photo of each item as the primary photo", + "produces": [ + "application/json" + ], + "tags": [ + "Actions" + ], + "summary": "Set Primary Photos", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/v1.ActionAmountResult" + } + } + } + } + }, + "/v1/actions/zero-item-time-fields": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "Resets all item date fields to the beginning of the day", + "produces": [ + "application/json" + ], + "tags": [ + "Actions" + ], + "summary": "Zero Out Time Fields", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/v1.ActionAmountResult" + } + } + } + } + }, + "/v1/assets/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Get Item by Asset ID", + "parameters": [ + { + "type": "string", + "description": "Asset ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.PaginationResult-repo_ItemSummary" + } + } + } + } + }, + "/v1/currency": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Base" + ], + "summary": "Currency", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/currencies.Currency" + } + } + } + } + }, + "/v1/groups": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Group" + ], + "summary": "Get Group", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.Group" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Group" + ], + "summary": "Update Group", + "parameters": [ + { + "description": "User Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.GroupUpdate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.Group" + } + } + } + } + }, + "/v1/groups/invitations": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Group" + ], + "summary": "Create Group Invitation", + "parameters": [ + { + "description": "User Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1.GroupInvitationCreate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/v1.GroupInvitation" + } + } + } + } + }, + "/v1/groups/statistics": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Statistics" + ], + "summary": "Get Group Statistics", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.GroupStatistics" + } + } + } + } + }, + "/v1/groups/statistics/labels": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Statistics" + ], + "summary": "Get Label Statistics", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.TotalsByOrganizer" + } + } + } + } + } + }, + "/v1/groups/statistics/locations": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Statistics" + ], + "summary": "Get Location Statistics", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.TotalsByOrganizer" + } + } + } + } + } + }, + "/v1/groups/statistics/purchase-price": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Statistics" + ], + "summary": "Get Purchase Price Statistics", + "parameters": [ + { + "type": "string", + "description": "start date", + "name": "start", + "in": "query" + }, + { + "type": "string", + "description": "end date", + "name": "end", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.ValueOverTime" + } + } + } + } + }, + "/v1/items": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Query All Items", + "parameters": [ + { + "type": "string", + "description": "search string", + "name": "q", + "in": "query" + }, + { + "type": "integer", + "description": "page number", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "items per page", + "name": "pageSize", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "label Ids", + "name": "labels", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "location Ids", + "name": "locations", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "parent Ids", + "name": "parentIds", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.PaginationResult-repo_ItemSummary" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Create Item", + "parameters": [ + { + "description": "Item Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.ItemCreate" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/repo.ItemSummary" + } + } + } + } + }, + "/v1/items/export": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "tags": [ + "Items" + ], + "summary": "Export Items", + "responses": { + "200": { + "description": "text/csv", + "schema": { + "type": "string" + } + } + } + } + }, + "/v1/items/fields": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Get All Custom Field Names", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "/v1/items/fields/values": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Get All Custom Field Values", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "/v1/items/import": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Import Items", + "parameters": [ + { + "type": "file", + "description": "Image to upload", + "name": "csv", + "in": "formData", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/v1/items/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Get Item", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.ItemOut" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Update Item", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Item Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.ItemUpdate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.ItemOut" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Delete Item", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + }, + "patch": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Update Item", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Item Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.ItemPatch" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.ItemOut" + } + } + } + } + }, + "/v1/items/{id}/attachments": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items Attachments" + ], + "summary": "Create Item Attachment", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "file", + "description": "File attachment", + "name": "file", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Type of file", + "name": "type", + "in": "formData" + }, + { + "type": "boolean", + "description": "Is this the primary attachment", + "name": "primary", + "in": "formData" + }, + { + "type": "string", + "description": "name of the file including extension", + "name": "name", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.ItemOut" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/validate.ErrorResponse" + } + } + } + } + }, + "/v1/items/{id}/attachments/{attachment_id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/octet-stream" + ], + "tags": [ + "Items Attachments" + ], + "summary": "Get Item Attachment", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Attachment ID", + "name": "attachment_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/v1.ItemAttachmentToken" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "tags": [ + "Items Attachments" + ], + "summary": "Update Item Attachment", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Attachment ID", + "name": "attachment_id", + "in": "path", + "required": true + }, + { + "description": "Attachment Update", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.ItemAttachmentUpdate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.ItemOut" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "tags": [ + "Items Attachments" + ], + "summary": "Delete Item Attachment", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Attachment ID", + "name": "attachment_id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/v1/items/{id}/duplicate": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Duplicate Item", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Duplicate Options", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.DuplicateOptions" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/repo.ItemOut" + } + } + } + } + }, + "/v1/items/{id}/maintenance": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Item Maintenance" + ], + "summary": "Get Maintenance Log", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + }, + { + "enum": [ + "scheduled", + "completed", + "both" + ], + "type": "string", + "x-enum-varnames": [ + "MaintenanceFilterStatusScheduled", + "MaintenanceFilterStatusCompleted", + "MaintenanceFilterStatusBoth" + ], + "name": "status", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.MaintenanceEntryWithDetails" + } + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Item Maintenance" + ], + "summary": "Create Maintenance Entry", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Entry Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.MaintenanceEntryCreate" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/repo.MaintenanceEntry" + } + } + } + } + }, + "/v1/items/{id}/path": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Get the full path of an item", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.ItemPath" + } + } + } + } + } + }, + "/v1/labelmaker/assets/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Get Asset label", + "parameters": [ + { + "type": "string", + "description": "Asset ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Print this label, defaults to false", + "name": "print", + "in": "query" + } + ], + "responses": { + "200": { + "description": "image/png", + "schema": { + "type": "string" + } + } + } + } + }, + "/v1/labelmaker/item/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Get Item label", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Print this label, defaults to false", + "name": "print", + "in": "query" + } + ], + "responses": { + "200": { + "description": "image/png", + "schema": { + "type": "string" + } + } + } + } + }, + "/v1/labelmaker/location/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Locations" + ], + "summary": "Get Location label", + "parameters": [ + { + "type": "string", + "description": "Location ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Print this label, defaults to false", + "name": "print", + "in": "query" + } + ], + "responses": { + "200": { + "description": "image/png", + "schema": { + "type": "string" + } + } + } + } + }, + "/v1/labels": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "Get All Labels", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.LabelOut" + } + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "Create Label", + "parameters": [ + { + "description": "Label Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.LabelCreate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.LabelSummary" + } + } + } + } + }, + "/v1/labels/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "Get Label", + "parameters": [ + { + "type": "string", + "description": "Label ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.LabelOut" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "Update Label", + "parameters": [ + { + "type": "string", + "description": "Label ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.LabelOut" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "Delete Label", + "parameters": [ + { + "type": "string", + "description": "Label ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/v1/locations": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Locations" + ], + "summary": "Get All Locations", + "parameters": [ + { + "type": "boolean", + "description": "Filter locations with parents", + "name": "filterChildren", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.LocationOutCount" + } + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Locations" + ], + "summary": "Create Location", + "parameters": [ + { + "description": "Location Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.LocationCreate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.LocationSummary" + } + } + } + } + }, + "/v1/locations/tree": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Locations" + ], + "summary": "Get Locations Tree", + "parameters": [ + { + "type": "boolean", + "description": "include items in response tree", + "name": "withItems", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.TreeItem" + } + } + } + } + } + }, + "/v1/locations/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Locations" + ], + "summary": "Get Location", + "parameters": [ + { + "type": "string", + "description": "Location ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.LocationOut" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Locations" + ], + "summary": "Update Location", + "parameters": [ + { + "type": "string", + "description": "Location ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Location Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.LocationUpdate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.LocationOut" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Locations" + ], + "summary": "Delete Location", + "parameters": [ + { + "type": "string", + "description": "Location ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/v1/maintenance": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maintenance" + ], + "summary": "Query All Maintenance", + "parameters": [ + { + "enum": [ + "scheduled", + "completed", + "both" + ], + "type": "string", + "x-enum-varnames": [ + "MaintenanceFilterStatusScheduled", + "MaintenanceFilterStatusCompleted", + "MaintenanceFilterStatusBoth" + ], + "name": "status", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.MaintenanceEntryWithDetails" + } + } + } + } + } + }, + "/v1/maintenance/{id}": { + "put": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maintenance" + ], + "summary": "Update Maintenance Entry", + "parameters": [ + { + "type": "string", + "description": "Maintenance ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Entry Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.MaintenanceEntryUpdate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.MaintenanceEntry" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maintenance" + ], + "summary": "Delete Maintenance Entry", + "parameters": [ + { + "type": "string", + "description": "Maintenance ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/v1/notifiers": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Notifiers" + ], + "summary": "Get Notifiers", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.NotifierOut" + } + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Notifiers" + ], + "summary": "Create Notifier", + "parameters": [ + { + "description": "Notifier Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.NotifierCreate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.NotifierOut" + } + } + } + } + }, + "/v1/notifiers/test": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Notifiers" + ], + "summary": "Test Notifier", + "parameters": [ + { + "type": "string", + "description": "URL", + "name": "url", + "in": "query", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/v1/notifiers/{id}": { + "put": { + "security": [ + { + "Bearer": [] + } + ], + "tags": [ + "Notifiers" + ], + "summary": "Update Notifier", + "parameters": [ + { + "type": "string", + "description": "Notifier ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Notifier Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.NotifierUpdate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.NotifierOut" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "tags": [ + "Notifiers" + ], + "summary": "Delete a Notifier", + "parameters": [ + { + "type": "string", + "description": "Notifier ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/v1/products/search-from-barcode": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Search EAN from Barcode", + "parameters": [ + { + "type": "string", + "description": "barcode to be searched", + "name": "data", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.BarcodeProduct" + } + } + } + } + } + }, + "/v1/qrcode": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Create QR Code", + "parameters": [ + { + "type": "string", + "description": "data to be encoded into qrcode", + "name": "data", + "in": "query" + } + ], + "responses": { + "200": { + "description": "image/jpeg", + "schema": { + "type": "string" + } + } + } + } + }, + "/v1/reporting/bill-of-materials": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Reporting" + ], + "summary": "Export Bill of Materials", + "responses": { + "200": { + "description": "text/csv", + "schema": { + "type": "string" + } + } + } + } + }, + "/v1/status": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Base" + ], + "summary": "Application Info", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/v1.APISummary" + } + } + } + } + }, + "/v1/users/change-password": { + "put": { + "security": [ + { + "Bearer": [] + } + ], + "tags": [ + "User" + ], + "summary": "Change Password", + "parameters": [ + { + "description": "Password Payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1.ChangePassword" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/v1/users/login": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Authentication" + ], + "summary": "User Login", + "parameters": [ + { + "description": "Login Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1.LoginForm" + } + }, + { + "type": "string", + "description": "auth provider", + "name": "provider", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/v1.TokenResponse" + } + } + } + } + }, + "/v1/users/logout": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "tags": [ + "Authentication" + ], + "summary": "User Logout", + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/v1/users/refresh": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "handleAuthRefresh returns a handler that will issue a new token from an existing token.\nThis does not validate that the user still exists within the database.", + "tags": [ + "Authentication" + ], + "summary": "User Token Refresh", + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/v1/users/register": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "User" + ], + "summary": "Register New User", + "parameters": [ + { + "description": "User Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/services.UserRegistration" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/v1/users/self": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "User" + ], + "summary": "Get User Self", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/v1.Wrapped" + }, + { + "type": "object", + "properties": { + "item": { + "$ref": "#/definitions/repo.UserOut" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "User" + ], + "summary": "Update Account", + "parameters": [ + { + "description": "User Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.UserUpdate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/v1.Wrapped" + }, + { + "type": "object", + "properties": { + "item": { + "$ref": "#/definitions/repo.UserUpdate" + } + } + } + ] + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "User" + ], + "summary": "Delete Account", + "responses": { + "204": { + "description": "No Content" + } + } + } + } + }, + "definitions": { + "attachment.Type": { + "type": "string", + "enum": [ + "attachment", + "photo", + "manual", + "warranty", + "attachment", + "receipt", + "thumbnail" + ], + "x-enum-varnames": [ + "DefaultType", + "TypePhoto", + "TypeManual", + "TypeWarranty", + "TypeAttachment", + "TypeReceipt", + "TypeThumbnail" + ] + }, + "authroles.Role": { + "type": "string", + "enum": [ + "user", + "admin", + "user", + "attachments" + ], + "x-enum-varnames": [ + "DefaultRole", + "RoleAdmin", + "RoleUser", + "RoleAttachments" + ] + }, + "currencies.Currency": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "local": { + "type": "string" + }, + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + } + } + }, + "ent.Attachment": { + "type": "object", + "properties": { + "created_at": { + "description": "CreatedAt holds the value of the \"created_at\" field.", + "type": "string" + }, + "edges": { + "description": "Edges holds the relations/edges for other nodes in the graph.\nThe values are being populated by the AttachmentQuery when eager-loading is set.", + "allOf": [ + { + "$ref": "#/definitions/ent.AttachmentEdges" + } + ] + }, + "id": { + "description": "ID of the ent.", + "type": "string" + }, + "mime_type": { + "description": "MimeType holds the value of the \"mime_type\" field.", + "type": "string" + }, + "path": { + "description": "Path holds the value of the \"path\" field.", + "type": "string" + }, + "primary": { + "description": "Primary holds the value of the \"primary\" field.", + "type": "boolean" + }, + "title": { + "description": "Title holds the value of the \"title\" field.", + "type": "string" + }, + "type": { + "description": "Type holds the value of the \"type\" field.", + "allOf": [ + { + "$ref": "#/definitions/attachment.Type" + } + ] + }, + "updated_at": { + "description": "UpdatedAt holds the value of the \"updated_at\" field.", + "type": "string" + } + } + }, + "ent.AttachmentEdges": { + "type": "object", + "properties": { + "item": { + "description": "Item holds the value of the item edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.Item" + } + ] + }, + "thumbnail": { + "description": "Thumbnail holds the value of the thumbnail edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.Attachment" + } + ] + } + } + }, + "ent.AuthRoles": { + "type": "object", + "properties": { + "edges": { + "description": "Edges holds the relations/edges for other nodes in the graph.\nThe values are being populated by the AuthRolesQuery when eager-loading is set.", + "allOf": [ + { + "$ref": "#/definitions/ent.AuthRolesEdges" + } + ] + }, + "id": { + "description": "ID of the ent.", + "type": "integer" + }, + "role": { + "description": "Role holds the value of the \"role\" field.", + "allOf": [ + { + "$ref": "#/definitions/authroles.Role" + } + ] + } + } + }, + "ent.AuthRolesEdges": { + "type": "object", + "properties": { + "token": { + "description": "Token holds the value of the token edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.AuthTokens" + } + ] + } + } + }, + "ent.AuthTokens": { + "type": "object", + "properties": { + "created_at": { + "description": "CreatedAt holds the value of the \"created_at\" field.", + "type": "string" + }, + "edges": { + "description": "Edges holds the relations/edges for other nodes in the graph.\nThe values are being populated by the AuthTokensQuery when eager-loading is set.", + "allOf": [ + { + "$ref": "#/definitions/ent.AuthTokensEdges" + } + ] + }, + "expires_at": { + "description": "ExpiresAt holds the value of the \"expires_at\" field.", + "type": "string" + }, + "id": { + "description": "ID of the ent.", + "type": "string" + }, + "token": { + "description": "Token holds the value of the \"token\" field.", + "type": "array", + "items": { + "type": "integer" + } + }, + "updated_at": { + "description": "UpdatedAt holds the value of the \"updated_at\" field.", + "type": "string" + } + } + }, + "ent.AuthTokensEdges": { + "type": "object", + "properties": { + "roles": { + "description": "Roles holds the value of the roles edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.AuthRoles" + } + ] + }, + "user": { + "description": "User holds the value of the user edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.User" + } + ] + } + } + }, + "ent.Group": { + "type": "object", + "properties": { + "created_at": { + "description": "CreatedAt holds the value of the \"created_at\" field.", + "type": "string" + }, + "currency": { + "description": "Currency holds the value of the \"currency\" field.", + "type": "string" + }, + "edges": { + "description": "Edges holds the relations/edges for other nodes in the graph.\nThe values are being populated by the GroupQuery when eager-loading is set.", + "allOf": [ + { + "$ref": "#/definitions/ent.GroupEdges" + } + ] + }, + "id": { + "description": "ID of the ent.", + "type": "string" + }, + "name": { + "description": "Name holds the value of the \"name\" field.", + "type": "string" + }, + "updated_at": { + "description": "UpdatedAt holds the value of the \"updated_at\" field.", + "type": "string" + } + } + }, + "ent.GroupEdges": { + "type": "object", + "properties": { + "invitation_tokens": { + "description": "InvitationTokens holds the value of the invitation_tokens edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.GroupInvitationToken" + } + }, + "items": { + "description": "Items holds the value of the items edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.Item" + } + }, + "labels": { + "description": "Labels holds the value of the labels edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.Label" + } + }, + "locations": { + "description": "Locations holds the value of the locations edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.Location" + } + }, + "notifiers": { + "description": "Notifiers holds the value of the notifiers edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.Notifier" + } + }, + "users": { + "description": "Users holds the value of the users edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.User" + } + } + } + }, + "ent.GroupInvitationToken": { + "type": "object", + "properties": { + "created_at": { + "description": "CreatedAt holds the value of the \"created_at\" field.", + "type": "string" + }, + "edges": { + "description": "Edges holds the relations/edges for other nodes in the graph.\nThe values are being populated by the GroupInvitationTokenQuery when eager-loading is set.", + "allOf": [ + { + "$ref": "#/definitions/ent.GroupInvitationTokenEdges" + } + ] + }, + "expires_at": { + "description": "ExpiresAt holds the value of the \"expires_at\" field.", + "type": "string" + }, + "id": { + "description": "ID of the ent.", + "type": "string" + }, + "token": { + "description": "Token holds the value of the \"token\" field.", + "type": "array", + "items": { + "type": "integer" + } + }, + "updated_at": { + "description": "UpdatedAt holds the value of the \"updated_at\" field.", + "type": "string" + }, + "uses": { + "description": "Uses holds the value of the \"uses\" field.", + "type": "integer" + } + } + }, + "ent.GroupInvitationTokenEdges": { + "type": "object", + "properties": { + "group": { + "description": "Group holds the value of the group edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.Group" + } + ] + } + } + }, + "ent.Item": { + "type": "object", + "properties": { + "archived": { + "description": "Archived holds the value of the \"archived\" field.", + "type": "boolean" + }, + "asset_id": { + "description": "AssetID holds the value of the \"asset_id\" field.", + "type": "integer" + }, + "created_at": { + "description": "CreatedAt holds the value of the \"created_at\" field.", + "type": "string" + }, + "description": { + "description": "Description holds the value of the \"description\" field.", + "type": "string" + }, + "edges": { + "description": "Edges holds the relations/edges for other nodes in the graph.\nThe values are being populated by the ItemQuery when eager-loading is set.", + "allOf": [ + { + "$ref": "#/definitions/ent.ItemEdges" + } + ] + }, + "id": { + "description": "ID of the ent.", + "type": "string" + }, + "import_ref": { + "description": "ImportRef holds the value of the \"import_ref\" field.", + "type": "string" + }, + "insured": { + "description": "Insured holds the value of the \"insured\" field.", + "type": "boolean" + }, + "lifetime_warranty": { + "description": "LifetimeWarranty holds the value of the \"lifetime_warranty\" field.", + "type": "boolean" + }, + "manufacturer": { + "description": "Manufacturer holds the value of the \"manufacturer\" field.", + "type": "string" + }, + "model_number": { + "description": "ModelNumber holds the value of the \"model_number\" field.", + "type": "string" + }, + "name": { + "description": "Name holds the value of the \"name\" field.", + "type": "string" + }, + "notes": { + "description": "Notes holds the value of the \"notes\" field.", + "type": "string" + }, + "purchase_from": { + "description": "PurchaseFrom holds the value of the \"purchase_from\" field.", + "type": "string" + }, + "purchase_price": { + "description": "PurchasePrice holds the value of the \"purchase_price\" field.", + "type": "number" + }, + "purchase_time": { + "description": "PurchaseTime holds the value of the \"purchase_time\" field.", + "type": "string" + }, + "quantity": { + "description": "Quantity holds the value of the \"quantity\" field.", + "type": "integer" + }, + "serial_number": { + "description": "SerialNumber holds the value of the \"serial_number\" field.", + "type": "string" + }, + "sold_notes": { + "description": "SoldNotes holds the value of the \"sold_notes\" field.", + "type": "string" + }, + "sold_price": { + "description": "SoldPrice holds the value of the \"sold_price\" field.", + "type": "number" + }, + "sold_time": { + "description": "SoldTime holds the value of the \"sold_time\" field.", + "type": "string" + }, + "sold_to": { + "description": "SoldTo holds the value of the \"sold_to\" field.", + "type": "string" + }, + "sync_child_items_locations": { + "description": "SyncChildItemsLocations holds the value of the \"sync_child_items_locations\" field.", + "type": "boolean" + }, + "updated_at": { + "description": "UpdatedAt holds the value of the \"updated_at\" field.", + "type": "string" + }, + "warranty_details": { + "description": "WarrantyDetails holds the value of the \"warranty_details\" field.", + "type": "string" + }, + "warranty_expires": { + "description": "WarrantyExpires holds the value of the \"warranty_expires\" field.", + "type": "string" + } + } + }, + "ent.ItemEdges": { + "type": "object", + "properties": { + "attachments": { + "description": "Attachments holds the value of the attachments edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.Attachment" + } + }, + "children": { + "description": "Children holds the value of the children edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.Item" + } + }, + "fields": { + "description": "Fields holds the value of the fields edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.ItemField" + } + }, + "group": { + "description": "Group holds the value of the group edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.Group" + } + ] + }, + "label": { + "description": "Label holds the value of the label edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.Label" + } + }, + "location": { + "description": "Location holds the value of the location edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.Location" + } + ] + }, + "maintenance_entries": { + "description": "MaintenanceEntries holds the value of the maintenance_entries edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.MaintenanceEntry" + } + }, + "parent": { + "description": "Parent holds the value of the parent edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.Item" + } + ] + } + } + }, + "ent.ItemField": { + "type": "object", + "properties": { + "boolean_value": { + "description": "BooleanValue holds the value of the \"boolean_value\" field.", + "type": "boolean" + }, + "created_at": { + "description": "CreatedAt holds the value of the \"created_at\" field.", + "type": "string" + }, + "description": { + "description": "Description holds the value of the \"description\" field.", + "type": "string" + }, + "edges": { + "description": "Edges holds the relations/edges for other nodes in the graph.\nThe values are being populated by the ItemFieldQuery when eager-loading is set.", + "allOf": [ + { + "$ref": "#/definitions/ent.ItemFieldEdges" + } + ] + }, + "id": { + "description": "ID of the ent.", + "type": "string" + }, + "name": { + "description": "Name holds the value of the \"name\" field.", + "type": "string" + }, + "number_value": { + "description": "NumberValue holds the value of the \"number_value\" field.", + "type": "integer" + }, + "text_value": { + "description": "TextValue holds the value of the \"text_value\" field.", + "type": "string" + }, + "time_value": { + "description": "TimeValue holds the value of the \"time_value\" field.", + "type": "string" + }, + "type": { + "description": "Type holds the value of the \"type\" field.", + "allOf": [ + { + "$ref": "#/definitions/itemfield.Type" + } + ] + }, + "updated_at": { + "description": "UpdatedAt holds the value of the \"updated_at\" field.", + "type": "string" + } + } + }, + "ent.ItemFieldEdges": { + "type": "object", + "properties": { + "item": { + "description": "Item holds the value of the item edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.Item" + } + ] + } + } + }, + "ent.Label": { + "type": "object", + "properties": { + "color": { + "description": "Color holds the value of the \"color\" field.", + "type": "string" + }, + "created_at": { + "description": "CreatedAt holds the value of the \"created_at\" field.", + "type": "string" + }, + "description": { + "description": "Description holds the value of the \"description\" field.", + "type": "string" + }, + "edges": { + "description": "Edges holds the relations/edges for other nodes in the graph.\nThe values are being populated by the LabelQuery when eager-loading is set.", + "allOf": [ + { + "$ref": "#/definitions/ent.LabelEdges" + } + ] + }, + "id": { + "description": "ID of the ent.", + "type": "string" + }, + "name": { + "description": "Name holds the value of the \"name\" field.", + "type": "string" + }, + "updated_at": { + "description": "UpdatedAt holds the value of the \"updated_at\" field.", + "type": "string" + } + } + }, + "ent.LabelEdges": { + "type": "object", + "properties": { + "group": { + "description": "Group holds the value of the group edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.Group" + } + ] + }, + "items": { + "description": "Items holds the value of the items edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.Item" + } + } + } + }, + "ent.Location": { + "type": "object", + "properties": { + "created_at": { + "description": "CreatedAt holds the value of the \"created_at\" field.", + "type": "string" + }, + "description": { + "description": "Description holds the value of the \"description\" field.", + "type": "string" + }, + "edges": { + "description": "Edges holds the relations/edges for other nodes in the graph.\nThe values are being populated by the LocationQuery when eager-loading is set.", + "allOf": [ + { + "$ref": "#/definitions/ent.LocationEdges" + } + ] + }, + "id": { + "description": "ID of the ent.", + "type": "string" + }, + "name": { + "description": "Name holds the value of the \"name\" field.", + "type": "string" + }, + "updated_at": { + "description": "UpdatedAt holds the value of the \"updated_at\" field.", + "type": "string" + } + } + }, + "ent.LocationEdges": { + "type": "object", + "properties": { + "children": { + "description": "Children holds the value of the children edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.Location" + } + }, + "group": { + "description": "Group holds the value of the group edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.Group" + } + ] + }, + "items": { + "description": "Items holds the value of the items edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.Item" + } + }, + "parent": { + "description": "Parent holds the value of the parent edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.Location" + } + ] + } + } + }, + "ent.MaintenanceEntry": { + "type": "object", + "properties": { + "cost": { + "description": "Cost holds the value of the \"cost\" field.", + "type": "number" + }, + "created_at": { + "description": "CreatedAt holds the value of the \"created_at\" field.", + "type": "string" + }, + "date": { + "description": "Date holds the value of the \"date\" field.", + "type": "string" + }, + "description": { + "description": "Description holds the value of the \"description\" field.", + "type": "string" + }, + "edges": { + "description": "Edges holds the relations/edges for other nodes in the graph.\nThe values are being populated by the MaintenanceEntryQuery when eager-loading is set.", + "allOf": [ + { + "$ref": "#/definitions/ent.MaintenanceEntryEdges" + } + ] + }, + "id": { + "description": "ID of the ent.", + "type": "string" + }, + "item_id": { + "description": "ItemID holds the value of the \"item_id\" field.", + "type": "string" + }, + "name": { + "description": "Name holds the value of the \"name\" field.", + "type": "string" + }, + "scheduled_date": { + "description": "ScheduledDate holds the value of the \"scheduled_date\" field.", + "type": "string" + }, + "updated_at": { + "description": "UpdatedAt holds the value of the \"updated_at\" field.", + "type": "string" + } + } + }, + "ent.MaintenanceEntryEdges": { + "type": "object", + "properties": { + "item": { + "description": "Item holds the value of the item edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.Item" + } + ] + } + } + }, + "ent.Notifier": { + "type": "object", + "properties": { + "created_at": { + "description": "CreatedAt holds the value of the \"created_at\" field.", + "type": "string" + }, + "edges": { + "description": "Edges holds the relations/edges for other nodes in the graph.\nThe values are being populated by the NotifierQuery when eager-loading is set.", + "allOf": [ + { + "$ref": "#/definitions/ent.NotifierEdges" + } + ] + }, + "group_id": { + "description": "GroupID holds the value of the \"group_id\" field.", + "type": "string" + }, + "id": { + "description": "ID of the ent.", + "type": "string" + }, + "is_active": { + "description": "IsActive holds the value of the \"is_active\" field.", + "type": "boolean" + }, + "name": { + "description": "Name holds the value of the \"name\" field.", + "type": "string" + }, + "updated_at": { + "description": "UpdatedAt holds the value of the \"updated_at\" field.", + "type": "string" + }, + "user_id": { + "description": "UserID holds the value of the \"user_id\" field.", + "type": "string" + } + } + }, + "ent.NotifierEdges": { + "type": "object", + "properties": { + "group": { + "description": "Group holds the value of the group edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.Group" + } + ] + }, + "user": { + "description": "User holds the value of the user edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.User" + } + ] + } + } + }, + "ent.User": { + "type": "object", + "properties": { + "activated_on": { + "description": "ActivatedOn holds the value of the \"activated_on\" field.", + "type": "string" + }, + "created_at": { + "description": "CreatedAt holds the value of the \"created_at\" field.", + "type": "string" + }, + "edges": { + "description": "Edges holds the relations/edges for other nodes in the graph.\nThe values are being populated by the UserQuery when eager-loading is set.", + "allOf": [ + { + "$ref": "#/definitions/ent.UserEdges" + } + ] + }, + "email": { + "description": "Email holds the value of the \"email\" field.", + "type": "string" + }, + "id": { + "description": "ID of the ent.", + "type": "string" + }, + "is_superuser": { + "description": "IsSuperuser holds the value of the \"is_superuser\" field.", + "type": "boolean" + }, + "name": { + "description": "Name holds the value of the \"name\" field.", + "type": "string" + }, + "role": { + "description": "Role holds the value of the \"role\" field.", + "allOf": [ + { + "$ref": "#/definitions/user.Role" + } + ] + }, + "superuser": { + "description": "Superuser holds the value of the \"superuser\" field.", + "type": "boolean" + }, + "updated_at": { + "description": "UpdatedAt holds the value of the \"updated_at\" field.", + "type": "string" + } + } + }, + "ent.UserEdges": { + "type": "object", + "properties": { + "auth_tokens": { + "description": "AuthTokens holds the value of the auth_tokens edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.AuthTokens" + } + }, + "group": { + "description": "Group holds the value of the group edge.", + "allOf": [ + { + "$ref": "#/definitions/ent.Group" + } + ] + }, + "notifiers": { + "description": "Notifiers holds the value of the notifiers edge.", + "type": "array", + "items": { + "$ref": "#/definitions/ent.Notifier" + } + } + } + }, + "itemfield.Type": { + "type": "string", + "enum": [ + "text", + "number", + "boolean", + "time" + ], + "x-enum-varnames": [ + "TypeText", + "TypeNumber", + "TypeBoolean", + "TypeTime" + ] + }, + "repo.BarcodeProduct": { + "type": "object", + "properties": { + "barcode": { + "type": "string" + }, + "imageBase64": { + "type": "string" + }, + "imageURL": { + "type": "string" + }, + "item": { + "$ref": "#/definitions/repo.ItemCreate" + }, + "manufacturer": { + "type": "string" + }, + "modelNumber": { + "description": "Identifications", + "type": "string" + }, + "notes": { + "description": "Extras", + "type": "string" + }, + "search_engine_name": { + "type": "string" + } + } + }, + "repo.DuplicateOptions": { + "type": "object", + "properties": { + "copyAttachments": { + "type": "boolean" + }, + "copyCustomFields": { + "type": "boolean" + }, + "copyMaintenance": { + "type": "boolean" + }, + "copyPrefix": { + "type": "string" + } + } + }, + "repo.Group": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "currency": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "repo.GroupStatistics": { + "type": "object", + "properties": { + "totalItemPrice": { + "type": "number" + }, + "totalItems": { + "type": "integer" + }, + "totalLabels": { + "type": "integer" + }, + "totalLocations": { + "type": "integer" + }, + "totalUsers": { + "type": "integer" + }, + "totalWithWarranty": { + "type": "integer" + } + } + }, + "repo.GroupUpdate": { + "type": "object", + "properties": { + "currency": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "repo.ItemAttachment": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "mimeType": { + "type": "string" + }, + "path": { + "type": "string" + }, + "primary": { + "type": "boolean" + }, + "thumbnail": { + "$ref": "#/definitions/ent.Attachment" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "repo.ItemAttachmentUpdate": { + "type": "object", + "properties": { + "primary": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "repo.ItemCreate": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "description": { + "type": "string", + "maxLength": 1000 + }, + "labelIds": { + "type": "array", + "items": { + "type": "string" + } + }, + "locationId": { + "description": "Edges", + "type": "string" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "parentId": { + "type": "string", + "x-nullable": true + }, + "quantity": { + "type": "integer" + } + } + }, + "repo.ItemField": { + "type": "object", + "properties": { + "booleanValue": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "numberValue": { + "type": "integer" + }, + "textValue": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "repo.ItemOut": { + "type": "object", + "properties": { + "archived": { + "type": "boolean" + }, + "assetId": { + "type": "string", + "example": "0" + }, + "attachments": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.ItemAttachment" + } + }, + "createdAt": { + "type": "string" + }, + "description": { + "type": "string" + }, + "fields": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.ItemField" + } + }, + "id": { + "type": "string" + }, + "imageId": { + "type": "string", + "x-nullable": true, + "x-omitempty": true + }, + "insured": { + "type": "boolean" + }, + "labels": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.LabelSummary" + } + }, + "lifetimeWarranty": { + "description": "Warranty", + "type": "boolean" + }, + "location": { + "description": "Edges", + "allOf": [ + { + "$ref": "#/definitions/repo.LocationSummary" + } + ], + "x-nullable": true, + "x-omitempty": true + }, + "manufacturer": { + "type": "string" + }, + "modelNumber": { + "type": "string" + }, + "name": { + "type": "string" + }, + "notes": { + "description": "Extras", + "type": "string" + }, + "parent": { + "allOf": [ + { + "$ref": "#/definitions/repo.ItemSummary" + } + ], + "x-nullable": true, + "x-omitempty": true + }, + "purchaseFrom": { + "type": "string" + }, + "purchasePrice": { + "type": "number" + }, + "purchaseTime": { + "description": "Purchase", + "type": "string" + }, + "quantity": { + "type": "integer" + }, + "serialNumber": { + "type": "string" + }, + "soldNotes": { + "type": "string" + }, + "soldPrice": { + "type": "number" + }, + "soldTime": { + "description": "Sold", + "type": "string" + }, + "soldTo": { + "type": "string" + }, + "syncChildItemsLocations": { + "type": "boolean" + }, + "thumbnailId": { + "type": "string", + "x-nullable": true, + "x-omitempty": true + }, + "updatedAt": { + "type": "string" + }, + "warrantyDetails": { + "type": "string" + }, + "warrantyExpires": { + "type": "string" + } + } + }, + "repo.ItemPatch": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "quantity": { + "type": "integer", + "x-nullable": true, + "x-omitempty": true + } + } + }, + "repo.ItemPath": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/repo.ItemType" + } + } + }, + "repo.ItemSummary": { + "type": "object", + "properties": { + "archived": { + "type": "boolean" + }, + "assetId": { + "type": "string", + "example": "0" + }, + "createdAt": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "imageId": { + "type": "string", + "x-nullable": true, + "x-omitempty": true + }, + "insured": { + "type": "boolean" + }, + "labels": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.LabelSummary" + } + }, + "location": { + "description": "Edges", + "allOf": [ + { + "$ref": "#/definitions/repo.LocationSummary" + } + ], + "x-nullable": true, + "x-omitempty": true + }, + "name": { + "type": "string" + }, + "purchasePrice": { + "type": "number" + }, + "quantity": { + "type": "integer" + }, + "soldTime": { + "description": "Sale details", + "type": "string" + }, + "thumbnailId": { + "type": "string", + "x-nullable": true, + "x-omitempty": true + }, + "updatedAt": { + "type": "string" + } + } + }, + "repo.ItemType": { + "type": "string", + "enum": [ + "location", + "item" + ], + "x-enum-varnames": [ + "ItemTypeLocation", + "ItemTypeItem" + ] + }, + "repo.ItemUpdate": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "archived": { + "type": "boolean" + }, + "assetId": { + "type": "string" + }, + "description": { + "type": "string", + "maxLength": 1000 + }, + "fields": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.ItemField" + } + }, + "id": { + "type": "string" + }, + "insured": { + "type": "boolean" + }, + "labelIds": { + "type": "array", + "items": { + "type": "string" + } + }, + "lifetimeWarranty": { + "description": "Warranty", + "type": "boolean" + }, + "locationId": { + "description": "Edges", + "type": "string" + }, + "manufacturer": { + "type": "string" + }, + "modelNumber": { + "type": "string" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "notes": { + "description": "Extras", + "type": "string" + }, + "parentId": { + "type": "string", + "x-nullable": true, + "x-omitempty": true + }, + "purchaseFrom": { + "type": "string", + "maxLength": 255 + }, + "purchasePrice": { + "type": "number", + "x-nullable": true, + "x-omitempty": true + }, + "purchaseTime": { + "description": "Purchase", + "type": "string" + }, + "quantity": { + "type": "integer" + }, + "serialNumber": { + "description": "Identifications", + "type": "string" + }, + "soldNotes": { + "type": "string" + }, + "soldPrice": { + "type": "number", + "x-nullable": true, + "x-omitempty": true + }, + "soldTime": { + "description": "Sold", + "type": "string" + }, + "soldTo": { + "type": "string", + "maxLength": 255 + }, + "syncChildItemsLocations": { + "type": "boolean" + }, + "warrantyDetails": { + "type": "string" + }, + "warrantyExpires": { + "type": "string" + } + } + }, + "repo.LabelCreate": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "color": { + "type": "string" + }, + "description": { + "type": "string", + "maxLength": 1000 + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1 + } + } + }, + "repo.LabelOut": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "repo.LabelSummary": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "repo.LocationCreate": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parentId": { + "type": "string", + "x-nullable": true + } + } + }, + "repo.LocationOut": { + "type": "object", + "properties": { + "children": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.LocationSummary" + } + }, + "createdAt": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parent": { + "$ref": "#/definitions/repo.LocationSummary" + }, + "totalPrice": { + "type": "number" + }, + "updatedAt": { + "type": "string" + } + } + }, + "repo.LocationOutCount": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "itemCount": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "repo.LocationSummary": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "repo.LocationUpdate": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parentId": { + "type": "string", + "x-nullable": true + } + } + }, + "repo.MaintenanceEntry": { + "type": "object", + "properties": { + "completedDate": { + "type": "string" + }, + "cost": { + "type": "string", + "example": "0" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "scheduledDate": { + "type": "string" + } + } + }, + "repo.MaintenanceEntryCreate": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "completedDate": { + "type": "string" + }, + "cost": { + "type": "string", + "example": "0" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "scheduledDate": { + "type": "string" + } + } + }, + "repo.MaintenanceEntryUpdate": { + "type": "object", + "properties": { + "completedDate": { + "type": "string" + }, + "cost": { + "type": "string", + "example": "0" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "scheduledDate": { + "type": "string" + } + } + }, + "repo.MaintenanceEntryWithDetails": { + "type": "object", + "properties": { + "completedDate": { + "type": "string" + }, + "cost": { + "type": "string", + "example": "0" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "itemID": { + "type": "string" + }, + "itemName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "scheduledDate": { + "type": "string" + } + } + }, + "repo.MaintenanceFilterStatus": { + "type": "string", + "enum": [ + "scheduled", + "completed", + "both" + ], + "x-enum-varnames": [ + "MaintenanceFilterStatusScheduled", + "MaintenanceFilterStatusCompleted", + "MaintenanceFilterStatusBoth" + ] + }, + "repo.NotifierCreate": { + "type": "object", + "required": [ + "name", + "url" + ], + "properties": { + "isActive": { + "type": "boolean" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "url": { + "type": "string" + } + } + }, + "repo.NotifierOut": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "groupId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "isActive": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "url": { + "type": "string" + }, + "userId": { + "type": "string" + } + } + }, + "repo.NotifierUpdate": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "isActive": { + "type": "boolean" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "url": { + "type": "string", + "x-nullable": true + } + } + }, + "repo.PaginationResult-repo_ItemSummary": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.ItemSummary" + } + }, + "page": { + "type": "integer" + }, + "pageSize": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + }, + "repo.TotalsByOrganizer": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "total": { + "type": "number" + } + } + }, + "repo.TreeItem": { + "type": "object", + "properties": { + "children": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.TreeItem" + } + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "repo.UserOut": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "groupId": { + "type": "string" + }, + "groupName": { + "type": "string" + }, + "id": { + "type": "string" + }, + "isOwner": { + "type": "boolean" + }, + "isSuperuser": { + "type": "boolean" + }, + "name": { + "type": "string" + } + } + }, + "repo.UserUpdate": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "repo.ValueOverTime": { + "type": "object", + "properties": { + "end": { + "type": "string" + }, + "entries": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.ValueOverTimeEntry" + } + }, + "start": { + "type": "string" + }, + "valueAtEnd": { + "type": "number" + }, + "valueAtStart": { + "type": "number" + } + } + }, + "repo.ValueOverTimeEntry": { + "type": "object", + "properties": { + "date": { + "type": "string" + }, + "name": { + "type": "string" + }, + "value": { + "type": "number" + } + } + }, + "services.Latest": { + "type": "object", + "properties": { + "date": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "services.UserRegistration": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "token": { + "type": "string" + } + } + }, + "user.Role": { + "type": "string", + "enum": [ + "user", + "user", + "owner" + ], + "x-enum-varnames": [ + "DefaultRole", + "RoleUser", + "RoleOwner" + ] + }, + "v1.APISummary": { + "type": "object", + "properties": { + "allowRegistration": { + "type": "boolean" + }, + "build": { + "$ref": "#/definitions/v1.Build" + }, + "demo": { + "type": "boolean" + }, + "health": { + "type": "boolean" + }, + "labelPrinting": { + "type": "boolean" + }, + "latest": { + "$ref": "#/definitions/services.Latest" + }, + "message": { + "type": "string" + }, + "title": { + "type": "string" + }, + "versions": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1.ActionAmountResult": { + "type": "object", + "properties": { + "completed": { + "type": "integer" + } + } + }, + "v1.Build": { + "type": "object", + "properties": { + "buildTime": { + "type": "string" + }, + "commit": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "v1.ChangePassword": { + "type": "object", + "properties": { + "current": { + "type": "string" + }, + "new": { + "type": "string" + } + } + }, + "v1.GroupInvitation": { + "type": "object", + "properties": { + "expiresAt": { + "type": "string" + }, + "token": { + "type": "string" + }, + "uses": { + "type": "integer" + } + } + }, + "v1.GroupInvitationCreate": { + "type": "object", + "required": [ + "uses" + ], + "properties": { + "expiresAt": { + "type": "string" + }, + "uses": { + "type": "integer", + "maximum": 100, + "minimum": 1 + } + } + }, + "v1.ItemAttachmentToken": { + "type": "object", + "properties": { + "token": { + "type": "string" + } + } + }, + "v1.LoginForm": { + "type": "object", + "properties": { + "password": { + "type": "string", + "example": "admin" + }, + "stayLoggedIn": { + "type": "boolean" + }, + "username": { + "type": "string", + "example": "admin@admin.com" + } + } + }, + "v1.TokenResponse": { + "type": "object", + "properties": { + "attachmentToken": { + "type": "string" + }, + "expiresAt": { + "type": "string" + }, + "token": { + "type": "string" + } + } + }, + "v1.Wrapped": { + "type": "object", + "properties": { + "item": {} + } + }, + "validate.ErrorResponse": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "fields": { + "type": "string" + } + } + } + }, + "securityDefinitions": { + "Bearer": { + "description": "\"Type 'Bearer TOKEN' to correctly set the API Key\"", + "type": "apiKey", + "name": "Authorization", + "in": "header" + } + } +} \ No newline at end of file