refactor: decompose hub arguments into separate, dedicated classes for improved modularity.

This commit is contained in:
Achintha Isuru
2026-01-21 19:58:22 -05:00
parent 0599e9b351
commit 9d9d2aa456
11 changed files with 115 additions and 46 deletions

View File

@@ -2,36 +2,44 @@ import 'package:krow_data_connect/krow_data_connect.dart';
import 'package:krow_domain/krow_domain.dart'; import 'package:krow_domain/krow_domain.dart';
import '../../domain/repositories/hub_repository_interface.dart'; import '../../domain/repositories/hub_repository_interface.dart';
/// Implementation of [HubRepositoryInterface]. /// Implementation of [HubRepositoryInterface] that uses [BusinessRepositoryMock].
/// ///
/// This implementation delegates data access to the [BusinessRepositoryMock] /// This class serves as a data adapter that bridges the domain repository interface
/// from the `data_connect` package. /// with the backend data source provided by the `data_connect` package. It strictly
/// delegates all operations to the [BusinessRepositoryMock], ensuring no business
/// logic resides in the data layer.
class HubRepositoryImpl implements HubRepositoryInterface { class HubRepositoryImpl implements HubRepositoryInterface {
/// The business repository mock from data connect. /// The business repository mock from data connect.
final BusinessRepositoryMock mock; final BusinessRepositoryMock mock;
/// Creates a [HubRepositoryImpl] with the required [mock]. /// Creates a [HubRepositoryImpl] instance.
///
/// Takes a [BusinessRepositoryMock] as a dependency to perform data operations.
HubRepositoryImpl({required this.mock}); HubRepositoryImpl({required this.mock});
@override @override
Future<List<Hub>> getHubs() { Future<List<Hub>> getHubs() {
// In a real app, we would get the business ID from a session or state. // In a production environment, the business ID would be retrieved from
// For this prototype/mock, we use a hardcoded value. // a session manager or authentication state. For the current mock strategy,
// we use a hardcoded value 'biz_1' to represent the active client.
return mock.getHubs('biz_1'); return mock.getHubs('biz_1');
} }
@override @override
Future<Hub> createHub({required String name, required String address}) { Future<Hub> createHub({required String name, required String address}) {
// Delegates hub creation to the mock repository.
return mock.createHub(businessId: 'biz_1', name: name, address: address); return mock.createHub(businessId: 'biz_1', name: name, address: address);
} }
@override @override
Future<void> deleteHub(String id) { Future<void> deleteHub(String id) {
// Delegates hub deletion to the mock repository.
return mock.deleteHub(id); return mock.deleteHub(id);
} }
@override @override
Future<void> assignNfcTag({required String hubId, required String nfcTagId}) { Future<void> assignNfcTag({required String hubId, required String nfcTagId}) {
// Delegates NFC tag assignment to the mock repository.
return mock.assignNfcTag(hubId: hubId, nfcTagId: nfcTagId); return mock.assignNfcTag(hubId: hubId, nfcTagId: nfcTagId);
} }
} }

View File

@@ -0,0 +1,20 @@
import 'package:krow_core/core.dart';
/// Represents the arguments required for the AssignNfcTagUseCase.
///
/// Encapsulates the hub ID and the NFC tag ID to be assigned.
class AssignNfcTagArguments extends UseCaseArgument {
/// The unique identifier of the hub.
final String hubId;
/// The unique identifier of the NFC tag.
final String nfcTagId;
/// Creates an [AssignNfcTagArguments] instance.
///
/// Both [hubId] and [nfcTagId] are required.
const AssignNfcTagArguments({required this.hubId, required this.nfcTagId});
@override
List<Object?> get props => [hubId, nfcTagId];
}

View File

@@ -0,0 +1,20 @@
import 'package:krow_core/core.dart';
/// Represents the arguments required for the CreateHubUseCase.
///
/// Encapsulates the name and address of the hub to be created.
class CreateHubArguments extends UseCaseArgument {
/// The name of the hub.
final String name;
/// The physical address of the hub.
final String address;
/// Creates a [CreateHubArguments] instance.
///
/// Both [name] and [address] are required.
const CreateHubArguments({required this.name, required this.address});
@override
List<Object?> get props => [name, address];
}

View File

@@ -0,0 +1,17 @@
import 'package:krow_core/core.dart';
/// Represents the arguments required for the DeleteHubUseCase.
///
/// Encapsulates the hub ID of the hub to be deleted.
class DeleteHubArguments extends UseCaseArgument {
/// The unique identifier of the hub to delete.
final String hubId;
/// Creates a [DeleteHubArguments] instance.
///
/// The [hubId] is required.
const DeleteHubArguments({required this.hubId});
@override
List<Object?> get props => [hubId];
}

View File

@@ -1,33 +0,0 @@
import 'package:krow_core/core.dart';
/// Arguments for creating a new hub.
class CreateHubArguments extends UseCaseArgument {
final String name;
final String address;
const CreateHubArguments({required this.name, required this.address});
@override
List<Object?> get props => [name, address];
}
/// Arguments for assigning an NFC tag to a hub.
class AssignNfcTagArguments extends UseCaseArgument {
final String hubId;
final String nfcTagId;
const AssignNfcTagArguments({required this.hubId, required this.nfcTagId});
@override
List<Object?> get props => [hubId, nfcTagId];
}
/// Arguments for deleting a hub.
class DeleteHubArguments extends UseCaseArgument {
final String hubId;
const DeleteHubArguments({required this.hubId});
@override
List<Object?> get props => [hubId];
}

View File

@@ -2,18 +2,26 @@ import 'package:krow_domain/krow_domain.dart';
/// Interface for the Hub repository. /// Interface for the Hub repository.
/// ///
/// This repository handles hub-related operations such as /// This repository defines the contract for hub-related operations in the
/// fetching, creating, deleting hubs and assigning NFC tags. /// domain layer. It handles fetching, creating, deleting hubs and assigning
/// NFC tags. The implementation will be provided in the data layer.
abstract interface class HubRepositoryInterface { abstract interface class HubRepositoryInterface {
/// Fetches the list of hubs for the current client. /// Fetches the list of hubs for the current client.
///
/// Returns a list of [Hub] entities.
Future<List<Hub>> getHubs(); Future<List<Hub>> getHubs();
/// Creates a new hub. /// Creates a new hub.
///
/// Takes the [name] and [address] of the new hub.
/// Returns the created [Hub] entity.
Future<Hub> createHub({required String name, required String address}); Future<Hub> createHub({required String name, required String address});
/// Deletes a hub by its [id]. /// Deletes a hub by its [id].
Future<void> deleteHub(String id); Future<void> deleteHub(String id);
/// Assigns an NFC tag to a hub. /// Assigns an NFC tag to a hub.
///
/// Takes the [hubId] and the [nfcTagId] to be associated.
Future<void> assignNfcTag({required String hubId, required String nfcTagId}); Future<void> assignNfcTag({required String hubId, required String nfcTagId});
} }

View File

@@ -1,11 +1,17 @@
import 'package:krow_core/core.dart'; import 'package:krow_core/core.dart';
import '../arguments/hub_arguments.dart'; import '../arguments/assign_nfc_tag_arguments.dart';
import '../repositories/hub_repository_interface.dart'; import '../repositories/hub_repository_interface.dart';
/// Use case for assigning an NFC tag to a hub. /// Use case for assigning an NFC tag to a hub.
///
/// This use case handles the association of a physical NFC tag with a specific
/// hub by calling the [HubRepositoryInterface].
class AssignNfcTagUseCase implements UseCase<AssignNfcTagArguments, void> { class AssignNfcTagUseCase implements UseCase<AssignNfcTagArguments, void> {
final HubRepositoryInterface _repository; final HubRepositoryInterface _repository;
/// Creates an [AssignNfcTagUseCase].
///
/// Requires a [HubRepositoryInterface] to interact with the backend.
AssignNfcTagUseCase(this._repository); AssignNfcTagUseCase(this._repository);
@override @override

View File

@@ -1,12 +1,19 @@
import 'package:krow_core/core.dart'; import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart'; import 'package:krow_domain/krow_domain.dart';
import '../arguments/hub_arguments.dart'; import '../arguments/create_hub_arguments.dart';
import '../repositories/hub_repository_interface.dart'; import '../repositories/hub_repository_interface.dart';
/// Use case for creating a new hub. /// Use case for creating a new hub.
///
/// This use case orchestrates the creation of a hub by interacting with the
/// [HubRepositoryInterface]. It requires [CreateHubArguments] which includes
/// the name and address of the hub.
class CreateHubUseCase implements UseCase<CreateHubArguments, Hub> { class CreateHubUseCase implements UseCase<CreateHubArguments, Hub> {
final HubRepositoryInterface _repository; final HubRepositoryInterface _repository;
/// Creates a [CreateHubUseCase].
///
/// Requires a [HubRepositoryInterface] to perform the actual creation.
CreateHubUseCase(this._repository); CreateHubUseCase(this._repository);
@override @override

View File

@@ -1,11 +1,16 @@
import 'package:krow_core/core.dart'; import 'package:krow_core/core.dart';
import '../arguments/hub_arguments.dart'; import '../arguments/delete_hub_arguments.dart';
import '../repositories/hub_repository_interface.dart'; import '../repositories/hub_repository_interface.dart';
/// Use case for deleting a hub. /// Use case for deleting a hub.
///
/// This use case removes a hub from the system via the [HubRepositoryInterface].
class DeleteHubUseCase implements UseCase<DeleteHubArguments, void> { class DeleteHubUseCase implements UseCase<DeleteHubArguments, void> {
final HubRepositoryInterface _repository; final HubRepositoryInterface _repository;
/// Creates a [DeleteHubUseCase].
///
/// Requires a [HubRepositoryInterface] to perform the deletion.
DeleteHubUseCase(this._repository); DeleteHubUseCase(this._repository);
@override @override

View File

@@ -3,9 +3,15 @@ import 'package:krow_domain/krow_domain.dart';
import '../repositories/hub_repository_interface.dart'; import '../repositories/hub_repository_interface.dart';
/// Use case for fetching the list of hubs. /// Use case for fetching the list of hubs.
///
/// This use case retrieves all hubs associated with the current client
/// by interacting with the [HubRepositoryInterface].
class GetHubsUseCase implements NoInputUseCase<List<Hub>> { class GetHubsUseCase implements NoInputUseCase<List<Hub>> {
final HubRepositoryInterface _repository; final HubRepositoryInterface _repository;
/// Creates a [GetHubsUseCase].
///
/// Requires a [HubRepositoryInterface] to fetch the data.
GetHubsUseCase(this._repository); GetHubsUseCase(this._repository);
@override @override

View File

@@ -1,6 +1,8 @@
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:flutter_modular/flutter_modular.dart'; import 'package:flutter_modular/flutter_modular.dart';
import '../../domain/arguments/hub_arguments.dart'; import '../../domain/arguments/assign_nfc_tag_arguments.dart';
import '../../domain/arguments/create_hub_arguments.dart';
import '../../domain/arguments/delete_hub_arguments.dart';
import '../../domain/usecases/assign_nfc_tag_usecase.dart'; import '../../domain/usecases/assign_nfc_tag_usecase.dart';
import '../../domain/usecases/create_hub_usecase.dart'; import '../../domain/usecases/create_hub_usecase.dart';
import '../../domain/usecases/delete_hub_usecase.dart'; import '../../domain/usecases/delete_hub_usecase.dart';
@@ -8,7 +10,10 @@ import '../../domain/usecases/get_hubs_usecase.dart';
import 'client_hubs_event.dart'; import 'client_hubs_event.dart';
import 'client_hubs_state.dart'; import 'client_hubs_state.dart';
/// BLoC responsible for managing client hubs. /// BLoC responsible for managing the state of the Client Hubs feature.
///
/// It orchestrates the flow between the UI and the domain layer by invoking
/// specific use cases for fetching, creating, deleting, and assigning tags to hubs.
class ClientHubsBloc extends Bloc<ClientHubsEvent, ClientHubsState> class ClientHubsBloc extends Bloc<ClientHubsEvent, ClientHubsState>
implements Disposable { implements Disposable {
final GetHubsUseCase _getHubsUseCase; final GetHubsUseCase _getHubsUseCase;