From d0585d12abfbecc87578f8d5f1a392697464e99c Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Mon, 16 Feb 2026 15:47:01 -0500 Subject: [PATCH] feat(auth): Refactor AuthRepositoryImpl and ProfileSetupRepositoryImpl to use DataConnectService for authentication and data operations --- .../auth_repository_impl.dart | 103 ++++++++++-------- .../profile_setup_repository_impl.dart | 32 +++--- .../lib/src/staff_authentication_module.dart | 15 +-- 3 files changed, 76 insertions(+), 74 deletions(-) diff --git a/apps/mobile/packages/features/staff/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart b/apps/mobile/packages/features/staff/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart index 0d4bca6b..b247880e 100644 --- a/apps/mobile/packages/features/staff/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart +++ b/apps/mobile/packages/features/staff/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart @@ -10,20 +10,14 @@ import '../../domain/ui_entities/auth_mode.dart'; import '../../domain/repositories/auth_repository_interface.dart'; /// Implementation of [AuthRepositoryInterface]. -class AuthRepositoryImpl - with DataErrorHandler - implements AuthRepositoryInterface { - AuthRepositoryImpl({ - required this.firebaseAuth, - required this.dataConnect, - }); +class AuthRepositoryImpl implements AuthRepositoryInterface { + AuthRepositoryImpl() : _service = DataConnectService.instance; - final FirebaseAuth firebaseAuth; - final ExampleConnector dataConnect; + final DataConnectService _service; Completer? _pendingVerification; @override - Stream get currentUser => firebaseAuth + Stream get currentUser => _service.auth .authStateChanges() .map((User? firebaseUser) { if (firebaseUser == null) { @@ -44,7 +38,7 @@ class AuthRepositoryImpl final Completer completer = Completer(); _pendingVerification = completer; - await firebaseAuth.verifyPhoneNumber( + await _service.auth.verifyPhoneNumber( phoneNumber: phoneNumber, verificationCompleted: (PhoneAuthCredential credential) { // Skip auto-verification for test numbers to allow manual code entry @@ -101,7 +95,8 @@ class AuthRepositoryImpl @override Future signOut() { StaffSessionStore.instance.clear(); - return firebaseAuth.signOut(); + _service.clearCache(); + return _service.auth.signOut(); } /// Verifies an OTP code and returns the authenticated user. @@ -115,10 +110,10 @@ class AuthRepositoryImpl verificationId: verificationId, smsCode: smsCode, ); - final UserCredential userCredential = await executeProtected( + final UserCredential userCredential = await _service.run( () async { try { - return await firebaseAuth.signInWithCredential(credential); + return await _service.auth.signInWithCredential(credential); } on FirebaseAuthException catch (e) { if (e.code == 'invalid-verification-code') { throw const domain.InvalidCredentialsException( @@ -128,45 +123,56 @@ class AuthRepositoryImpl rethrow; } }, + requiresAuthentication: false, ); final User? firebaseUser = userCredential.user; if (firebaseUser == null) { throw const domain.SignInFailedException( - technicalMessage: 'Phone verification failed, no Firebase user received.', + technicalMessage: + 'Phone verification failed, no Firebase user received.', ); } final QueryResult response = - await executeProtected(() => dataConnect - .getUserById( - id: firebaseUser.uid, - ) - .execute()); + await _service.run( + () => _service.connector + .getUserById( + id: firebaseUser.uid, + ) + .execute(), + requiresAuthentication: false, + ); final GetUserByIdUser? user = response.data.user; GetStaffByUserIdStaffs? staffRecord; if (mode == AuthMode.signup) { if (user == null) { - await executeProtected(() => dataConnect - .createUser( - id: firebaseUser.uid, - role: UserBaseRole.USER, - ) - .userRole('STAFF') - .execute()); + await _service.run( + () => _service.connector + .createUser( + id: firebaseUser.uid, + role: UserBaseRole.USER, + ) + .userRole('STAFF') + .execute(), + requiresAuthentication: false, + ); } else { // User exists in PostgreSQL. Check if they have a STAFF profile. final QueryResult - staffResponse = await executeProtected(() => dataConnect - .getStaffByUserId( - userId: firebaseUser.uid, - ) - .execute()); + staffResponse = await _service.run( + () => _service.connector + .getStaffByUserId( + userId: firebaseUser.uid, + ) + .execute(), + requiresAuthentication: false, + ); if (staffResponse.data.staffs.isNotEmpty) { // If profile exists, they should use Login mode. - await firebaseAuth.signOut(); + await _service.auth.signOut(); throw const domain.AccountExistsException( technicalMessage: 'This user already has a staff profile. Please log in.', @@ -177,35 +183,44 @@ class AuthRepositoryImpl // they are allowed to "Sign Up" for Staff. // We update their userRole to 'BOTH'. if (user.userRole == 'BUSINESS') { - await executeProtected(() => - dataConnect.updateUser(id: firebaseUser.uid).userRole('BOTH').execute()); + await _service.run( + () => _service.connector + .updateUser(id: firebaseUser.uid) + .userRole('BOTH') + .execute(), + requiresAuthentication: false, + ); } } } else { if (user == null) { - await firebaseAuth.signOut(); + await _service.auth.signOut(); throw const domain.UserNotFoundException( technicalMessage: 'Authenticated user profile not found in database.', ); } // Allow STAFF or BOTH roles to log in to the Staff App if (user.userRole != 'STAFF' && user.userRole != 'BOTH') { - await firebaseAuth.signOut(); + await _service.auth.signOut(); throw const domain.UnauthorizedAppException( technicalMessage: 'User is not authorized for this app.', ); } final QueryResult - staffResponse = await executeProtected(() => dataConnect - .getStaffByUserId( - userId: firebaseUser.uid, - ) - .execute()); + staffResponse = await _service.run( + () => _service.connector + .getStaffByUserId( + userId: firebaseUser.uid, + ) + .execute(), + requiresAuthentication: false, + ); if (staffResponse.data.staffs.isEmpty) { - await firebaseAuth.signOut(); + await _service.auth.signOut(); throw const domain.UserNotFoundException( - technicalMessage: 'Your account is not registered yet. Please register first.', + technicalMessage: + 'Your account is not registered yet. Please register first.', ); } staffRecord = staffResponse.data.staffs.first; diff --git a/apps/mobile/packages/features/staff/authentication/lib/src/data/repositories_impl/profile_setup_repository_impl.dart b/apps/mobile/packages/features/staff/authentication/lib/src/data/repositories_impl/profile_setup_repository_impl.dart index 1aeabdc2..fe25eea3 100644 --- a/apps/mobile/packages/features/staff/authentication/lib/src/data/repositories_impl/profile_setup_repository_impl.dart +++ b/apps/mobile/packages/features/staff/authentication/lib/src/data/repositories_impl/profile_setup_repository_impl.dart @@ -1,18 +1,13 @@ -import 'package:firebase_auth/firebase_auth.dart' as auth; import 'package:krow_data_connect/krow_data_connect.dart'; import 'package:firebase_data_connect/firebase_data_connect.dart' as fdc; import 'package:krow_domain/krow_domain.dart'; +import 'package:firebase_auth/firebase_auth.dart' as auth; import '../../domain/repositories/profile_setup_repository.dart'; class ProfileSetupRepositoryImpl implements ProfileSetupRepository { - final auth.FirebaseAuth _firebaseAuth; - final ExampleConnector _dataConnect; + final DataConnectService _service; - ProfileSetupRepositoryImpl({ - required auth.FirebaseAuth firebaseAuth, - required ExampleConnector dataConnect, - }) : _firebaseAuth = firebaseAuth, - _dataConnect = dataConnect; + ProfileSetupRepositoryImpl() : _service = DataConnectService.instance; @override Future submitProfile({ @@ -23,17 +18,19 @@ class ProfileSetupRepositoryImpl implements ProfileSetupRepository { required List industries, required List skills, }) async { - final auth.User? firebaseUser = _firebaseAuth.currentUser; - if (firebaseUser == null) { - throw Exception('User not authenticated.'); - } + return _service.run(() async { + final auth.User? firebaseUser = _service.auth.currentUser; + if (firebaseUser == null) { + throw const NotAuthenticatedException( + technicalMessage: 'User not authenticated.'); + } - final StaffSession? session = StaffSessionStore.instance.session; - final String email = session?.user.email ?? ''; - final String? phone = firebaseUser.phoneNumber; + final StaffSession? session = StaffSessionStore.instance.session; + final String email = session?.user.email ?? ''; + final String? phone = firebaseUser.phoneNumber; - final fdc.OperationResult - result = await _dataConnect + final fdc.OperationResult result = + await _service.connector .createStaff( userId: firebaseUser.uid, fullName: fullName, @@ -63,5 +60,6 @@ class ProfileSetupRepositoryImpl implements ProfileSetupRepository { StaffSession(user: session.user, staff: staff, ownerId: session.ownerId), ); } + }); } } diff --git a/apps/mobile/packages/features/staff/authentication/lib/src/staff_authentication_module.dart b/apps/mobile/packages/features/staff/authentication/lib/src/staff_authentication_module.dart index ef1f34da..c5380d68 100644 --- a/apps/mobile/packages/features/staff/authentication/lib/src/staff_authentication_module.dart +++ b/apps/mobile/packages/features/staff/authentication/lib/src/staff_authentication_module.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; 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 'package:staff_authentication/src/data/repositories_impl/auth_repository_impl.dart'; import 'package:staff_authentication/src/domain/repositories/auth_repository_interface.dart'; import 'package:staff_authentication/src/domain/usecases/sign_in_with_phone_usecase.dart'; @@ -28,18 +27,8 @@ class StaffAuthenticationModule extends Module { @override void binds(Injector i) { // Repositories - i.addLazySingleton( - () => AuthRepositoryImpl( - firebaseAuth: firebase.FirebaseAuth.instance, - dataConnect: ExampleConnector.instance, - ), - ); - i.addLazySingleton( - () => ProfileSetupRepositoryImpl( - firebaseAuth: firebase.FirebaseAuth.instance, - dataConnect: ExampleConnector.instance, - ), - ); + i.addLazySingleton(AuthRepositoryImpl.new); + i.addLazySingleton(ProfileSetupRepositoryImpl.new); i.addLazySingleton(PlaceRepositoryImpl.new); // UseCases