initial commit

This commit is contained in:
2025-08-06 11:28:28 +03:00
commit b63eca8440
88 changed files with 3392 additions and 0 deletions

25
domain/build.gradle.kts Normal file
View File

@@ -0,0 +1,25 @@
// [FILE] domain/build.gradle.kts
// [PURPOSE] Build script for the domain module.
plugins {
id("org.jetbrains.kotlin.jvm")
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
dependencies {
// [DEPENDENCY] KotlinX Coroutines for asynchronous operations
implementation(Libs.coroutinesCore)
// [DEPENDENCY] Javax Inject for DI annotations
implementation("javax.inject:javax.inject:1")
}
// [END_FILE_domain/build.gradle.kts]

View File

@@ -0,0 +1,18 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] CustomField.kt
// [SEMANTICS] data_structure, entity, custom_field
// [CORE-LOGIC]
/**
* [CONTRACT]
* Модель данных для представления кастомного поля.
* @property name Имя поля.
* @property value Значение поля.
* @property type Тип поля (например, "text", "number").
*/
data class CustomField(
val name: String,
val value: String,
val type: String
)
// [END_FILE_CustomField.kt]

View File

@@ -0,0 +1,20 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] GroupStatistics.kt
// [SEMANTICS] data_structure, statistics
// [CORE-LOGIC]
/**
* [CONTRACT]
* Модель данных для представления агрегированной статистики.
* @property items Общее количество вещей.
* @property labels Общее количество меток.
* @property locations Общее количество местоположений.
* @property totalValue Общая стоимость всех вещей.
*/
data class GroupStatistics(
val items: Int,
val labels: Int,
val locations: Int,
val totalValue: Double
)
// [END_FILE_GroupStatistics.kt]

View File

@@ -0,0 +1,18 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] Image.kt
// [SEMANTICS] data_structure, entity, image
// [CORE-LOGIC]
/**
* [CONTRACT]
* Модель данных для представления изображения, привязанного к вещи.
* @property id Уникальный идентификатор изображения.
* @property path Путь к файлу изображения.
* @property isPrimary Является ли это изображение основным для вещи.
*/
data class Image(
val id: String,
val path: String,
val isPrimary: Boolean
)
// [END_FILE_Image.kt]

View File

@@ -0,0 +1,32 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] Item.kt
package com.homebox.lens.domain.model
import java.math.BigDecimal
// [CONTRACT]
/**
* [ENTITY: DataClass('Item')]
* [PURPOSE] Представляет собой вещь в инвентаре.
* @property id Уникальный идентификатор вещи.
* @property name Название вещи.
* @property description Описание вещи.
* @property image Url изображения.
* @property location Местоположение вещи.
* @property labels Список меток, присвоенных вещи.
* @property value Стоимость вещи.
* @property createdAt Дата создания.
*/
data class Item(
val id: String,
val name: String,
val description: String?,
val image: String?,
val location: Location?,
val labels: List<Label>,
val value: BigDecimal?,
val createdAt: String?
)
// [END_FILE_Item.kt]

View File

@@ -0,0 +1,24 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] ItemAttachment.kt
// [SEMANTICS] data_structure, entity, attachment
// [CORE-LOGIC]
/**
* [CONTRACT]
* Модель данных для представления вложения (файла), привязанного к вещи.
* @property id Уникальный идентификатор вложения.
* @property name Имя файла.
* @property path Путь к файлу.
* @property type MIME-тип файла.
* @property createdAt Дата и время создания.
* @property updatedAt Дата и время последнего обновления.
*/
data class ItemAttachment(
val id: String,
val name: String,
val path: String,
val type: String,
val createdAt: String,
val updatedAt: String
)
// [END_FILE_ItemAttachment.kt]

View File

@@ -0,0 +1,38 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] ItemCreate.kt
// [SEMANTICS] data_structure, entity, input, create
// [CORE-LOGIC]
/**
* [CONTRACT]
* Модель данных для создания новой "Вещи".
* @property name Название вещи (обязательно).
* @property assetId Идентификатор актива.
* @property description Описание.
* @property notes Заметки.
* @property serialNumber Серийный номер.
* @property quantity Количество.
* @property value Стоимость.
* @property purchasePrice Цена покупки.
* @property purchaseDate Дата покупки.
* @property warrantyUntil Гарантия до.
* @property locationId ID местоположения.
* @property parentId ID родительской вещи.
* @property labelIds Список ID меток.
*/
data class ItemCreate(
val name: String,
val assetId: String?,
val description: String?,
val notes: String?,
val serialNumber: String?,
val quantity: Int?,
val value: Double?,
val purchasePrice: Double?,
val purchaseDate: String?,
val warrantyUntil: String?,
val locationId: String?,
val parentId: String?,
val labelIds: List<String>?
)
// [END_FILE_ItemCreate.kt]

View File

@@ -0,0 +1,56 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] ItemOut.kt
// [SEMANTICS] data_structure, entity, detailed
// [CORE-LOGIC]
/**
* [CONTRACT]
* Полная модель данных для представления "Вещи" со всеми полями.
* @property id Уникальный идентификатор.
* @property name Название.
* @property assetId Идентификатор актива.
* @property description Описание.
* @property notes Заметки.
* @property serialNumber Серийный номер.
* @property quantity Количество.
* @property isArchived Флаг архивации.
* @property value Стоимость.
* @property purchasePrice Цена покупки.
* @property purchaseDate Дата покупки.
* @property warrantyUntil Гарантия до.
* @property location Местоположение.
* @property parent Родительская вещь (если есть).
* @property children Дочерние вещи.
* @property labels Список меток.
* @property attachments Список вложений.
* @property images Список изображений.
* @property fields Список кастомных полей.
* @property maintenance Список записей об обслуживании.
* @property createdAt Дата и время создания.
* @property updatedAt Дата и время последнего обновления.
*/
data class ItemOut(
val id: String,
val name: String,
val assetId: String?,
val description: String?,
val notes: String?,
val serialNumber: String?,
val quantity: Int,
val isArchived: Boolean,
val value: Double,
val purchasePrice: Double?,
val purchaseDate: String?,
val warrantyUntil: String?,
val location: LocationOut?,
val parent: ItemSummary?,
val children: List<ItemSummary>,
val labels: List<LabelOut>,
val attachments: List<ItemAttachment>,
val images: List<Image>,
val fields: List<CustomField>,
val maintenance: List<MaintenanceEntry>,
val createdAt: String,
val updatedAt: String
)
// [END_FILE_ItemOut.kt]

View File

@@ -0,0 +1,32 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] ItemSummary.kt
// [SEMANTICS] data_structure, entity, summary
// [CORE-LOGIC]
/**
* [CONTRACT]
* Сокращенная модель данных для представления "Вещи" в списках.
* @property id Уникальный идентификатор вещи.
* @property name Название вещи.
* @property assetId Идентификатор актива.
* @property image Основное изображение. Может быть null.
* @property isArchived Флаг архивации.
* @property labels Список меток.
* @property location Местоположение. Может быть null.
* @property value Стоимость.
* @property createdAt Дата и время создания.
* @property updatedAt Дата и время последнего обновления.
*/
data class ItemSummary(
val id: String,
val name: String,
val assetId: String?,
val image: Image?,
val isArchived: Boolean,
val labels: List<LabelOut>,
val location: LocationOut?,
val value: Double,
val createdAt: String,
val updatedAt: String
)
// [END_FILE_ItemSummary.kt]

View File

@@ -0,0 +1,40 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] ItemUpdate.kt
// [SEMANTICS] data_structure, entity, input, update
// [CORE-LOGIC]
/**
* [CONTRACT]
* Модель данных для обновления существующей "Вещи".
* @property name Название вещи.
* @property assetId Идентификатор актива.
* @property description Описание.
* @property notes Заметки.
* @property serialNumber Серийный номер.
* @property quantity Количество.
* @property isArchived Флаг архивации.
* @property value Стоимость.
* @property purchasePrice Цена покупки.
* @property purchaseDate Дата покупки.
* @property warrantyUntil Гарантия до.
* @property locationId ID местоположения.
* @property parentId ID родительской вещи.
* @property labelIds Список ID меток для полной замены.
*/
data class ItemUpdate(
val name: String?,
val assetId: String?,
val description: String?,
val notes: String?,
val serialNumber: String?,
val quantity: Int?,
val isArchived: Boolean?,
val value: Double?,
val purchasePrice: Double?,
val purchaseDate: String?,
val warrantyUntil: String?,
val locationId: String?,
val parentId: String?,
val labelIds: List<String>?
)
// [END_FILE_ItemUpdate.kt]

View File

@@ -0,0 +1,18 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] Label.kt
package com.homebox.lens.domain.model
// [CONTRACT]
/**
* [ENTITY: DataClass('Label')]
* [PURPOSE] Представляет собой метку (тег), которую можно присвоить вещи.
* @property id Уникальный идентификатор метки.
* @property name Название метки.
*/
data class Label(
val id: String,
val name: String
)
// [END_FILE_Label.kt]

View File

@@ -0,0 +1,24 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] LabelOut.kt
// [SEMANTICS] data_structure, entity, label
// [CORE-LOGIC]
/**
* [CONTRACT]
* Модель данных для представления метки (тега).
* @property id Уникальный идентификатор.
* @property name Название метки.
* @property color Цвет метки в формате HEX (например, "#FF0000").
* @property isArchived Флаг, указывающий, заархивирована ли метка.
* @property createdAt Дата и время создания.
* @property updatedAt Дата и время последнего обновления.
*/
data class LabelOut(
val id: String,
val name: String,
val color: String,
val isArchived: Boolean,
val createdAt: String,
val updatedAt: String
)
// [END_FILE_LabelOut.kt]

View File

@@ -0,0 +1,18 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] Location.kt
package com.homebox.lens.domain.model
// [CONTRACT]
/**
* [ENTITY: DataClass('Location')]
* [PURPOSE] Представляет собой местоположение, где может находиться вещь.
* @property id Уникальный идентификатор местоположения.
* @property name Название местоположения.
*/
data class Location(
val id: String,
val name: String
)
// [END_FILE_Location.kt]

View File

@@ -0,0 +1,24 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] LocationOut.kt
// [SEMANTICS] data_structure, entity, location
// [CORE-LOGIC]
/**
* [CONTRACT]
* Модель данных для представления местоположения (без счетчика).
* @property id Уникальный идентификатор.
* @property name Название местоположения.
* @property color Цвет в формате HEX.
* @property isArchived Флаг архивации.
* @property createdAt Дата и время создания.
* @property updatedAt Дата и время последнего обновления.
*/
data class LocationOut(
val id: String,
val name: String,
val color: String,
val isArchived: Boolean,
val createdAt: String,
val updatedAt: String
)
// [END_FILE_LocationOut.kt]

View File

@@ -0,0 +1,26 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] LocationOutCount.kt
// [SEMANTICS] data_structure, entity, location
// [CORE-LOGIC]
/**
* [CONTRACT]
* Модель данных для представления местоположения со счетчиком вещей.
* @property id Уникальный идентификатор.
* @property name Название местоположения.
* @property color Цвет в формате HEX.
* @property isArchived Флаг архивации.
* @property itemCount Количество вещей в данном местоположении.
* @property createdAt Дата и время создания.
* @property updatedAt Дата и время последнего обновления.
*/
data class LocationOutCount(
val id: String,
val name: String,
val color: String,
val isArchived: Boolean,
val itemCount: Int,
val createdAt: String,
val updatedAt: String
)
// [END_FILE_LocationOutCount.kt]

View File

@@ -0,0 +1,28 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] MaintenanceEntry.kt
// [SEMANTICS] data_structure, entity, maintenance
// [CORE-LOGIC]
/**
* [CONTRACT]
* Модель данных для записи о техническом обслуживании.
* @property id Уникальный идентификатор записи.
* @property itemId ID связанной вещи.
* @property title Заголовок.
* @property details Детальное описание.
* @property dueAt Дата, до которой нужно выполнить.
* @property completedAt Дата выполнения.
* @property createdAt Дата и время создания.
* @property updatedAt Дата и время последнего обновления.
*/
data class MaintenanceEntry(
val id: String,
val itemId: String,
val title: String,
val details: String?,
val dueAt: String?,
val completedAt: String?,
val createdAt: String,
val updatedAt: String
)
// [END_FILE_MaintenanceEntry.kt]

View File

@@ -0,0 +1,21 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] PaginationResult.kt
// [SEMANTICS] data_structure, generic, pagination
// [CORE-LOGIC]
/**
* [CONTRACT]
* Генерик-класс для представления постраничных результатов от API.
* @param T Тип элементов в списке.
* @property items Список элементов на текущей странице.
* @property page Номер текущей страницы.
* @property pageSize Количество элементов на странице.
* @property total Общее количество элементов.
*/
data class PaginationResult<T>(
val items: List<T>,
val page: Int,
val pageSize: Int,
val total: Int
)
// [END_FILE_PaginationResult.kt]

View File

@@ -0,0 +1,28 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] Result.kt
package com.homebox.lens.domain.model
// [CONTRACT]
/**
* [ENTITY: SealedClass('Result')]
* [PURPOSE] Представляет собой результат операции, который может быть либо успешным, либо неуспешным.
* @param T Тип данных в случае успеха.
*/
sealed class Result<out T> {
/**
* [ENTITY: DataClass('Success')]
* [PURPOSE] Представляет собой успешный результат операции.
* @param data Данные, полученные в результате операции.
*/
data class Success<out T>(val data: T) : Result<T>()
/**
* [ENTITY: DataClass('Error')]
* [PURPOSE] Представляет собой неуспешный результат операции.
* @param exception Исключение, которое произошло во время операции.
*/
data class Error(val exception: Exception) : Result<Nothing>()
}
// [END_FILE_Result.kt]

View File

@@ -0,0 +1,24 @@
// [PACKAGE] com.homebox.lens.domain.model
// [FILE] Statistics.kt
package com.homebox.lens.domain.model
import java.math.BigDecimal
// [CONTRACT]
/**
* [ENTITY: DataClass('Statistics')]
* [PURPOSE] Представляет собой статистику по инвентарю.
* @property totalValue Общая стоимость всех вещей.
* @property totalItems Общее количество вещей.
* @property locations Общее количество местоположений.
* @property labels Общее количество меток.
*/
data class Statistics(
val totalValue: BigDecimal,
val totalItems: Int,
val locations: Int,
val labels: Int
)
// [END_FILE_Statistics.kt]

View File

@@ -0,0 +1,25 @@
// [PACKAGE] com.homebox.lens.domain.repository
// [FILE] ItemRepository.kt
// [SEMANTICS] data_access, abstraction, repository
// [IMPORTS]
import com.homebox.lens.domain.model.*
// [CORE-LOGIC]
/**
* [CONTRACT]
* Абстракция репозитория для работы с "Вещами".
* Определяет контракт, которому должен следовать слой данных.
*/
interface ItemRepository {
suspend fun createItem(newItemData: ItemCreate): ItemSummary
suspend fun getItemDetails(itemId: String): ItemOut
suspend fun updateItem(itemId: String, item: ItemUpdate): ItemOut
suspend fun deleteItem(itemId: String)
suspend fun syncInventory(page: Int, pageSize: Int): PaginationResult<ItemSummary>
suspend fun getStatistics(): GroupStatistics
suspend fun getAllLocations(): List<LocationOutCount>
suspend fun getAllLabels(): List<LabelOut>
suspend fun searchItems(query: String): PaginationResult<ItemSummary>
}
// [END_FILE_ItemRepository.kt]

View File

@@ -0,0 +1,44 @@
// [PACKAGE] com.homebox.lens.domain.usecase
// [FILE] CreateItemUseCase.kt
// [SEMANTICS] business_logic, use_case, item_creation
// [IMPORTS]
import com.homebox.lens.domain.model.ItemCreate
import com.homebox.lens.domain.model.ItemSummary
import com.homebox.lens.domain.repository.ItemRepository
import javax.inject.Inject
// [CORE-LOGIC]
/**
* [CONTRACT]
* Use case для создания новой вещи.
* @param itemRepository Репозиторий для работы с данными о вещах.
*/
class CreateItemUseCase @Inject constructor(
private val itemRepository: ItemRepository
) {
/**
* [CONTRACT]
* Выполняет операцию создания вещи.
* @param itemCreate Данные для создания новой вещи.
* @return Возвращает сокращенную модель созданной вещи.
* @throws IllegalArgumentException если название вещи пустое.
*/
suspend operator fun invoke(itemCreate: ItemCreate): ItemSummary {
// [PRECONDITION] Название вещи не может быть пустым.
require(itemCreate.name.isNotBlank()) {
"[PRECONDITION_FAILED] Item name cannot be blank."
}
// [ACTION]
val result = itemRepository.createItem(itemCreate)
// [POSTCONDITION] Убеждаемся, что репозиторий вернул результат.
check(result != null) {
"[POSTCONDITION_FAILED] Repository returned null after creating an item."
}
return result
}
}
// [END_FILE_CreateItemUseCase.kt]

View File

@@ -0,0 +1,34 @@
// [PACKAGE] com.homebox.lens.domain.usecase
// [FILE] DeleteItemUseCase.kt
// [SEMANTICS] business_logic, use_case, item_deletion
// [IMPORTS]
import com.homebox.lens.domain.repository.ItemRepository
import javax.inject.Inject
// [CORE-LOGIC]
/**
* [CONTRACT]
* Use case для удаления вещи.
* @param itemRepository Репозиторий для работы с данными о вещах.
*/
class DeleteItemUseCase @Inject constructor(
private val itemRepository: ItemRepository
) {
/**
* [CONTRACT]
* Выполняет операцию удаления вещи.
* @param itemId ID удаляемой вещи.
* @throws IllegalArgumentException если ID вещи пустое.
*/
suspend operator fun invoke(itemId: String) {
// [PRECONDITION] ID не может быть пустым.
require(itemId.isNotBlank()) {
"[PRECONDITION_FAILED] Item ID cannot be blank."
}
// [ACTION]
itemRepository.deleteItem(itemId)
}
}
// [END_FILE_DeleteItemUseCase.kt]

View File

@@ -0,0 +1,29 @@
// [PACKAGE] com.homebox.lens.domain.usecase
// [FILE] GetAllLabelsUseCase.kt
// [SEMANTICS] business_logic, use_case, label_retrieval
// [IMPORTS]
import com.homebox.lens.domain.model.LabelOut
import com.homebox.lens.domain.repository.ItemRepository
import javax.inject.Inject
// [CORE-LOGIC]
/**
* [CONTRACT]
* Use case для получения всех меток.
* @param itemRepository Репозиторий для работы с данными.
*/
class GetAllLabelsUseCase @Inject constructor(
private val itemRepository: ItemRepository
) {
/**
* [CONTRACT]
* Выполняет операцию получения всех меток.
* @return Возвращает список меток.
*/
suspend operator fun invoke(): List<LabelOut> {
// [ACTION]
return itemRepository.getAllLabels()
}
}
// [END_FILE_GetAllLabelsUseCase.kt]

View File

@@ -0,0 +1,29 @@
// [PACKAGE] com.homebox.lens.domain.usecase
// [FILE] GetAllLocationsUseCase.kt
// [SEMANTICS] business_logic, use_case, location_retrieval
// [IMPORTS]
import com.homebox.lens.domain.model.LocationOutCount
import com.homebox.lens.domain.repository.ItemRepository
import javax.inject.Inject
// [CORE-LOGIC]
/**
* [CONTRACT]
* Use case для получения всех местоположений.
* @param itemRepository Репозиторий для работы с данными.
*/
class GetAllLocationsUseCase @Inject constructor(
private val itemRepository: ItemRepository
) {
/**
* [CONTRACT]
* Выполняет операцию получения всех местоположений.
* @return Возвращает список местоположений со счетчиками.
*/
suspend operator fun invoke(): List<LocationOutCount> {
// [ACTION]
return itemRepository.getAllLocations()
}
}
// [END_FILE_GetAllLocationsUseCase.kt]

View File

@@ -0,0 +1,43 @@
// [PACKAGE] com.homebox.lens.domain.usecase
// [FILE] GetItemDetailsUseCase.kt
// [SEMANTICS] business_logic, use_case, item_retrieval
// [IMPORTS]
import com.homebox.lens.domain.model.ItemOut
import com.homebox.lens.domain.repository.ItemRepository
import javax.inject.Inject
// [CORE-LOGIC]
/**
* [CONTRACT]
* Use case для получения детальной информации о вещи.
* @param itemRepository Репозиторий для работы с данными о вещах.
*/
class GetItemDetailsUseCase @Inject constructor(
private val itemRepository: ItemRepository
) {
/**
* [CONTRACT]
* Выполняет операцию получения детальной информации о вещи.
* @param itemId ID запрашиваемой вещи.
* @return Возвращает полную модель вещи.
* @throws IllegalArgumentException если ID вещи пустое.
*/
suspend operator fun invoke(itemId: String): ItemOut {
// [PRECONDITION] ID не может быть пустым.
require(itemId.isNotBlank()) {
"[PRECONDITION_FAILED] Item ID cannot be blank."
}
// [ACTION]
val result = itemRepository.getItemDetails(itemId)
// [POSTCONDITION] Убеждаемся, что репозиторий вернул результат.
check(result != null) {
"[POSTCONDITION_FAILED] Repository returned null for item ID: $itemId"
}
return result
}
}
// [END_FILE_GetItemDetailsUseCase.kt]

View File

@@ -0,0 +1,29 @@
// [PACKAGE] com.homebox.lens.domain.usecase
// [FILE] GetStatisticsUseCase.kt
// [SEMANTICS] business_logic, use_case, statistics
// [IMPORTS]
import com.homebox.lens.domain.model.GroupStatistics
import com.homebox.lens.domain.repository.ItemRepository
import javax.inject.Inject
// [CORE-LOGIC]
/**
* [CONTRACT]
* Use case для получения статистики.
* @param itemRepository Репозиторий для работы с данными.
*/
class GetStatisticsUseCase @Inject constructor(
private val itemRepository: ItemRepository
) {
/**
* [CONTRACT]
* Выполняет операцию получения статистики.
* @return Возвращает объект со статистикой.
*/
suspend operator fun invoke(): GroupStatistics {
// [ACTION]
return itemRepository.getStatistics()
}
}
// [END_FILE_GetStatisticsUseCase.kt]

View File

@@ -0,0 +1,32 @@
// [PACKAGE] com.homebox.lens.domain.usecase
// [FILE] SearchItemsUseCase.kt
// [SEMANTICS] business_logic, use_case, search
// [IMPORTS]
import com.homebox.lens.domain.model.ItemSummary
import com.homebox.lens.domain.model.PaginationResult
import com.homebox.lens.domain.repository.ItemRepository
import javax.inject.Inject
// [CORE-LOGIC]
/**
* [CONTRACT]
* Use case для поиска вещей по текстовому запросу.
* @param itemRepository Репозиторий для работы с данными.
*/
class SearchItemsUseCase @Inject constructor(
private val itemRepository: ItemRepository
) {
/**
* [CONTRACT]
* Выполняет операцию поиска.
* @param query Поисковый запрос.
* @return Возвращает объект с результатами пагинации.
*/
suspend operator fun invoke(query: String): PaginationResult<ItemSummary> {
// [ACTION]
// Поисковый запрос может быть пустым, сервер обработает это как запрос всех элементов.
return itemRepository.searchItems(query)
}
}
// [END_FILE_SearchItemsUseCase.kt]

View File

@@ -0,0 +1,38 @@
// [PACKAGE] com.homebox.lens.domain.usecase
// [FILE] SyncInventoryUseCase.kt
// [SEMANTICS] business_logic, use_case, data_sync
// [IMPORTS]
import com.homebox.lens.domain.model.ItemSummary
import com.homebox.lens.domain.model.PaginationResult
import com.homebox.lens.domain.repository.ItemRepository
import javax.inject.Inject
// [CORE-LOGIC]
/**
* [CONTRACT]
* Use case для синхронизации (получения) списка вещей.
* @param itemRepository Репозиторий для работы с данными о вещах.
*/
class SyncInventoryUseCase @Inject constructor(
private val itemRepository: ItemRepository
) {
/**
* [CONTRACT]
* Выполняет операцию получения страницы со списком вещей.
* @param page Номер страницы.
* @param pageSize Размер страницы.
* @return Возвращает объект с результатами пагинации.
* @throws IllegalArgumentException если параметры пагинации некорректны.
*/
suspend operator fun invoke(page: Int, pageSize: Int): PaginationResult<ItemSummary> {
// [PRECONDITION] Параметры пагинации должны быть положительными.
require(page > 0 && pageSize > 0) {
"[PRECONDITION_FAILED] Page and pageSize must be positive."
}
// [ACTION]
return itemRepository.syncInventory(page, pageSize)
}
}
// [END_FILE_SyncInventoryUseCase.kt]

View File

@@ -0,0 +1,45 @@
// [PACKAGE] com.homebox.lens.domain.usecase
// [FILE] UpdateItemUseCase.kt
// [SEMANTICS] business_logic, use_case, item_update
// [IMPORTS]
import com.homebox.lens.domain.model.ItemOut
import com.homebox.lens.domain.model.ItemUpdate
import com.homebox.lens.domain.repository.ItemRepository
import javax.inject.Inject
// [CORE-LOGIC]
/**
* [CONTRACT]
* Use case для обновления существующей вещи.
* @param itemRepository Репозиторий для работы с данными о вещах.
*/
class UpdateItemUseCase @Inject constructor(
private val itemRepository: ItemRepository
) {
/**
* [CONTRACT]
* Выполняет операцию обновления вещи.
* @param itemId ID обновляемой вещи.
* @param itemUpdate Данные для обновления.
* @return Возвращает обновленную полную модель вещи.
* @throws IllegalArgumentException если ID вещи пустое.
*/
suspend operator fun invoke(itemId: String, itemUpdate: ItemUpdate): ItemOut {
// [PRECONDITION] ID не может быть пустым.
require(itemId.isNotBlank()) {
"[PRECONDITION_FAILED] Item ID cannot be blank."
}
// [ACTION]
val result = itemRepository.updateItem(itemId, itemUpdate)
// [POSTCONDITION] Убеждаемся, что репозиторий вернул результат.
check(result != null) {
"[POSTCONDITION_FAILED] Repository returned null after updating item ID: $itemId"
}
return result
}
}
// [END_FILE_UpdateItemUseCase.kt]