mirror of
https://github.com/we-promise/sure.git
synced 2026-04-07 14:31:25 +00:00
f52b3fceb6ca40e1b0d9d2ff51f9048c44e22e83
1801 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f52b3fceb6 |
feat: implement mobile AI chat feature and fix duplicate response issue (#610)
Backend fixes: - Fix duplicate AssistantResponseJob triggering causing duplicate AI responses - UserMessage model already handles job triggering via after_create_commit callback - Remove redundant job enqueue in chats_controller and messages_controller Mobile app features: - Implement complete AI chat interface and conversation management - Add Chat, Message, and ToolCall data models - Add ChatProvider for state management with polling mechanism - Add ChatService to handle all chat-related API requests - Add chat list screen (ChatListScreen) - Add conversation detail screen (ChatConversationScreen) - Refactor navigation structure with bottom navigation bar (MainNavigationScreen) - Add settings screen (SettingsScreen) - Optimize TransactionsProvider to support account filtering Technical details: - Implement message polling mechanism for real-time AI responses - Support chat creation, deletion, retry and other operations - Integrate Material Design 3 design language - Improve user experience and error handling Co-authored-by: dwvwdv <dwvwdv@protonmail.com> |
||
|
|
38f4c2222c |
Revert "Add print stylesheet for reports page (#499)" (#609)
This reverts commit
|
||
|
|
a5bccaf2a1 |
Generic LLMs improvements (#605)
* Generic LLMs improvements 1. app/models/provider/openai/auto_categorizer.rb:535-540 - If description is blank, now falls back to merchant name 2. app/models/provider/openai/auto_merchant_detector.rb:492-498 - Now includes merchant first, then description (joined with " - ") * FIX linter |
||
|
|
3dfa569bed |
Mobile offline features (#580)
* 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> |
||
|
|
b5ccea4961 |
Update version to 0.6.7-alpha.7
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> |
||
|
|
b99e2ecd5e |
Fixing version bump
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> |
||
|
|
5eb4ca29c3 |
CSV drag&drop styling fixes (#604)
* CSV drop improvements * FIX flex is fine |
||
|
|
c3395ef06d |
Fix struct compatibility error in IncomeStatement::Totals (#603)
The TotalsRow struct was expanded from 5 to 6 fields in commit
|
||
|
|
d4ab29ae1b |
Revise Helm chart CHANGELOG.md for versions 0.0.0 and 0.6.6
Update changelog to reflect version changes and new features. Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> |
||
|
|
a135866dbf |
Add Redis Sentinel support for Sidekiq high availability (#457)
* Initial plan * Add Redis Sentinel support for Sidekiq configuration Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> * Add documentation for Redis Sentinel configuration Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> * Improve Sentinel host parsing with better validation and error handling Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> * Add port validation to prevent invalid Sentinel configurations Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> * Linter * Add Sentinel authentication credentials to fix NOAUTH error - Add sentinel_username (defaults to "default") - Add sentinel_password (uses REDIS_PASSWORD) - Update documentation for sentinel auth configuration Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> * Add CHANGELOG.md for Helm chart documenting Redis Sentinel support Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> * Set REDIS_URL alongside in Sentinel mode also --------- Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> Co-authored-by: Juan José Mata <juanjo.mata@gmail.com> |
||
|
|
dddc2182a4 |
feat(zh-TW): add Traditional Chinese localization support (#503)
* feat(zh-TW): add Traditional Chinese localization support Integrates comprehensive zh-TW locale files across UI, models, emails, and helpers. Updates language mapping for Chinese (Traditional) and adds translations for various modules. Establishes full Traditional Chinese support in the app. * feat(locales): add zh-TW translations Add comprehensive Traditional Chinese (zh-TW) translations for UI, defaults, Doorkeeper, mailers, models, and views to provide full Taiwanese localization and improve wording consistency. Replace and update several existing zh-TW entries for clarity and consistency. Also expose the Postgres port in the example compose for easier local development and apply minor locale/typo/whitespace fixes. * feat(locales): add zh-TW translations Add Traditional Chinese (zh-TW) locale files across many views and settings to provide Taiwanese localization. Introduce updated translations for authentication, onboarding, settings, integrations (Plaid, SimpleFin, Lunch Flow), accounts, reports, and various resource pages. Remove or replace legacy locale files to align with the revamped i18n structure and copy organization. This enables full zh-TW support for the UI. * chore(docker): remove published Postgres port Remove the published Postgres port mapping (5432) from the example docker-compose file to avoid exposing the database to the host and to prevent accidental port conflicts. Keeps the example more secure and focused on internal service networking. * docs(i18n): 統一 SimpleFIN 在繁體中文翻譯的大小寫 將 zh-TW 翻譯中所有出現的 "SimpleFin" 更新為品牌正確的 "SimpleFIN", 包含標題、提示文字、成功/錯誤訊息及表單標籤,以維持品牌名稱一致性 並提升使用者介面的翻譯準確性。 |
||
|
|
3658e812a8 |
Add pending transaction handling and duplicate reconciliation logic (#602)
* Add pending transaction handling and duplicate reconciliation logic - Implemented logic to exclude pending transactions from budgets and analytics calculations. - Introduced mechanisms for reconciling pending transactions with posted versions. - Added duplicate detection with support for merging or dismissing matches. - Updated transaction search filters to include a `status_filter` for pending/confirmed transactions. - Introduced UI elements for reviewing and resolving duplicates. - Enhanced `ProviderSyncSummary` with stats for reconciled and stale pending transactions. * Refactor translation handling and enhance transaction and sync logic - Moved hardcoded strings to locale files for improved translation support. - Refined styling for duplicate transaction indicators and sync summaries. - Improved logic for excluding stale pending transactions and updating timestamps on batch exclusion. - Added unique IDs to status filters for better element targeting in UI. - Optimized database queries to avoid N+1 issues in stale pending calculations. * Add sync settings and enhance pending transaction handling - Introduced a new "Sync Settings" section in hosting settings with UI to toggle inclusion of pending transactions. - Updated handling of pending transactions with improved inference logic for `posted=0` and `transacted_at` in processors. - Added priority order for pending transaction inclusion: explicit argument > environment variable > runtime configurable setting. - Refactored settings and controllers to store updated sync preferences. * Refactor sync settings and pending transaction reconciliation - Extracted logic for pending transaction reconciliation, stale exclusion, and unmatched tracking into dedicated methods for better maintainability. - Updated sync settings to infer defaults from multiple provider environment variables (`SIMPLEFIN_INCLUDE_PENDING`, `PLAID_INCLUDE_PENDING`). - Refined UI and messaging to handle multi-provider configurations in sync settings. # Conflicts: # app/models/simplefin_item/importer.rb * Debounce transaction reconciliation during imports - Added per-run reconciliation debouncing to prevent repeated scans for the same account during chunked history imports. - Trimmed size of reconciliation stats to retain recent details only. - Introduced error tracking for reconciliation steps to improve UI visibility of issues. * Apply ABS() in pending transaction queries and improve error handling - Updated pending transaction logic to use ABS() for consistent handling of negative amounts. - Adjusted amount bounds calculations to ensure accuracy for both positive and negative values. - Refined exception handling in `merge_duplicate` to log failures and update user alert. - Replaced `Date.today` with `Date.current` in tests to ensure timezone consistency. - Minor optimization to avoid COUNT queries by loading limited records directly. * Improve error handling in duplicate suggestion and dismissal logic - Added exception handling for `store_duplicate_suggestion` to log failures and prevent crashes during fuzzy/low-confidence matches. - Enhanced `dismiss_duplicate` action to handle `ActiveRecord::RecordInvalid` and display appropriate user alerts. --------- Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com> |
||
|
|
f012e38824 |
Remove invalid logo.synthfinance.com URLs from merchants table (#553)
* Initial plan * Add migration to remove synthfinance.com logo URLs from merchants table Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> * Update migration to match specific logo.synthfinance.com domain Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> * Update schema version to include RemoveSynthfinanceLogoUrls migration Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> --------- Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> Co-authored-by: Juan José Mata <juanjo.mata@gmail.com> |
||
|
|
78aa064bb0 |
Add overpayment detection for SimpleFIN liabilities (default ON) with heuristic-based classification and robust fallbacks (#412)
* Add liability balance normalization logic with comprehensive tests - Updated `SimplefinAccount::Processor` to normalize liability balances based on observed values, ensuring correct handling of debts and overpayments. - Enhanced `SimplefinItem::Importer` to apply similar normalization rules during imports, improving consistency. - Added multiple test cases in `SimplefinAccountProcessorTest` to validate edge cases for liabilities and mixed-sign scenarios. - Introduced helper methods (`to_decimal`, `same_sign?`) to simplify numeric operations in normalization logic. * Add overpayment detection for liabilities with heuristic-based classification - Introduced `SimplefinAccount::Liabilities::OverpaymentAnalyzer` to classify liability balances as credit, debt, or unknown using transaction history. - Updated `SimplefinAccount::Processor` and `SimplefinItem::Importer` to integrate heuristic-based balance normalization with fallback logic for ambiguous cases. - Added comprehensive unit tests in `OverpaymentAnalyzerTest` to validate classification logic and edge cases. - Enhanced logging and observability around classification results and fallback scenarios. * Refactor liability handling for better fallback consistency - Updated `sticky_key` method in `OverpaymentAnalyzer` to handle missing `@sfa.id` with a default value. - Enhanced `SimplefinAccount::Processor` to use `with_indifferent_access` for `raw_payload` and `org_data`, improving robustness in liability type inference. * Extract numeric helper methods into `SimplefinNumericHelpers` concern and apply across models - Moved `to_decimal` and `same_sign?` methods into a new `SimplefinNumericHelpers` concern for reuse. - Updated `OverpaymentAnalyzer`, `Processor`, and `Importer` to include the concern and remove redundant method definitions. - Added empty fixtures for `simplefin_accounts` and `simplefin_items` to ensure test isolation. - Refactored `OverpaymentAnalyzerTest` to reduce fixture dependencies and ensure cleanup of created records. * Refactor overpayment detection logic for clarity and fallback consistency - Simplified `enabled?` method in `OverpaymentAnalyzer` for clearer precedence order (Setting > ENV > default). - Added `parse_bool` helper to streamline boolean parsing. - Enhanced error handling with detailed logging for transaction gathering failures. - Improved `sticky_key` method to use a temporary object ID fallback when `@sfa.id` is missing. --------- Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com> |
||
|
|
14c169e6b9 |
Include actual iOS IPA
Added debugging information to list downloaded artifacts and check for mobile and iOS build directories. Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> |
||
|
|
b957aea497 |
Update version to 0.6.7-alpha.6
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> |
||
|
|
b56dbdb9eb |
Feat: /import endpoint & drag-n-drop imports (#501)
* Implement API v1 Imports controller - Add Api::V1::ImportsController with index, show, and create actions - Add Jbuilder views for index and show - Add integration tests - Implement row generation logic in create action - Update routes * Validate import account belongs to family - Add validation to Import model to ensure account belongs to the same family - Add regression test case in Api::V1::ImportsControllerTest * updating docs to be more detailed * Rescue StandardError instead of bare rescue in ImportsController * Optimize Imports API and fix documentation - Implement rows_count counter cache for Imports - Preload rows in Api::V1::ImportsController#show - Update documentation to show correct OAuth scopes * Fix formatting in ImportsControllerTest * Permit all import parameters and fix unknown attribute error * Restore API routes for auth, chats, and messages * removing pr summary * Fix trailing whitespace and configured? test failure - Update Import#configured? to use rows_count for performance and consistency - Mock rows_count in TransactionImportTest - Fix trailing whitespace in migration * Harden security and fix mass assignment in ImportsController - Handle type and account_id explicitly in create action - Rename import_params to import_config_params for clarity - Validate type against Import::TYPES * Fix MintImport rows_count update and migration whitespace - Update MintImport#generate_rows_from_csv to update rows_count counter cache - Fix trailing whitespace and final newline in AddRowsCountToImports migration * Implement full-screen Drag and Drop CSV import on Transactions page - Add DragAndDropImport Stimulus controller listening on document - Add full-screen overlay with icon and text to Transactions index - Update ImportsController to handle direct file uploads via create action - Add system test for drag and drop functionality * Implement Drag and Drop CSV upload on Import Upload page - Add drag-and-drop-import controller to import/uploads/show - Add full-screen overlay to import/uploads/show - Annotate upload form and input with drag-and-drop targets - Add PR_SUMMARY.md * removing pr summary * Add file validation to ImportsController - Validate file size (max 10MB) and MIME type in create action - Prevent memory exhaustion and invalid file processing - Defined MAX_CSV_SIZE and ALLOWED_MIME_TYPES in Import model * Refactor dragLeave logic with counter pattern to prevent flickering * Extract shared drag-and-drop overlay partial - Create app/views/imports/_drag_drop_overlay.html.erb - Update transactions/index and import/uploads/show to use the partial - Reduce code duplication in views * Update Brakeman and harden ImportsController security - Update brakeman to 7.1.2 - Explicitly handle type assignment in ImportsController#create to avoid mass assignment - Remove :type from permitted import parameters * Fix trailing whitespace in DragAndDropImportTest * Don't commit LLM comments as file * FIX add api validation --------- Co-authored-by: Carlos Adames <cj@Carloss-MacBook-Air.local> Co-authored-by: Juan José Mata <jjmata@jjmata.com> Co-authored-by: sokie <sokysrm@gmail.com> |
||
|
|
61caaf056c |
Actually change the version!
Add logic to update version file and handle commits. Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> |
||
|
|
5750e69acf |
Provider investment fixes (#600)
* FIX issue with stock price retrieval on weekend * make weekend provisional and increase lookback * FIX query error * fix gap fill The bug: When a price is provisional but the provider doesn't return a new value (weekends), we fall back to the existing DB value instead of gap-filling from Friday's correct price. * Update importer.rb Align provider fetch to use PROVISIONAL_LOOKBACK_DAYS for consistency. In the DB fallback, derive currency from provider_prices or db_prices and filter the query accordingly. * Update 20260110122603_mark_suspicious_prices_provisional.rb * Delete db/migrate/20260110122603_mark_suspicious_prices_provisional.rb Signed-off-by: soky srm <sokysrm@gmail.com> * Update importer.rb * FIX tests * FIX last tests * Update importer_test.rb The test doesn't properly force effective_start_date to skip old dates because there are many missing dates between the old date and recent dates. Let me fix it to properly test the subset processing scenario. --------- Signed-off-by: soky srm <sokysrm@gmail.com> |
||
|
|
2f4e2eab8d |
Workflow chores: publish Flutter builds & bump alpha versions (#599)
* Add debug mobile artifacts to GitHub releases - Modify flutter-build.yml to trigger on version tags (v*) and support workflow_call for use by other workflows - Add mobile job to publish.yml that calls flutter-build workflow - Add release job that creates GitHub release with debug APK and unsigned iOS build when a version tag is pushed - Auto-detect debug vs release APK and name appropriately - Mark alpha/beta/rc versions as pre-releases * Add automatic alpha version bump after release When an alpha tag (e.g., v0.6.7-alpha.3) is published and the Docker image is built, automatically bump the alpha number in version.rb (e.g., alpha.3 -> alpha.4) and push to main branch. * Fix APK copying to include both debug and release builds Change if/elif to separate if statements so both app-debug.apk and app-release.apk are copied to release assets when both exist. * Rename artifact names in publish workflow Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> * Revert rename of artifact names Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> * Enhance version bump process in publish.yml Refactor version bump script to ensure version file exists and improve error handling. Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> --------- Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
a1f5da870d |
Update version to 0.6.7-alpha.5
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> |
||
|
|
a4f70f4d4a |
Support uncategorized investments (#593)
* Support uncategorized investments * FIX sankey id collision * Fix reports * Fix hardcoded string and i8n * FIX plurals * Remove spending patterns section add net worth section to reports |
||
|
|
76dc91377c |
Merchants improvements (#594)
* FIX logos * Implement merchant mods * FIX confirm issue * FIX linter * Add recently seen merchants to re-add if needed * Update merge.html.erb * FIX do security check * Add error handling for update failures. |
||
|
|
140ea78b0e |
Add global sync summary component for all providers (#588)
* Add shared sync statistics collection and provider sync summary UI - Introduced `SyncStats::Collector` concern to centralize sync statistics logic, including account, transaction, holdings, and health stats collection. - Added collapsible `ProviderSyncSummary` component for displaying sync summaries across providers. - Updated syncers (e.g., `LunchflowItem::Syncer`) to use the shared collector methods for consistent stats calculation. - Added rake tasks under `dev:sync_stats` for testing and development purposes, including fake stats generation with optional issues. - Enhanced provider-specific views to include sync summaries using the new shared component. * Refactor `ProviderSyncSummary` to improve maintainability - Extracted `severity_color_class` to simplify severity-to-CSS mapping. - Replaced `holdings_label` with `holdings_label_key` for streamlined localization. - Updated locale file to separate `found` and `processed` translations for clarity. --------- Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com> Co-authored-by: Juan José Mata <juanjo.mata@gmail.com> |
||
|
|
aaa336b091 |
Merge pull request #587 from samuelcseto/fix/provider-merchant-case-insensitive-lookup
Fix provider merchant lookup to handle case variations in names |
||
|
|
ca4fb7995c |
Implement holdings for lunch flow (#590)
* Implement holdings for lunch flow * Implement holdings function call |
||
|
|
6ebe8da928 |
Add investment tracking to expenses (#381)
* Add investment tracking to expenses Add new sections to dashboard and reporting around investments. * Create investment-integration-assessment.md * Delete .claude/settings.local.json Signed-off-by: soky srm <sokysrm@gmail.com> * Category trades * Simplify * Simplification and test fixes * FIX merge * Update views * Update 20251125141213_add_category_to_trades.rb * FIX tests * FIX statements and account status * cleanup * Add default cat for csv imports * Delete docs/roadmap/investment-integration-assessment.md Signed-off-by: soky srm <sokysrm@gmail.com> * Update trend calculation Use already existing column cost basis for trend calculation - Current value: qty * price (already stored as amount) - Cost basis total: qty * cost_basis - Unrealized gain: current value - cost basis total Fixes N+1 query also --------- Signed-off-by: soky srm <sokysrm@gmail.com> |
||
|
|
d185c6161c | FIX providers invalid currency handling (#589) | ||
|
|
83ff095edf |
Fix provider merchant lookup to handle case variations in names
Problem: Transactions were silently failing to import when the provider (e.g., Lunchflow) returned merchant names with inconsistent casing. Root cause discovered when: 1. User A connected their account, synced transactions with merchant "JOHN DOE" 2. User A disconnected their account (but ProviderMerchant records persist) 3. User B connected their account 4. User B had a transaction to the same person but provider returned it as "John Doe" (different casing) 5. Lookup by (source, name) failed to find existing "JOHN DOE" merchant 6. Tried to create new merchant with same provider_merchant_id (derived from MD5 of lowercased name) → unique constraint violation 7. Transaction import failed silently Impact: - Missing transactions caused incorrect account balances (showing negative when they shouldn't) - Balance chart displayed incorrect historical data - Users saw fewer transactions than actually existed in their bank Solution: Look up merchants by provider_merchant_id first (the stable, case-insensitive identifier derived from the normalized merchant name), then fall back to exact name match for backwards compatibility. |
||
|
|
701742e218 | Revert "FIX migration files ordering" (#583) | ||
|
|
cb74856f61 |
Fix linked account balance currency mismatch (#566)
* Fix linked account balance currency mismatch When linking accounts from providers (Lunchflow, SimpleFIN, Enable Banking), the initial sync was creating balances before the correct currency was known. This caused: 1. Opening anchor entry created with default currency (USD/EUR) 2. First sync created balances with wrong currency 3. Later syncs created balances with correct currency 4. Both currency balances existed, charts showed wrong (zero) values Changes: - Add `skip_initial_sync` parameter to `Account.create_and_sync` - Skip initial sync for linked accounts (provider sync handles it) - Add currency filter to ChartSeriesBuilder query to only fetch balances matching the account's current currency * Add migration script and add tests * Update schema.rb --------- Signed-off-by: soky srm <sokysrm@gmail.com> Co-authored-by: sokie <sokysrm@gmail.com> |
||
|
|
93a535f0ac |
Add stale SimpleFin account detection and improve unlink cleanup (#574)
* Add stale account detection and handling in SimpleFin setup - Introduced UI for managing stale accounts during SimpleFin setup. - Added logic to detect accounts no longer provided by SimpleFin. - Implemented actions to delete, move transactions, or skip stale accounts. - Updated `simplefin_items_controller` with stale account processing and handling. - Enhanced tests to validate stale account scenarios, including detection, deletion, moving transactions, and skipping. * Update SimpleFin to SimpleFIN in locale file Signed-off-by: Juan José Mata <jjmata@jjmata.com> * Silly changes break things ... Signed-off-by: Juan José Mata <jjmata@jjmata.com> * Refactor stale account processing and UI handling - Moved `target_account.sync_later` to execute after commit for proper recalculation of balances. - Added additional safeguard in JavaScript to check for `moveRadioTarget` before updating target visibility. * More silly capitalization changes * Enhance stale account action handling in SimpleFIN setup - Introduced `permitted_stale_account_actions` to validate and permit nested `stale_account_actions` parameters. - Updated `complete_account_setup` to use the new method for safer processing. - Corrected capitalization in SimpleFIN update success and error messages. * Add error tracking and UI feedback for stale account actions - Updated `process_stale_account_actions` to track errors for delete and move actions. - Enhanced UI to display success and error messages for stale account processing. - Implemented destruction of conflicting transfers during account move to maintain data integrity. * Refactor transfer destruction and improve SimpleFIN account setup messages - Updated `simplefin_items_controller` to use `find_each(&:destroy!)` for transfer deletions, ensuring callbacks are invoked. - Enhanced localization for success messages in account creation to handle singular and plural cases. --------- Signed-off-by: Juan José Mata <jjmata@jjmata.com> Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com> Co-authored-by: Juan José Mata <jjmata@jjmata.com> |
||
|
|
e37c03d1d4 | Implement Run all rules (#582) | ||
|
|
c315e08a6e |
Update version to 0.6.7-alpha.3
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> |
||
|
|
74da949f40 | Upgrade lucide-rails from 0.2.0 to 0.7.3 (#570) | ||
|
|
e121969f2c |
Fix false positive inactive hints for SimpleFin accounts during chunked imports (#573)
* Add tests and logic for zero balance handling and inactivity detection - Updated `SimplefinItem::ImporterInactiveTest` to include cases for chunked imports, credit cards, and loans. - Added logic to skip zero balance detection for liability accounts (e.g., credit cards, loans). - Ensured zero balance runs are counted only once per sync to avoid false positives during chunked imports. * Add nil safety --------- Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com> |
||
|
|
7866598057 |
Mobile native client via Flutter (#426)
* 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. * Enhance Flutter build workflow with keystore checks Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> * Implement conditional signing configuration Added a check for keystore properties before configuring signing. Signed-off-by: Lazy Bone <89256478+dwvwdv@users.noreply.github.com> --------- 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> |
||
|
|
362ffd72bc |
Merge pull request #577 from sokie/fix-clean-slate
FIX migration files ordering |
||
|
|
1e940931df | FIX migration files ordering | ||
|
|
ae3eb0abf1 |
Added troubleshooting information for CSV import. (#558)
* Document CSV import processing delay issue Added troubleshooting information for CSV import delays. Signed-off-by: zenaufa <zenaufa@hotmail.com> * Small edits suggested by LLM --------- Signed-off-by: zenaufa <zenaufa@hotmail.com> Co-authored-by: Juan José Mata <jjmata@jjmata.com> |
||
|
|
828c53f62d |
Fix variable injection vulnerability in helm-release workflow (#541)
* Fix variable injection vulnerability in helm-release workflow - Use explicit env block to pass GitHub context variables safely - Remove duplicate hardcoded git config that overwrote earlier settings - Prevents potential shell injection via expansion Signed-off-by: luojiyin <luojiyin@hotmail.com> * Fix git config for gh-pages repository checkout Apply git user config inside gh-pages directory before commit, as the earlier config only applies to the main repository checkout. Signed-off-by: luojiyin <luojiyin@hotmail.com> --------- Signed-off-by: luojiyin <luojiyin@hotmail.com> |
||
|
|
b6d67b5348 |
Fix disabled rules executing during automatic sync (#552)
* Initial plan * Fix: Only apply active rules during sync Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> * FIX test --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> Co-authored-by: sokie <sokysrm@gmail.com> |
||
|
|
02e203e8ee |
Add security measures for SSO-only users: block password resets, enforce SSO authentication, and refactor validations for JIT provisioning. (#569)
Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com> |
||
|
|
66671d9e1f |
Merge pull request #511 from we-promise/codex/conditionally-load-plaid-javascript-library
Scope Plaid Link script to Plaid flows |
||
|
|
ccd84742e9 |
Merge pull request #549 from hendriksen-mark/export_style
Update button styles in family export form |
||
|
|
4dfd2913c7 |
Investment prices fixes (#559)
* Fix investments retrieval
Problem Summary
Stock prices for securities like European stocks become stale because:
1. sync_all_accounts runs at 2:22 UTC (before European markets open)
2. Provider doesn't have today's price yet, so importer gap-fills with LOCF (yesterday's price)
3. Later import_market_data at 22:00 UTC sees all prices exist and skips fetching
4. Real closing price is never retrieved
Solution Overview
Add a provisional boolean column to mark gap-filled prices that should be re-fetched.
* Update schema.rb
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
|
||
|
|
3f97f316e0 |
Fix missing SimpleFIN investment account transactions (#562)
* Add tests and update logic for processing SimpleFIN investment transactions - Added `SimplefinAccount::Transactions::ProcessorInvestmentTest` to validate dividend transaction processing, transaction linking, and stale linkage repairs. - Enhanced `SimplefinItem#process_accounts` with stale linkage repair logic and detailed logging for unlinked accounts with transactions. - Updated `SimplefinAccount::Transactions::Processor` for improved logging and error handling during transaction processing. - Adjusted `SimplefinItem::Importer` to log detailed account and transaction information and use extended sync windows for investment accounts. * Refactor `SimplefinItem#process_accounts` to use direct queries for fresh data and streamline stale linkage repair logic; update tests for improved coverage and clarity. * Improve stale linkage repair logic in `SimplefinItem#repair_stale_linkages` - Updated to handle multiple linked accounts matching the same unlinked account by selecting the first match. - Added detailed logging to warn about multiple matches for easier debugging. * Include `:linked_account` in `SimplefinItem#process_accounts` queries for more comprehensive account data processing. * Expand `merge_transactions` logic with composite key fallback for deduplication; document edge cases. --------- Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com> |
||
|
|
3b4ab735b0 |
Add (beta) CoinStats Crypto Wallet Integration with Balance and Transaction Syncing (#512)
* Feat(CoinStats): Scaffold implementation, not yet functional * Feat(CoinStats): Implement crypto wallet balance and transactions * Feat(CoinStats): Add tests, Minor improvements * Feat(CoinStats): Utilize bulk fetch API endpoints * Feat(CoinStats): Migrate strings to i8n * Feat(CoinStats): Fix error handling in wallet link modal * Feat(CoinStats): Implement hourly provider sync job * Feat(CoinStats): Generate docstrings * Fix(CoinStats): Validate API Key on provider update * Fix(Providers): Safely handle race condition in merchance creation * Fix(CoinStats): Don't catch system signals in account processor * Fix(CoinStats): Preload before iterating accounts * Fix(CoinStats): Add no opener / referrer to API dashboard link * Fix(CoinStats): Use strict matching for symbols * Fix(CoinStats): Remove dead code in transactions importer * Fix(CoinStats): Avoid transaction fallback ID collisions * Fix(CoinStats): Improve Blockchains fetch error handling * Fix(CoinStats): Enforce NOT NULL constraint for API Key schema * Fix(CoinStats): Migrate sync status strings to i8n * Fix(CoinStats): Use class name rather than hardcoded string * Fix(CoinStats): Use account currency rather than hardcoded USD * Fix(CoinStats): Migrate from standalone to Provider class * Fix(CoinStats): Fix test failures due to string changes |
||
|
|
42b94947bf |
Fix: SimpleFIN account re-link duplication (#554)
* Add orphan pruning tests for Simplefin importer and implement pruning logic - Introduced `SimplefinItem::ImporterOrphanPruneTest` to verify orphaned `SimplefinAccount` pruning scenarios. - Added logic in `SimplefinItem::Importer` to remove orphaned `SimplefinAccounts` when upstream account IDs change. - Ensured linked accounts via legacy FK or `AccountProvider` are preserved during pruning. - Updated sync stats to track pruned accounts. * Optimize SimplefinAccount query in importer to prevent N+1 issues - Added eager-loading of `account` and `account_provider` associations when retrieving orphaned `SimplefinAccounts`. --------- Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com> |
||
|
|
3b1495422a | DS::Menu: Prevent scrolling page content (#520) |