* feat: Add CORS support for Flutter mobile client
Add rack-cors gem and configure CORS for API and OAuth endpoints
to enable cross-origin requests from mobile clients and other
external applications.
https://claude.ai/code/session_01RJ6MKLkjBv7x5AQLEUn8AF
* feat: Add /sessions/* to CORS for webview authentication
Enable CORS for session endpoints to support webview-based
authentication flows in the Flutter mobile client.
https://claude.ai/code/session_01RJ6MKLkjBv7x5AQLEUn8AF
* test: Add integration tests for CORS configuration
Test that CORS middleware is configured and returns proper headers
for API, OAuth, and session endpoints including preflight requests.
https://claude.ai/code/session_01RJ6MKLkjBv7x5AQLEUn8AF
* Gemfile.lock
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Add warning for TwelveData plan-restricted tickers
Fixes#800
- Add Security::PlanRestrictionTracker concern using Rails cache
- Detect plan upgrade errors during Security::Price::Importer sync
- Display amber warning on /settings/hosting with affected tickers
- Include unit tests for the new functionality
* Scope plan restriction cache by provider
Addresses review feedback:
- Cache key now includes provider name to support multiple data providers
- Methods now require provider parameter for proper scoping
- Added tests for provider-scoped restrictions
- Added documentation explaining instance-level API key architecture
* Fix RuboCop array bracket spacing
* Fix empty array bracket spacing
* Move plan upgrade detection to Provider::TwelveData
* Fix provider scoping tests to use direct cache writes
---------
Co-authored-by: mkdev11 <jaysmth689+github@users.noreply.github.com>
* feat: Move upcoming transactions in a dedicated tab
* Adjust formatting
* feat: adjust visibility on mobile
* feat: change translation label
* feat: show only upcoming transactions expected in the next 10 days
* feat: show upcoming transactions tab only when option enabled
* feat: render empty partial when there are no recurring transactions
* feat: align icon sizing and spacing between transactions and upcoming sections
* feat: add missing localitazion labels
* fix: move filter on upcoming transactions in controller
* fix: add missing localitazion labels
* fix: Handle uncategorized transactions filter correctly
When filtering for 'Uncategorized' transactions, the filter was not working
because 'Uncategorized' is a virtual category (Category.uncategorized returns
a non-persisted Category object) and does not exist in the database.
The filter was attempting to match 'categories.name IN (Uncategorized)' which
returned zero results.
This fix removes 'Uncategorized' from the category names array before querying
the database, allowing the existing 'category_id IS NULL' condition to work
correctly.
Fixes filtering for uncategorized transactions while maintaining backward
compatibility with all other category filters.
* test: Add comprehensive tests for Uncategorized filter
- Test filtering for only uncategorized transactions
- Test combining uncategorized with real categories
- Test excluding uncategorized when not in filter
- Ensures fix prevents regression
* refactor: Use Category.uncategorized.name for i18n support
- Replace hard-coded 'Uncategorized' string with Category.uncategorized.name
- Conditionally build SQL query based on include_uncategorized flag
- Avoid adding category_id IS NULL clause when not needed
- Update tests to use Category.uncategorized.name for consistency
- Cleaner logic: only include uncategorized condition when requested
Addresses code review feedback on i18n support and query optimization.
* test: Fix travel category fixture error
Create travel category dynamically instead of using non-existent fixture
* style: Fix rubocop spacing in array brackets
---------
Co-authored-by: Charsel <charsel@charsel.com>
* Update chart version in pre-release bump
Keep Helm chart version and appVersion aligned with app releases.
* Publish Helm chart with releases
Package the Helm chart on tag releases, upload it to GitHub Pages, and attach it to the GitHub Release assets.
* Move Helm chart release to helm workflow
Publish Helm chart packages from the helm-release workflow on tags and keep publish.yml focused on app release assets.
* Derive nightly chart version from latest release
Use the most recent v* tag as the base for nightly Helm chart versions.
* Add transaction type condition filter for rules
Add ability to filter rules by transaction type (income, expense, transfer).
This allows users to create rules that differentiate between transactions
with the same name but different types.
- Add Rule::ConditionFilter::TransactionType with select dropdown
- Register in TransactionResource condition_filters
- Add tests for income, expense, and transfer filtering
Closes#373
* Address PR review feedback for transaction type filter
- Fix income filter to exclude transfers and investment_contribution
- Fix expense filter to include investment_contribution regardless of sign
- Add i18n for option and operator labels
- Add tests for edge cases (transfer inflows, investment contributions)
Logic now matches Transaction::Search#apply_type_filter for consistency.
- Move family-scoped queries to models via family_scope class method
- Remove hardcoded model names from Enrichable concern
- Replace inline rescue with proper respond_to? check
- Add count tracking for better logging
- Preserve user locks: Only unlock attributes where current value still matches
what AI set. If user changed the value, they took ownership.
- Add nil guard clause for family parameter in ClearAiCacheJob
- Add partial failure handling so one model's failure doesn't block the other
Add ClearAiCacheJob for async cache clearing with low priority. Extend Enrichable concern with clear_ai_cache methods to unlock AI-enriched attributes and delete AI enrichment records. Trigger automatic cache clearing when OpenAI model setting changes.
* Generalize pre-release bump workflow
Handle alpha, beta, and rc tags when incrementing the version.
* Change commit message for version bump in workflow
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
* First commit
* Use subscription flow for monetary contributions
* Removed only part of the SPAN
* Localize Stripe payments message
* More localization of contribution strings
* Missed two billing to payment changes
* Fix tests
* Localization of "Open Demo" strings
* Fix grammar error
* Update for consistency
* Localize CTA
* More localilzation strings
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
* fix: Register sync_all_accounts cron job on Sidekiq startup
AutoSyncScheduler.sync! was only called when changing settings in the UI,
so the nightly sync job was never registered. Now it's initialized when
Sidekiq starts, ensuring accounts sync nightly as configured.
* Utilize existing configure_server block
---------
Co-authored-by: Pieter <ptr@arcsec.org>
* Use Accept-Language for unauthenticated locale
* Add per-user locale overrides
* Fix test
* Use more than the top `accept-language` entry
* Localization of string
* feat: add protection indicator to entries and unlock functionality
- Introduced protection indicator component rendering on hover and in detail views.
- Added support to unlock entries, clearing protection flags (`user_modified`, `import_locked`, and locked attributes).
- Updated routes, controllers, and models to enable unlock functionality for trades and transactions.
- Refactored views and localized content to support the new feature.
- Added relevant tests for unlocking functionality and attribute handling.
* feat: improve sync protection and turbo stream updates for entries
- Added tests for turbo stream updates reflecting protection indicators.
- Ensured user-modified entries lock specific attributes to prevent overwrites.
- Updated controllers to mark entries as user-modified and reload for accurate rendering.
- Enhanced protection indicator rendering using turbo frames.
- Applied consistent lock state handling across trades and transactions.
* Address PR review comments for protection indicator
---------
Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
* feat: display shared budget as a badge
* fix: reduce margin on badge
* fix: adjust mobile spacing
* Consistent opacity
Signed-off-by: Juan José Mata <jjmata@jjmata.com>
---------
Signed-off-by: Juan José Mata <jjmata@jjmata.com>
Co-authored-by: Juan José Mata <jjmata@jjmata.com>
The encryption initializer previously only supported environment variables
in self-hosted mode. In managed mode, it expected encryption credentials
to exist in Rails.application.credentials, which would cause boot failures
if they were missing.
This change updates the encryption configuration to support environment
variables in both managed and self-hosted modes:
- Environment variables (ACTIVE_RECORD_ENCRYPTION_*) now work in both modes
- Priority: env vars > auto-generation (self-hosted only) > credentials
- Updated documentation in .env.example and Helm chart README
This allows managed mode deployments to provide encryption keys via
environment variables instead of requiring Rails credentials.
Co-authored-by: Claude <noreply@anthropic.com>
* refactor: rename `raw_investments_payload` to `raw_holdings_payload`
- Update references and models to use consistent naming.
- Adjust migrations, tests, and encryption setup accordingly.
* fix: improve safety when accessing raw_holdings_payload keys
- Use `dig` with safe navigation to prevent potential nil errors.
- Add support for decryption from the old column name `raw_investments_payload`.
- Adjust related methods and calculations for consistency.
---------
Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
* feat: add auto-open functionality for collapsible sections and streamline unlinked account handling
- Introduce `auto-open` Stimulus controller to auto-expand <details> elements based on URL params.
- Update all settings sections and panels to support the new `auto_open_param` for seamless navigation.
- Improve unlinked account logic for Coinbase, SimpleFIN, and SnapTrade, ensuring consistent and optimized handling.
- Refactor sync warnings and badges for better readability and user experience.
- Extend localization for additional menu items, warnings, and setup prompts.
* fix: improve error handling and safe HTML usage in Coinbase and settings components
- Log warning for unhandled exceptions in Coinbase unlinked account count fallback.
- Escape `auto_open_param` in settings section for safe HTML injection.
- Clean up URL params in `auto-open` controller after auto-expansion.
---------
Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
* fix: Enable scrolling on login page for small mobile devices
Changed auth layout containers from `h-full` to `min-h-full` and added
`overflow-y-auto` to allow content to scroll when it exceeds viewport
height on small mobile phones.
* Real fix
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Initial sec
* Update PII fields
* FIX add tests
* FIX safely read plaintext data on rake backfill
* Update user.rb
* FIX tests
* encryption_ready? block
* Test conditional to encryption on
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
* fix: Handle missing encryption keys gracefully on providers page
When Active Record encryption keys are not configured, the settings/providers
page would crash with an unhandled exception. This change catches the
ActiveRecord::Encryption::Errors::Configuration error and displays a
friendly error message instead, explaining that encryption credentials
need to be configured before using sync providers.
https://claude.ai/code/session_015nPsLWkr12i5ok5bwLtA7p
* Simplify rescue block
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix: Show cancellation message when subscription is pending cancellation
When a subscription is cancelled via Stripe, the UI incorrectly showed
"Your contribution continues on..." instead of reflecting the cancellation
status. This fix adds tracking of `cancel_at_period_end` from Stripe webhooks
and displays "Your contribution ends on..." when a subscription has been
cancelled but is still active until the billing period ends.
https://claude.ai/code/session_01Y8ELTdK1k9o315iSq43TRN
* chore: Update schema.rb with cancel_at_period_end column
https://claude.ai/code/session_01Y8ELTdK1k9o315iSq43TRN
* Schema version
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Add security remapping support to holdings
- Introduced `provider_security` tracking for holdings with schema updates.
- Implemented security remap/reset workflows in `Holding` model and UI.
- Updated routes, controllers, and tests to support new functionality.
- Enhanced client-side interaction with Stimulus controller for remapping.
# Conflicts:
# app/components/UI/account/activity_feed.html.erb
# db/schema.rb
* Refactor "New transaction" to "New activity" across UI and tests
- Updated localized strings, button labels, and ARIA attributes.
- Improved error handling in holdings' current price display.
- Scoped fallback queries in `provider_import_adapter` to prevent overwrites.
- Added safeguard for offline securities in price fetching logic.
* Update security remapping to merge holdings on collision by deleting duplicates
- Removed error handling for collisions in `remap_security!`.
- Added logic to merge holdings by deleting duplicates on conflicting dates.
- Modified associated test to validate merging behavior.
* Update security remapping to merge holdings on collision by combining qty and amount
- Modified `remap_security!` to merge holdings by summing `qty` and `amount` on conflicting dates.
- Adjusted logic to calculate `price` for merged holdings.
- Updated test to validate new merge behavior.
* Improve DOM handling in Turbo redirect action & enhance holdings merge logic
- Updated Turbo's custom `redirect` action to use the "replace" option for cleaner DOM updates without clearing the cache.
- Enhanced holdings merge logic to calculate weighted average cost basis during security remapping, ensuring more accurate cost_basis updates.
* Track provider_security_id during security updates to support reset workflows
* Fix provider tracking: guard nil ticker lookups and preserve merge attrs
- Guard fallback 1b lookup when security.ticker is blank to avoid matching NULL tickers
- Preserve external_id, provider_security_id, account_provider_id during collision merge
* Fix schema.rb version after merge (includes tax_treatment migration)
* fix: Rename migration to run after schema version
The migration 20260117000001 was skipped in CI because it had a timestamp
earlier than the schema version (2026_01_17_200000). CI loads schema.rb
directly and only runs migrations with versions after the schema version.
Renamed to 20260119000001 so it runs correctly.
* Update schema: remove Coinbase tables, add new fields and indexes
* Update schema: add back `tax_treatment` field with default value "taxable"
* Improve Turbo redirect action: use "replace" to avoid form submission in history
* Lock merged holdings to prevent provider overwrites and fix activity feed template indentation
* Refactor holdings transfer logic: enforce currency checks during collisions and enhance merge handling
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
* Hide payment contribution options from demo and manually created users
Demo data users and manually created users don't have stripe_customer_id
set on their family, so they should not see payment/contribution options.
Changes:
- Add can_manage_subscription? method to Family::Subscribeable that checks
for presence of stripe_customer_id
- Guard Settings::PaymentsController to return 403 for users without
stripe_customer_id
- Guard SubscriptionsController#show action (Stripe portal redirect) for
users without stripe_customer_id
- Update settings navigation to hide the payment link when
stripe_customer_id is not present
- Add tests for the new behavior
* Fix broken test
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix: replace invalid redirect("about:blank") with proper controller actions
The privacy and terms routes were using redirect("about:blank") which is
invalid because about:blank is a browser-specific pseudo URL, not a valid
HTTP redirect target. This fix replaces them with proper controller actions
that render placeholder pages.
Changes:
- Add privacy and terms actions to PagesController with skip_authentication
- Create privacy.html.erb and terms.html.erb view templates
- Add i18n translations for the new pages
- Update routes to use pages#privacy and pages#terms
https://claude.ai/code/session_01RL36dMda1o6LXGsnGnTJZu
* Make legal routes configurable
---------
Co-authored-by: Claude <noreply@anthropic.com>