diff --git a/apps/mobile/apps/client/pubspec.yaml b/apps/mobile/apps/client/pubspec.yaml index edbf3c43..95b95834 100644 --- a/apps/mobile/apps/client/pubspec.yaml +++ b/apps/mobile/apps/client/pubspec.yaml @@ -11,22 +11,26 @@ dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.8 + flutter_modular: ^6.3.2 + flutter_bloc: ^8.1.3 + flutter_localizations: + sdk: flutter + + # Architecture Packages design_system: path: ../../packages/design_system + core_localization: + path: ../../packages/core_localization + + # Feature Packages client_authentication: path: ../../packages/features/client/authentication client_home: path: ../../packages/features/client/home client_settings: path: ../../packages/features/client/settings - core_localization: - path: ../../packages/core_localization client_hubs: path: ../../packages/features/client/hubs - flutter_modular: ^6.3.2 - flutter_bloc: ^8.1.3 - flutter_localizations: - sdk: flutter dev_dependencies: flutter_test: diff --git a/apps/mobile/apps/staff/pubspec.yaml b/apps/mobile/apps/staff/pubspec.yaml index 659a41ad..4a968d93 100644 --- a/apps/mobile/apps/staff/pubspec.yaml +++ b/apps/mobile/apps/staff/pubspec.yaml @@ -13,12 +13,16 @@ dependencies: sdk: flutter cupertino_icons: ^1.0.8 flutter_modular: ^6.3.0 + + # Architecture Packages design_system: path: ../../packages/design_system - staff_authentication: - path: ../../packages/features/staff/authentication core_localization: path: ../../packages/core_localization + + # Feature Packages + staff_authentication: + path: ../../packages/features/staff/authentication dev_dependencies: flutter_test: diff --git a/apps/mobile/packages/design_system/CHANGELOG.md b/apps/mobile/packages/design_system/CHANGELOG.md deleted file mode 100644 index 41cc7d81..00000000 --- a/apps/mobile/packages/design_system/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -## 0.0.1 - -* TODO: Describe initial release. diff --git a/apps/mobile/packages/design_system/LICENSE b/apps/mobile/packages/design_system/LICENSE deleted file mode 100644 index ba75c69f..00000000 --- a/apps/mobile/packages/design_system/LICENSE +++ /dev/null @@ -1 +0,0 @@ -TODO: Add your license here. diff --git a/apps/mobile/packages/design_system/README.md b/apps/mobile/packages/design_system/README.md deleted file mode 100644 index 4a260d8d..00000000 --- a/apps/mobile/packages/design_system/README.md +++ /dev/null @@ -1,39 +0,0 @@ - - -TODO: Put a short description of the package here that helps potential users -know whether this package might be useful for them. - -## Features - -TODO: List what your package can do. Maybe include images, gifs, or videos. - -## Getting started - -TODO: List prerequisites and provide or point to information on how to -start using the package. - -## Usage - -TODO: Include short and useful examples for package users. Add longer examples -to `/example` folder. - -```dart -const like = 'sample'; -``` - -## Additional information - -TODO: Tell users more about the package: where to find more information, how to -contribute to the package, how to file issues, what response they can expect -from the package authors, and more. diff --git a/apps/mobile/packages/features/client/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart b/apps/mobile/packages/features/client/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart index ede79873..ef697865 100644 --- a/apps/mobile/packages/features/client/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart +++ b/apps/mobile/packages/features/client/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart @@ -1,5 +1,5 @@ -import 'package:firebase_auth/firebase_auth.dart' as firebase; -import 'package:krow_data_connect/krow_data_connect.dart' as dc; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:krow_data_connect/krow_data_connect.dart'; import 'package:krow_domain/krow_domain.dart' as domain; import '../../domain/repositories/auth_repository_interface.dart'; @@ -8,15 +8,15 @@ import '../../domain/repositories/auth_repository_interface.dart'; /// This implementation integrates with Firebase Authentication for user /// identity management and Krow's Data Connect SDK for storing user profile data. class AuthRepositoryImpl implements AuthRepositoryInterface { - final firebase.FirebaseAuth _firebaseAuth; - final dc.ExampleConnector _dataConnect; + final FirebaseAuth _firebaseAuth; + final ExampleConnector _dataConnect; /// Creates an [AuthRepositoryImpl] with the real dependencies. AuthRepositoryImpl({ - required firebase.FirebaseAuth firebaseAuth, - required dc.ExampleConnector dataConnect, - }) : _firebaseAuth = firebaseAuth, - _dataConnect = dataConnect; + required FirebaseAuth firebaseAuth, + required ExampleConnector dataConnect, + }) : _firebaseAuth = firebaseAuth, + _dataConnect = dataConnect; @override Future signInWithEmail({ @@ -40,8 +40,7 @@ class AuthRepositoryImpl implements AuthRepositoryInterface { ); //TO-DO: validate that user is business role and has business account - - } on firebase.FirebaseAuthException catch (e) { + } on FirebaseAuthException catch (e) { if (e.code == 'invalid-credential' || e.code == 'wrong-password') { throw Exception('Incorrect email or password.'); } else { @@ -72,23 +71,25 @@ class AuthRepositoryImpl implements AuthRepositoryInterface { // Client-specific business logic: // 1. Create a `Business` entity. // 2. Create a `User` entity associated with the business. - final createBusinessResponse = await _dataConnect.createBusiness( - businessName: companyName, - userId: firebaseUser.uid, - rateGroup: dc.BusinessRateGroup.STANDARD, - status: dc.BusinessStatus.PENDING, - ).execute(); + final createBusinessResponse = await _dataConnect + .createBusiness( + businessName: companyName, + userId: firebaseUser.uid, + rateGroup: BusinessRateGroup.STANDARD, + status: BusinessStatus.PENDING, + ) + .execute(); final businessData = createBusinessResponse.data?.business_insert; if (businessData == null) { await firebaseUser.delete(); // Rollback if business creation fails - throw Exception('Business creation failed after Firebase user registration.'); + throw Exception( + 'Business creation failed after Firebase user registration.', + ); } - final createUserResponse = await _dataConnect.createUser( - id: firebaseUser.uid, - role: dc.UserBaseRole.USER, - ) + final createUserResponse = await _dataConnect + .createUser(id: firebaseUser.uid, role: UserBaseRole.USER) .email(email) .userRole('BUSINESS') .execute(); @@ -97,15 +98,16 @@ class AuthRepositoryImpl implements AuthRepositoryInterface { if (newUserData == null) { await firebaseUser.delete(); // Rollback if user profile creation fails // TO-DO: Also delete the created Business if this fails - throw Exception('User profile creation failed after Firebase user registration.'); + throw Exception( + 'User profile creation failed after Firebase user registration.', + ); } return _getUserProfile( firebaseUserId: firebaseUser.uid, fallbackEmail: firebaseUser.email ?? email, ); - - } on firebase.FirebaseAuthException catch (e) { + } on FirebaseAuthException catch (e) { if (e.code == 'weak-password') { throw Exception('The password provided is too weak.'); } else if (e.code == 'email-already-in-use') { @@ -114,7 +116,9 @@ class AuthRepositoryImpl implements AuthRepositoryInterface { throw Exception('Sign-up error: ${e.message}'); } } catch (e) { - throw Exception('Failed to sign up and create user data: ${e.toString()}'); + throw Exception( + 'Failed to sign up and create user data: ${e.toString()}', + ); } } @@ -129,14 +133,18 @@ class AuthRepositoryImpl implements AuthRepositoryInterface { @override Future signInWithSocial({required String provider}) { - throw UnimplementedError('Social authentication with $provider is not yet implemented.'); + throw UnimplementedError( + 'Social authentication with $provider is not yet implemented.', + ); } Future _getUserProfile({ required String firebaseUserId, required String? fallbackEmail, }) async { - final response = await _dataConnect.getUserById(id: firebaseUserId).execute(); + final response = await _dataConnect + .getUserById(id: firebaseUserId) + .execute(); final user = response.data?.user; if (user == null) { throw Exception('Authenticated user profile not found in database.'); @@ -147,10 +155,6 @@ class AuthRepositoryImpl implements AuthRepositoryInterface { throw Exception('User email is missing in profile data.'); } - return domain.User( - id: user.id, - email: email, - role: user.role.stringValue, - ); + return domain.User(id: user.id, email: email, role: user.role.stringValue); } } diff --git a/apps/mobile/packages/features/client/authentication/pubspec.yaml b/apps/mobile/packages/features/client/authentication/pubspec.yaml index 590bcf27..a70cf83a 100644 --- a/apps/mobile/packages/features/client/authentication/pubspec.yaml +++ b/apps/mobile/packages/features/client/authentication/pubspec.yaml @@ -20,9 +20,13 @@ dependencies: # Architecture Packages design_system: - path: ../../../../design_system + path: ../../../design_system core_localization: path: ../../../core_localization + krow_data_connect: + path: ../../../data_connect + krow_domain: + path: ../../../domain dev_dependencies: flutter_test: diff --git a/apps/mobile/packages/features/client/home/REFACTOR_SUMMARY.md b/apps/mobile/packages/features/client/home/REFACTOR_SUMMARY.md deleted file mode 100644 index ad2d979b..00000000 --- a/apps/mobile/packages/features/client/home/REFACTOR_SUMMARY.md +++ /dev/null @@ -1,133 +0,0 @@ -# Client Home Feature - Architecture Refactor Summary - -## ✅ Completed Refactor - -The `packages/features/client/home` feature has been successfully refactored to fully comply with KROW Clean Architecture principles. - -## 📋 Changes Made - -### 1. Domain Layer Improvements - -**Created:** -- `lib/src/domain/entities/home_dashboard_data.dart` - - Proper domain entity to replace raw `Map` - - Immutable, equatable data class - - Clear field definitions with documentation - -**Updated:** -- `lib/src/domain/repositories/home_repository_interface.dart` - - Changed from `abstract class` to `abstract interface class` - - Return type changed from `Map` to `HomeDashboardData` - -- `lib/src/domain/usecases/get_dashboard_data_usecase.dart` - - Return type updated to `HomeDashboardData` - -### 2. Data Layer Improvements - -**Updated:** -- `lib/src/data/repositories_impl/home_repository_impl.dart` - - Returns `HomeDashboardData` entity instead of raw map - - Properly typed mock data - -### 3. Presentation Layer Refactor - -**Major Changes to `client_home_page.dart`:** -- ✅ Converted from `StatefulWidget` to `StatelessWidget` -- ✅ Removed local state management (moved to BLoC) -- ✅ BLoC lifecycle managed by `BlocProvider.create` -- ✅ All event dispatching uses `BlocProvider.of(context)` -- ✅ Removed direct BLoC instance storage -- ✅ Fixed deprecated `withOpacity` → `withValues(alpha:)` - -**Updated `client_home_state.dart`:** -- Replaced individual primitive fields with `HomeDashboardData` entity -- Simplified state structure -- Cleaner `copyWith` implementation - -**Updated `client_home_bloc.dart`:** -- Simplified event handler to use entity directly -- No more manual field extraction from maps - -**Widget Updates:** -- `coverage_widget.dart`: Now accepts typed parameters -- All widgets: Fixed deprecated `withOpacity` calls -- `shift_order_form_sheet.dart`: Fixed deprecated `value` → `initialValue` - -## 🎯 Architecture Compliance - -### ✅ Clean Architecture Rules -- [x] Domain layer is pure Dart (entities only) -- [x] Repository interfaces in domain, implementations in data -- [x] Use cases properly delegate to repositories -- [x] Presentation layer depends on domain abstractions -- [x] No feature-to-feature imports - -### ✅ Presentation Rules -- [x] Page is `StatelessWidget` -- [x] State managed by BLoC -- [x] No business logic in page -- [x] BLoC lifecycle properly managed -- [x] Named parameters used throughout - -### ✅ Code Quality -- [x] No deprecation warnings -- [x] All files have doc comments -- [x] Consistent naming conventions -- [x] `flutter analyze` passes with 0 issues - -## 📊 Before vs After - -### Before: -```dart -// StatefulWidget with local state -class ClientHomePage extends StatefulWidget { - late final ClientHomeBloc _homeBloc; - - @override - void initState() { - _homeBloc = Modular.get(); - } -} - -// Raw maps in domain -Future> getDashboardData(); - -// Manual field extraction -weeklySpending: data['weeklySpending'] as double?, -``` - -### After: -```dart -// StatelessWidget, BLoC-managed -class ClientHomePage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => Modular.get()..add(ClientHomeStarted()), - // ... - ); - } -} - -// Typed entities -Future getDashboardData(); - -// Direct entity usage -dashboardData: data, -``` - -## 🔍 Reference Alignment - -The refactored code now matches the structure of `packages/features/staff/authentication`: -- StatelessWidget pages -- BLoC-managed state -- Typed domain entities -- Clean separation of concerns - -## 🚀 Next Steps - -The feature is now production-ready and follows all architectural guidelines. Future enhancements should: -1. Add unit tests for use cases -2. Add widget tests for pages -3. Add integration tests for complete flows -4. Consider extracting reusable widgets to design_system if used across features diff --git a/apps/mobile/packages/features/client/home/pubspec.yaml b/apps/mobile/packages/features/client/home/pubspec.yaml index 3ee5f5f7..6c32f138 100644 --- a/apps/mobile/packages/features/client/home/pubspec.yaml +++ b/apps/mobile/packages/features/client/home/pubspec.yaml @@ -16,6 +16,7 @@ dependencies: equatable: ^2.0.5 lucide_icons: ^0.257.0 + # Architecture Packages design_system: path: ../../../design_system core_localization: diff --git a/apps/mobile/packages/features/client/hubs/pubspec.yaml b/apps/mobile/packages/features/client/hubs/pubspec.yaml index f625494a..58edd20c 100644 --- a/apps/mobile/packages/features/client/hubs/pubspec.yaml +++ b/apps/mobile/packages/features/client/hubs/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: equatable: ^2.0.5 lucide_icons: ^0.257.0 - # KROW Packages + # Architecture Packages krow_core: path: ../../../core krow_domain: diff --git a/apps/mobile/packages/features/client/settings/pubspec.yaml b/apps/mobile/packages/features/client/settings/pubspec.yaml index 67077c9a..85acb228 100644 --- a/apps/mobile/packages/features/client/settings/pubspec.yaml +++ b/apps/mobile/packages/features/client/settings/pubspec.yaml @@ -16,6 +16,7 @@ dependencies: equatable: ^2.0.5 lucide_icons: ^0.257.0 + # Architecture Packages design_system: path: ../../../design_system core_localization: