Documentation Index
Fetch the complete documentation index at: https://docs-mstore.faisalaffan.com/llms.txt
Use this file to discover all available pages before exploring further.
Arsitektur Aplikasi
MStore Mobile dibangun dengan Clean Architecture dan BLoC Pattern untuk memastikan separation of concerns, testability, dan maintainability.
๐๏ธ Arsitektur Overview
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Presentation Layer โ
โ (UI, Widgets, Pages, BLoC/Cubit State Management) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Domain Layer โ
โ (Business Logic, Use Cases, Entities, Repos) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Data Layer โ
โ (Repository Impl, API, Local DB, Data Sources) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Infrastructure โ
โ (Dio, Retrofit, Isar, Firebase, MQTT) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Struktur Folder
lib/
โโโ app.dart # Root application widget
โโโ main_development.dart # Development entry point
โโโ main_staging.dart # Staging entry point
โโโ main_production.dart # Production entry point
โ
โโโ core/ # Core business logic (Domain + Data)
โ โโโ auth/ # Authentication domain
โ โ โโโ auth_api.dart # Retrofit API
โ โ โโโ auth_repository.dart # Repository interface
โ โ โโโ auth_service.dart # Business logic
โ โ โโโ models/ # Domain models
โ โ
โ โโโ product/ # Product domain
โ โโโ inventory/ # Inventory domain
โ โโโ transaction/ # Transaction domain
โ โโโ dashboard/ # Dashboard domain
โ โโโ payments/ # Payments domain
โ โ
โ โโโ network/ # Networking infrastructure
โ โ โโโ dio_client.dart # Dio factory
โ โ โโโ interceptors/ # HTTP interceptors
โ โ โโโ network_exceptions.dart # Error handling
โ โ
โ โโโ mqtt/ # MQTT real-time sync
โ โโโ firebase/ # Firebase services
โ โโโ observers/ # BLoC observers
โ โโโ ...
โ
โโโ features/ # Feature modules (Presentation)
โ โโโ cashier/ # Kasir feature
โ โ โโโ bloc/ # BLoC state management
โ โ โโโ pages/ # UI pages
โ โ โโโ widgets/ # Feature widgets
โ โ โโโ models/ # UI models
โ โ
โ โโโ inventory/ # Inventory feature
โ โโโ dashboard/ # Dashboard feature
โ โโโ auth/ # Auth UI
โ โโโ home/ # Home feature
โ โโโ ...
โ
โโโ di/ # Dependency Injection
โ โโโ injection.dart # GetIt setup
โ โโโ injection.config.dart # Generated DI config
โ โโโ network_module.dart # Network DI module
โ
โโโ pkg/ # Shared utilities & components
โ โโโ component/ # Reusable widgets
โ โโโ theme/ # Theme configuration
โ โโโ utils/ # Helper functions
โ โโโ common/ # Constants
โ
โโโ database/ # Local database schemas
โ โโโ isar/ # Isar collections
โ
โโโ i18n/ # Internationalization
โ โโโ strings.g.dart # Generated translations
โ โโโ strings_id.g.dart # Indonesian
โ โโโ strings_en.g.dart # English
โ
โโโ middlewares/ # Router middlewares
โโโ auth_middleware.dart # Auth guard
๐ฏ Layer Responsibilities
1. Presentation Layer (features/)
Tanggung jawab:
- Menampilkan UI
- Menangani user interaction
- Mengelola UI state dengan BLoC/Cubit
- Tidak boleh mengakses data source langsung
Komponen:
- Pages: Full screen widgets
- Widgets: Reusable UI components
- BLoC/Cubit: State management
- Models: UI-specific models (jika berbeda dari domain)
Contoh:
// features/cashier/bloc/cashier_bloc.dart
class CashierBloc extends Bloc<CashierEvent, CashierState> {
final ProductRepository _productRepository;
CashierBloc(this._productRepository) : super(CashierInitial()) {
on<LoadProducts>(_onLoadProducts);
}
Future<void> _onLoadProducts(
LoadProducts event,
Emitter<CashierState> emit,
) async {
emit(CashierLoading());
final result = await _productRepository.getProducts();
result.fold(
(failure) => emit(CashierError(failure.message)),
(products) => emit(CashierLoaded(products)),
);
}
}
2. Domain Layer (core/*/)
Tanggung jawab:
- Business logic
- Domain models (entities)
- Repository interfaces
- Use cases (optional, untuk logic kompleks)
Prinsip:
- Pure Dart (no Flutter dependencies)
- Framework-agnostic
- Testable
Contoh:
// core/product/product_repository.dart
abstract class ProductRepository {
Future<Either<Failure, List<Product>>> getProducts();
Future<Either<Failure, Product>> getProductById(String id);
Future<Either<Failure, void>> createProduct(Product product);
}
3. Data Layer (core/*/)
Tanggung jawab:
- Implementasi repository
- API calls (Retrofit)
- Local database operations (Isar)
- Data mapping (DTO โ Entity)
- Caching strategy
Komponen:
- Repository Implementation: Concrete repository
- API: Retrofit interfaces
- Local Data Source: Isar collections
- DTOs: Data Transfer Objects
Contoh:
// core/product/product_repository_retrofit.dart
class ProductRepositoryRetrofit implements ProductRepository {
final Dio dio;
final String baseUrl;
@override
Future<Either<Failure, List<Product>>> getProducts() async {
try {
final api = ProductApi(dio, baseUrl: baseUrl);
final response = await api.getProducts();
return Right(response.data);
} on DioException catch (e) {
return Left(NetworkException.fromDioError(e));
}
}
}
4. Infrastructure Layer
Tanggung jawab:
- HTTP client (Dio)
- Database (Isar)
- Firebase services
- MQTT client
- External services
๐ Data Flow
Request Flow (User Action โ API)
User Interaction
โ
Widget
โ
BLoC Event Dispatch
โ
BLoC Event Handler
โ
Repository Method Call
โ
API Call (Retrofit)
โ
Dio Interceptors Pipeline:
- CorrelationInterceptor (X-Correlation-ID)
- HeadersInterceptor (Common headers)
- AuthInterceptor (Authorization token)
- RefreshTokenInterceptor (Auto refresh)
- RetryInterceptor (Retry on failure)
- LoggingInterceptor (Logging)
โ
HTTP Request โ Backend
โ
HTTP Response
โ
Repository returns Either<Failure, Data>
โ
BLoC emits new State
โ
Widget rebuilds with new State
Offline-First Flow
User Action
โ
BLoC Event
โ
Repository checks local cache (Isar)
โ
If cached: Return immediately
โ
Background: Sync with API
โ
Update local cache
โ
Emit updated state
๐งฉ Design Patterns
1. Repository Pattern
Abstraksi akses data, memisahkan business logic dari data source.
abstract class ProductRepository {
Future<Either<Failure, List<Product>>> getProducts();
}
class ProductRepositoryRetrofit implements ProductRepository {
// Implementation with Retrofit
}
class ProductRepositoryMock implements ProductRepository {
// Mock implementation for testing
}
2. BLoC Pattern
State management dengan event-driven architecture.
// Event
abstract class ProductEvent {}
class LoadProducts extends ProductEvent {}
// State
abstract class ProductState {}
class ProductLoading extends ProductState {}
class ProductLoaded extends ProductState {
final List<Product> products;
ProductLoaded(this.products);
}
// BLoC
class ProductBloc extends Bloc<ProductEvent, ProductState> {
// Handle events and emit states
}
3. Dependency Injection
Menggunakan GetIt + Injectable untuk DI.
@module
abstract class NetworkModule {
@LazySingleton()
Dio dio(@Named('baseUrl') String baseUrl) => createDio(baseUrl: baseUrl);
@LazySingleton(as: ProductRepository)
ProductRepositoryRetrofit productRepository(Dio dio) {
return ProductRepositoryRetrofit(dio: dio);
}
}
4. Either Pattern (Functional Error Handling)
Menggunakan Dartz untuk error handling yang eksplisit.
Future<Either<Failure, Product>> getProduct(String id) async {
try {
final product = await api.getProduct(id);
return Right(product);
} catch (e) {
return Left(ServerFailure('Failed to fetch product'));
}
}
// Usage
final result = await repository.getProduct('123');
result.fold(
(failure) => print('Error: ${failure.message}'),
(product) => print('Success: ${product.name}'),
);
๐ Security Architecture
1. Authentication Flow
Login Request
โ
AuthRepository.login()
โ
API returns: accessToken, refreshToken
โ
Store in secure storage (Isar)
โ
AuthInterceptor adds token to all requests
โ
On 401 response:
RefreshTokenInterceptor triggers
โ
Silent refresh with refreshToken
โ
Update tokens
โ
Retry original request
2. Token Management
- Access Token: Short-lived (15 minutes)
- Refresh Token: Long-lived (30 days)
- Auto-refresh: Handled by
RefreshTokenInterceptor
- Storage: Encrypted in Isar database
๐ก Real-Time Architecture
MQTT Integration
App Start
โ
MqttService.InitMQTT()
โ
Connect to MQTT broker
โ
Subscribe to topics:
- branch/{branchId}/inventory
- branch/{branchId}/transactions
- user/{userId}/notifications
โ
On message received:
Parse payload
โ
Update local database (Isar)
โ
Emit BLoC event
โ
UI updates automatically
๐๏ธ Database Architecture
Isar (Local NoSQL Database)
@collection
class ProductLocal {
Id id = Isar.autoIncrement;
@Index()
late String productId;
late String name;
late double price;
late int stock;
@Index()
late DateTime updatedAt;
}
Strategi:
- Write-through cache
- Background sync
- Conflict resolution (last-write-wins)
๐จ UI Architecture
if (Platform.isIOS) {
return CupertinoApp.router(
theme: iosTheme,
routerConfig: GlobalRouter,
);
} else {
return MaterialApp.router(
theme: androidTheme,
routerConfig: GlobalRouter,
);
}
Theme System
- AppTheme: Centralized theme configuration
- Theme Tailor: Type-safe theme extensions
- Dark Mode: Full support
๐ Observability
Logging
// AppLog - Structured logging
AppLog.i('category', 'message', meta: {'key': 'value'});
AppLog.e('category', 'error', exception, stackTrace);
// BLoC Observer
class AppBlocObserver extends BlocObserver {
@override
void onEvent(Bloc bloc, Object? event) {
AppLog.i('bloc.${bloc.runtimeType}', 'event: $event');
}
}
Crash Reporting
- Firebase Crashlytics: Production crashes
- AppLog: Development logging
- Sentry (optional): Error tracking
๐งช Testing Architecture
test/
โโโ unit/ # Unit tests (business logic)
โโโ widget/ # Widget tests (UI)
โโโ integration/ # Integration tests
โโโ mocks/ # Mock implementations
Next Steps
Arsitektur ini dirancang untuk:
- โ
Scalability
- โ
Maintainability
- โ
Testability
- โ
Separation of Concerns
- โ
Code Reusability