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

View File

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