mirror of
https://github.com/we-promise/sure.git
synced 2026-04-07 14:31:25 +00:00
* feat: mobile support. Basic functionality development includes adding and deleting transactions,viewing balances, * Fix mobile support issues in PR #426 This commit addresses the critical issues identified in the mobile-support PR: 1. **GitHub Actions Workflow Path Issues (Critical)** - Add mobile/ prefix to all path filters in flutter-build.yml - Add working-directory to all Flutter commands - Fix Android keystore and iOS CocoaPods paths - Fix artifact upload paths 2. **Error Handling Improvements** - Add try-catch blocks to all HTTP requests in services - Wrap all JSON parsing operations in error handling - Add proper error messages for network failures 3. **HTTP Request Timeout Configuration** - Add 30-second timeout to all HTTP requests - Prevents hanging on network failures 4. **Defensive Null Checks in Providers** - Add containsKey() checks before accessing result maps - Add proper type casting with null safety - Add fallback error messages These changes ensure the workflow triggers correctly on mobile/ directory changes and improves overall code robustness. * Fix transactions exposure and error handling issues - Add UnmodifiableListView to transactions getter to prevent external mutation - Call notifyListeners() immediately after setting _isLoading = false - Move jsonDecode to run only after successful statusCode verification - Replace string concatenation with Uri.replace() for proper URL encoding - Add try/catch for jsonDecode on non-2xx responses to handle non-JSON errors * Fix exception handling and duplicate parsing in auth_service.dart - Replace broad catch-all exception handlers with targeted exception handling - Add specific catches for SocketException, TimeoutException, HttpException, FormatException, and TypeError - Return safe, user-friendly error messages instead of exposing internal details - Log full exception details and stack traces using debugPrint for debugging - Fix duplicate User.fromJson calls in login and signup methods by parsing once and reusing the instance - Improve code efficiency and security by preventing information leakage * Fix 2FA login crash and improve UX Fixed the crash that occurred when logging in with 2FA-enabled accounts and improved the user experience by not showing error messages when MFA is required (it's a normal flow, not an error). Changes: - Added mounted check before setState() in login screen - Modified AuthProvider to not set error message when MFA is required - Ensures smooth transition from password entry to OTP entry - Prevents "setState() called after dispose()" error The flow now works correctly: 1. User enters email/password → clicks Sign In 2. Backend responds with mfa_required 3. OTP input field appears with friendly blue prompt (no red error) 4. User enters 6-digit code → clicks Sign In again 5. Login succeeds * Add debug logs to trace 2FA login flow Added comprehensive debug logging to understand why OTP field is not showing when MFA is required: - Log backend response status and body - Log login result in AuthProvider - Log MFA required state - Log when OTP field should be shown This will help identify if the issue is: 1. Backend not returning mfa_required flag 2. Response parsing issue 3. State management issue 4. UI rendering issue * Fix 2FA login flow by moving MFA state to AuthProvider PROBLEM: The LoginScreen was being recreated when AuthProvider called notifyListeners(), causing all internal state (_showOtpField) to be lost. This resulted in the OTP input field never appearing, making 2FA login impossible. ROOT CAUSE: The AppWrapper uses a Consumer<AuthProvider> that rebuilds the entire widget tree when auth state changes. When login() sets isLoading=false and calls notifyListeners(), a brand new LoginScreen instance is created, resetting all internal state. SOLUTION: - Moved _showMfaInput state from LoginScreen to AuthProvider - AuthProvider now manages when to show the MFA input field - LoginScreen uses Consumer to read this state reactively - State survives widget rebuilds FLOW: 1. User enters email/password → clicks Sign In 2. Backend responds with mfa_required: true 3. AuthProvider sets _showMfaInput = true 4. Consumer rebuilds, showing OTP field (state preserved) 5. User enters code → clicks Sign In 6. Backend validates → returns tokens → login succeeds Backend is confirmed working via tests (auth_controller_test.rb). * Fix mobile 2FA login requiring double password entry Problem: When 2FA is required during mobile login, the LoginScreen was being destroyed and recreated, causing text controllers to reset and forcing users to re-enter their credentials. Root cause: AppWrapper was checking authProvider.isLoading and showing a full-screen loading indicator during login attempts. This caused LoginScreen to be unmounted when isLoading=true, destroying the State and text controllers. When the backend returned mfa_required, isLoading=false triggered recreation of LoginScreen with empty fields. Solution: - Add isInitializing state to AuthProvider to distinguish initial auth check from active login attempts - Update AppWrapper to only show loading spinner during isInitializing, not during login flow - LoginScreen now persists across login attempts, preserving entered credentials Flow after fix: 1. User enters email/password 2. LoginScreen stays mounted (shows loading in button only) 3. Backend returns mfa_required 4. MFA field appears, email/password fields retain values 5. User enters OTP and submits (email/password automatically included) Files changed: - mobile/lib/providers/auth_provider.dart: Add isInitializing state - mobile/lib/main.dart: Use isInitializing instead of isLoading in AppWrapper * Add OTP error feedback for mobile 2FA login When users enter an incorrect OTP code during 2FA login, the app now: - Displays an error message indicating the code was invalid - Keeps the MFA input field visible for retry - Automatically clears the OTP field for easy re-entry Changes: - mobile/lib/providers/auth_provider.dart: * Distinguish between first MFA request vs invalid OTP error * Show error message when OTP code was submitted but invalid * Keep MFA input visible when in MFA flow with errors - mobile/lib/screens/login_screen.dart: * Clear OTP field after failed login attempt * Improve UX by allowing easy retry without re-entering credentials User flow after fix: 1. User enters email/password 2. MFA required - OTP field appears 3. User enters wrong OTP 4. Error message shows "Two-factor authentication required" 5. OTP field clears, ready for new code 6. User can immediately retry without re-entering email/password * Improve OTP error message clarity When user enters an invalid OTP code, show clearer error message "Invalid authentication code. Please try again." instead of the confusing "Two-factor authentication required" from backend. This makes it clear that the OTP was wrong, not that they need to start the 2FA process. * chore: delete generation ai create test flow md. * Update mobile/lib/screens/login_screen.dart Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * feat: add pubspec.lock file. * Linter * Update mobile/android/app/build.gradle Co-authored-by: Pedro Piñera Buendía <663605+pepicrft@users.noreply.github.com> Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Update mobile/android/app/build.gradle com.sure.mobile -> am.sure.mobile Co-authored-by: Pedro Piñera Buendía <663605+pepicrft@users.noreply.github.com> Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Update mobile/ios/Runner.xcodeproj/project.pbxproj Co-authored-by: Pedro Piñera Buendía <663605+pepicrft@users.noreply.github.com> Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Update mobile/ios/Runner.xcodeproj/project.pbxproj Co-authored-by: Pedro Piñera Buendía <663605+pepicrft@users.noreply.github.com> Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Update mobile/ios/Runner.xcodeproj/project.pbxproj Co-authored-by: Pedro Piñera Buendía <663605+pepicrft@users.noreply.github.com> Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Fix iOS deployment target and update documentation - Update iOS minimum deployment target from 12.0 to 13.0 in Podfile for Flutter compatibility - Translate SIGNING_SETUP.md from Chinese to English for better accessibility - Remove TECHNICAL_GUIDE.md as requested * Restore TECHNICAL_GUIDE.md with partial content removal - Restore mobile/docs/TECHNICAL_GUIDE.md (previously deleted) - Remove only License, Contributing, and Related Links sections (from line 445 onwards) - Keep all technical documentation content (lines 1-444) * Fix setState after dispose errors across mobile app This commit fixes 5 critical setState/dispose errors identified by Cursor: 1. backend_config_screen.dart: Add mounted checks in _testConnection() and _saveAndContinue() methods to prevent setState calls after async operations (http.get, SharedPreferences) when widget is disposed. 2. transaction_form_screen.dart: Add mounted check in _selectDate() after showDatePicker to prevent setState when modal is dismissed while date picker is open. 3. main.dart: Add mounted check in _checkBackendConfig() after ApiConfig.initialize() to handle disposal during async initialization. 4. transactions_list_screen.dart: Add mounted check in the .then() callback of _showAddTransactionForm() to prevent calling _loadTransactions() on a disposed widget when modal is closed. 5. transactions_provider.dart: Fix premature notifyListeners() by removing intermediate notification after _isLoading = false, ensuring listeners only get notified once with complete state updates to prevent momentary stale UI state. All setState calls after async operations now properly check mounted status to prevent "setState() called after dispose()" errors. * Fix Android build: Remove package attribute from AndroidManifest.xml Remove deprecated package attribute from AndroidManifest.xml. The namespace is now correctly defined only in build.gradle as required by newer versions of Android Gradle Plugin. This fixes the build error: "Incorrect package="com.sure.mobile" found in source AndroidManifest.xml. Setting the namespace via the package attribute in the source AndroidManifest.xml is no longer supported." * Update issue templates * Change package name from com.sure.mobile to am.sure.mobile Updated Android package name across all files: - build.gradle: namespace and applicationId - MainActivity.kt: package declaration and file path - Moved MainActivity.kt from com/sure/mobile to am/sure/mobile This aligns with the package name change made in the mobile-support branch and fixes app crashes caused by package name mismatch. * Fix mobile app code quality issues - Add mounted check in backend_config_screen.dart to prevent setState after dispose - Translate Chinese comments to English in transactions_list_screen.dart for better maintainability - Replace brittle string-split date conversion with DateFormat in transaction_form_screen.dart for safer date handling These changes address code review feedback and improve code robustness. * Remove feature request template Delete unused feature request issue template file. * Fix mobile app code quality issues - Fix URL construction in backend_config_screen.dart to prevent double slashes by normalizing base URL (removing trailing slashes) before appending paths - Update pubspec.yaml to require Flutter 3.27.0+ for withValues API compatibility - Improve amount parsing robustness in transactions_list_screen.dart with proper locale handling, sign detection, and fallback error handling - Fix dismissible delete handler to prevent UI/backend inconsistency by moving deletion to confirmDismiss and only allowing dismissal on success * Fix mobile app performance and security issues - Eliminate duplicate _getAmountDisplayInfo calls in transactions list by computing display info once per transaction item - Upgrade flutter_secure_storage from 9.0.0 to 10.0.0 for AES-GCM encryption - Update dev dependencies: flutter_lints to 6.0.0 and flutter_launcher_icons to 0.14.4 * Update Android SDK requirements for flutter_secure_storage v10 - Increase compileSdk from 35 to 36 - Increase minSdkVersion from 21 to 24 This is required by flutter_secure_storage v10+ which uses newer Android APIs for AES-GCM encryption. * Fix transaction deletion message not displaying properly The success message was being shown in the onDismissed callback, which executes after the dismissal animation completes. By that time, the context may have become invalid due to widget tree rebuilds, causing the SnackBar to not display. Moved the success message to the confirmDismiss callback where we already have a captured scaffoldMessenger reference, ensuring the message displays reliably before the dismissal animation begins. * Add mounted check before showing SnackBar after async operation * Update mobile/android/app/build.gradle Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Fix empty state refresh and auth error feedback in mobile transactions screen - Wrap empty state in RefreshIndicator with CustomScrollView to enable pull-to-refresh when no transactions exist - Wrap error state in RefreshIndicator as well for consistency - Add SnackBar feedback when auth token is null in _loadTransactions instead of silent failure - Ensure mounted check before showing SnackBar to prevent errors after widget disposal * Fix flash of 'No accounts yet' page on app startup Added initialization state tracking to AccountsProvider to prevent the empty state from briefly showing while accounts are being loaded for the first time. Changes: - Add _isInitializing flag to AccountsProvider (starts as true) - Set to false after first fetchAccounts() completes - Reset to true when clearAccounts() is called - Update DashboardScreen to show loading during initialization This ensures a smooth user experience without visual flashing on app launch. * Refactor: Extract transaction deletion logic into dedicated method Improved code readability by extracting the 67-line confirmDismiss callback into a separate _confirmAndDeleteTransaction method. Changes: - Add Transaction model import - Create _confirmAndDeleteTransaction method that handles: - Confirmation dialog - Token retrieval - Deletion API call - Success/failure feedback - Simplify confirmDismiss to single line calling new method This separation of concerns makes the code more maintainable and the Dismissible widget configuration more concise. * Add offline-first architecture for mobile app Implement comprehensive offline functionality for the Sure mobile app: - SQLite local storage for transactions and accounts - Network connectivity detection and monitoring - Offline transaction creation with pending sync status - Automatic synchronization when network is restored - Visual indicators for offline status and pending syncs New Services: - ConnectivityService: Real-time network status monitoring - DatabaseHelper: SQLite database management with schema - OfflineStorageService: High-level API for local data operations - SyncService: Bidirectional sync between local DB and server New Models: - OfflineTransaction: Extended transaction model with sync status - SyncStatus enum: Track transaction sync state (synced/pending/failed) New UI Components: - ConnectivityBanner: Shows offline status and sync actions - SyncStatusBadge: Displays sync status on transactions Updated Components: - TransactionsProvider: Offline-first data fetching and caching - Main app: Wire up connectivity and sync services - Dashboard: Display connectivity banner Dependencies Added: - sqflite: SQLite database - connectivity_plus: Network status detection - uuid: Generate local transaction IDs - path: Database path utilities The app now works seamlessly offline, saving all transactions locally and automatically syncing when connectivity is restored. * Fix lint errors and warnings in offline features - Fix connectivity_service to handle ConnectivityResult (not List) - Remove unused imports in database_helper - Replace deprecated withOpacity with withValues in sync_status_badge - Use super parameters in OfflineTransaction constructor * Add offline support for AccountsProvider - Implement offline-first architecture for accounts - Load cached accounts from SQLite first for instant display - Sync with server when online and save to cache - Wire up ConnectivityService to AccountsProvider - Show cached data even when offline This fixes the issue where accounts couldn't be loaded offline. * Add debug logging to track offline transaction sync issues - Add detailed logging in TransactionsProvider.fetchTransactions - Add logging in SyncService.syncFromServer - Track transaction counts at each step - Log server responses and database operations This will help identify why transaction lists are empty. * Fix critical offline sync issues and add auto-sync Major fixes: 1. Fix accountId missing issue when syncing from server - Server may not return account_id in transaction JSON - Now use provided accountId parameter as fallback - Ensures transactions are saved with correct account_id 2. Add automatic sync when connectivity restored - Store last access token for auto-sync - Automatically upload pending transactions when back online - Prevent duplicate auto-sync attempts 3. Enhanced debug logging - Track accountId from server vs provided parameter - Log transaction upsert operations - Better error tracking This fixes: - Empty transaction lists when viewing account details - Offline transactions not auto-syncing when online - Data not being properly saved to local database * Add comprehensive debug logging for transaction storage Added detailed logging to track: - Account ID values from server vs provided parameter - Effective account ID being used for storage - Database insert/update operations - Number of transactions retrieved from database - Sample account IDs from stored transactions This will help identify: 1. Whether server returns account_id in transaction JSON 2. If fallback accountId parameter is being used correctly 3. What values are actually stored in the database 4. Why queries might not be finding transactions * Add detailed database query logging Added SQL query logging to DatabaseHelper: - Log all INSERT operations with account_id values - Log SELECT queries with WHERE conditions - Log result counts from queries This will show: - Exact account_id values being stored in database - SQL WHERE clauses being used for queries - Whether queries are finding matching records Combined with OfflineStorageService logs, this gives complete visibility into the data flow from server to database to UI. * Add debug log viewer screen - Create LogService for centralized log management - Add LogViewerScreen with filtering and export capabilities - Add debug logs button to dashboard - Support log levels: ERROR, WARNING, INFO, DEBUG - Features: filter by level, auto-scroll, copy to clipboard, clear logs - Keep last 1000 log entries * Add visual indicators for offline transactions and sync success Implemented the following features: 1. Pending transactions are now displayed with 50% opacity (gray) 2. Sync status badges (orange sync icon) show next to pending transaction amounts 3. Green cloud icon appears in dashboard AppBar when sync completes successfully 4. Auto-hide sync success indicator after 3 seconds with fade animation 5. Transaction list now uses offlineTransactions to access sync status Changes: - transactions_list_screen.dart: Display pending status with opacity and badges - dashboard_screen.dart: Add sync success indicator with listener - transactions_provider.dart: Already had offline-first architecture from previous commit * Fix offline transaction creation and add comprehensive logging This commit fixes all three reported issues: 1. Log viewer now showing logs - Added test log when log viewer opens - Added LogService to all critical services - Comprehensive logging throughout the stack 2. Offline transaction creation now working - TransactionFormScreen now uses TransactionsProvider (offline-first) - Previously was calling HTTP API directly, bypassing offline storage - Transactions now save to SQLite immediately, then sync in background 3. Sync and cloud icon improvements - Dashboard already has sync success indicator from previous commit - Added connectivity logging to track online/offline state changes - Sync will trigger automatically when connectivity restored Changes: - transaction_form_screen.dart: Use TransactionsProvider instead of TransactionsService - offline_storage_service.dart: Add comprehensive logging with LogService - connectivity_service.dart: Add logging for connectivity state changes - log_viewer_screen.dart: Add test log on screen open - main.dart: Add app startup log All operations now properly logged and can be viewed in the debug log viewer. * Fix transaction disappearing after sync and add manual sync Critical fixes: 1. Fixed syncTransactionsFromServer deleting uploaded transactions - Changed clearTransactions() to clearSyncedTransactions() - Now only clears synced transactions, preserves pending/failed ones - Added comprehensive logging to track sync process 2. Converted dashboard refresh button to manual sync - Now triggers full sync: upload pending, download from server - Shows progress indicator during sync - Displays success/error messages Technical details: - database_helper.dart: Added clearSyncedTransactions() method - offline_storage_service.dart: Use clearSyncedTransactions() in syncTransactionsFromServer() - sync_service.dart: Added detailed logging to all sync operations - dashboard_screen.dart: Refresh button now calls performManualSync() Previous issue: When connectivity restored, pending transactions were uploaded successfully, but then syncTransactionsFromServer() would call clearTransactions() which deleted ALL transactions including the just-uploaded ones, causing them to disappear from the UI even though they were on the server. Now fixed by only clearing synced transactions, keeping pending ones safe. * Change sync to use upsert logic instead of clear+insert Critical fix: syncTransactionsFromServer now uses upsert for each transaction instead of clearing synced transactions first. This prevents the race condition where: 1. Pending transaction uploaded and marked as synced 2. syncTransactionsFromServer clears all synced transactions (including just uploaded) 3. Server response doesn't include the new transaction yet 4. Transaction disappears from local database Changes: - offline_storage_service.dart: syncTransactionsFromServer now calls upsertTransactionFromServer for each transaction - Added logic to preserve existing accountId if server response has empty accountId - Replaced debugPrint with LogService for better tracking - Added detailed logging to track upsert operations This ensures uploaded transactions are never deleted, only updated with server data when available. * Fix flutter analyze warnings - Remove unused import 'package:flutter/foundation.dart' from offline_storage_service.dart - Fix use_build_context_synchronously warnings in transactions_list_screen.dart by capturing providers before async gap (showDialog) * Fix offline transaction sync not uploading pending transactions Critical bug: performFullSync was calling syncPendingTransactions which immediately returned 'Sync already in progress' error because performFullSync had already set _isSyncing = true. This caused pending transactions to never be uploaded to the server. Solution: - Extract core upload logic into _syncPendingTransactionsInternal() method - This internal method doesn't check _isSyncing flag - performFullSync calls the internal method directly - Public syncPendingTransactions() still checks _isSyncing for standalone calls Now pending transactions will properly upload during full sync. * Initial plan * Fix lifecycle, logging, error handling, and accessibility issues - Fixed provider lifecycle in dashboard_screen.dart to prevent accessing disposed providers - Fixed connectivity listener tracking in transactions_provider.dart with proper cleanup - Fixed async callback race conditions by checking mounted state - Replaced all debugPrint with LogService for consistent production logging - Added comprehensive error handling for database initialization with FlutterError reporting - Added missing index on server_id column for improved query performance - Optimized LogService memory usage (reduced from 1000 to 500 max logs) - Added debounced notifications in LogService (only when log viewer is active) - Added semantic labels to sync status badge icons for accessibility - Added semantic label to debug logs button for screen readers - Fixed misleading success message in transaction form (conditional based on sync status) - Fixed fire-and-forget async error handling to properly surface errors to UI - Improved error messages in accounts_provider with specific error types Co-authored-by: dwvwdv <89256478+dwvwdv@users.noreply.github.com> * Fix semantic labels and connectivity check issues from code review - Added semantic label to non-compact sync status badge for consistency - Fixed connectivity check in transaction form to use actual ConnectivityService.isOnline instead of lastSyncTime Co-authored-by: dwvwdv <89256478+dwvwdv@users.noreply.github.com> * Fix mounted check to properly track provider disposal state - Added _isDisposed flag to track actual provider disposal - Updated mounted getter to use _isDisposed instead of connectivity service availability - Ensures disposed providers don't continue processing connectivity changes Co-authored-by: dwvwdv <89256478+dwvwdv@users.noreply.github.com> * Address code review nitpicks for better code quality - Improved exception type checking in accounts_provider using instanceof instead of string contains - Improved ternary operator formatting for better readability - Added clarifying comment for fire-and-forget async pattern in connectivity change handler Co-authored-by: dwvwdv <89256478+dwvwdv@users.noreply.github.com> * Fix exception handling, error messages, and database index - Removed HandshakeException instanceof check, use string-based check for SSL/certificate errors - Improved error message clarity: 'Transaction upload failed' instead of 'Background sync failed' - Optimized server_id index to exclude NULL values for better performance and reduced size Co-authored-by: dwvwdv <89256478+dwvwdv@users.noreply.github.com> * Remove partial index syntax for better SQLite compatibility - Changed server_id index to standard syntax without WHERE clause - SQLite handles NULL values efficiently without explicit exclusion - Ensures compatibility across all SQLite versions Co-authored-by: dwvwdv <89256478+dwvwdv@users.noreply.github.com> * Fix Android release build to work without keystore - Made signing config optional when key.properties is missing - Prevents null pointer exception during release build - APK will be unsigned if no keystore is configured (debug signing will be used) Co-authored-by: dwvwdv <89256478+dwvwdv@users.noreply.github.com> * Improve keystore validation in build.gradle Enhanced keystore validation by checking keyAlias, keyPassword, and storePassword in addition to storeFile existence. Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Enhance Flutter build workflow with keystore checks Added checks for keystore secrets and adjusted APK build process based on their presence. Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Revert "Improve keystore validation in build.gradle" * Update mobile/lib/services/connectivity_service.dart Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Update mobile/lib/services/sync_service.dart Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Fix mobile provider null handling and connectivity issues - Fix null handling in ChangeNotifierProxyProvider callbacks for AccountsProvider and TransactionsProvider - Change connectivity service fallback from online to offline to prevent unwanted network calls - Replace raw error messages with user-friendly messages in TransactionsProvider - Add VPN and Bluetooth to online connectivity check - Fix database close() method to properly reset static cache - Add loading state and error handling to connectivity banner sync button - Update dependencies to latest stable versions (sqflite 2.4.2, path 1.9.1, connectivity_plus 7.0.0, uuid 4.5.2) * Replace all debugPrint with LogService in mobile app - Replace debugPrint with LogService in transactions_list_screen.dart - Replace debugPrint with LogService in auth_provider.dart - Replace debugPrint with LogService in auth_service.dart (login, signup, refreshToken methods) - Add LogService imports to all affected files - Use appropriate log levels: debug for informational logs, error for exceptions - Keep debugPrint only in LogService internal implementation All debugPrint calls now properly use the centralized LogService for consistent logging. * Fix Flutter analyze errors and warnings - Remove unused flutter/foundation.dart import in auth_service.dart - Update connectivity_service.dart to handle List<ConnectivityResult> for connectivity_plus 7.0.0 - Change StreamSubscription type from ConnectivityResult to List<ConnectivityResult> - Update _updateConnectionStatus to handle list of results using .any() - Check if any connectivity result indicates online status (mobile, wifi, ethernet, vpn, bluetooth) - Fix BuildContext usage across async gaps in connectivity_banner.dart - Use immediate mounted check before context usage (if (!mounted) return) - Properly guard all ScaffoldMessenger calls after async operations All flutter analyze errors and info warnings resolved. * Update mobile/lib/providers/accounts_provider.dart Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Update mobile/lib/providers/transactions_provider.dart Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Update mobile/lib/screens/dashboard_screen.dart Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Update mobile/lib/screens/dashboard_screen.dart Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Add error logging and implement pending delete tracking for offline transactions This commit adds comprehensive error logging and implements a robust pending delete system for offline transactions, ensuring data integrity and proper synchronization. Changes: - Add LogService error logging in AccountsProvider and DashboardScreen - Add SyncStatus.pendingDelete enum for tracking offline deletions - Implement markTransactionForDeletion in OfflineStorageService - Update offline delete logic to mark transactions instead of immediate deletion - Add _syncPendingDeletesInternal to SyncService for processing pending deletes - Update performFullSync to process pending deletes before uploads - Update hasPendingTransactions and pendingCount to include pending deletes The pending delete system ensures that: - Offline deletions are tracked and synced when connectivity is restored - Transactions with server IDs are deleted from both local and server - Transactions without server IDs (never synced) are deleted locally only - Failed delete attempts are marked and retried on next sync * Fix Flutter analyzer issues for pending delete feature - Add SyncStatus.pendingDelete case to sync_status_badge.dart switch - Use const constructor for SnackBar in dashboard_screen.dart - Display "Deleting" badge with delete icon for pendingDelete status * Add undo functionality for pending transactions This commit adds the ability to undo pending operations (both creates and deletes) while offline, providing users with better control over their pending transactions. Features: - Gray out pending delete transactions (50% opacity) similar to pending creates - Add "Undo" button on all pending transactions (both pending and pendingDelete) - Implement undoPendingTransaction in OfflineStorageService: - Pending creates: delete the transaction from local storage - Pending deletes: restore transaction to synced status - Add undoPendingTransaction method to TransactionsProvider - Show appropriate confirmation dialogs for undo operations - Display success/error messages after undo attempts User experience: - Pending transactions are visually distinct (grayed out with status badge) - Users can easily revert offline actions before they sync - Clear feedback on undo success or failure --------- Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> Co-authored-by: dwvwdv <dwvwdv@protonmail.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: Pedro Piñera Buendía <663605+pepicrft@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>