স্কিপ করে মূল কন্টেন্ট এ যান

⚙️ Use Case Code Samples

FLX CLI দিয়ে তৈরি হওয়া বিভিন্ন ধরনের Use Case class-এর comprehensive examples।

🎯 Basic Use Case Pattern

Simple CRUD Use Case

import '../entities/user_entity.dart';
import '../repositories/user_repository.dart';

class UserUseCase {
final UserRepository _repository;

UserUseCase(this._repository);

/// Get user by ID
Future<UserEntity> getUserById(String id) async {
if (id.isEmpty) {
throw Exception('User ID is required');
}

try {
final user = await _repository.getUserById(id);
return user;
} catch (e) {
throw Exception('Failed to get user: ${e.toString()}');
}
}

/// Get all users with pagination
Future<List<UserEntity>> getAllUsers({
int page = 1,
int limit = 20,
String? searchQuery,
}) async {
if (page <= 0 || limit <= 0) {
throw Exception('Invalid pagination parameters');
}

try {
final users = await _repository.getAllUsers(
page: page,
limit: limit,
searchQuery: searchQuery,
);

return users;
} catch (e) {
throw Exception('Failed to get users: ${e.toString()}');
}
}

/// Create new user
Future<UserEntity> createUser(UserEntity user) async {
// Validation
_validateUser(user);

try {
final createdUser = await _repository.createUser(user);
return createdUser;
} catch (e) {
throw Exception('Failed to create user: ${e.toString()}');
}
}

/// Update existing user
Future<UserEntity> updateUser(UserEntity user) async {
if (user.id.isEmpty) {
throw Exception('User ID is required for update');
}

// Validation
_validateUser(user);

try {
final updatedUser = await _repository.updateUser(user);
return updatedUser;
} catch (e) {
throw Exception('Failed to update user: ${e.toString()}');
}
}

/// Delete user
Future<void> deleteUser(String id) async {
if (id.isEmpty) {
throw Exception('User ID is required');
}

try {
await _repository.deleteUser(id);
} catch (e) {
throw Exception('Failed to delete user: ${e.toString()}');
}
}

/// Search users by criteria
Future<List<UserEntity>> searchUsers({
String? name,
String? email,
bool? isActive,
}) async {
if (name?.isEmpty == true && email?.isEmpty == true && isActive == null) {
throw Exception('At least one search criteria is required');
}

try {
final users = await _repository.searchUsers(
name: name,
email: email,
isActive: isActive,
);
return users;
} catch (e) {
throw Exception('Failed to search users: ${e.toString()}');
}
}

// Private validation method
void _validateUser(UserEntity user) {
if (user.name.trim().isEmpty) {
throw Exception('User name is required');
}

if (user.email.trim().isEmpty) {
throw Exception('User email is required');
}

if (!_isValidEmail(user.email)) {
throw Exception('Invalid email format');
}
}

bool _isValidEmail(String email) {
return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(email);
}
}

🔐 Authentication Use Case

Complex Authentication Logic

import '../entities/auth_entity.dart';
import '../repositories/auth_repository.dart';

class AuthUseCase {
final AuthRepository _repository;

AuthUseCase(this._repository);

/// Login with email and password
Future<AuthEntity> login({
required String email,
required String password,
bool rememberMe = false,
}) async {
// Input validation
if (email.trim().isEmpty) {
throw Exception('ইমেইল প্রয়োজন');
}

if (password.isEmpty) {
throw Exception('পাসওয়ার্ড প্রয়োজন');
}

if (!_isValidEmail(email)) {
throw Exception('সঠিক ইমেইল ফরম্যাট প্রয়োজন');
}

if (password.length < 6) {
throw Exception('পাসওয়ার্ড কমপক্ষে ৬ অক্ষরের হতে হবে');
}

try {
// Check for rate limiting
await _checkRateLimit(email);

// Attempt login
final authEntity = await _repository.login(
email: email.trim().toLowerCase(),
password: password,
);

// Handle remember me
if (rememberMe) {
await _repository.setRememberMe(true);
}

// Log successful login
await _logLoginAttempt(email, success: true);

return authEntity;
} on AuthenticationException catch (e) {
// Log failed login attempt
await _logLoginAttempt(email, success: false, reason: e.message);

// Re-throw with localized message
throw Exception(_getLocalizedAuthError(e.code));
} catch (e) {
// Log unexpected error
await _logLoginAttempt(email, success: false, reason: e.toString());
throw Exception('লগইন করতে সমস্যা হয়েছে');
}
}

/// Register new user
Future<AuthEntity> register({
required String name,
required String email,
required String password,
required String confirmPassword,
}) async {
// Comprehensive validation
final validationErrors = _validateRegistration(
name: name,
email: email,
password: password,
confirmPassword: confirmPassword,
);

if (validationErrors.isNotEmpty) {
throw Exception(validationErrors.first);
}

try {
// Check if email already exists
final emailExists = await _repository.checkEmailExists(email.trim().toLowerCase());
if (emailExists) {
throw Exception('এই ইমেইল দিয়ে ইতিমধ্যে একাউন্ট আছে');
}

// Register user
final authEntity = await _repository.register(
name: name.trim(),
email: email.trim().toLowerCase(),
password: password,
);

// Send verification email
await _repository.sendVerificationEmail(authEntity.email);

return authEntity;
} catch (e) {
if (e.toString().contains('already exists')) {
throw Exception('এই ইমেইল দিয়ে ইতিমধ্যে একাউন্ট আছে');
}
throw Exception('রেজিস্ট্রেশন করতে সমস্যা হয়েছে');
}
}

/// Logout user
Future<void> logout() async {
try {
await _repository.logout();
} catch (e) {
// Even if remote logout fails, we should clear local data
throw Exception('লগআউট করতে সমস্যা হয়েছে');
}
}

/// Send password reset email
Future<void> sendPasswordResetEmail(String email) async {
if (email.trim().isEmpty) {
throw Exception('ইমেইল প্রয়োজন');
}

if (!_isValidEmail(email)) {
throw Exception('সঠিক ইমেইল ফরম্যাট প্রয়োজন');
}

try {
// Check if email exists
final emailExists = await _repository.checkEmailExists(email.trim().toLowerCase());
if (!emailExists) {
// For security, don't reveal if email exists or not
return;
}

await _repository.sendPasswordResetEmail(email.trim().toLowerCase());
} catch (e) {
throw Exception('পাসওয়ার্ড রিসেট ইমেইল পাঠাতে সমস্যা হয়েছে');
}
}

/// Reset password with token
Future<void> resetPassword({
required String token,
required String newPassword,
required String confirmPassword,
}) async {
if (token.trim().isEmpty) {
throw Exception('রিসেট টোকেন প্রয়োজন');
}

if (newPassword.isEmpty) {
throw Exception('নতুন পাসওয়ার্ড প্রয়োজন');
}

if (newPassword != confirmPassword) {
throw Exception('পাসওয়ার্ড মিলছে না');
}

if (!_isStrongPassword(newPassword)) {
throw Exception('পাসওয়ার্ড যথেষ্ট শক্তিশালী নয়');
}

try {
await _repository.resetPassword(
token: token,
newPassword: newPassword,
);
} catch (e) {
throw Exception('পাসওয়ার্ড রিসেট করতে সমস্যা হয়েছে');
}
}

/// Change password for logged in user
Future<void> changePassword({
required String currentPassword,
required String newPassword,
required String confirmPassword,
}) async {
if (currentPassword.isEmpty) {
throw Exception('বর্তমান পাসওয়ার্ড প্রয়োজন');
}

if (newPassword.isEmpty) {
throw Exception('নতুন পাসওয়ার্ড প্রয়োজন');
}

if (newPassword != confirmPassword) {
throw Exception('নতুন পাসওয়ার্ড মিলছে না');
}

if (currentPassword == newPassword) {
throw Exception('নতুন পাসওয়ার্ড বর্তমান পাসওয়ার্ডের থেকে আলাদা হতে হবে');
}

if (!_isStrongPassword(newPassword)) {
throw Exception('পাসওয়ার্ড যথেষ্ট শক্তিশালী নয়');
}

try {
await _repository.changePassword(
currentPassword: currentPassword,
newPassword: newPassword,
);
} catch (e) {
if (e.toString().contains('invalid')) {
throw Exception('বর্তমান পাসওয়ার্ড ভুল');
}
throw Exception('পাসওয়ার্ড পরিবর্তন করতে সমস্যা হয়েছে');
}
}

/// Verify email with OTP
Future<void> verifyEmail(String otp) async {
if (otp.trim().isEmpty) {
throw Exception('OTP প্রয়োজন');
}

if (otp.length != 6) {
throw Exception('OTP ৬ সংখ্যার হতে হবে');
}

if (!RegExp(r'^\d{6}$').hasMatch(otp)) {
throw Exception('OTP শুধু সংখ্যা হতে হবে');
}

try {
await _repository.verifyEmail(otp);
} catch (e) {
if (e.toString().contains('expired')) {
throw Exception('OTP মেয়াদ শেষ হয়ে গেছে');
} else if (e.toString().contains('invalid')) {
throw Exception('ভুল OTP');
}
throw Exception('ইমেইল যাচাই করতে সমস্যা হয়েছে');
}
}

/// Get current user
Future<AuthEntity?> getCurrentUser() async {
try {
return await _repository.getCurrentUser();
} catch (e) {
return null;
}
}

/// Check if user is logged in
Future<bool> isLoggedIn() async {
try {
final user = await getCurrentUser();
return user != null;
} catch (e) {
return false;
}
}

/// Refresh authentication token
Future<String> refreshToken() async {
try {
return await _repository.refreshToken();
} catch (e) {
throw Exception('টোকেন রিফ্রেশ করতে সমস্যা হয়েছে');
}
}

// Private validation methods
List<String> _validateRegistration({
required String name,
required String email,
required String password,
required String confirmPassword,
}) {
final errors = <String>[];

// Name validation
if (name.trim().isEmpty) {
errors.add('নাম প্রয়োজন');
} else if (name.trim().length < 2) {
errors.add('নাম কমপক্ষে ২ অক্ষরের হতে হবে');
}

// Email validation
if (email.trim().isEmpty) {
errors.add('ইমেইল প্রয়োজন');
} else if (!_isValidEmail(email)) {
errors.add('সঠিক ইমেইল ফরম্যাট প্রয়োজন');
}

// Password validation
if (password.isEmpty) {
errors.add('পাসওয়ার্ড প্রয়োজন');
} else if (!_isStrongPassword(password)) {
errors.add('পাসওয়ার্ড যথেষ্ট শক্তিশালী নয়');
}

// Confirm password validation
if (confirmPassword.isEmpty) {
errors.add('পাসওয়ার্ড নিশ্চিতকরণ প্রয়োজন');
} else if (password != confirmPassword) {
errors.add('পাসওয়ার্ড মিলছে না');
}

return errors;
}

bool _isValidEmail(String email) {
return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(email);
}

bool _isStrongPassword(String password) {
// At least 8 characters, contains uppercase, lowercase, number, and special character
return password.length >= 8 &&
RegExp(r'[A-Z]').hasMatch(password) &&
RegExp(r'[a-z]').hasMatch(password) &&
RegExp(r'\d').hasMatch(password) &&
RegExp(r'[!@#$%^&*(),.?":{}|<>]').hasMatch(password);
}

Future<void> _checkRateLimit(String email) async {
// Implementation for rate limiting
// This is a placeholder - implement based on your needs
}

Future<void> _logLoginAttempt(
String email, {
required bool success,
String? reason,
}) async {
// Implementation for logging login attempts
// This is a placeholder - implement based on your needs
}

String _getLocalizedAuthError(String errorCode) {
switch (errorCode) {
case 'invalid_credentials':
return 'ভুল ইমেইল বা পাসওয়ার্ড';
case 'user_not_found':
return 'ব্যবহারকারী পাওয়া যায়নি';
case 'account_disabled':
return 'অ্যাকাউন্ট নিষ্ক্রিয় করা হয়েছে';
case 'too_many_attempts':
return 'অনেকবার চেষ্টা করেছেন। কিছুক্ষণ পর চেষ্টা করুন';
default:
return 'লগইন করতে সমস্যা হয়েছে';
}
}
}

📊 Business Logic Use Case

Order Processing Use Case

import '../entities/order_entity.dart';
import '../repositories/order_repository.dart';
import '../repositories/inventory_repository.dart';
import '../repositories/payment_repository.dart';

class OrderUseCase {
final OrderRepository _orderRepository;
final InventoryRepository _inventoryRepository;
final PaymentRepository _paymentRepository;

OrderUseCase(
this._orderRepository,
this._inventoryRepository,
this._paymentRepository,
);

/// Create new order with complete validation
Future<OrderEntity> createOrder(OrderEntity order) async {
// Validate order
await _validateOrder(order);

// Check inventory availability
await _checkInventoryAvailability(order.items);

// Calculate pricing
final pricedOrder = await _calculateOrderPricing(order);

try {
// Reserve inventory
await _reserveInventory(pricedOrder.items);

// Create order
final createdOrder = await _orderRepository.createOrder(pricedOrder);

// Send order confirmation
await _sendOrderConfirmation(createdOrder);

return createdOrder;
} catch (e) {
// Rollback inventory reservation on failure
await _releaseInventoryReservation(order.items);
throw Exception('অর্ডার তৈরি করতে সমস্যা হয়েছে: ${e.toString()}');
}
}

/// Process payment for order
Future<OrderEntity> processPayment({
required String orderId,
required String paymentMethodId,
required double amount,
}) async {
if (orderId.isEmpty) {
throw Exception('অর্ডার ID প্রয়োজন');
}

if (paymentMethodId.isEmpty) {
throw Exception('পেমেন্ট মেথড প্রয়োজন');
}

if (amount <= 0) {
throw Exception('অবৈধ পেমেন্ট পরিমাণ');
}

try {
// Get order
final order = await _orderRepository.getOrderById(orderId);

// Validate payment amount
if (amount != order.totalAmount) {
throw Exception('পেমেন্ট পরিমাণ অর্ডার টোটালের সাথে মিলছে না');
}

// Process payment
final paymentResult = await _paymentRepository.processPayment(
orderId: orderId,
paymentMethodId: paymentMethodId,
amount: amount,
);

// Update order status based on payment result
OrderEntity updatedOrder;
if (paymentResult.success) {
updatedOrder = await _orderRepository.updateOrderStatus(
orderId,
OrderStatus.paid,
);

// Confirm inventory allocation
await _confirmInventoryAllocation(order.items);

// Send payment confirmation
await _sendPaymentConfirmation(updatedOrder, paymentResult);
} else {
updatedOrder = await _orderRepository.updateOrderStatus(
orderId,
OrderStatus.paymentFailed,
);

// Release inventory reservation
await _releaseInventoryReservation(order.items);

throw Exception('পেমেন্ট ব্যর্থ: ${paymentResult.errorMessage}');
}

return updatedOrder;
} catch (e) {
throw Exception('পেমেন্ট প্রসেস করতে সমস্যা হয়েছে: ${e.toString()}');
}
}

/// Cancel order
Future<OrderEntity> cancelOrder(String orderId, String reason) async {
if (orderId.isEmpty) {
throw Exception('অর্ডার ID প্রয়োজন');
}

if (reason.trim().isEmpty) {
throw Exception('বাতিলের কারণ প্রয়োজন');
}

try {
final order = await _orderRepository.getOrderById(orderId);

// Check if order can be cancelled
if (!_canCancelOrder(order)) {
throw Exception('এই অর্ডার বাতিল করা যাবে না');
}

// Process refund if payment was made
if (order.paymentStatus == PaymentStatus.paid) {
await _processRefund(order);
}

// Release inventory
await _releaseInventoryReservation(order.items);

// Update order status
final cancelledOrder = await _orderRepository.cancelOrder(orderId, reason);

// Send cancellation notification
await _sendCancellationNotification(cancelledOrder, reason);

return cancelledOrder;
} catch (e) {
throw Exception('অর্ডার বাতিল করতে সমস্যা হয়েছে: ${e.toString()}');
}
}

/// Track order status
Future<OrderTrackingInfo> trackOrder(String orderId) async {
if (orderId.isEmpty) {
throw Exception('অর্ডার ID প্রয়োজন');
}

try {
final order = await _orderRepository.getOrderById(orderId);
final trackingInfo = await _orderRepository.getTrackingInfo(orderId);

return trackingInfo;
} catch (e) {
throw Exception('অর্ডার ট্র্যাক করতে সমস্যা হয়েছে: ${e.toString()}');
}
}

/// Get user orders with filtering
Future<List<OrderEntity>> getUserOrders({
required String userId,
OrderStatus? status,
DateTime? fromDate,
DateTime? toDate,
int page = 1,
int limit = 20,
}) async {
if (userId.isEmpty) {
throw Exception('ইউজার ID প্রয়োজন');
}

try {
final orders = await _orderRepository.getUserOrders(
userId: userId,
status: status,
fromDate: fromDate,
toDate: toDate,
page: page,
limit: limit,
);

return orders;
} catch (e) {
throw Exception('অর্ডার তালিকা পেতে সমস্যা হয়েছে: ${e.toString()}');
}
}

/// Calculate order statistics
Future<OrderStatistics> calculateOrderStatistics({
String? userId,
DateTime? fromDate,
DateTime? toDate,
}) async {
try {
final statistics = await _orderRepository.calculateStatistics(
userId: userId,
fromDate: fromDate,
toDate: toDate,
);

return statistics;
} catch (e) {
throw Exception('অর্ডার পরিসংখ্যান গণনা করতে সমস্যা হয়েছে: ${e.toString()}');
}
}

// Private helper methods
Future<void> _validateOrder(OrderEntity order) async {
if (order.userId.isEmpty) {
throw Exception('ইউজার ID প্রয়োজন');
}

if (order.items.isEmpty) {
throw Exception('অর্ডারে কমপক্ষে একটি আইটেম থাকতে হবে');
}

for (final item in order.items) {
if (item.quantity <= 0) {
throw Exception('অবৈধ পরিমাণ: ${item.productName}');
}
if (item.unitPrice <= 0) {
throw Exception('অবৈধ মূল্য: ${item.productName}');
}
}

if (order.shippingAddress == null) {
throw Exception('শিপিং ঠিকানা প্রয়োজন');
}
}

Future<void> _checkInventoryAvailability(List<OrderItem> items) async {
for (final item in items) {
final availableQuantity = await _inventoryRepository
.getAvailableQuantity(item.productId);

if (availableQuantity < item.quantity) {
throw Exception(
'${item.productName} এর জন্য পর্যাপ্ত স্টক নেই। '
'উপলব্ধ: $availableQuantity, প্রয়োজন: ${item.quantity}',
);
}
}
}

Future<OrderEntity> _calculateOrderPricing(OrderEntity order) async {
double subtotal = 0;

for (final item in order.items) {
subtotal += item.quantity * item.unitPrice;
}

// Calculate tax
final taxRate = await _orderRepository.getTaxRate(order.shippingAddress!);
final taxAmount = subtotal * (taxRate / 100);

// Calculate shipping cost
final shippingCost = await _orderRepository.calculateShippingCost(
order.shippingAddress!,
order.items,
);

// Apply discounts
final discountAmount = await _calculateDiscounts(order, subtotal);

final totalAmount = subtotal + taxAmount + shippingCost - discountAmount;

return order.copyWith(
subtotal: subtotal,
taxAmount: taxAmount,
shippingCost: shippingCost,
discountAmount: discountAmount,
totalAmount: totalAmount,
);
}

Future<double> _calculateDiscounts(OrderEntity order, double subtotal) async {
// Implementation for discount calculation
// This could include coupon codes, loyalty discounts, etc.
return 0.0;
}

Future<void> _reserveInventory(List<OrderItem> items) async {
for (final item in items) {
await _inventoryRepository.reserveQuantity(
item.productId,
item.quantity,
);
}
}

Future<void> _releaseInventoryReservation(List<OrderItem> items) async {
for (final item in items) {
await _inventoryRepository.releaseReservation(
item.productId,
item.quantity,
);
}
}

Future<void> _confirmInventoryAllocation(List<OrderItem> items) async {
for (final item in items) {
await _inventoryRepository.confirmAllocation(
item.productId,
item.quantity,
);
}
}

bool _canCancelOrder(OrderEntity order) {
final cancellableStatuses = [
OrderStatus.pending,
OrderStatus.confirmed,
OrderStatus.processing,
];

return cancellableStatuses.contains(order.status);
}

Future<void> _processRefund(OrderEntity order) async {
await _paymentRepository.processRefund(
orderId: order.id,
amount: order.totalAmount,
reason: 'Order cancellation',
);
}

Future<void> _sendOrderConfirmation(OrderEntity order) async {
// Implementation for sending order confirmation email/SMS
}

Future<void> _sendPaymentConfirmation(
OrderEntity order,
PaymentResult paymentResult,
) async {
// Implementation for sending payment confirmation
}

Future<void> _sendCancellationNotification(
OrderEntity order,
String reason,
) async {
// Implementation for sending cancellation notification
}
}

🎯 Key Use Case Patterns

  1. Single Responsibility: Each use case handles one business operation
  2. Input Validation: Comprehensive validation of all inputs
  3. Error Handling: Proper error handling and messaging
  4. Transaction Management: Handle complex business transactions
  5. Business Logic: Core business rules implementation
  6. Dependency Injection: Repository dependencies injected
  7. Localization: Error messages in appropriate language
  8. Logging: Audit trails for important operations
  9. Security: Permission and authorization checks
  10. Performance: Efficient data processing

✅ Best Practices

  1. Pure Business Logic: No framework dependencies
  2. Validation First: Always validate inputs
  3. Error Messages: Clear, localized error messages
  4. Transaction Handling: Proper rollback on failures
  5. Logging: Log important business events
  6. Testing: Easy to unit test
  7. Documentation: Clear method documentation
  8. Single Purpose: One business operation per method

এই patterns follow করে: আপনি যেকোনো complex business logic implement করতে পারবেন! ⚙️