Files
minhthu/lib/features/auth/domain/usecases/login_usecase.dart
2025-10-28 00:09:46 +07:00

127 lines
3.5 KiB
Dart

import 'package:dartz/dartz.dart';
import '../../../../core/errors/failures.dart';
import '../../data/models/login_request_model.dart';
import '../entities/user_entity.dart';
import '../repositories/auth_repository.dart';
/// Use case for user login
///
/// Encapsulates the business logic for authentication
/// Validates input, calls repository, and handles the response
class LoginUseCase {
final AuthRepository repository;
LoginUseCase(this.repository);
/// Execute login operation
///
/// [request] - Login credentials (username and password)
///
/// Returns [Right(UserEntity)] on successful login
/// Returns [Left(Failure)] on error:
/// - [ValidationFailure] if credentials are invalid
/// - [AuthenticationFailure] if login fails
/// - [NetworkFailure] if network error occurs
Future<Either<Failure, UserEntity>> call(LoginRequestModel request) async {
// Validate input
final validationError = _validateInput(request);
if (validationError != null) {
return Left(validationError);
}
// Call repository to perform login
return await repository.login(request);
}
/// Validate login request input
///
/// Returns [ValidationFailure] if validation fails, null otherwise
ValidationFailure? _validateInput(LoginRequestModel request) {
// Validate username
if (request.username.trim().isEmpty) {
return const ValidationFailure('Username is required');
}
if (request.username.length < 3) {
return const ValidationFailure('Username must be at least 3 characters');
}
// Validate password
if (request.password.isEmpty) {
return const ValidationFailure('Password is required');
}
if (request.password.length < 6) {
return const ValidationFailure('Password must be at least 6 characters');
}
return null;
}
}
/// Use case for user logout
class LogoutUseCase {
final AuthRepository repository;
LogoutUseCase(this.repository);
/// Execute logout operation
///
/// Returns [Right(void)] on successful logout
/// Returns [Left(Failure)] on error
Future<Either<Failure, void>> call() async {
return await repository.logout();
}
}
/// Use case for checking authentication status
class CheckAuthStatusUseCase {
final AuthRepository repository;
CheckAuthStatusUseCase(this.repository);
/// Check if user is authenticated
///
/// Returns true if user has valid access token
Future<bool> call() async {
return await repository.isAuthenticated();
}
}
/// Use case for getting current user
class GetCurrentUserUseCase {
final AuthRepository repository;
GetCurrentUserUseCase(this.repository);
/// Get current authenticated user
///
/// Returns [Right(UserEntity)] if user is authenticated
/// Returns [Left(Failure)] if no user found or error occurs
Future<Either<Failure, UserEntity>> call() async {
return await repository.getCurrentUser();
}
}
/// Use case for refreshing access token
class RefreshTokenUseCase {
final AuthRepository repository;
RefreshTokenUseCase(this.repository);
/// Refresh access token using refresh token
///
/// [refreshToken] - The refresh token
///
/// Returns [Right(UserEntity)] with new tokens on success
/// Returns [Left(Failure)] on error
Future<Either<Failure, UserEntity>> call(String refreshToken) async {
if (refreshToken.isEmpty) {
return const Left(ValidationFailure('Refresh token is required'));
}
return await repository.refreshToken(refreshToken);
}
}