diff --git a/agent_promts/roles/architect.xml b/agent_promts/roles/architect.xml
index d7de1ea..095f3de 100644
--- a/agent_promts/roles/architect.xml
+++ b/agent_promts/roles/architect.xml
@@ -18,7 +18,7 @@
- При исполнении этой роли, я, Gemini, действую как стратегический интерфейс между человеком-архитектором и автоматизированной системой разработки. Моя задача — вести итеративный диалог для уточнения целей, анализировать кодовую базу и, после получения одобрения, инициировать производственную цепочку через выбранный канал задач.
+ При исполнении этой роли, я действую как стратегический интерфейс между человеком-архитектором и автоматизированной системой разработки. Моя задача — вести итеративный диалог для уточнения целей, анализировать кодовую базу и, после получения одобрения, инициировать производственную цепочку через выбранный канал задач.Основная цель этой роли — трансформировать неструктурированный человеческий диалог в структурированный, машиночитаемый и полностью готовый к исполнению `Work Order` для роли 'Агента-Разработчика'.
diff --git a/agent_promts/roles/semantic_linter.xml b/agent_promts/roles/semantic_linter.xml
index 110f287..2afb586 100644
--- a/agent_promts/roles/semantic_linter.xml
+++ b/agent_promts/roles/semantic_linter.xml
@@ -30,21 +30,6 @@
-
- Задачи для этой роли должны содержать XML-блок, определяющий режим работы.
-
-
- full_project | recent_changes | single_file
-
-
-
-
-
- ]]>
-
-
-
diff --git a/data/src/main/java/com/homebox/lens/data/api/dto/TokenResponseDto.kt b/data/src/main/java/com/homebox/lens/data/api/dto/TokenResponseDto.kt
index 9d860f6..446b133 100644
--- a/data/src/main/java/com/homebox/lens/data/api/dto/TokenResponseDto.kt
+++ b/data/src/main/java/com/homebox/lens/data/api/dto/TokenResponseDto.kt
@@ -28,7 +28,9 @@ data class TokenResponseDto(
*/
fun TokenResponseDto.toDomain(): TokenResponse {
return TokenResponse(
- token = this.token
+ token = this.token,
+ attachmentToken = this.attachmentToken,
+ expiresAt = this.expiresAt
)
}
// [END_ENTITY: Function('toDomain')]
diff --git a/data/src/main/java/com/homebox/lens/data/api/model/LoginRequest.kt b/data/src/main/java/com/homebox/lens/data/api/model/LoginRequest.kt
index b71fd40..0b5296c 100644
--- a/data/src/main/java/com/homebox/lens/data/api/model/LoginRequest.kt
+++ b/data/src/main/java/com/homebox/lens/data/api/model/LoginRequest.kt
@@ -4,9 +4,6 @@
package com.homebox.lens.data.api.model
-import com.squareup.moshi.Json
-import com.squareup.moshi.JsonClass
-
// [IMPORTS]
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
diff --git a/data/src/main/java/com/homebox/lens/data/mapper/DtoToDomain.kt b/data/src/main/java/com/homebox/lens/data/mapper/DtoToDomain.kt
index e868b79..3e720d9 100644
--- a/data/src/main/java/com/homebox/lens/data/mapper/DtoToDomain.kt
+++ b/data/src/main/java/com/homebox/lens/data/mapper/DtoToDomain.kt
@@ -20,6 +20,7 @@ import com.homebox.lens.domain.model.LocationOut as DomainLocationOut
import com.homebox.lens.domain.model.LocationOutCount as DomainLocationOutCount
import com.homebox.lens.domain.model.MaintenanceEntry as DomainMaintenanceEntry
import com.homebox.lens.domain.model.PaginationResult as DomainPaginationResult
+import com.homebox.lens.domain.model.TokenResponse as DomainTokenResponse
// [END_IMPORTS]
// [ENTITY: Function('ItemOutDto.toDomain')]
@@ -265,4 +266,5 @@ fun LabelSummaryDto.toDomain(): DomainLabelSummary {
}
// [END_ENTITY: Function('LabelSummaryDto.toDomain')]
+
// [END_FILE_DtoToDomain.kt]
\ No newline at end of file
diff --git a/data/src/main/java/com/homebox/lens/data/repository/AuthRepositoryImpl.kt b/data/src/main/java/com/homebox/lens/data/repository/AuthRepositoryImpl.kt
index d1d16dd..cce0a9d 100644
--- a/data/src/main/java/com/homebox/lens/data/repository/AuthRepositoryImpl.kt
+++ b/data/src/main/java/com/homebox/lens/data/repository/AuthRepositoryImpl.kt
@@ -8,8 +8,9 @@ package com.homebox.lens.data.repository
import android.content.SharedPreferences
import com.homebox.lens.data.api.HomeboxApiService
import com.homebox.lens.data.api.dto.LoginFormDto
-import com.homebox.lens.data.api.mapper.toDomain
+import com.homebox.lens.data.api.dto.toDomain
import com.homebox.lens.domain.model.Credentials
+import com.homebox.lens.domain.model.Result
import com.homebox.lens.domain.model.TokenResponse
import com.homebox.lens.domain.repository.AuthRepository
import kotlinx.coroutines.Dispatchers
@@ -56,7 +57,7 @@ class AuthRepositoryImpl @Inject constructor(
require(credentials.serverUrl.isNotBlank()) { "Server URL cannot be blank." }
return withContext(Dispatchers.IO) {
- runCatching {
+ try {
Timber.d("[DEBUG][ACTION][creating_retrofit_client] Creating temporary Retrofit client for URL: ${credentials.serverUrl}")
val tempApiService = Retrofit.Builder()
.baseUrl(credentials.serverUrl)
@@ -70,7 +71,10 @@ class AuthRepositoryImpl @Inject constructor(
val tokenResponseDto = tempApiService.login(loginForm)
Timber.d("[DEBUG][ACTION][mapping_to_domain] Mapping token response to domain model.")
- tokenResponseDto.toDomain()
+ Result.Success(tokenResponseDto.toDomain())
+ } catch (e: Exception) {
+ Timber.e(e, "[ERROR][FAILURE][login_failed] Login failed.")
+ Result.Error(e)
}
}
}
diff --git a/domain/src/main/java/com/homebox/lens/domain/model/TokenResponse.kt b/domain/src/main/java/com/homebox/lens/domain/model/TokenResponse.kt
index 170c1a8..9e40f62 100644
--- a/domain/src/main/java/com/homebox/lens/domain/model/TokenResponse.kt
+++ b/domain/src/main/java/com/homebox/lens/domain/model/TokenResponse.kt
@@ -8,9 +8,15 @@ package com.homebox.lens.domain.model
/**
* @summary Data model representing a response from the server with an authentication token.
* @param token A string containing a JWT or other access token.
+ * @param attachmentToken A token for accessing attachments.
+ * @param expiresAt The expiration date of the token.
* @invariant `token` must not be blank.
*/
-data class TokenResponse(val token: String) {
+data class TokenResponse(
+ val token: String,
+ val attachmentToken: String,
+ val expiresAt: String
+) {
init {
require(token.isNotBlank()) { "Token cannot be blank." }
}
diff --git a/domain/src/main/java/com/homebox/lens/domain/usecase/LoginUseCase.kt b/domain/src/main/java/com/homebox/lens/domain/usecase/LoginUseCase.kt
index ae6b253..befb896 100644
--- a/domain/src/main/java/com/homebox/lens/domain/usecase/LoginUseCase.kt
+++ b/domain/src/main/java/com/homebox/lens/domain/usecase/LoginUseCase.kt
@@ -31,17 +31,19 @@ class LoginUseCase @Inject constructor(
"Server URL and username must not be blank."
}
- val loginResult: com.homebox.lens.domain.model.Result = authRepository.login(credentials)
-
- return loginResult.fold(
- onSuccess = {
- authRepository.saveToken(it.token)
- com.homebox.lens.domain.model.Result.Success(Unit)
- },
- onFailure = {
- com.homebox.lens.domain.model.Result.Error(it as Exception)
+ return try {
+ when (val loginResult = authRepository.login(credentials)) {
+ is com.homebox.lens.domain.model.Result.Success -> {
+ authRepository.saveToken(loginResult.data.token)
+ Result.success(Unit)
+ }
+ is com.homebox.lens.domain.model.Result.Error -> {
+ Result.failure(loginResult.exception)
+ }
}
- )
+ } catch (e: Exception) {
+ Result.failure(e)
+ }
}
// [END_ENTITY: Function('invoke')]
}
diff --git a/tasks/enrichment_task_1.xml b/tasks/enrichment_task_1.xml
deleted file mode 100644
index 6c1763a..0000000
--- a/tasks/enrichment_task_1.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- enrichment-task-001
- Perform initial semantic enrichment
- agent-enrichment
- type::enrichment
- status::pending
-
-
-
- full_project
-
-
-
-
-]]>
\ No newline at end of file
diff --git a/tasks/enrichment_ui.xml b/tasks/enrichment_ui.xml
deleted file mode 100644
index 2707fc1..0000000
--- a/tasks/enrichment_ui.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
- directory
- app/src/main/java/com/homebox/lens/ui
-
-]]>
\ No newline at end of file
diff --git a/tasks/work_order_item_edit_screen.xml b/tasks/work_order_item_edit_screen.xml
deleted file mode 100644
index 12145a2..0000000
--- a/tasks/work_order_item_edit_screen.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
- WO-ITEMEDIT-FIX
- [ARCHITECT -> DEV] Исправление выбора локации и меток на экране ItemEdit
- В текущей реализации на экране редактирования/создания элемента (ItemEditScreen) поля "Location" и "Labels" неактивны. Необходимо реализовать функционал выбора значения для этих полей из списка доступных.
- architect-agent
- developer-agent
- pending
-
-
-
-
- Загрузка списков локаций и меток.
-
- 1. Внедрите `GetAllLocationsUseCase` и `GetAllLabelsUseCase` в `ItemEditViewModel`.
- 2. Обновите `ItemEditUiState`, добавив два новых поля: `val allLocations: List = emptyList()` и `val allLabels: List
-
-
-
- Реализация UI для выбора локации.
-
- 1. Замените `OutlinedTextField` для локации на `ExposedDropdownMenuBox`.
- 2. В качестве `dropdownMenu` используйте `DropdownMenuItem` для каждого элемента из `uiState.allLocations`.
- 3. При выборе элемента из списка вызывайте `viewModel.updateLocation(selectedLocation)`.
- 4. В `ExposedDropdownMenuBox` должно отображаться `item.location?.name`.
-
-
-
-
- Реализация UI для выбора меток (множественный выбор).
-
- 1. Поле для меток `Labels` должно оставаться `OutlinedTextField` (read-only), но `onClick` по нему должен открывать диалоговое окно (`AlertDialog`).
- 2. В `AlertDialog` отобразите список всех меток (`uiState.allLabels`) с `Checkbox`'ами.
- 3. Состояние `Checkbox`'ов должно соответствовать списку `item.labels`.
- 4. При нажатии на "OK" в диалоге, вызывайте `viewModel.updateLabels(selectedLabels)`.
-
-
-
-
-
- При нажатии на поле "Location" открывается выпадающий список со всеми локациями.
- Выбранная локация отображается в поле и сохраняется вместе с элементом.
- При нажатии на поле "Labels" открывается диалоговое окно со списком всех меток и чекбоксами.
- Выбранные метки отображаются в поле и сохраняются вместе с элементом.
-
-
-
\ No newline at end of file
diff --git a/tasks/work_order_login_screen.xml b/tasks/work_order_login_screen.xml
deleted file mode 100644
index c43e4c1..0000000
--- a/tasks/work_order_login_screen.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
- WO-LOGIN-REFACTOR
- [ARCHITECT -> DEV] Рефакторинг экрана входа и логики первого запуска
- Цель этой задачи - изменить логику запуска приложения. Экран входа (SetupScreen) должен появляться только при первом запуске, когда учетные данные еще не сохранены. В последующие запуски пользователь должен сразу попадать на главный экран (Dashboard). Также необходимо улучшить визуальное оформление экрана входа.
- architect-agent
- developer-agent
- pending
-
-
-
-
- Добавить public-метод для синхронной проверки наличия учетных данных.
-
- Добавьте в класс `SetupViewModel` новый метод `fun areCredentialsSaved(): Boolean`.
- Этот метод должен синхронно проверять, сохранены ли учетные данные в `CredentialsRepository`.
- Текущая реализация `getCredentials()` асинхронна, что не подходит для быстрой проверки в `NavGraph`.
- Вам может потребоваться изменить `CredentialsRepository` для поддержки синхронной проверки (например, используя `SharedPreferences` напрямую).
-
-
-
-
- Создать новый `SplashScreen`.
-
- Создайте новый Composable-экран `SplashScreen.kt`.
- Этот экран будет новой точкой входа в `NavGraph`.
- Он будет использовать `SetupViewModel` для вызова `areCredentialsSaved()` и, в зависимости от результата, немедленно навигироваться либо на `Screen.Setup`, либо на `Screen.Dashboard`.
- Пока идет проверка, на экране должен отображаться `CircularProgressIndicator`.
-
-
-
-
- Обновить `NavGraph` для использования `SplashScreen`.
-
- Измените `startDestination` в `NavHost` на `Screen.Splash.route`.
- Добавьте `composable` для `SplashScreen`.
- В `SplashScreen` вызовите `navController.navigate` с очисткой бэкстека (`popUpTo(Screen.Splash.route) { inclusive = true }`), чтобы пользователь не мог вернуться на сплэш-экран.
-
-
-
-
- Улучшить UI экрана `SetupScreen`.
-
- Текущий UI слишком прост. Добавьте заголовок, иконку приложения, и более приятное расположение элементов.
- Используйте `Card` для группировки полей ввода. Добавьте `Spacer` для лучшего отступа.
- Кнопку "Connect" сделайте более заметной.
-
-
-
-
-
-
- При первом запуске приложения открывается `SetupScreen`.
- После успешного ввода данных и входа, при последующих перезапусках приложения открывается `DashboardScreen`, минуя `SetupScreen`.
- `SetupScreen` имеет улучшенный и более привлекательный дизайн.
-
-
-
\ No newline at end of file