chore: Refactor imports and update architecture package structure
Reorganized and clarified dependency sections in multiple pubspec.yaml files, grouping architecture and feature packages. Updated import statements in AuthRepositoryImpl for direct usage of types. Added missing dependencies to client authentication. Removed obsolete documentation and summary files from design_system and client home packages.
This commit is contained in:
@@ -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<domain.User> 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<domain.User> 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<domain.User> _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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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<String, dynamic>`
|
||||
- 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<String, dynamic>` 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<ClientHomeBloc>(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<ClientHomeBloc>();
|
||||
}
|
||||
}
|
||||
|
||||
// Raw maps in domain
|
||||
Future<Map<String, dynamic>> 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<ClientHomeBloc>(
|
||||
create: (context) => Modular.get<ClientHomeBloc>()..add(ClientHomeStarted()),
|
||||
// ...
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Typed entities
|
||||
Future<HomeDashboardData> 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
|
||||
@@ -16,6 +16,7 @@ dependencies:
|
||||
equatable: ^2.0.5
|
||||
lucide_icons: ^0.257.0
|
||||
|
||||
# Architecture Packages
|
||||
design_system:
|
||||
path: ../../../design_system
|
||||
core_localization:
|
||||
|
||||
@@ -16,7 +16,7 @@ dependencies:
|
||||
equatable: ^2.0.5
|
||||
lucide_icons: ^0.257.0
|
||||
|
||||
# KROW Packages
|
||||
# Architecture Packages
|
||||
krow_core:
|
||||
path: ../../../core
|
||||
krow_domain:
|
||||
|
||||
@@ -16,6 +16,7 @@ dependencies:
|
||||
equatable: ^2.0.5
|
||||
lucide_icons: ^0.257.0
|
||||
|
||||
# Architecture Packages
|
||||
design_system:
|
||||
path: ../../../design_system
|
||||
core_localization:
|
||||
|
||||
Reference in New Issue
Block a user