feat: Refactor HubRepositoryImpl to remove FirebaseAuth dependency and utilize DataConnectService

This commit is contained in:
Achintha Isuru
2026-02-16 17:43:50 -05:00
parent a7e8704e4f
commit 21f0e2ee89
2 changed files with 86 additions and 105 deletions

View File

@@ -3,7 +3,6 @@ library;
import 'package:flutter_modular/flutter_modular.dart';
import 'package:krow_core/core.dart';
import 'package:krow_data_connect/krow_data_connect.dart';
import 'package:firebase_auth/firebase_auth.dart' as firebase;
import 'src/data/repositories_impl/hub_repository_impl.dart';
import 'src/domain/repositories/hub_repository_interface.dart';
import 'src/domain/usecases/assign_nfc_tag_usecase.dart';
@@ -23,12 +22,7 @@ class ClientHubsModule extends Module {
@override
void binds(Injector i) {
// Repositories
i.addLazySingleton<HubRepositoryInterface>(
() => HubRepositoryImpl(
firebaseAuth: firebase.FirebaseAuth.instance,
dataConnect: ExampleConnector.instance,
),
);
i.addLazySingleton<HubRepositoryInterface>(HubRepositoryImpl.new);
// UseCases
i.addLazySingleton(GetHubsUseCase.new);
@@ -37,14 +31,7 @@ class ClientHubsModule extends Module {
i.addLazySingleton(AssignNfcTagUseCase.new);
// BLoCs
i.add<ClientHubsBloc>(
() => ClientHubsBloc(
getHubsUseCase: i.get<GetHubsUseCase>(),
createHubUseCase: i.get<CreateHubUseCase>(),
deleteHubUseCase: i.get<DeleteHubUseCase>(),
assignNfcTagUseCase: i.get<AssignNfcTagUseCase>(),
),
);
i.add<ClientHubsBloc>(ClientHubsBloc.new);
}
@override

View File

@@ -9,30 +9,26 @@ import 'package:krow_domain/krow_domain.dart' as domain;
import 'package:krow_domain/krow_domain.dart'
show
HubHasOrdersException,
HubCreationFailedException,
BusinessNotFoundException,
NotAuthenticatedException;
import '../../domain/repositories/hub_repository_interface.dart';
/// Implementation of [HubRepositoryInterface] backed by Data Connect.
class HubRepositoryImpl
with dc.DataErrorHandler
implements HubRepositoryInterface {
class HubRepositoryImpl implements HubRepositoryInterface {
HubRepositoryImpl({
required firebase.FirebaseAuth firebaseAuth,
required dc.ExampleConnector dataConnect,
}) : _firebaseAuth = firebaseAuth,
_dataConnect = dataConnect;
required dc.DataConnectService service,
}) : _service = service;
final firebase.FirebaseAuth _firebaseAuth;
final dc.ExampleConnector _dataConnect;
final dc.DataConnectService _service;
@override
Future<List<domain.Hub>> getHubs() async {
final dc.GetBusinessesByUserIdBusinesses business = await _getBusinessForCurrentUser();
final String teamId = await _getOrCreateTeamId(business);
return _fetchHubsForTeam(teamId: teamId, businessId: business.id);
return _service.run(() async {
final dc.GetBusinessesByUserIdBusinesses business = await _getBusinessForCurrentUser();
final String teamId = await _getOrCreateTeamId(business);
return _fetchHubsForTeam(teamId: teamId, businessId: business.id);
});
}
@override
@@ -48,82 +44,80 @@ class HubRepositoryImpl
String? country,
String? zipCode,
}) async {
final dc.GetBusinessesByUserIdBusinesses business = await _getBusinessForCurrentUser();
final String teamId = await _getOrCreateTeamId(business);
final _PlaceAddress? placeAddress =
placeId == null || placeId.isEmpty ? null : await _fetchPlaceAddress(placeId);
final String? cityValue = city ?? placeAddress?.city ?? business.city;
final String? stateValue = state ?? placeAddress?.state;
final String? streetValue = street ?? placeAddress?.street;
final String? countryValue = country ?? placeAddress?.country;
final String? zipCodeValue = zipCode ?? placeAddress?.zipCode;
return _service.run(() async {
final dc.GetBusinessesByUserIdBusinesses business = await _getBusinessForCurrentUser();
final String teamId = await _getOrCreateTeamId(business);
final _PlaceAddress? placeAddress =
placeId == null || placeId.isEmpty ? null : await _fetchPlaceAddress(placeId);
final String? cityValue = city ?? placeAddress?.city ?? business.city;
final String? stateValue = state ?? placeAddress?.state;
final String? streetValue = street ?? placeAddress?.street;
final String? countryValue = country ?? placeAddress?.country;
final String? zipCodeValue = zipCode ?? placeAddress?.zipCode;
final OperationResult<dc.CreateTeamHubData, dc.CreateTeamHubVariables>
result = await executeProtected(() => _dataConnect
.createTeamHub(
teamId: teamId,
hubName: name,
address: address,
)
.placeId(placeId)
.latitude(latitude)
.longitude(longitude)
.city(cityValue?.isNotEmpty == true ? cityValue : '')
.state(stateValue)
.street(streetValue)
.country(countryValue)
.zipCode(zipCodeValue)
.execute());
final String createdId = result.data.teamHub_insert.id;
final OperationResult<dc.CreateTeamHubData, dc.CreateTeamHubVariables>
result = await _service.connector
.createTeamHub(
teamId: teamId,
hubName: name,
address: address,
)
.placeId(placeId)
.latitude(latitude)
.longitude(longitude)
.city(cityValue?.isNotEmpty == true ? cityValue : '')
.state(stateValue)
.street(streetValue)
.country(countryValue)
.zipCode(zipCodeValue)
.execute();
final String createdId = result.data.teamHub_insert.id;
final List<domain.Hub> hubs = await _fetchHubsForTeam(
teamId: teamId,
businessId: business.id,
);
domain.Hub? createdHub;
for (final domain.Hub hub in hubs) {
if (hub.id == createdId) {
createdHub = hub;
break;
final List<domain.Hub> hubs = await _fetchHubsForTeam(
teamId: teamId,
businessId: business.id,
);
domain.Hub? createdHub;
for (final domain.Hub hub in hubs) {
if (hub.id == createdId) {
createdHub = hub;
break;
}
}
}
return createdHub ??
domain.Hub(
id: createdId,
businessId: business.id,
name: name,
address: address,
nfcTagId: null,
status: domain.HubStatus.active,
);
return createdHub ??
domain.Hub(
id: createdId,
businessId: business.id,
name: name,
address: address,
nfcTagId: null,
status: domain.HubStatus.active,
);
});
}
@override
Future<void> deleteHub(String id) async {
final String? businessId = dc.ClientSessionStore.instance.session?.business?.id;
if (businessId == null || businessId.isEmpty) {
await _firebaseAuth.signOut();
throw const BusinessNotFoundException(
technicalMessage: 'Business ID missing from session',
);
}
return _service.run(() async {
final String businessId = await _service.getBusinessId();
final QueryResult<dc.ListOrdersByBusinessAndTeamHubData,
dc.ListOrdersByBusinessAndTeamHubVariables> result =
await executeProtected(() => _dataConnect
.listOrdersByBusinessAndTeamHub(
businessId: businessId,
teamHubId: id,
)
.execute());
final QueryResult<dc.ListOrdersByBusinessAndTeamHubData,
dc.ListOrdersByBusinessAndTeamHubVariables> result =
await _service.connector
.listOrdersByBusinessAndTeamHub(
businessId: businessId,
teamHubId: id,
)
.execute();
if (result.data.orders.isNotEmpty) {
throw HubHasOrdersException(
technicalMessage: 'Hub $id has ${result.data.orders.length} orders',
);
}
if (result.data.orders.isNotEmpty) {
throw HubHasOrdersException(
technicalMessage: 'Hub $id has ${result.data.orders.length} orders',
);
}
await executeProtected(() => _dataConnect.deleteTeamHub(id: id).execute());
await _service.connector.deleteTeamHub(id: id).execute();
});
}
@override
@@ -141,7 +135,7 @@ class HubRepositoryImpl
return dc.GetBusinessesByUserIdBusinesses(
id: cachedBusiness.id,
businessName: cachedBusiness.businessName,
userId: _firebaseAuth.currentUser?.uid ?? '',
userId: _service.auth.currentUser?.uid ?? '',
rateGroup: const dc.Known<dc.BusinessRateGroup>(dc.BusinessRateGroup.STANDARD),
status: const dc.Known<dc.BusinessStatus>(dc.BusinessStatus.ACTIVE),
contactName: cachedBusiness.contactName,
@@ -159,7 +153,7 @@ class HubRepositoryImpl
);
}
final firebase.User? user = _firebaseAuth.currentUser;
final firebase.User? user = _service.auth.currentUser;
if (user == null) {
throw const NotAuthenticatedException(
technicalMessage: 'No Firebase user in currentUser',
@@ -168,11 +162,11 @@ class HubRepositoryImpl
final QueryResult<dc.GetBusinessesByUserIdData,
dc.GetBusinessesByUserIdVariables> result =
await executeProtected(() => _dataConnect.getBusinessesByUserId(
await _service.connector.getBusinessesByUserId(
userId: user.uid,
).execute());
).execute();
if (result.data.businesses.isEmpty) {
await _firebaseAuth.signOut();
await _service.auth.signOut();
throw BusinessNotFoundException(
technicalMessage: 'No business found for user ${user.uid}',
);
@@ -203,14 +197,14 @@ class HubRepositoryImpl
dc.GetBusinessesByUserIdBusinesses business,
) async {
final QueryResult<dc.GetTeamsByOwnerIdData, dc.GetTeamsByOwnerIdVariables>
teamsResult = await executeProtected(() => _dataConnect.getTeamsByOwnerId(
teamsResult = await _service.connector.getTeamsByOwnerId(
ownerId: business.id,
).execute());
).execute();
if (teamsResult.data.teams.isNotEmpty) {
return teamsResult.data.teams.first.id;
}
final dc.CreateTeamVariablesBuilder createTeamBuilder = _dataConnect.createTeam(
final dc.CreateTeamVariablesBuilder createTeamBuilder = _service.connector.createTeam(
teamName: '${business.businessName} Team',
ownerId: business.id,
ownerName: business.contactName ?? '',
@@ -222,7 +216,7 @@ class HubRepositoryImpl
final OperationResult<dc.CreateTeamData, dc.CreateTeamVariables>
createTeamResult =
await executeProtected(() => createTeamBuilder.execute());
await createTeamBuilder.execute();
final String teamId = createTeamResult.data.team_insert.id;
return teamId;
@@ -234,9 +228,9 @@ class HubRepositoryImpl
}) async {
final QueryResult<dc.GetTeamHubsByTeamIdData,
dc.GetTeamHubsByTeamIdVariables> hubsResult =
await executeProtected(() => _dataConnect.getTeamHubsByTeamId(
await _service.connector.getTeamHubsByTeamId(
teamId: teamId,
).execute());
).execute();
return hubsResult.data.teamHubs
.map(