* feat(settings): split imports and exports
* feat(security): sanitize pagination params to prevent abuse
* fix(settings): fix syntax in settings nav
* feat(settings): internationalize family_exports and imports UI strings
* fix(settings): fix coderabbit review
* fix(settings): fix coderabbit review
* fix(settings): fix coderabbit review
* Change default per_page value from 20 to 10
Signed-off-by: Juan José Mata <jjmata@jjmata.com>
* Add `/family_export` to navigation
* Consistency with old defaults
* Align `safe_per_page` even if not DRY
---------
Signed-off-by: Julien Orain <julien.orain@gmail.com>
Signed-off-by: Juan José Mata <jjmata@jjmata.com>
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: JulienOrain <your-github-email@example.com>
Co-authored-by: Juan José Mata <jjmata@jjmata.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
* feat: Add subcategory breakdown to Cash Flow and Reports
Implements Discussion #546 - adds hierarchical category/subcategory
visualization to both the Sankey chart and Reports breakdown tables.
Sankey chart changes:
- Income: subcategory → parent category → Cash Flow
- Expense: Cash Flow → parent category → subcategory
- Extracted process_category_totals helper to DRY up income/expense logic
Reports breakdown changes:
- Subcategories display nested under parent categories
- Smaller dots and indented rows for visual hierarchy
- Extracted _breakdown_table partial to eliminate duplication
* fix: Dynamic node padding for Sankey chart with many nodes
- Add dynamic nodePadding calculation to prevent padding from dominating
chart height when there are many subcategory nodes
- Extract magic numbers to static constants for configuration
- Decompose monolithic #draw() into focused methods
- Consolidate duplicate tooltip/currency formatting code
- Modernize syntax with spread operators and optional chaining
* fix: Hide overlapping Sankey labels, show on hover
- Add label overlap detection by grouping nodes by column depth
- Hide labels that would overlap with adjacent nodes
- Show hidden labels on hover (node rectangle or connected links)
- Add hover events to node rectangles (not just text)
* fix: Use deterministic fallback colors for categories
- Replace Category::COLORS.sample with Category::UNCATEGORIZED_COLOR
for income categories in Sankey chart (was producing different colors
on each page load)
- Add nil color fallback in reports_controller for parent and root
categories
Addresses CodeRabbit review feedback.
* fix: Expand CSS variable map for d3 color manipulation
Add hex mappings for commonly used CSS variables so d3 can manipulate
opacity for gradients and hover effects:
- var(--color-destructive) -> #EC2222
- var(--color-gray-400) -> #9E9E9E
- var(--color-gray-500) -> #737373
* test: Add tests for subcategory breakdown in dashboard and reports
- Test dashboard renders Sankey chart with parent/subcategory transactions
- Test reports groups transactions by parent and subcategories
- Test reports handles categories with nil colors
- Use EntriesTestHelper#create_transaction for cleaner test setup
* Fix lint: use Number.NEGATIVE_INFINITY
* Remove obsolete nil color test
Category model now validates color presence, so nil color categories
cannot exist. The fallback handling in reports_controller is still in
place but the scenario is unreachable.
* Update reports_controller.rb
* FIX trade category
---------
Co-authored-by: sokie <sokysrm@gmail.com>
* Refactor: Enhance cash balance calculation and holdings management with money market classification and provider-sourced data handling
* Fix: Clear fixture holdings in test to ensure clean creation and update raw_holdings_payload format
---------
Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
* Add tax treatment support for accounts, investments, and cryptos
* Replace hardcoded region labels with I18n translations
* Add I18n support for subtype labels with fallback to hardcoded values
* fixed schema
---------
Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
* Update activity menu to conditionally display options for linked and investment accounts
* Update transaction test to reflect "New activity" menu change
---------
Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
* feat: Support multiple crypto wallets with same token
Allows users to import multiple wallets containing the same
cryptocurrency (e.g., ETH on different wallet addresses).
Changes:
- Add wallet_address column to coinstats_accounts
- Update uniqueness validation to include wallet_address
- Extract and store wallet address in WalletLinker
- Add composite unique index on [item_id, account_id, wallet_address]
- Add tests for multi-wallet support and backwards compatibility
Users can now have:
- ETH (0xAAA...) → "Ethereum (0xAA...AA)"
- ETH (0xBBB...) → "Ethereum (0xBB...BB)"
Backwards compatible: existing accounts with wallet_address: nil
continue to work.
* style: Fix array bracket spacing in migration
* chore: Update schema.rb with wallet_address column and index
Add the missing wallet_address column and composite unique index
to db/schema.rb for CI compatibility with db:schema:load
* test: Add test for wallet deletion with same token different addresses
Verifies that deleting one wallet does not affect other wallets
that share the same token but have different addresses.
Addresses review comment from @EthanC via @jjmata
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
* fix: Allow locale preview on onboarding preferences page
When a user selects a different language on /onboarding/preferences,
the page now immediately displays in the selected language. This is
achieved by checking for a valid locale URL parameter before falling
back to the family's saved locale setting.
* fix: Harden locale param handling and restore locale in tests
- Add type check to ensure params[:locale] is a String before calling
.to_sym, preventing 500 errors from array/hash injection attacks
- Add teardown to tests to restore original locale, preventing test
pollution
* fix: Reload family in teardown to handle update_column
* fix: Remove edge case test that used update_column with nil locale
* fix: Simplify localize tests - rely on fixture defaults and transactional isolation
* fix: Update system test to expect Spanish button text after locale preview
* refactor: Use I18n.t for button text in system test instead of hardcoded string
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix: Locale-aware currency formatting
Add locale-specific formatting for money display:
- French (fr): symbol after number with non-breaking space (1 000,12 €)
- German (de): symbol after number (1.000,12 €)
- Spanish (es): symbol after number (1.000,12 €)
- Italian (it): symbol after number (1.000,12 €)
- Portuguese-Brazil (pt-BR): symbol before with space (R$ 1.000,12)
This follows international conventions where most European languages
place the currency symbol after the number, unlike English.
* fix: Address CodeRabbit review comments
- Use non-breaking spaces (NBSP) for French locale formatting
- Add nil guard in locale_options to prevent NoMethodError
- Add test coverage for Portuguese (Brazil) locale
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Implement dynamic role assignment for new family creators.
Introduced `User.role_for_new_family_creator` to assign `super_admin` to the first user of an instance and a configurable fallback role (e.g., `admin`) to subsequent users. Updated controllers and tests accordingly.
* Update default fallback role for family creators to admin.
---------
Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
* Add `investment_activity_label` to trades and enhance activity label handling
- Introduced `investment_activity_label` column to the `trades` table with a migration.
- Backfilled existing `trades` with activity labels based on quantity (`Buy`, `Sell`, or `Other`).
- Replaced `category_id` in trades with `investment_activity_label` for better alignment with transaction labels.
- Updated views and controllers to display and manage activity labels for trades.
- Added localized badge components for displaying and editing labels dynamically.
- Enhanced `PlaidAccount::Investments::TransactionsProcessor` to assign and process activity labels automatically.
- Added investment flows section to reports for tracking contributions and withdrawals.
- Refactored related tests and models for consistency and to ensure proper validation and filtering.
* Improve handling of `investment_activity_label`, trade type, and security selection in trades and transactions
- Refined label assignment logic in `trades_controller` to default to `Buy`/`Sell` based on transaction nature.
- Simplified security selection in `transactions_controller` by resolving via unique IDs or custom tickers.
- Streamlined UI for trade and transaction forms by updating dropdown options and label text.
- Enabled quick-edit badges to open `convert_to_trade` modal when applicable, enhancing flexibility.
- Adjusted tests and views to align with updated workflows and ensure consistent behavior.
* Improve handling of `investment_activity_label`, trade type, and security selection in trades and transactions
- Refined label assignment logic in `trades_controller` to default to `Buy`/`Sell` based on transaction nature.
- Simplified security selection in `transactions_controller` by resolving via unique IDs or custom tickers.
- Streamlined UI for trade and transaction forms by updating dropdown options and label text.
- Enabled quick-edit badges to open `convert_to_trade` modal when applicable, enhancing flexibility.
- Adjusted tests and views to align with updated workflows and ensure consistent behavior.
* Improve handling of `investment_activity_label`, trade type, and security selection in trades and transactions
- Refined label assignment logic in `trades_controller` to default to `Buy`/`Sell` based on transaction nature.
- Simplified security selection in `transactions_controller` by resolving via unique IDs or custom tickers.
- Streamlined UI for trade and transaction forms by updating dropdown options and label text.
- Enabled quick-edit badges to open `convert_to_trade` modal when applicable, enhancing flexibility.
- Adjusted tests and views to align with updated workflows and ensure consistent behavior.
* Add safeguard for `dropdownTarget` existence in quick edit controller
- Prevent errors by ensuring `dropdownTarget` is present before toggling its visibility.
* Fix undefined method 'category' for Trade on mobile view
Trade model uses investment_activity_label, not category. The upstream
merge introduced a call to trade.category which doesn't exist. Use the
activity label badge on mobile instead.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix activity label logic for zero/blank quantity and sell inference
- Return `nil` for blank or zero quantity in `investment_activity_label_for`.
- Correct `is_sell` logic to use the amount’s sign properly in `transactions_controller`.
* Fix i18n key paths in transactions controller for convert_to_trade
- Update flash message translations to use full i18n paths.
- Use `BigDecimal` for quantity and price calculations to improve precision.
---------
Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com>
Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Add UI and functionality for new user registration via OIDC integration
* Add tests and localization for new user registration via OIDC
---------
Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
* fix: Preserve transaction tags during rule application
When rules set tags, they now ADD to existing tags instead of replacing
them. This fixes issue #518 where tags were being removed during bank sync.
The root cause was that SetTransactionTags called enrich_attribute with
just the single tag from the rule, which replaced all existing tags.
Now it merges the new tag with existing tags using .uniq to prevent
duplicates.
This preserves:
- User-applied tags that shouldn't be overwritten by rules
- Tags from other rules when multiple rules match the same transaction
- Tags set during previous syncs
* fix: Add nil guard for tag in SetTransactionTags
Return early with 0 if the tag is not found, preventing NoMethodError
when find_by_id returns nil. This matches the pattern used in
SetTransactionMerchant.
---------
Co-authored-by: Claude <noreply@anthropic.com>
- Introduced `update_access_url!` method to reuse existing SimpleFIN items during reconnections, preserving account linkages.
- Refactored `SimplefinConnectionUpdateJob` to update access URLs in place without creating new items or transferring accounts.
- Adjusted sync logic to leverage `repair_stale_linkages` for seamless reconnections.
- Enhanced `SimplefinItem::Importer` to auto-recover the `good` status if no auth errors are found during sync.
- Updated tests to validate in-place updates and preserved account relationships.
Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com>
- Added a new test to validate how dormant credit cards with zero balance and negative available balance are processed.
- Updated processor logic to ensure `current_balance` takes precedence when explicitly set to zero, preventing incorrect usage of `available_balance`.
Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com>
- Updated `PLAID_TYPE_TO_LABEL` in `TransactionsProcessor` to consolidate labels ("Cancel" and "Cash" now mapped to "Other").
- Adjusted `label_from_plaid_type` to return "Other" as the default fallback.
- Enhanced tests to include additional valid activity labels and ensure label consistency.
- Minor fixes to locale keys for transaction views.
- Removed `exclude_from_cashflow` attribute across models, controllers, and views.
- Updated queries to rely solely on the `excluded` flag for filtering transactions and entries.
- Simplified migration by consolidating `exclude_from_cashflow` functionality into the existing `excluded` toggle.
- Refactored related tests to remove outdated logic and ensured compatibility with the updated implementation.
- Deleted the `InvestmentActivityDetector` and associated tests.
- Removed rake tasks for backfilling and clearing investment activity labels.
- Simplified transaction processing in `SimplefinEntry::Processor` by removing inferred activity label logic.
- Added new rule `SetInvestmentActivityLabel` for setting labels using rules.
- Updated `Rule::Registry::TransactionResource` to include the new rule executor.
- Introduced `InvestmentActivityDetector` to mark internal investment activity as excluded from cashflow and assign appropriate labels.
- Added `exclude_from_cashflow` flag to `entries` and `investment_activity_label` to `transactions` with migrations.
- Implemented rake tasks to backfill and clear investment activity labels.
- Updated `PlaidAccount::Investments::TransactionsProcessor` to map Plaid transaction types to labels.
- Included comprehensive test coverage for new functionality.
* Print initial impl
* Try to keep the bigger section together
* /* Tufte-inspired Print Report Styles */
* styling
* I8n
* Move print styling out.
* FIX unrelated test ordering
on line 53 - import.rows.first doesn't guarantee ordering. Without an explicit ORDER BY, the database may return rows in any order.
* Update print-report.css
* Update print.html.erb
* pass data to view
* Update index.html.erb
* Fix ERB helpers
* Update reports_helper.rb
* Add cost basis tracking and management to holdings
- Added migration to introduce `cost_basis_source` and `cost_basis_locked` fields to `holdings`.
- Implemented backfill for existing holdings to set `cost_basis_source` based on heuristics.
- Introduced `Holding::CostBasisReconciler` to manage cost basis resolution logic.
- Added user interface components for editing and locking cost basis in holdings.
- Updated `materializer` to integrate reconciliation logic and respect locked holdings.
- Extended tests for cost basis-related workflows to ensure accuracy and reliability.
* Fix cost basis calculation in holdings controller
- Ensure `cost_basis` is converted to decimal for accurate arithmetic.
- Fix conditional check to properly validate positive `cost_basis`.
* Improve cost basis validation and error handling in holdings controller
- Allow zero as a valid cost basis for gifted/inherited shares.
- Add error handling with user feedback for invalid cost basis values.
---------
Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com>
- Refactored `persist_holdings` to separate and conditionally upsert holdings with and without cost_basis.
- Updated `avg_cost` logic to treat 0 cost_basis as unknown and return nil when cost_basis cannot be determined.
- Modified trend and investment calculation to exclude holdings with unknown cost_basis.
- Adjusted `average_cost` formatting to handle nil values in API responses and views.
- Added comprehensive tests to ensure cost_basis preservation and fallback behavior.
- Localized `unknown` label for display when cost_basis is unavailable.
Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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
* 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>
* Add tests and enhance logic for SimpleFin account synchronization and reconciliation
- Added retry logic with exponential backoff for network errors in `Provider::Simplefin`.
- Introduced tests to verify retry functionality and error handling for rate-limit, server errors, and stale data.
- Updated `SimplefinItem` to detect stale sync status and reconciliation issues.
- Enhanced UI to display stale sync warnings and data integrity notices.
- Improved SimpleFin account matching during updates with multi-tier strategy (ID, fingerprint, fuzzy match).
- Added transaction reconciliation logic to detect data gaps, transaction count drops, and duplicate transaction IDs.
* Introduce `SimplefinConnectionUpdateJob` for asynchronous SimpleFin connection updates
- Moved SimpleFin connection update logic to `SimplefinConnectionUpdateJob` to improve response times by offloading network retries, data fetching, and reconciliation tasks.
- Enhanced SimpleFin account matching with a multi-tier strategy (ID, fingerprint, fuzzy name match).
- Added retry logic and bounded latency for token claim requests in `Provider::Simplefin`.
- Updated tests to cover the new job flow and ensure correct account reconciliation during updates.
* Remove unused SimpleFin account matching logic and improve error handling in `SimplefinConnectionUpdateJob`
- Deleted the multi-tier account matching logic from `SimplefinItemsController` as it is no longer used.
- Enhanced error handling in `SimplefinConnectionUpdateJob` to gracefully handle import failures, ensuring orphaned items can be manually resolved.
- Updated job flow to conditionally set item status based on the success of import operations.
* Fix SimpleFin sync: check both legacy FK and AccountProvider for linked accounts
* Add crypto, checking, savings, and cash account detection; refine subtype selection and linking
- Enhanced `Simplefin::AccountTypeMapper` to include detection for crypto, checking, savings, and standalone cash accounts.
- Improved subtype selection UI with validation and warning indicators for missing selections.
- Updated SimpleFin account linking to handle both legacy FK and `AccountProvider` associations consistently.
- Refined job flow and importer logic for better handling of linked accounts and subtype inference.
* Improve `SimplefinConnectionUpdateJob` and holdings processing logic
- Fixed race condition in `SimplefinConnectionUpdateJob` by moving `destroy_later` calls outside of transactions.
- Updated fuzzy name match logic to use Levenshtein distance for better accuracy.
- Enhanced synthetic ticker generation in holdings processor with hash suffix for uniqueness.
* Refine SimpleFin entry processing logic and ensure `extra` data persistence
- Simplified pending flag determination to rely solely on provider-supplied values.
- Fixed potential stale values in `extra` by ensuring deep merge overwrite with `entry.transaction.save!`.
* Replace hardcoded fallback transaction description with localized string
* Refine pending flag logic in SimpleFin processor tests
- Adjust test to prevent falsely inferring pending status from missing posted dates.
- Ensure provider explicitly sets pending flag for transactions.
* Add `has_many :holdings` association to `AccountProvider` with `dependent: :nullify`
---------
Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com>
- Simplified `name_id_format` selection logic in SSO provider form.
- Switched raw database query to sanitized SQL in client secret tests.
- Added condition to log JIT account creation only when identity persists.
- Sanitized failure reasons in SSO login failure handling.
- Added SSO provider connection test policy tests for super admin and regular users.