Merge pull request #286 from Oloodi/hub_creation

Hub creation
This commit is contained in:
Achintha Isuru
2026-01-22 12:39:38 -05:00
committed by GitHub
17 changed files with 20055 additions and 19885 deletions

View File

@@ -1,16 +1,16 @@
# Basic Usage
```dart
ExampleConnector.instance.createDocument(createDocumentVariables).execute();
ExampleConnector.instance.updateDocument(updateDocumentVariables).execute();
ExampleConnector.instance.deleteDocument(deleteDocumentVariables).execute();
ExampleConnector.instance.createConversation(createConversationVariables).execute();
ExampleConnector.instance.updateConversation(updateConversationVariables).execute();
ExampleConnector.instance.updateConversationLastMessage(updateConversationLastMessageVariables).execute();
ExampleConnector.instance.deleteConversation(deleteConversationVariables).execute();
ExampleConnector.instance.listHubs().execute();
ExampleConnector.instance.getHubById(getHubByIdVariables).execute();
ExampleConnector.instance.getHubsByOwnerId(getHubsByOwnerIdVariables).execute();
ExampleConnector.instance.createTeamHudDepartment(createTeamHudDepartmentVariables).execute();
ExampleConnector.instance.updateTeamHudDepartment(updateTeamHudDepartmentVariables).execute();
ExampleConnector.instance.deleteTeamHudDepartment(deleteTeamHudDepartmentVariables).execute();
ExampleConnector.instance.listAssignments(listAssignmentsVariables).execute();
ExampleConnector.instance.getAssignmentById(getAssignmentByIdVariables).execute();
ExampleConnector.instance.listAssignmentsByWorkforceId(listAssignmentsByWorkforceIdVariables).execute();
ExampleConnector.instance.listAssignmentsByWorkforceIds(listAssignmentsByWorkforceIdsVariables).execute();
ExampleConnector.instance.listAssignmentsByShiftRole(listAssignmentsByShiftRoleVariables).execute();
ExampleConnector.instance.filterAssignments(filterAssignmentsVariables).execute();
ExampleConnector.instance.CreateCertificate(createCertificateVariables).execute();
```
@@ -23,8 +23,8 @@ Optional fields can be discovered based on classes that have `Optional` object t
This is an example of a mutation with an optional field:
```dart
await ExampleConnector.instance.filterVendorBenefitPlans({ ... })
.vendorId(...)
await ExampleConnector.instance.updateShift({ ... })
.title(...)
.execute();
```

View File

@@ -4,14 +4,30 @@ class CreateTeamHubVariablesBuilder {
String teamId;
String hubName;
String address;
String city;
String state;
String zipCode;
String managerName;
Optional<String> _city = Optional.optional(nativeFromJson, nativeToJson);
Optional<String> _state = Optional.optional(nativeFromJson, nativeToJson);
Optional<String> _zipCode = Optional.optional(nativeFromJson, nativeToJson);
Optional<String> _managerName = Optional.optional(nativeFromJson, nativeToJson);
Optional<bool> _isActive = Optional.optional(nativeFromJson, nativeToJson);
Optional<AnyValue> _departments = Optional.optional(AnyValue.fromJson, defaultSerializer);
final FirebaseDataConnect _dataConnect; CreateTeamHubVariablesBuilder isActive(bool? t) {
final FirebaseDataConnect _dataConnect; CreateTeamHubVariablesBuilder city(String? t) {
_city.value = t;
return this;
}
CreateTeamHubVariablesBuilder state(String? t) {
_state.value = t;
return this;
}
CreateTeamHubVariablesBuilder zipCode(String? t) {
_zipCode.value = t;
return this;
}
CreateTeamHubVariablesBuilder managerName(String? t) {
_managerName.value = t;
return this;
}
CreateTeamHubVariablesBuilder isActive(bool? t) {
_isActive.value = t;
return this;
}
@@ -20,7 +36,7 @@ class CreateTeamHubVariablesBuilder {
return this;
}
CreateTeamHubVariablesBuilder(this._dataConnect, {required this.teamId,required this.hubName,required this.address,required this.city,required this.state,required this.zipCode,required this.managerName,});
CreateTeamHubVariablesBuilder(this._dataConnect, {required this.teamId,required this.hubName,required this.address,});
Deserializer<CreateTeamHubData> dataDeserializer = (dynamic json) => CreateTeamHubData.fromJson(jsonDecode(json));
Serializer<CreateTeamHubVariables> varsSerializer = (CreateTeamHubVariables vars) => jsonEncode(vars.toJson());
Future<OperationResult<CreateTeamHubData, CreateTeamHubVariables>> execute() {
@@ -28,7 +44,7 @@ class CreateTeamHubVariablesBuilder {
}
MutationRef<CreateTeamHubData, CreateTeamHubVariables> ref() {
CreateTeamHubVariables vars= CreateTeamHubVariables(teamId: teamId,hubName: hubName,address: address,city: city,state: state,zipCode: zipCode,managerName: managerName,isActive: _isActive,departments: _departments,);
CreateTeamHubVariables vars= CreateTeamHubVariables(teamId: teamId,hubName: hubName,address: address,city: _city,state: _state,zipCode: _zipCode,managerName: _managerName,isActive: _isActive,departments: _departments,);
return _dataConnect.mutation("createTeamHub", dataDeserializer, varsSerializer, vars);
}
}
@@ -106,10 +122,10 @@ class CreateTeamHubVariables {
final String teamId;
final String hubName;
final String address;
final String city;
final String state;
final String zipCode;
final String managerName;
late final Optional<String>city;
late final Optional<String>state;
late final Optional<String>zipCode;
late final Optional<String>managerName;
late final Optional<bool>isActive;
late final Optional<AnyValue>departments;
@Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.')
@@ -117,18 +133,26 @@ class CreateTeamHubVariables {
teamId = nativeFromJson<String>(json['teamId']),
hubName = nativeFromJson<String>(json['hubName']),
address = nativeFromJson<String>(json['address']),
city = nativeFromJson<String>(json['city']),
state = nativeFromJson<String>(json['state']),
zipCode = nativeFromJson<String>(json['zipCode']),
managerName = nativeFromJson<String>(json['managerName']) {
address = nativeFromJson<String>(json['address']) {
city = Optional.optional(nativeFromJson, nativeToJson);
city.value = json['city'] == null ? null : nativeFromJson<String>(json['city']);
state = Optional.optional(nativeFromJson, nativeToJson);
state.value = json['state'] == null ? null : nativeFromJson<String>(json['state']);
zipCode = Optional.optional(nativeFromJson, nativeToJson);
zipCode.value = json['zipCode'] == null ? null : nativeFromJson<String>(json['zipCode']);
managerName = Optional.optional(nativeFromJson, nativeToJson);
managerName.value = json['managerName'] == null ? null : nativeFromJson<String>(json['managerName']);
isActive = Optional.optional(nativeFromJson, nativeToJson);
@@ -169,10 +193,18 @@ class CreateTeamHubVariables {
json['teamId'] = nativeToJson<String>(teamId);
json['hubName'] = nativeToJson<String>(hubName);
json['address'] = nativeToJson<String>(address);
json['city'] = nativeToJson<String>(city);
json['state'] = nativeToJson<String>(state);
json['zipCode'] = nativeToJson<String>(zipCode);
json['managerName'] = nativeToJson<String>(managerName);
if(city.state == OptionalState.set) {
json['city'] = city.toJson();
}
if(state.state == OptionalState.set) {
json['state'] = state.toJson();
}
if(zipCode.state == OptionalState.set) {
json['zipCode'] = zipCode.toJson();
}
if(managerName.state == OptionalState.set) {
json['managerName'] = managerName.toJson();
}
if(isActive.state == OptionalState.set) {
json['isActive'] = isActive.toJson();
}

View File

@@ -23,10 +23,10 @@ class GetTeamHubByIdTeamHub {
final String teamId;
final String hubName;
final String address;
final String city;
final String state;
final String zipCode;
final String managerName;
final String? city;
final String? state;
final String? zipCode;
final String? managerName;
final bool isActive;
final AnyValue? departments;
final Timestamp? createdAt;
@@ -38,10 +38,10 @@ class GetTeamHubByIdTeamHub {
teamId = nativeFromJson<String>(json['teamId']),
hubName = nativeFromJson<String>(json['hubName']),
address = nativeFromJson<String>(json['address']),
city = nativeFromJson<String>(json['city']),
state = nativeFromJson<String>(json['state']),
zipCode = nativeFromJson<String>(json['zipCode']),
managerName = nativeFromJson<String>(json['managerName']),
city = json['city'] == null ? null : nativeFromJson<String>(json['city']),
state = json['state'] == null ? null : nativeFromJson<String>(json['state']),
zipCode = json['zipCode'] == null ? null : nativeFromJson<String>(json['zipCode']),
managerName = json['managerName'] == null ? null : nativeFromJson<String>(json['managerName']),
isActive = nativeFromJson<bool>(json['isActive']),
departments = json['departments'] == null ? null : AnyValue.fromJson(json['departments']),
createdAt = json['createdAt'] == null ? null : Timestamp.fromJson(json['createdAt']),
@@ -82,10 +82,18 @@ class GetTeamHubByIdTeamHub {
json['teamId'] = nativeToJson<String>(teamId);
json['hubName'] = nativeToJson<String>(hubName);
json['address'] = nativeToJson<String>(address);
json['city'] = nativeToJson<String>(city);
json['state'] = nativeToJson<String>(state);
json['zipCode'] = nativeToJson<String>(zipCode);
json['managerName'] = nativeToJson<String>(managerName);
if (city != null) {
json['city'] = nativeToJson<String?>(city);
}
if (state != null) {
json['state'] = nativeToJson<String?>(state);
}
if (zipCode != null) {
json['zipCode'] = nativeToJson<String?>(zipCode);
}
if (managerName != null) {
json['managerName'] = nativeToJson<String?>(managerName);
}
json['isActive'] = nativeToJson<bool>(isActive);
if (departments != null) {
json['departments'] = departments!.toJson();
@@ -107,10 +115,10 @@ class GetTeamHubByIdTeamHub {
required this.teamId,
required this.hubName,
required this.address,
required this.city,
required this.state,
required this.zipCode,
required this.managerName,
this.city,
this.state,
this.zipCode,
this.managerName,
required this.isActive,
this.departments,
this.createdAt,

View File

@@ -23,10 +23,10 @@ class GetTeamHubsByTeamIdTeamHubs {
final String teamId;
final String hubName;
final String address;
final String city;
final String state;
final String zipCode;
final String managerName;
final String? city;
final String? state;
final String? zipCode;
final String? managerName;
final bool isActive;
final AnyValue? departments;
final Timestamp? createdAt;
@@ -38,10 +38,10 @@ class GetTeamHubsByTeamIdTeamHubs {
teamId = nativeFromJson<String>(json['teamId']),
hubName = nativeFromJson<String>(json['hubName']),
address = nativeFromJson<String>(json['address']),
city = nativeFromJson<String>(json['city']),
state = nativeFromJson<String>(json['state']),
zipCode = nativeFromJson<String>(json['zipCode']),
managerName = nativeFromJson<String>(json['managerName']),
city = json['city'] == null ? null : nativeFromJson<String>(json['city']),
state = json['state'] == null ? null : nativeFromJson<String>(json['state']),
zipCode = json['zipCode'] == null ? null : nativeFromJson<String>(json['zipCode']),
managerName = json['managerName'] == null ? null : nativeFromJson<String>(json['managerName']),
isActive = nativeFromJson<bool>(json['isActive']),
departments = json['departments'] == null ? null : AnyValue.fromJson(json['departments']),
createdAt = json['createdAt'] == null ? null : Timestamp.fromJson(json['createdAt']),
@@ -82,10 +82,18 @@ class GetTeamHubsByTeamIdTeamHubs {
json['teamId'] = nativeToJson<String>(teamId);
json['hubName'] = nativeToJson<String>(hubName);
json['address'] = nativeToJson<String>(address);
json['city'] = nativeToJson<String>(city);
json['state'] = nativeToJson<String>(state);
json['zipCode'] = nativeToJson<String>(zipCode);
json['managerName'] = nativeToJson<String>(managerName);
if (city != null) {
json['city'] = nativeToJson<String?>(city);
}
if (state != null) {
json['state'] = nativeToJson<String?>(state);
}
if (zipCode != null) {
json['zipCode'] = nativeToJson<String?>(zipCode);
}
if (managerName != null) {
json['managerName'] = nativeToJson<String?>(managerName);
}
json['isActive'] = nativeToJson<bool>(isActive);
if (departments != null) {
json['departments'] = departments!.toJson();
@@ -107,10 +115,10 @@ class GetTeamHubsByTeamIdTeamHubs {
required this.teamId,
required this.hubName,
required this.address,
required this.city,
required this.state,
required this.zipCode,
required this.managerName,
this.city,
this.state,
this.zipCode,
this.managerName,
required this.isActive,
this.departments,
this.createdAt,

View File

@@ -22,10 +22,10 @@ class ListTeamHubsTeamHubs {
final String teamId;
final String hubName;
final String address;
final String city;
final String state;
final String zipCode;
final String managerName;
final String? city;
final String? state;
final String? zipCode;
final String? managerName;
final bool isActive;
final AnyValue? departments;
final Timestamp? createdAt;
@@ -37,10 +37,10 @@ class ListTeamHubsTeamHubs {
teamId = nativeFromJson<String>(json['teamId']),
hubName = nativeFromJson<String>(json['hubName']),
address = nativeFromJson<String>(json['address']),
city = nativeFromJson<String>(json['city']),
state = nativeFromJson<String>(json['state']),
zipCode = nativeFromJson<String>(json['zipCode']),
managerName = nativeFromJson<String>(json['managerName']),
city = json['city'] == null ? null : nativeFromJson<String>(json['city']),
state = json['state'] == null ? null : nativeFromJson<String>(json['state']),
zipCode = json['zipCode'] == null ? null : nativeFromJson<String>(json['zipCode']),
managerName = json['managerName'] == null ? null : nativeFromJson<String>(json['managerName']),
isActive = nativeFromJson<bool>(json['isActive']),
departments = json['departments'] == null ? null : AnyValue.fromJson(json['departments']),
createdAt = json['createdAt'] == null ? null : Timestamp.fromJson(json['createdAt']),
@@ -81,10 +81,18 @@ class ListTeamHubsTeamHubs {
json['teamId'] = nativeToJson<String>(teamId);
json['hubName'] = nativeToJson<String>(hubName);
json['address'] = nativeToJson<String>(address);
json['city'] = nativeToJson<String>(city);
json['state'] = nativeToJson<String>(state);
json['zipCode'] = nativeToJson<String>(zipCode);
json['managerName'] = nativeToJson<String>(managerName);
if (city != null) {
json['city'] = nativeToJson<String?>(city);
}
if (state != null) {
json['state'] = nativeToJson<String?>(state);
}
if (zipCode != null) {
json['zipCode'] = nativeToJson<String?>(zipCode);
}
if (managerName != null) {
json['managerName'] = nativeToJson<String?>(managerName);
}
json['isActive'] = nativeToJson<bool>(isActive);
if (departments != null) {
json['departments'] = departments!.toJson();
@@ -106,10 +114,10 @@ class ListTeamHubsTeamHubs {
required this.teamId,
required this.hubName,
required this.address,
required this.city,
required this.state,
required this.zipCode,
required this.managerName,
this.city,
this.state,
this.zipCode,
this.managerName,
required this.isActive,
this.departments,
this.createdAt,

View File

@@ -23,10 +23,10 @@ class ListTeamHubsByOwnerIdTeamHubs {
final String teamId;
final String hubName;
final String address;
final String city;
final String state;
final String zipCode;
final String managerName;
final String? city;
final String? state;
final String? zipCode;
final String? managerName;
final bool isActive;
final AnyValue? departments;
final Timestamp? createdAt;
@@ -36,10 +36,10 @@ class ListTeamHubsByOwnerIdTeamHubs {
teamId = nativeFromJson<String>(json['teamId']),
hubName = nativeFromJson<String>(json['hubName']),
address = nativeFromJson<String>(json['address']),
city = nativeFromJson<String>(json['city']),
state = nativeFromJson<String>(json['state']),
zipCode = nativeFromJson<String>(json['zipCode']),
managerName = nativeFromJson<String>(json['managerName']),
city = json['city'] == null ? null : nativeFromJson<String>(json['city']),
state = json['state'] == null ? null : nativeFromJson<String>(json['state']),
zipCode = json['zipCode'] == null ? null : nativeFromJson<String>(json['zipCode']),
managerName = json['managerName'] == null ? null : nativeFromJson<String>(json['managerName']),
isActive = nativeFromJson<bool>(json['isActive']),
departments = json['departments'] == null ? null : AnyValue.fromJson(json['departments']),
createdAt = json['createdAt'] == null ? null : Timestamp.fromJson(json['createdAt']);
@@ -76,10 +76,18 @@ class ListTeamHubsByOwnerIdTeamHubs {
json['teamId'] = nativeToJson<String>(teamId);
json['hubName'] = nativeToJson<String>(hubName);
json['address'] = nativeToJson<String>(address);
json['city'] = nativeToJson<String>(city);
json['state'] = nativeToJson<String>(state);
json['zipCode'] = nativeToJson<String>(zipCode);
json['managerName'] = nativeToJson<String>(managerName);
if (city != null) {
json['city'] = nativeToJson<String?>(city);
}
if (state != null) {
json['state'] = nativeToJson<String?>(state);
}
if (zipCode != null) {
json['zipCode'] = nativeToJson<String?>(zipCode);
}
if (managerName != null) {
json['managerName'] = nativeToJson<String?>(managerName);
}
json['isActive'] = nativeToJson<bool>(isActive);
if (departments != null) {
json['departments'] = departments!.toJson();
@@ -95,10 +103,10 @@ class ListTeamHubsByOwnerIdTeamHubs {
required this.teamId,
required this.hubName,
required this.address,
required this.city,
required this.state,
required this.zipCode,
required this.managerName,
this.city,
this.state,
this.zipCode,
this.managerName,
required this.isActive,
this.departments,
this.createdAt,

View File

@@ -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

View File

@@ -1,45 +1,151 @@
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;
final result = await _dataConnect
.createTeamHub(
teamId: teamId,
hubName: name,
address: address,
)
.city(city?.isNotEmpty == true ? 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();
}
}