diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index eed5d4c7..93eb43c7 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -41,9 +41,6 @@
-
-
-
diff --git a/core/network-api/build.gradle.kts b/core/network-api/build.gradle.kts
index 162a2039..fcc2d14d 100644
--- a/core/network-api/build.gradle.kts
+++ b/core/network-api/build.gradle.kts
@@ -32,7 +32,7 @@ android {
}
dependencies {
-
+ implementation(libs.gson)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
diff --git a/core/network-api/src/main/java/ru/yeahub/network_api/ApiService.kt b/core/network-api/src/main/java/ru/yeahub/network_api/ApiService.kt
index 8fecf80b..77378f55 100644
--- a/core/network-api/src/main/java/ru/yeahub/network_api/ApiService.kt
+++ b/core/network-api/src/main/java/ru/yeahub/network_api/ApiService.kt
@@ -7,9 +7,21 @@ import ru.yeahub.network_api.models.GetSkillsResponse
import ru.yeahub.network_api.models.GetSpecializationResponse
import ru.yeahub.network_api.models.GetSpecializationsResponse
import ru.yeahub.network_api.models.RegistrationRequestDto
+import ru.yeahub.network_api.models.AuthUserDto
+import ru.yeahub.network_api.models.LoginRequestDto
+import ru.yeahub.network_api.models.LoginResponseDto
interface ApiService {
+ /**
+ * API авторизации:
+ * - login - выполняет вход по email и паролю
+ * - getProfile - получает профиль авторизованного пользователя
+ */
+ suspend fun login(request: LoginRequestDto): LoginResponseDto
+
+ suspend fun getProfile(): AuthUserDto
+
suspend fun register(request: RegistrationRequestDto)
suspend fun getQuestions(
diff --git a/core/network-api/src/main/java/ru/yeahub/network_api/models/AuthPermissionDto.kt b/core/network-api/src/main/java/ru/yeahub/network_api/models/AuthPermissionDto.kt
new file mode 100644
index 00000000..b27dc421
--- /dev/null
+++ b/core/network-api/src/main/java/ru/yeahub/network_api/models/AuthPermissionDto.kt
@@ -0,0 +1,11 @@
+package ru.yeahub.network_api.models
+
+/**
+ * DTO разрешения пользователя:
+ * - id - идентификатор разрешения
+ * - name - название разрешения
+ */
+data class AuthPermissionDto(
+ val id: Int,
+ val name: String,
+)
\ No newline at end of file
diff --git a/core/network-api/src/main/java/ru/yeahub/network_api/models/AuthUserDto.kt b/core/network-api/src/main/java/ru/yeahub/network_api/models/AuthUserDto.kt
new file mode 100644
index 00000000..7a7abaa5
--- /dev/null
+++ b/core/network-api/src/main/java/ru/yeahub/network_api/models/AuthUserDto.kt
@@ -0,0 +1,35 @@
+package ru.yeahub.network_api.models
+
+/**
+ * DTO пользователя из auth response:
+ * - id - идентификатор пользователя
+ * - username - имя пользователя
+ * - phone - телефон
+ * - email - email
+ * - country - страна
+ * - city - город
+ * - address - адрес
+ * - avatarUrl - ссылка на аватар
+ * - birthday - дата рождения
+ * - updatedAt - дата обновления
+ * - createdAt - дата создания
+ * - userRoles - роли пользователя
+ * - isVerified - подтверждён ли пользователь
+ * - isEmailNotificationsEnable - включены ли email-уведомления
+ */
+data class AuthUserDto(
+ val id: String?,
+ val username: String?,
+ val phone: String?,
+ val email: String?,
+ val country: String?,
+ val city: String?,
+ val address: String?,
+ val avatarUrl: String?,
+ val birthday: String?,
+ val updatedAt: String?,
+ val createdAt: String?,
+ val userRoles: List?,
+ val isVerified: Boolean?,
+ val isEmailNotificationsEnable: Boolean?,
+)
\ No newline at end of file
diff --git a/core/network-api/src/main/java/ru/yeahub/network_api/models/AuthUserRoleDto.kt b/core/network-api/src/main/java/ru/yeahub/network_api/models/AuthUserRoleDto.kt
new file mode 100644
index 00000000..5237652c
--- /dev/null
+++ b/core/network-api/src/main/java/ru/yeahub/network_api/models/AuthUserRoleDto.kt
@@ -0,0 +1,13 @@
+package ru.yeahub.network_api.models
+
+/**
+ * DTO роли пользователя:
+ * - id - идентификатор роли
+ * - name - название роли
+ * - permissions - список разрешений роли
+ */
+data class AuthUserRoleDto(
+ val id: Int,
+ val name: String,
+ val permissions: List,
+)
\ No newline at end of file
diff --git a/core/network-api/src/main/java/ru/yeahub/network_api/models/ErrorResponseDto.kt b/core/network-api/src/main/java/ru/yeahub/network_api/models/ErrorResponseDto.kt
new file mode 100644
index 00000000..4d3098e5
--- /dev/null
+++ b/core/network-api/src/main/java/ru/yeahub/network_api/models/ErrorResponseDto.kt
@@ -0,0 +1,11 @@
+package ru.yeahub.network_api.models
+
+/**
+ * Response модель ошибки backend:
+ * - key - backend key ошибки
+ * - message - текстовое описание ошибки
+ */
+data class ErrorResponseDto(
+ val key: String?,
+ val message: String?,
+)
\ No newline at end of file
diff --git a/core/network-api/src/main/java/ru/yeahub/network_api/models/LoginRequestDto.kt b/core/network-api/src/main/java/ru/yeahub/network_api/models/LoginRequestDto.kt
new file mode 100644
index 00000000..ce66432f
--- /dev/null
+++ b/core/network-api/src/main/java/ru/yeahub/network_api/models/LoginRequestDto.kt
@@ -0,0 +1,11 @@
+package ru.yeahub.network_api.models
+
+/**
+ * Request модель авторизации:
+ * - email - email пользователя
+ * - password - пароль пользователя
+ */
+data class LoginRequestDto(
+ val email: String,
+ val password: String,
+)
\ No newline at end of file
diff --git a/core/network-api/src/main/java/ru/yeahub/network_api/models/LoginResponseDto.kt b/core/network-api/src/main/java/ru/yeahub/network_api/models/LoginResponseDto.kt
new file mode 100644
index 00000000..2342f5b5
--- /dev/null
+++ b/core/network-api/src/main/java/ru/yeahub/network_api/models/LoginResponseDto.kt
@@ -0,0 +1,13 @@
+package ru.yeahub.network_api.models
+
+import com.google.gson.annotations.SerializedName
+/**
+ * Response модель авторизации:
+ * - accessToken - access token пользователя
+ * - user - данные пользователя
+ */
+data class LoginResponseDto(
+ @SerializedName("access_token")
+ val accessToken: String,
+ val user: AuthUserDto,
+)
\ No newline at end of file
diff --git a/feature/authentication/impl/build.gradle.kts b/feature/authentication/impl/build.gradle.kts
index f19c0873..3c03380e 100644
--- a/feature/authentication/impl/build.gradle.kts
+++ b/feature/authentication/impl/build.gradle.kts
@@ -75,6 +75,7 @@ dependencies {
// Retrofit (for HttpException)
implementation(libs.retrofit.core)
+ implementation(libs.gson)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
diff --git a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/mapper/LoginDomainToDataMapper.kt b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/mapper/LoginDomainToDataMapper.kt
new file mode 100644
index 00000000..d4798c8b
--- /dev/null
+++ b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/mapper/LoginDomainToDataMapper.kt
@@ -0,0 +1,18 @@
+package ru.yeahub.authentication.impl.login.data.mapper
+
+import ru.yeahub.authentication.impl.login.domain.entity.LoginModel
+import ru.yeahub.network_api.models.LoginRequestDto
+
+/**
+ * Mapper domain модели авторизации в request модель backend:
+ * - LoginModel преобразует в LoginRequestDto
+ */
+class LoginDomainToDataMapper {
+
+ fun map(model: LoginModel): LoginRequestDto {
+ return LoginRequestDto(
+ email = model.email,
+ password = model.password,
+ )
+ }
+}
\ No newline at end of file
diff --git a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/mapper/LoginResponseToDomainMapper.kt b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/mapper/LoginResponseToDomainMapper.kt
new file mode 100644
index 00000000..0b009cbd
--- /dev/null
+++ b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/mapper/LoginResponseToDomainMapper.kt
@@ -0,0 +1,27 @@
+package ru.yeahub.authentication.impl.login.data.mapper
+
+import ru.yeahub.authentication.impl.login.domain.entity.AuthResult
+import ru.yeahub.authentication.impl.login.domain.entity.AuthTokens
+import ru.yeahub.authentication.impl.login.domain.entity.UserProfile
+import ru.yeahub.network_api.models.LoginResponseDto
+
+/**
+ * Mapper response модели авторизации в domain модель:
+ * - LoginResponseDto преобразует в AuthResult
+ */
+class LoginResponseToDomainMapper {
+
+ fun map(dto: LoginResponseDto): AuthResult {
+ return AuthResult(
+ tokens = AuthTokens(
+ accessToken = dto.accessToken,
+ ),
+ userProfile = UserProfile(
+ id = dto.user.id,
+ email = dto.user.email,
+ username = dto.user.username,
+ avatarUrl = dto.user.avatarUrl,
+ ),
+ )
+ }
+}
\ No newline at end of file
diff --git a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/repository/LoginRepositoryImpl.kt b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/repository/LoginRepositoryImpl.kt
new file mode 100644
index 00000000..bb34b6c4
--- /dev/null
+++ b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/repository/LoginRepositoryImpl.kt
@@ -0,0 +1,121 @@
+package ru.yeahub.authentication.impl.login.data.repository
+
+import com.google.gson.Gson
+import kotlinx.coroutines.CancellationException
+import retrofit2.HttpException
+import ru.yeahub.authentication.impl.login.data.mapper.LoginDomainToDataMapper
+import ru.yeahub.authentication.impl.login.data.mapper.LoginResponseToDomainMapper
+import ru.yeahub.authentication.impl.login.data.repository.remote.LoginRemoteDataSourceApi
+import ru.yeahub.authentication.impl.login.domain.entity.AuthResult
+import ru.yeahub.authentication.impl.login.domain.entity.Failure
+import ru.yeahub.authentication.impl.login.domain.entity.LoginError
+import ru.yeahub.authentication.impl.login.domain.entity.LoginException
+import ru.yeahub.authentication.impl.login.domain.entity.LoginModel
+import ru.yeahub.authentication.impl.login.domain.repository.LoginRepositoryApi
+import ru.yeahub.network_api.models.ErrorResponseDto
+import java.io.IOException
+
+/**
+ * Реализация репозитория авторизации:
+ * - преобразует domain модель в DTO
+ * - вызывает remote data source
+ * - преобразует DTO в domain модель
+ * - маппит сетевые и backend ошибки в LoginException
+ */
+class LoginRepositoryImpl(
+ private val remoteDataSourceApi: LoginRemoteDataSourceApi,
+ private val domainToDataMapper: LoginDomainToDataMapper,
+ private val responseToDomainMapper: LoginResponseToDomainMapper,
+ private val gson: Gson,
+) : LoginRepositoryApi {
+
+ override suspend fun login(loginModel: LoginModel): AuthResult {
+ return try {
+ val request = domainToDataMapper.map(loginModel)
+ val response = remoteDataSourceApi.login(request)
+ responseToDomainMapper.map(response)
+ } catch (exception: CancellationException) {
+ throw exception
+ } catch (exception: IOException) {
+ throw LoginException(
+ error = LoginError.Network,
+ failure = Failure(cause = exception),
+ )
+ } catch (exception: HttpException) {
+ throw mapHttpException(exception)
+ }
+ }
+
+ /**
+ * Маппит HTTP-ошибку backend в domain ошибку авторизации:
+ * - сначала пытается прочитать backend key
+ * - если key неизвестен, использует HTTP status code
+ */
+ private fun mapHttpException(exception: HttpException): LoginException {
+ val code = exception.code()
+ val backendKey = exception.getBackendErrorKey()
+
+ val error = when (backendKey) {
+ BACKEND_KEY_INVALID_PASSWORD -> LoginError.InvalidPassword
+ BACKEND_KEY_INVALID_CREDENTIALS -> LoginError.InvalidCredentials
+ BACKEND_KEY_USER_NOT_FOUND -> LoginError.UserNotFound
+ BACKEND_KEY_ACCOUNT_BLOCKED -> LoginError.AccountBlocked
+ BACKEND_KEY_TOO_MANY_ATTEMPTS -> LoginError.TooManyAttempts
+ BACKEND_KEY_EMAIL_NOT_CONFIRMED -> LoginError.EmailNotConfirmed
+ else -> mapHttpCodeToError(code)
+ }
+
+ return LoginException(
+ error = error,
+ failure = Failure(
+ cause = exception,
+ httpCode = code,
+ ),
+ )
+ }
+
+ /**
+ * Маппит HTTP status code в domain ошибку авторизации:
+ * - используется как fallback, если backend key отсутствует или неизвестен
+ */
+ private fun mapHttpCodeToError(code: Int): LoginError {
+ return when (code) {
+ HTTP_BAD_REQUEST,
+ HTTP_UNAUTHORIZED -> LoginError.InvalidCredentials
+
+ HTTP_NOT_FOUND -> LoginError.UserNotFound
+
+ in HTTP_SERVER_ERROR_MIN..HTTP_SERVER_ERROR_MAX -> LoginError.Server
+
+ else -> LoginError.Unknown
+ }
+ }
+
+ /**
+ * Извлекает backend key из error body:
+ * - парсит ErrorResponseDto
+ * - возвращает null, если body пустой или формат неизвестен
+ */
+ private fun HttpException.getBackendErrorKey(): String? {
+ val errorBody = response()?.errorBody()?.string() ?: return null
+
+ return runCatching {
+ gson.fromJson(errorBody, ErrorResponseDto::class.java).key
+ }.getOrNull()
+ }
+
+ private companion object {
+ private const val HTTP_BAD_REQUEST = 400
+ private const val HTTP_UNAUTHORIZED = 401
+ private const val HTTP_NOT_FOUND = 404
+ private const val HTTP_SERVER_ERROR_MIN = 500
+ private const val HTTP_SERVER_ERROR_MAX = 599
+
+ private const val BACKEND_KEY_INVALID_PASSWORD = "auth.user.password.invalid"
+ private const val BACKEND_KEY_INVALID_CREDENTIALS = "auth.login.invalid_credentials"
+ private const val BACKEND_KEY_USER_NOT_FOUND = "user.user.id.not_found"
+ private const val BACKEND_KEY_ACCOUNT_BLOCKED = "user.user.status.blocked"
+ private const val BACKEND_KEY_TOO_MANY_ATTEMPTS = "auth.throttle.too_many_attempts"
+ private const val BACKEND_KEY_EMAIL_NOT_CONFIRMED = "auth.user.email.not_confirmed"
+ }
+}
\ No newline at end of file
diff --git a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/repository/remote/LoginRemoteDataSourceApi.kt b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/repository/remote/LoginRemoteDataSourceApi.kt
new file mode 100644
index 00000000..9cffad66
--- /dev/null
+++ b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/repository/remote/LoginRemoteDataSourceApi.kt
@@ -0,0 +1,13 @@
+package ru.yeahub.authentication.impl.login.data.repository.remote
+
+import ru.yeahub.network_api.models.LoginRequestDto
+import ru.yeahub.network_api.models.LoginResponseDto
+
+/**
+ * Контракт remote data source авторизации:
+ * - login - выполняет сетевой запрос авторизации
+ */
+interface LoginRemoteDataSourceApi {
+
+ suspend fun login(request: LoginRequestDto): LoginResponseDto
+}
\ No newline at end of file
diff --git a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/repository/remote/LoginRemoteDataSourceImpl.kt b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/repository/remote/LoginRemoteDataSourceImpl.kt
new file mode 100644
index 00000000..528b9ac1
--- /dev/null
+++ b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/data/repository/remote/LoginRemoteDataSourceImpl.kt
@@ -0,0 +1,18 @@
+package ru.yeahub.authentication.impl.login.data.repository.remote
+
+import ru.yeahub.network_api.NetworkProvider
+import ru.yeahub.network_api.models.LoginRequestDto
+import ru.yeahub.network_api.models.LoginResponseDto
+
+/**
+ * Реализация remote data source авторизации:
+ * - вызывает методы apiService из NetworkProvider
+ */
+class LoginRemoteDataSourceImpl(
+ private val apiService: NetworkProvider,
+) : LoginRemoteDataSourceApi {
+
+ override suspend fun login(request: LoginRequestDto): LoginResponseDto {
+ return apiService.apiService.login(request)
+ }
+}
\ No newline at end of file
diff --git a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/di/LoginFeatureModule.kt b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/di/LoginFeatureModule.kt
new file mode 100644
index 00000000..61acadbe
--- /dev/null
+++ b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/di/LoginFeatureModule.kt
@@ -0,0 +1,45 @@
+package ru.yeahub.authentication.impl.login.di
+
+import com.google.gson.Gson
+import org.koin.androidx.viewmodel.dsl.viewModelOf
+import org.koin.core.module.dsl.bind
+import org.koin.core.module.dsl.factoryOf
+import org.koin.core.module.dsl.singleOf
+import org.koin.dsl.module
+import ru.yeahub.authentication.impl.login.data.mapper.LoginDomainToDataMapper
+import ru.yeahub.authentication.impl.login.data.mapper.LoginResponseToDomainMapper
+import ru.yeahub.authentication.impl.login.data.repository.remote.LoginRemoteDataSourceApi
+import ru.yeahub.authentication.impl.login.data.repository.LoginRepositoryImpl
+import ru.yeahub.authentication.impl.login.data.repository.remote.LoginRemoteDataSourceImpl
+import ru.yeahub.authentication.impl.login.domain.repository.LoginRepositoryApi
+import ru.yeahub.authentication.impl.login.domain.usecase.LoginUseCase
+import ru.yeahub.authentication.impl.login.presentation.mapper.LoginStateMapper
+import ru.yeahub.authentication.impl.login.presentation.viewmodel.LoginViewModel
+
+/**
+ * DI модуль авторизации:
+ * - регистрирует mapper'ы
+ * - регистрирует remote data source
+ * - регистрирует repository
+ * - регистрирует use case
+ * - регистрирует ViewModel
+ */
+val loginFeatureModule = module {
+ singleOf(::LoginDomainToDataMapper)
+ singleOf(::LoginResponseToDomainMapper)
+
+ singleOf(::Gson)
+
+ singleOf(::LoginRemoteDataSourceImpl) {
+ bind()
+ }
+
+ singleOf(::LoginRepositoryImpl) {
+ bind()
+ }
+
+ factoryOf(::LoginUseCase)
+
+ singleOf(::LoginStateMapper)
+ viewModelOf(::LoginViewModel)
+}
\ No newline at end of file
diff --git a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/entity/AuthResult.kt b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/entity/AuthResult.kt
new file mode 100644
index 00000000..24069f7c
--- /dev/null
+++ b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/entity/AuthResult.kt
@@ -0,0 +1,11 @@
+package ru.yeahub.authentication.impl.login.domain.entity
+
+/**
+ * Результат успешной авторизации:
+ * - tokens - токены авторизации
+ * - userProfile - профиль авторизованного пользователя
+ */
+data class AuthResult(
+ val tokens: AuthTokens,
+ val userProfile: UserProfile,
+)
\ No newline at end of file
diff --git a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/entity/AuthTokens.kt b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/entity/AuthTokens.kt
new file mode 100644
index 00000000..130a7cf4
--- /dev/null
+++ b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/entity/AuthTokens.kt
@@ -0,0 +1,9 @@
+package ru.yeahub.authentication.impl.login.domain.entity
+
+/**
+ * Токены авторизации:
+ * - accessToken - токен доступа для защищённых API-запросов
+ */
+data class AuthTokens(
+ val accessToken: String,
+)
\ No newline at end of file
diff --git a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/entity/LoginError.kt b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/entity/LoginError.kt
index 7b170012..f24bb38b 100644
--- a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/entity/LoginError.kt
+++ b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/entity/LoginError.kt
@@ -2,8 +2,12 @@ package ru.yeahub.authentication.impl.login.domain.entity
/**
* Бизнес-ошибки авторизации:
- * - InvalidCredentials - неверные логин/пароль
+ * - InvalidCredentials - неверные данные авторизации
+ * - InvalidPassword - неверный пароль
* - UserNotFound - пользователь не найден
+ * - AccountBlocked - аккаунт заблокирован
+ * - TooManyAttempts - слишком много попыток входа
+ * - EmailNotConfirmed - email не подтверждён
* - Network - ошибка сети
* - Server - ошибка сервера
* - Unknown - неизвестная ошибка
@@ -11,7 +15,11 @@ package ru.yeahub.authentication.impl.login.domain.entity
sealed interface LoginError {
data object InvalidCredentials : LoginError
+ data object InvalidPassword : LoginError
data object UserNotFound : LoginError
+ data object AccountBlocked : LoginError
+ data object TooManyAttempts : LoginError
+ data object EmailNotConfirmed : LoginError
data object Network : LoginError
data object Server : LoginError
data object Unknown : LoginError
diff --git a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/entity/UserProfile.kt b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/entity/UserProfile.kt
new file mode 100644
index 00000000..ed734e7e
--- /dev/null
+++ b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/entity/UserProfile.kt
@@ -0,0 +1,15 @@
+package ru.yeahub.authentication.impl.login.domain.entity
+
+/**
+ * Профиль авторизованного пользователя:
+ * - id - идентификатор пользователя
+ * - email - email пользователя
+ * - username - имя пользователя
+ * - avatarUrl - ссылка на аватар пользователя
+ */
+data class UserProfile(
+ val id: String?,
+ val email: String?,
+ val username: String?,
+ val avatarUrl: String?,
+)
\ No newline at end of file
diff --git a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/repository/LoginRepositoryApi.kt b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/repository/LoginRepositoryApi.kt
index 31f125a4..13025919 100644
--- a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/repository/LoginRepositoryApi.kt
+++ b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/repository/LoginRepositoryApi.kt
@@ -1,10 +1,12 @@
package ru.yeahub.authentication.impl.login.domain.repository
+import ru.yeahub.authentication.impl.login.domain.entity.AuthResult
import ru.yeahub.authentication.impl.login.domain.entity.LoginModel
/**
* Контракт репозитория авторизации:
* - login - выполняет вход по email и паролю
*/
interface LoginRepositoryApi {
- suspend fun login(loginModel: LoginModel)
+
+ suspend fun login(loginModel: LoginModel): AuthResult
}
\ No newline at end of file
diff --git a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/usecase/LoginUseCase.kt b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/usecase/LoginUseCase.kt
index 8eff7855..3af79955 100644
--- a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/usecase/LoginUseCase.kt
+++ b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/domain/usecase/LoginUseCase.kt
@@ -1,15 +1,18 @@
package ru.yeahub.authentication.impl.login.domain.usecase
+import ru.yeahub.authentication.impl.login.domain.entity.AuthResult
import ru.yeahub.authentication.impl.login.domain.entity.LoginModel
import ru.yeahub.authentication.impl.login.domain.repository.LoginRepositoryApi
+
/**
* UseCase авторизации:
- * - login — запускает вход через репозиторий
+ * - login - запускает вход через репозиторий
*/
class LoginUseCase(
- private val repository: LoginRepositoryApi
+ private val repository: LoginRepositoryApi,
) {
- suspend operator fun invoke(loginModel: LoginModel) {
- repository.login(loginModel)
+
+ suspend operator fun invoke(loginModel: LoginModel): AuthResult {
+ return repository.login(loginModel)
}
}
\ No newline at end of file
diff --git a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/presentation/viewmodel/LoginViewModel.kt b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/presentation/viewmodel/LoginViewModel.kt
index d8f2f450..1cb80a6d 100644
--- a/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/presentation/viewmodel/LoginViewModel.kt
+++ b/feature/authentication/impl/src/main/java/ru/yeahub/authentication/impl/login/presentation/viewmodel/LoginViewModel.kt
@@ -21,6 +21,7 @@ import ru.yeahub.authentication.impl.login.presentation.model.LoginAction
import ru.yeahub.authentication.impl.login.presentation.model.LoginCommand
import ru.yeahub.authentication.impl.login.presentation.model.LoginState
import ru.yeahub.core_utils.common.TextOrResource
+
private const val UI_STATE_STOP_TIMEOUT = 5000L
/**
@@ -228,7 +229,7 @@ class LoginViewModel(
)
}
- is LoginError.Unknown -> {
+ else -> {
sendCommand(
command = LoginCommand.ShowSnackbar(
message = TextOrResource.Resource(
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 047e5897..4f5055b6 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -63,6 +63,9 @@ compose-markdown = { group = "com.github.jeziellago", name = "compose-markdown",
retrofit-core = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
retrofit-gsonConverter = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" }
+#GSON
+gson = { module = "com.google.code.gson:gson", version = "2.14.0" }
+
#KOIN
koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
koin-android = { module = "io.insert-koin:koin-android", version.ref = "koin" }