Skip to content

feat: enhance app functionality with connectivity monitoring and analytics integration#59

Merged
cevheri merged 4 commits intomainfrom
feat/advanced-features
Mar 16, 2026
Merged

feat: enhance app functionality with connectivity monitoring and analytics integration#59
cevheri merged 4 commits intomainfrom
feat/advanced-features

Conversation

@cevheri
Copy link
Copy Markdown
Owner

@cevheri cevheri commented Mar 16, 2026

feat: enhance app functionality with connectivity monitoring and analytics integration

Added connectivity_plus and flutter_secure_storage dependencies to pubspec.yaml.
Implemented ConnectivityCubit for monitoring network status and displaying an offline banner.
Integrated analytics services for logging BLoC transitions and screen views.
Established crash reporting mechanisms to capture and log errors globally.
Introduced a developer console for debugging, featuring network and BLoC state inspection.
Added mock data for API responses and updated documentation for new features.

cevheri added 2 commits March 16, 2026 03:37
…ytics integration

- Added connectivity_plus and flutter_secure_storage dependencies to pubspec.yaml.
- Implemented ConnectivityCubit for monitoring network status and displaying an offline banner.
- Integrated analytics services for logging BLoC transitions and screen views.
- Established crash reporting mechanisms to capture and log errors globally.
- Introduced a developer console for debugging, featuring network and BLoC state inspection.
- Added mock data for API responses and updated documentation for new features.
@cevheri cevheri requested a review from Copilot March 16, 2026 00:38
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds connectivity monitoring, token refresh, caching/resilience mechanisms, analytics + crash reporting hooks, and an in-app developer console, plus new lifecycle/dynamic-forms features and associated tests.

Changes:

  • Added connectivity-aware request handling (connectivity interceptor + offline banner) and introduced caching, token refresh, circuit breaker, and dev-console network logging.
  • Integrated analytics (route + BLoC observers) and global crash reporting, plus a debug-only developer console with network/BLoC/storage/environment/time-travel tabs.
  • Added lifecycle gating (maintenance/force update + feature flags) and dynamic forms rendering + routing, with expanded unit/widget test coverage.

Reviewed changes

Copilot reviewed 137 out of 142 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
test/shared/utils/icon_utils_test.dart Adds unit coverage for string→Icon mappings.
test/mocks/mock_classes.dart Adds dynamic forms BLoC mocks/fakes for tests.
test/infrastructure/http/interceptors/connectivity_interceptor_test.dart Adds tests for connectivity interceptor/exception behavior.
test/infrastructure/config/environment_test.dart Updates allowed paths test for token refresh endpoint.
test/infrastructure/cache/cache_storage_test.dart Adds cache storage model/interface tests.
test/features/users/application/user_bloc_test.dart Adds value-equality/props tests for User events.
test/features/lifecycle/domain/entities/app_config_entity_test.dart Adds tests for lifecycle app config entity.
test/features/dynamic_forms/presentation/pages/dynamic_form_page_test.dart Adds widget tests for dynamic form page UI states.
test/features/dynamic_forms/domain/entities/form_schema_entity_test.dart Adds tests for dynamic form schema entities/enums.
test/features/dashboard/presentation/pages/home_screen_test.dart Adjusts viewport to avoid overflow with new dashboard header.
test/features/dashboard/presentation/pages/dashboard_page_test.dart Reworks dashboard page tests to new SystemDashboardCubit state.
test/features/dashboard/domain/entities/dashboard_entity_test.dart Removes tests for deleted legacy dashboard domain entities.
test/features/dashboard/application/usecases/load_dashboard_usecase_test.dart Removes tests for deleted legacy dashboard use case.
test/features/auth/data/models/jwt_token_test.dart Updates JWTToken equality/hash/toString expectations for refresh token support.
test/features/auth/data/mappers/auth_mapper_test.dart Configures logger in tests for new mapping behavior.
test/core/security/security_utils_test.dart Activates token-expiry checks + adds getTokenExpiration tests.
test/core/result/result_test.dart Adds tests for new Result implementation patterns.
test/core/feature_flags/feature_flag_service_test.dart Adds unit tests for feature flag singleton/service.
test/core/errors/app_error_test.dart Adds unit tests for AppError sealed hierarchy + equality/pattern matching.
test/core/analytics/log_analytics_service_test.dart Adds tests for LogAnalyticsService no-throw behavior.
test/architecture/import_guard_test.dart Updates cross-feature import exceptions for lifecycle usage in dashboard.
test/app/session/session_cubit_test.dart Adds tests for session state transitions and restore logic.
test/app/router/app_router_factory_test.dart Adjusts viewport for router widget tests.
test/app/di/repository_contracts_test.dart Removes dashboard repository contract test (dashboard repo removed).
test/app/connectivity/connectivity_banner_test.dart Adds widget tests for offline banner behavior/animations.
pubspec.yaml Adds connectivity_plus + flutter_secure_storage; bumps app version.
macos/Flutter/GeneratedPluginRegistrant.swift Registers new plugins for macOS build.
linux/flutter/generated_plugins.cmake Registers flutter_secure_storage plugin for Linux build.
linux/flutter/generated_plugin_registrant.cc Registers flutter_secure_storage plugin for Linux build.
lib/infrastructure/storage/secure_storage.dart Introduces secure storage abstraction + FlutterSecureStorage adapter.
lib/infrastructure/storage/local_storage.dart Adds refreshToken storage key.
lib/infrastructure/http/interceptors/token_refresh_interceptor.dart Adds 401 token refresh flow with retry + logout callback.
lib/infrastructure/http/interceptors/dev_console_interceptor.dart Adds debug-only interceptor to record requests for dev console.
lib/infrastructure/http/interceptors/connectivity_interceptor.dart Adds interceptor rejecting requests immediately when offline.
lib/infrastructure/http/interceptors/cache_interceptor.dart Adds caching interceptor (policies + TTL + offline fallback).
lib/infrastructure/http/dev_console_store.dart Adds in-memory store for dev console network + BLoC entries.
lib/infrastructure/http/circuit_breaker.dart Adds standalone circuit breaker implementation.
lib/infrastructure/http/api_client.dart Expands Dio interceptor chain; adds session-expired callback.
lib/infrastructure/connectivity/connectivity_service.dart Adds singleton connectivity service with optional DNS verification.
lib/infrastructure/config/template_config.dart Updates prod API URL value (currently set to localhost).
lib/infrastructure/cache/shared_prefs_cache_storage.dart Adds SharedPreferences-backed cache storage implementation.
lib/infrastructure/cache/cache_storage.dart Adds cache policy, storage interface, and cache entry model.
lib/features/lifecycle/presentation/pages/maintenance_screen.dart Adds maintenance UI.
lib/features/lifecycle/presentation/pages/lifecycle_gate.dart Adds lifecycle gating wrapper for force-update/maintenance.
lib/features/lifecycle/presentation/pages/force_update_screen.dart Adds force-update UI + store redirect.
lib/features/lifecycle/lifecycle.dart Adds lifecycle feature barrel exports.
lib/features/lifecycle/domain/repositories/lifecycle_repository.dart Adds lifecycle repository contract.
lib/features/lifecycle/domain/entities/app_config_entity.dart Adds app config entity for lifecycle checks + flags.
lib/features/lifecycle/data/repositories/lifecycle_repository.dart Adds repository implementation fetching /app/config.
lib/features/lifecycle/data/models/app_config_model.dart Adds JSON model mapping for app config.
lib/features/lifecycle/application/lifecycle_state.dart Adds lifecycle state model.
lib/features/lifecycle/application/lifecycle_event.dart Adds lifecycle events.
lib/features/lifecycle/application/lifecycle_bloc.dart Adds lifecycle bloc implementing checks + flags update.
lib/features/dynamic_forms/presentation/widgets/dynamic_form_renderer.dart Adds JSON-driven form renderer using flutter_form_builder.
lib/features/dynamic_forms/presentation/pages/dynamic_form_page.dart Adds page that loads/renders/submits dynamic forms.
lib/features/dynamic_forms/navigation/dynamic_forms_routes.dart Adds GoRouter routes for dynamic forms.
lib/features/dynamic_forms/dynamic_forms.dart Adds dynamic forms feature barrel exports.
lib/features/dynamic_forms/domain/entities/form_schema_entity.dart Adds dynamic form schema entities + enums.
lib/features/dynamic_forms/data/models/form_schema_model.dart Adds JSON parsing for dynamic form schema.
lib/features/dynamic_forms/application/dynamic_form_state.dart Adds dynamic forms state.
lib/features/dynamic_forms/application/dynamic_form_event.dart Adds dynamic forms events.
lib/features/dynamic_forms/application/dynamic_form_bloc.dart Adds dynamic forms bloc (load + submit).
lib/features/dashboard/presentation/pages/dashboard_home_page.dart Reworks home wrapper to use SystemDashboardCubit + lifecycle bridging.
lib/features/dashboard/domain/repositories/dashboard_repository.dart Removes legacy dashboard repository abstraction.
lib/features/dashboard/domain/entities/dashboard_entity.dart Removes legacy dashboard domain entities.
lib/features/dashboard/data/repositories/dashboard_mock_repository.dart Removes legacy dashboard mock repository.
lib/features/dashboard/data/repositories/dashboard_api_repository.dart Removes legacy dashboard API repository.
lib/features/dashboard/data/models/dashboard_model.dart Removes legacy dashboard model mapping.
lib/features/dashboard/dashboard.dart Updates dashboard exports to new page/cubit structure.
lib/features/dashboard/application/usecases/load_dashboard_usecase.dart Removes legacy dashboard use case.
lib/features/dashboard/application/dashboard_state.dart Replaces legacy dashboard state with SystemDashboardState model.
lib/features/dashboard/application/dashboard_cubit.dart Replaces legacy cubit with SystemDashboardCubit metrics aggregator.
lib/features/auth/domain/entities/auth_entity.dart Extends AuthTokenEntity to include refresh token + expiry.
lib/features/auth/data/models/jwt_token.dart Extends JWTToken to include refresh_token field.
lib/features/auth/data/mappers/auth_mapper.dart Maps JWT model to token entity + extracts exp into DateTime.
lib/features/auth/application/login_bloc.dart Persists refresh token on login flows.
lib/core/security/security_utils.dart Implements token expiry checking and adds getTokenExpiration.
lib/core/security/allowed_paths.dart Adds refresh endpoint to allowed paths.
lib/core/feature_flags/feature_flag_service.dart Adds singleton feature flag service based on ChangeNotifier.
lib/core/errors/app_api_exception.dart Adds CircuitBreakerOpenException.
lib/core/analytics/log_analytics_service.dart Adds logger-backed analytics provider.
lib/core/analytics/analytics_service.dart Adds analytics interface.
lib/app/shell/app_shell.dart Adds offline banner + dev console shortcut wrapper in shell layout.
lib/app/router/app_router.dart Adds dynamic forms routes + supports navigator observers injection.
lib/app/di/app_scope.dart Registers ConnectivityCubit + SystemDashboardCubit and new infra singletons.
lib/app/di/app_dependencies.dart Removes dashboard repository creation wiring.
lib/app/dev_console/time_travel/time_travel_store.dart Adds time-travel snapshot storage + rewind/export.
lib/app/dev_console/time_travel/time_travel_bloc_observer.dart Adds combined observer feeding dev console + time travel.
lib/app/dev_console/tabs/storage_tab.dart Adds local storage inspector tab for dev console.
lib/app/dev_console/tabs/network_tab.dart Adds network inspector tab for dev console.
lib/app/dev_console/tabs/environment_tab.dart Adds environment + route tree tab for dev console.
lib/app/dev_console/tabs/bloc_tab.dart Adds BLoC transition inspector tab for dev console.
lib/app/dev_console/dev_console_overlay.dart Adds Ctrl+Shift+D overlay panel with tabs.
lib/app/dev_console/dev_console_bloc_observer.dart Adds observer for recording transitions to dev console store.
lib/app/dev_console/dev_console.dart Adds dev console barrel exports.
lib/app/connectivity/connectivity_cubit.dart Adds app-level connectivity cubit bridging ConnectivityService.
lib/app/connectivity/connectivity_banner.dart Adds offline banner UI.
lib/app/bootstrap/app_bootstrap.dart Initializes connectivity + analytics/crash reporting + debug observer.
lib/app/app.dart Injects analytics into router via NavigatorObserver.
lib/app/analytics/crash_reporter.dart Adds global error capture forwarding to analytics.
lib/app/analytics/analytics_route_observer.dart Adds screen-view tracking observer.
lib/app/analytics/analytics_bloc_observer.dart Adds BLoC transition/error analytics observer.
e2e/playwright.config.ts Adds Playwright configuration for E2E runs.
docs/REAL_API_INFO.md Adds local “real API” endpoint documentation.
assets/mock/dashboard.json Removes legacy dashboard mock payload.
assets/mock/POST_authenticate_verify_otp.json Adds refresh_token to mocked auth OTP response.
assets/mock/POST_authenticate.json Adds refresh_token to mocked auth response.
assets/mock/POST_api_token_refresh.json Adds mock refresh endpoint response payload.
assets/mock/GET_dynamic_forms_pathParams.json Adds mock dynamic form schema payload.
assets/mock/GET_app_config.json Adds mock lifecycle app config payload.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.


// API
static const String prodApiUrl = '__PROD_API_URL__';
static const String prodApiUrl = 'http://localhost:8080/api';
Comment on lines 76 to 85
dio.interceptors.addAll([
ConnectivityInterceptor(),
AuthInterceptor(),
TokenRefreshInterceptor(dio: dio, onSessionExpired: onSessionExpired),
ResilienceInterceptor(),
if (!ProfileConstants.isProduction) MockInterceptor(),
CacheInterceptor(),
DevConsoleInterceptor(),
LoggingInterceptor(),
]);
Comment on lines +23 to +25
/// 5. [MockInterceptor] — (dev/test only) short-circuits with mock data
/// 6. [DevConsoleInterceptor] — records requests in debug console
/// 7. [LoggingInterceptor] — structured request/response logging
Comment on lines +95 to +118
Future<void> onError(DioException err, ErrorInterceptorHandler handler) async {
// On network error for GET requests with networkFirst policy: try cache fallback
if (err.requestOptions.method.toUpperCase() == 'GET') {
final policy = _extractPolicy(err.requestOptions);
if (policy == CachePolicy.networkFirst || policy == CachePolicy.cacheFirst) {
final entry = await _storage.read(_cacheKey(err.requestOptions));
if (entry != null) {
_log.info('Serving stale cache for offline request: {}', [err.requestOptions.path]);
handler.resolve(
Response(
requestOptions: err.requestOptions,
statusCode: 200,
data: entry.data,
headers: Headers.fromMap({
'x-cache': ['stale'],
}),
),
);
return;
}
}
}
handler.next(err);
}
Comment on lines +159 to +165
InterceptorInfo(name: 'AuthInterceptor', order: 1, detail: 'Attaches JWT token to requests'),
InterceptorInfo(name: 'TokenRefreshInterceptor', order: 2, detail: 'Refreshes expired access tokens'),
InterceptorInfo(name: 'ConnectivityInterceptor', order: 3, detail: 'Rejects requests when offline'),
InterceptorInfo(name: 'ResilienceInterceptor', order: 4, detail: 'Retry + circuit breaker'),
InterceptorInfo(name: 'CacheInterceptor', order: 5, detail: 'GET response caching with TTL'),
InterceptorInfo(name: 'DevConsoleInterceptor', order: 6, detail: 'Logs requests to dev console'),
InterceptorInfo(name: 'MockInterceptor', order: 7, active: false, detail: 'Serves mock data in dev/test'),
Comment on lines +22 to +24
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
final status = ConnectivityService.instance.currentStatus;
Comment on lines +85 to +88
final exp = payloadMap["exp"];
if (exp == null) return null;

return DateTime.fromMillisecondsSinceEpoch((exp as int) * 1000);
Comment on lines +90 to +96
FeatureFlagService.instance.addListener(() => notifyCount++);

FeatureFlagService.instance.updateFlags({'a': true});
expect(notifyCount, 1);

// Clean up listener
FeatureFlagService.instance.removeListener(() => notifyCount++);
Comment on lines +41 to +43
if (key == StorageKeys.jwtToken.name && value.length > 20) {
return '${value.substring(0, 10)}...[masked]...${value.substring(value.length - 10)}';
}
cevheri added 2 commits March 16, 2026 03:45
- Added type checks for expiration payload in SecurityUtils to ensure valid numeric types.
- Updated token expiration handling to convert expiration to integer.
- Enhanced CacheInterceptor to only fallback to cache for connectivity errors on GET requests, improving error handling logic.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants