new schemas of teams and hubs
This commit is contained in:
@@ -2,6 +2,7 @@ library client_hubs;
|
||||
|
||||
import 'package:flutter_modular/flutter_modular.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';
|
||||
@@ -22,7 +23,10 @@ class ClientHubsModule extends Module {
|
||||
void binds(Injector i) {
|
||||
// Repositories
|
||||
i.addLazySingleton<HubRepositoryInterface>(
|
||||
() => HubRepositoryImpl(mock: i.get<BusinessRepositoryMock>()),
|
||||
() => HubRepositoryImpl(
|
||||
firebaseAuth: firebase.FirebaseAuth.instance,
|
||||
dataConnect: ExampleConnector.instance,
|
||||
),
|
||||
);
|
||||
|
||||
// UseCases
|
||||
|
||||
@@ -1,45 +1,154 @@
|
||||
import 'package:krow_data_connect/krow_data_connect.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart' as firebase;
|
||||
import 'package:krow_data_connect/krow_data_connect.dart' as dc;
|
||||
import 'package:krow_domain/krow_domain.dart' as domain;
|
||||
import '../../domain/repositories/hub_repository_interface.dart';
|
||||
|
||||
/// Implementation of [HubRepositoryInterface] that uses [BusinessRepositoryMock].
|
||||
///
|
||||
/// This class serves as a data adapter that bridges the domain repository interface
|
||||
/// 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.
|
||||
/// Implementation of [HubRepositoryInterface] backed by Data Connect.
|
||||
class HubRepositoryImpl implements HubRepositoryInterface {
|
||||
/// The business repository mock from data connect.
|
||||
final BusinessRepositoryMock mock;
|
||||
final firebase.FirebaseAuth _firebaseAuth;
|
||||
final dc.ExampleConnector _dataConnect;
|
||||
|
||||
/// Creates a [HubRepositoryImpl] instance.
|
||||
///
|
||||
/// Takes a [BusinessRepositoryMock] as a dependency to perform data operations.
|
||||
HubRepositoryImpl({required this.mock});
|
||||
HubRepositoryImpl({
|
||||
required firebase.FirebaseAuth firebaseAuth,
|
||||
required dc.ExampleConnector dataConnect,
|
||||
}) : _firebaseAuth = firebaseAuth,
|
||||
_dataConnect = dataConnect;
|
||||
|
||||
@override
|
||||
Future<List<Hub>> getHubs() {
|
||||
// In a production environment, the business ID would be retrieved from
|
||||
// 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');
|
||||
Future<List<domain.Hub>> getHubs() async {
|
||||
final business = await _getBusinessForCurrentUser();
|
||||
final teamId = await _getOrCreateTeamId(business);
|
||||
return _fetchHubsForTeam(teamId: teamId, businessId: business.id);
|
||||
}
|
||||
|
||||
@override
|
||||
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);
|
||||
Future<domain.Hub> createHub({
|
||||
required String name,
|
||||
required String address,
|
||||
}) async {
|
||||
final business = await _getBusinessForCurrentUser();
|
||||
final teamId = await _getOrCreateTeamId(business);
|
||||
final city = business.city;
|
||||
if (city == null || city.isEmpty) {
|
||||
throw Exception('Business city is missing.');
|
||||
}
|
||||
|
||||
final result = await _dataConnect
|
||||
.createTeamHub(
|
||||
teamId: teamId,
|
||||
hubName: name,
|
||||
address: address,
|
||||
city: city,
|
||||
)
|
||||
.execute();
|
||||
final createdId = result.data?.teamHub_insert.id;
|
||||
if (createdId == null) {
|
||||
throw Exception('Hub creation failed.');
|
||||
}
|
||||
|
||||
final hubs = await _fetchHubsForTeam(
|
||||
teamId: teamId,
|
||||
businessId: business.id,
|
||||
);
|
||||
domain.Hub? createdHub;
|
||||
for (final 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,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteHub(String id) {
|
||||
// Delegates hub deletion to the mock repository.
|
||||
return mock.deleteHub(id);
|
||||
Future<void> deleteHub(String id) async {
|
||||
await _dataConnect.deleteTeamHub(id: id).execute();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> assignNfcTag({required String hubId, required String nfcTagId}) {
|
||||
// Delegates NFC tag assignment to the mock repository.
|
||||
return mock.assignNfcTag(hubId: hubId, nfcTagId: nfcTagId);
|
||||
Future<void> assignNfcTag({
|
||||
required String hubId,
|
||||
required String nfcTagId,
|
||||
}) {
|
||||
throw UnimplementedError('NFC tag assignment is not supported for team hubs.');
|
||||
}
|
||||
|
||||
Future<dc.GetBusinessesByUserIdBusinesses> _getBusinessForCurrentUser() async {
|
||||
final user = _firebaseAuth.currentUser;
|
||||
if (user == null) {
|
||||
throw Exception('User is not authenticated.');
|
||||
}
|
||||
|
||||
final result = await _dataConnect.getBusinessesByUserId(
|
||||
userId: user.uid,
|
||||
).execute();
|
||||
if (result.data.businesses.isEmpty) {
|
||||
await _firebaseAuth.signOut();
|
||||
throw Exception('No business found for this user. Please sign in again.');
|
||||
}
|
||||
|
||||
return result.data.businesses.first;
|
||||
}
|
||||
|
||||
Future<String> _getOrCreateTeamId(
|
||||
dc.GetBusinessesByUserIdBusinesses business,
|
||||
) async {
|
||||
final teamsResult = await _dataConnect.getTeamsByOwnerId(
|
||||
ownerId: business.id,
|
||||
).execute();
|
||||
if (teamsResult.data.teams.isNotEmpty) {
|
||||
return teamsResult.data.teams.first.id;
|
||||
}
|
||||
|
||||
final createTeamBuilder = _dataConnect.createTeam(
|
||||
teamName: '${business.businessName} Team',
|
||||
ownerId: business.id,
|
||||
ownerName: business.contactName ?? '',
|
||||
ownerRole: 'OWNER',
|
||||
);
|
||||
if (business.email != null) {
|
||||
createTeamBuilder.email(business.email);
|
||||
}
|
||||
|
||||
final createTeamResult = await createTeamBuilder.execute();
|
||||
final teamId = createTeamResult.data?.team_insert.id;
|
||||
if (teamId == null) {
|
||||
throw Exception('Team creation failed.');
|
||||
}
|
||||
|
||||
return teamId;
|
||||
}
|
||||
|
||||
Future<List<domain.Hub>> _fetchHubsForTeam({
|
||||
required String teamId,
|
||||
required String businessId,
|
||||
}) async {
|
||||
final hubsResult = await _dataConnect.getTeamHubsByTeamId(
|
||||
teamId: teamId,
|
||||
).execute();
|
||||
|
||||
return hubsResult.data.teamHubs
|
||||
.map(
|
||||
(hub) => domain.Hub(
|
||||
id: hub.id,
|
||||
businessId: businessId,
|
||||
name: hub.hubName,
|
||||
address: hub.address,
|
||||
nfcTagId: null,
|
||||
status:
|
||||
hub.isActive
|
||||
? domain.HubStatus.active
|
||||
: domain.HubStatus.inactive,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user