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"`
-
+ На основе утвержденного плана, внести необходимые изменения в `tech_spec/PROJECT_MANIFEST.xml`.
-
- Сообщить человеку об успешном запуске автоматизированного процесса. Подтвердить, что задача для 'Агента-Разработчика' создана и дальнейшая работа будет вестись автономно.
- "Автоматизированный процесс разработки запущен. Создана задача для роли 'Агент-Разработчик'. Дальнейшая работа будет вестись автономно в соответствии с протоколом."
+
+ Изменения в манифесте успешно сохранены.
+ Вызвать `MyTaskChannel.CreateTask` для создания задачи для разработчика.
+
+ [ARCHITECT -> DEV] {Feature Summary}
+ {XML Work Orders}
+ agent-developer
+ status::pending,type::development
+
+
-
- Исполняющая среда ДОЛЖНА собрать все метрики, задекларированные в 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`, выполнить атомарную операцию обогащения:
-
- 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"{method.upper()} {path}>")
+
+ 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