Commit Graph

109 Commits

Author SHA1 Message Date
Sophtron Rocky
b32e9dbc45 Add Sophtron Provider (#596)
* Add Sophtron Provider

* fix syncer test issue

* fix schema  wrong merge

* sync #588

* sync code for #588

* fixed a view issue

* modified by comment

* modified

* modifed

* modified

* modified

* fixed a schema issue

* use global subtypes

* add some locales

* fix a safe_return_to_path

* fix exposing raw exception messages issue

* fix a merged issue

* update schema.rb

* fix a schema issue

* fix some issue

* Update bank sync controller to reflect beta status

Signed-off-by: Juan José Mata <jjmata@jjmata.com>

* Rename settings section title to 'Sophtron (alpha)'

Signed-off-by: Juan José Mata <jjmata@jjmata.com>

* Consistency in alpha/beta for Sophtron

* Good PR suggestions from CodeRabbit

---------

Signed-off-by: soky srm <sokysrm@gmail.com>
Signed-off-by: Sophtron Rocky <rocky@sophtron.com>
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Signed-off-by: Juan José Mata <jjmata@jjmata.com>
Co-authored-by: soky srm <sokysrm@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <jjmata@jjmata.com>
2026-04-19 11:16:04 +02:00
Ang Wei Feng (Ted)
60929cdee0 feat: add currency management for families with enabled currencies (#1419)
* feat: add currency management for families with enabled currencies

* feat: update currency selection logic and improve accessibility

* feat: update currency preferences to use group moniker in titles

---------

Signed-off-by: Ang Wei Feng (Ted) <hello@tedawf.com>
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-04-13 19:53:04 +02:00
Louis
455c74dcfa Add Binance support, heavily inspired by the Coinbase one (#1317)
* feat: add Binance support (Items, Accounts, Importers, Processor, and Sync)

* refactor: deduplicate 'stablecoins' constant and push stale_rate filter to SQL

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-04-07 14:43:17 +02:00
Mikael Møller
5cb474d61c Quick Categorize Wizard — follow-up fixes (#1393)
* Extract Entry.uncategorized_transactions scope, remove Family#uncategorized_transaction_count

Adds a single Entry.uncategorized_transactions scope containing the
shared conditions (transactions join, active accounts, category nil,
not transfer kinds, not excluded). All callers now use this scope:

- Entry.uncategorized_matching builds on it
- Transaction::Grouper::ByMerchantOrName#uncategorized_entries uses it
- categorizes_controller#uncategorized_entries_for uses it (also fixes
  missing status/excluded filters that were silently absent before)
- Both controllers replace Current.family.uncategorized_transaction_count
  with Current.accessible_entries.uncategorized_transactions.count so
  the button count and wizard count both respect account sharing

Family#uncategorized_transaction_count removed as it is now unused and
was family-scoped rather than user-scoped.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Scope assign_entry write to Current.accessible_entries

Replaces unscoped Entry.where(id:) with Current.accessible_entries.where(id:)
so the write path is consistent with the find above it. Not exploitable
given the find would 404 first, but removes the pattern inconsistency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add privacy-sensitive class to amounts in categorize wizard

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Extract uncategorized_count helper in CategorizesController

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix comment on uncategorized_transactions scope to mention draft accounts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Use uncategorized_count helper in assign_entry action

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:17:37 +02:00
Mikael Møller
0870ebb56b Add Quick Categorize Wizard (#1386)
* Add Quick Categorize Wizard (iteration 1)

Adds a step-by-step wizard for bulk-categorizing uncategorized transactions
and optionally creating auto-categorization rules, reducing friction after
connecting a new bank account.

New files:
- Transaction::Grouper abstraction + ByMerchantOrName strategy (groups by
  merchant name when present, falls back to entry name; sorted by count desc)
- Transactions::CategorizesController (GET show / POST create)
- Wizard view at app/views/transactions/categorizes/show.html.erb
- Stimulus categorize_controller.js (Enter-key-to-select-first)
- Tests for grouper and controller

Modified files:
- routes.rb: resource :categorize inside namespace :transactions
- transactions_controller.rb: expose @uncategorized_count to index
- transactions/index.html.erb: Categorize (N) button in header
- family.rb: uncategorized_transaction_count query
- rules_controller.rb: return_to param support for wizard → rule editor flow
- rules/_form.html.erb, rules/new.html.erb: pass return_to through form
- i18n: categorizes show/create keys + rules.create.success

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Quick Categorize Wizard — iteration 2 polish

Six improvements from live testing:

- Breadcrumb: Home > Transactions > Categorize
- Layout: category picker + confirmation dialog above transaction list
- Inline confirmation dialog: clicking a category pill shows a <dialog>
  summarising what will happen (N transactions → category, rule if checked)
  with Confirm and Cancel buttons — no redirect to rule editor
- Direct rule creation: rule created with active: true in the controller
  instead of redirecting to the rule editor; revert return_to plumbing from
  RulesController, rules/_form, rules/new, rules/en.yml
- Individual row assignment: per-row category <select> submits via
  PATCH /transactions/categorize/assign_entry and removes the row via
  Turbo Stream (assign_entry action + route)
- Enter key guard: selectFirst only fires when exactly 1 pill is visible
  after filtering

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Quick Categorize Wizard — iteration 3 reliability fixes and UX polish

- Fix Stimulus controller not loading: remove invalid `@hotwired/turbo` named
  import (not in importmap); use global `Turbo.renderStreamMessage` instead
- Fix Enter key submitting form with wrong category when search field is
  unfocused: move keydown listener to document so it fires regardless of focus
- Prevent Enter from submitting when multiple categories are visible
- Clear search filter after bulk category assignment (pill click or Enter),
  but not after individual row dropdown assignment
- Update group transaction count and total amount live as entries are assigned
  via row dropdown or partial bulk assignment
- Add turbo frames for remaining count and group summary so they update
  without a full page reload

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Quick categorization polish

* refactoring

* Remove unused GROUPS_PER_BATCH constant, fix ERB self-closing tags

Wizard only ever uses one group at a time so limit: 1 is correct and
more honest than fetching 20 and discarding 19. ERB linter fixes are
whitespace/void-element corrections with no functional change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Move Categorize button into ... menu on transactions index

Reduces header clutter by putting it in the overflow menu at the bottom,
where it only appears when there are uncategorized transactions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Scope categorize wizard to accessible entries only

Fixes a security issue where users with restricted account access via
account sharing could view and categorize transactions from accounts
they cannot access through normal transaction flows.

- Pass Current.accessible_entries to Transaction::Grouper so the wizard
  only displays groups from accounts the user can see
- Use Current.accessible_entries on all write paths in create and
  assign_entry, matching the pattern in TransactionCategoriesController
- Refactor Grouper to accept an entries scope instead of a family object,
  keeping authorization concerns in the controller
- Add tests verifying inaccessible entries are hidden from the wizard
  and cannot be categorized via forged POST/PATCH params

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Clamp position param to >= 0 to guard against negative offset

Prevents ArgumentError from Array#drop when a negative position is
passed via a tampered query string or form value.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Surface rule creation failure and add accessible names to entry row

- Capture Rule.create_from_grouping! return value; set flash[:alert] when
  nil so users who checked "Create Rule" know it wasn't created (e.g. a
  duplicate already exists); stream the notification for partial updates
- Add aria-label to the per-row checkbox and category select in
  _entry_row so screen readers can identify which transaction each
  control belongs to

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Localize breadcrumb labels in categorizes controller

Follows the pattern used by FamilyExportsController and ImportsController.
Adds 'transactions' and 'categorize' keys to the breadcrumbs locale file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add error handling to categorize controller fetch calls

Check response.ok before parsing the body and add .catch handlers
so network failures and non-2xx responses are logged rather than
silently swallowed. On assignment failure the per-row select is
reset to empty so the user can retry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Scope preview_rule to accessible entries only

Entry.uncategorized_matching now accepts an entries scope instead of a
family object, matching the same pattern used for Transaction::Grouper.
The preview_rule action passes Current.accessible_entries so rule
previews respect account sharing permissions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Scope remaining count to accessible entries

Adds Entry.uncategorized_count(entries) following the same pattern as
uncategorized_matching. Replaces all three uses of
Current.family.uncategorized_transaction_count in the categorize
controller so the remaining-count badge reflects only the transactions
the current user can actually access and categorize.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Comments got separated from their function

* Remove quick-categorize-wizard dev notes

This was a planning document used during development, not intended
for the final branch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Recompute remaining entries from server state after writes

Adds uncategorized_entries_for helper that reloads remaining entries
from the DB with a category_id IS NULL filter after each write, so
the partial-update Turbo Stream reflects server-side state rather than
trusting the client-provided remaining_ids. This handles the case where
a concurrent request has categorized one of the remaining entries
between page render and form submit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Rename create_from_grouping! to create_from_grouping

The method rescues RecordInvalid and returns nil, which contradicts
the bang convention. Dropping the ! correctly signals that callers
should check the return value.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Clamp offset in grouper to guard against negative values

The controller already clamps position before passing it as offset,
but clamping in the grouper itself prevents ArgumentError from
Array#drop if the grouper is ever called directly with a negative offset.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Juan José Mata <jjmata@jjmata.com>
2026-04-07 11:24:50 +02:00
soky srm
9410e5b38d Providers sharing (#1273)
* third party provider scoping

* Simplify logic and allow only admins to mange providers

* Broadcast fixes

* FIX tests and build

* Fixes

* Reviews

* Scope merchants

* DRY fixes
2026-03-25 17:47:04 +01:00
soky srm
560c9fbff3 Family sharing (#1272)
* Initial account sharing changes

* Update schema.rb

* Update schema.rb

* Change sharing UI to modal

* UX fixes and sharing controls

* Scope include in finances better

* Update totals.rb

* Update totals.rb

* Scope reports to finance account scope

* Update impersonation_sessions_controller_test.rb

* Review fixes

* Update schema.rb

* Update show.html.erb

* FIX db validation

* Refine edit permissions

* Review items

* Review

* Review

* Add application level helper

* Critical review

* Address remaining review items

* Fix modals

* more scoping

* linter

* small UI fix

* Fix: Sync broadcasts push unscoped balance sheet to all users

* Update sync_complete_event.rb

 The fix removes the sidebar broadcasts (which rendered unscoped account groups using family.balance_sheet without user context)
  along with the now-unused sidebar_targets, account_group, and family_balance_sheet private methods.

  The sidebar will still update correctly — when the sync completes, Family::SyncCompleteEvent#broadcast fires family.broadcast_refresh, which triggers a
  morph-based page refresh for each user with their own authenticated session, rendering properly scoped sidebar content.
2026-03-25 10:50:23 +01:00
soky srm
e1ff6d46ee Make categories global (#1160)
* Make categories global

This solves us A LOT of cash flow and budgeting problems.

* Update schema.rb

* Update auto_categorizer.rb

* Update income_statement.rb

* FIX budget sub-categories

* FIX sub-categories and tests

* Add 2 step migration
2026-03-11 15:54:01 +01:00
MkDev11
111d6839e0 Feat/Abstract Assistant into module with registry (#1020)
* Abstract Assistant into module with registry (fixes #1016)

- Add Assistant module with registry/factory (builtin, external)
- Assistant.for_chat(chat) routes by family.assistant_type
- Assistant.config_for(chat) delegates to Builtin for backward compat
- Assistant.available_types returns registered types
- Add Assistant::Base (Broadcastable, respond_to contract)
- Move current behavior to Assistant::Builtin (Provided + Configurable)
- Add Assistant::External stub for future OpenClaw/WebSocket
- Migration: add families.assistant_type (default builtin)
- Family: validate assistant_type inclusion
- Tests: for_chat routing, available_types, External stub, blank chat guard

* Fix RuboCop layout: indentation in Assistant module and tests

* Move new test methods above private so Minitest discovers them

* Clear thinking indicator in External#respond_to to avoid stuck UI

* Rebase onto upstream main: fix schema to avoid spurious diffs

- Rebase feature/abstract-assistant-1016 onto we-promise/main
- Rename migration to 20260218120001 to avoid duplicate version with backfill_crypto_subtype
- Regenerate schema from upstream + assistant_type only (keeps vector_store_id, realized_gain, etc.)
- PR schema diff now shows only assistant_type addition and version bump

---------

Co-authored-by: mkdev11 <jaysmth689+github@users.noreply.github.com>
2026-02-23 07:38:58 -05:00
BitToby
e573896efe fix: locale-dependent category duplication bug (#956)
* fix: locale-dependent category duplication bug

* fix: use family locale for investment contributions category to prevent duplicates and handle legacy data

* Remove v* tag trigger from flutter-build to fix double-runs

publish.yml already calls flutter-build via workflow_call on v* tags,
so the direct push trigger was causing duplicate workflow runs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Refactor mobile release asset flow

* fix: category uniqueness and workflow issues

* fix: fix test issue

* fix: solve test issue

* fix: resolve legacy problem

* fix: solve lint test issue

* fix: revert unrelated changes

---------

Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 10:33:51 +01:00
Juan José Mata
868a0ae4d8 Add family moniker selection and dynamic UI labels (#981)
* Add family moniker selection and dynamic UI labels

Introduce a Family moniker persisted in the database with allowed values Family/Group, add required onboarding selection for it, and thread moniker-aware copy through key user-facing views and locales. Also add helper methods and tests for onboarding form presence and family moniker behavior.

* Small copy edits/change moniker question order

* Conditional Group/Family onboarding flow fixes

* Fix label

* Grouping of fields

* Profile Info page Group/Family changes

* Only admins can change Group/Family moniker

* Repetitive defaults

* Moniker in Account model

* Moniker in User model

* Auth fix

* Sure product is also a moniker

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
2026-02-13 19:30:29 +01:00
Juan José Mata
9e57954a99 Add Family vector search function call / support for document vault (#961)
* Add SearchFamilyImportedFiles assistant function with vector store support

Implement per-Family document search using OpenAI vector stores, allowing
the AI assistant to search through uploaded financial documents (tax returns,
statements, contracts, etc.). The architecture is modular with a provider-
agnostic VectorStoreConcept interface so other RAG backends can be added.

Key components:
- Assistant::Function::SearchFamilyImportedFiles - tool callable from any LLM
- Provider::VectorStoreConcept - abstract vector store interface
- Provider::Openai vector store methods (create, upload, search, delete)
- Family::VectorSearchable concern with document management
- FamilyDocument model for tracking uploaded files
- Migration adding vector_store_id to families and family_documents table

https://claude.ai/code/session_01TSkKc7a9Yu2ugm1RvSf4dh

* Extract VectorStore adapter layer for swappable backends

Replace the Provider::VectorStoreConcept mixin with a standalone adapter
architecture under VectorStore::. This cleanly separates vector store
concerns from the LLM provider and makes it trivial to swap backends.

Components:
- VectorStore::Base — abstract interface (create/delete/upload/remove/search)
- VectorStore::Openai — uses ruby-openai gem's native vector_stores.search
- VectorStore::Pgvector — skeleton for local pgvector + embedding model
- VectorStore::Qdrant — skeleton for Qdrant vector DB
- VectorStore::Registry — resolves adapter from VECTOR_STORE_PROVIDER env
- VectorStore::Response — success/failure wrapper (like Provider::Response)

Consumers updated to go through VectorStore.adapter:
- Family::VectorSearchable
- Assistant::Function::SearchFamilyImportedFiles
- FamilyDocument

Removed: Provider::VectorStoreConcept, vector store methods from Provider::Openai

https://claude.ai/code/session_01TSkKc7a9Yu2ugm1RvSf4dh

* Add Vector Store configuration docs to ai.md

Documents how to configure the document search feature, covering all
three supported backends (OpenAI, pgvector, Qdrant), environment
variables, Docker Compose examples, supported file types, and privacy
considerations.

https://claude.ai/code/session_01TSkKc7a9Yu2ugm1RvSf4dh

* No need to specify `imported` in code

* Missed a couple more places

* Tiny reordering for the human OCD

* Update app/models/assistant/function/search_family_files.rb

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Juan José Mata <jjmata@jjmata.com>

* PR comments

* More PR comments

---------

Signed-off-by: Juan José Mata <jjmata@jjmata.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-02-11 15:22:56 +01:00
David Gil
ba442d5f26 Implement Indexa Capital provider with real API integration (#933)
* Add Indexa Capital provider scaffold

Generate Indexa Capital provider scaffolding and align credential fields with the API authentication requirements.

* Fix PR 926 lint and schema CI failures

* Implement Indexa Capital provider with real API integration

- Rewrite all broken view templates (were meta-ERB from code generator)
- Create missing select_accounts.html.erb template
- Implement real API calls: list_accounts via /users/me, get_holdings
  via /accounts/{number}/fiscal-results, get_account_balance via
  /accounts/{number}/performance
- Add API token auth support (stored token > env token > credentials)
- Add api_token column with encryption support
- Redesign settings panel: API token prominent, credentials collapsible
- Fix account balances display using performance endpoint portfolios
- Fix accounts index empty-state guard missing indexa_capital_items
- Simplify activities fetch job (no activities API endpoint exists)
- Fix i18n interpolation (%%{ -> %{) throughout locale file

* Add tests for Indexa Capital provider integration

- IndexaCapitalItemTest: validations, credentials, scopes, sync status
- IndexaCapitalAccountTest: upsert, holdings, account provider linking
- Provider::IndexaCapitalTest: auth modes, API stubs, error handling
- IndexaCapitalItemsControllerTest: CRUD, setup, linking, authorization
- Fixtures for items (token + credentials) and accounts (mutual + pension)

52 tests, 98 assertions, 0 failures

* Address code review feedback from PR #933

- Fix zero balance bug: use `nil?` instead of `present?` so 0 is stored
- Fix has_indexa_capital_credentials? to check api_token (was ignored)
- Fix build_provider to delegate to Provided concern (was ignoring token)
- Fix IndexaCapital section outside encryption_error guard in settings
- Add account_number sanitization to prevent path traversal in API URLs
- Replace all skipped processor tests with real working tests
- Add zero-balance and path-traversal test coverage

61 tests, 107 assertions, 0 failures

* Address code review round 2: credentials validation, RuboCop, test quality

- Fix RuboCop SpaceInsideArrayLiteralBrackets in credentials check
- Chain where.not calls so all three username/document/password must be present
- Require all three credentials (||) instead of any one (&&) in validate_configuration!
- Move attr_reader to private to avoid exposing credentials publicly
- Parse dates with Date.parse in extract_balance for robustness
- Remove stale TODO and Crypto from supported_account_types
- Order build_provider query deterministically by created_at
- Replace no-op holdings assertion with meaningful assert_difference

* Address code review round 3: JSON parse safety and test precision

- Rescue JSON::ParserError on 2xx responses for clearer error messages
- Fix weak balance assertion: set balance to 0 before processing, assert
  expected value (27093.01 = sum of holdings amounts)

* Include Indexa Capital in automatic family sync

Add indexa_capital_items to Family::Syncer#child_syncables so balances
and holdings refresh on daily auto-sync and login sync, not only on
manual sync button clicks.

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <jjmata@jjmata.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-02-08 18:19:37 +01:00
LPW
36661bdc9b Auto-categorize investment contributions across all transfer paths (#924)
* Ensure investment contributions are auto-categorized with proper kind and category creation.

* Retrigger CI
2026-02-07 16:41:31 +01:00
MkDev11
68efe71cdb feat: Customizable Budget Month Start Day (#810)
* Add customizable budget month start day (#253)

Allow users to set a custom month-to-date start date (1st-28th) for
budgeting and MTD calculations. Useful for users who want budget
periods aligned with their pay schedule (e.g., 25th to 24th).

Changes:
- Add month_start_day column to families table (default: 1)
- Add database check constraint for valid range (1-28)
- Add Family#uses_custom_month_start?, custom_month_start_for,
  custom_month_end_for, current_custom_month_period helper methods
- Add Period.current_month_for(family), last_month_for(family) methods
- Update Budget model for custom month boundaries in find_or_bootstrap,
  param_to_date, budget_date_valid?, current?, and name methods
- Add month_start_day setting to Settings > Preferences UI
- Add warning message when custom month start day is configured
- Add comprehensive tests with travel_to for date robustness

Fixes #253

* Add /api/v1/user endpoint for Flutter mobile app and PWA

Expose user preferences including month_start_day via API endpoint
following existing pattern for default_period. This allows Flutter
mobile app and PWA to read/update user preferences through a
consistent API contract.

Endpoints:
- GET /api/v1/user - Read user preferences including family settings
- PATCH /api/v1/user - Update user preferences

Response includes: id, email, first_name, last_name, default_period,
locale, and family settings (currency, timezone, date_format, country,
month_start_day).

* Update Periodable to use family-aware MTD periods

When users select 'current_month' or 'last_month' period filters on
dashboard/reports, now respects the family's custom month_start_day
setting instead of using static calendar month boundaries.

This ensures MTD filter on dashboard is consistent with how budgets
calculate their periods when custom month start day is configured.

* Fix param_to_date to correctly map budget params to custom periods

When a family uses a custom start day, the previous implementation
called custom_month_start_for on the 1st of the month, which incorrectly
shifted dates before the start day to the previous month.

Now we directly construct the date using family.month_start_day, so
'jan-2026' with month_start_day=25 correctly returns Jan 25, 2026
instead of Dec 25, 2025.

* Fix param_to_date and use Current pattern in API controller

- Fix param_to_date to directly construct date with family.month_start_day
  instead of using custom_month_start_for which incorrectly shifted dates
- Replace current_user with Current.user/Current.family in API controller
  to follow project convention used in other API v1 controllers

* Add i18n for budget name method

Use I18n.t for localizable budget period names to follow
project conventions for user-facing strings.

* Remove unused budget_end variable in budget_date_valid?

* Use Date.current for timezone consistency in Budget#current?

* Address PR review feedback

- Remove API users endpoint (mobile won't use yet)
- Remove user route from config/routes.rb
- Remove ai_summary/document_type schema bleed from pdf-import-ai branch

* Pass family to param_to_date for custom month logic

* Run migration to add month_start_day column to schema

* Schema regressions

---------

Co-authored-by: mkdev11 <jaysmth689+github@users.noreply.github.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-02-04 23:58:09 +01:00
MkDev11
eeff4edbea Add warning for TwelveData plan-restricted tickers (#803)
* 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>
2026-01-27 15:45:50 +01:00
LPW
7bd1058b6e Exclude tax-advantaged account activity from budget & add provider data quality warnings (#724)
* Add tax-advantaged account exclusions and investment data warnings

* Address PR review feedback: translations + cache key stability

- Add proper translations for provider warnings in 8 locales (de, es, nb, pt-BR, ro, tr, zh-CN, zh-TW)
- Fix cache key stability: use SHA256.hexdigest instead of Array#hash (randomized per process)

---------

Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
2026-01-22 22:23:09 +01:00
LPW
a83f70425f Add SnapTrade brokerage integration with full trade history support (#737)
* Introduce SnapTrade integration with models, migrations, views, and activity processing logic.

* Refactor SnapTrade activities processing: improve activity fetching flow, handle pending states, and update UI elements for enhanced user feedback.

* Update Brakeman ignore file to include intentional redirect for SnapTrade OAuth portal.

* Refactor SnapTrade models, views, and processing logic: add currency extraction helper, improve pending state handling, optimize migration checks, and enhance user feedback in UI.

* Remove encryption for SnapTrade `snaptrade_user_id`, as it is an identifier, not a secret.

* Introduce `SnaptradeConnectionCleanupJob` to asynchronously handle SnapTrade connection cleanup and improve i18n for SnapTrade item status messages.

* Update SnapTrade encryption: make `snaptrade_user_secret` non-deterministic to enhance security.

---------

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>
2026-01-22 20:52:49 +01:00
soky srm
179552657c Mercury integration (#723)
* Initial mercury impl

* FIX both mercury and generator class

* Finish mercury integration and provider generator

* Fix schema

* Fix linter and tags

* Update routes.rb

* Avoid schema drift

---------

Signed-off-by: soky srm <sokysrm@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-01-22 20:37:07 +01:00
LPW
dd991fa339 Add Coinbase exchange integration with CDP API support (#704)
* **Add Coinbase integration with item and account management**
- Creates migrations for `coinbase_items` and `coinbase_accounts`.
- Adds models, controllers, views, and background tasks to support account linking, syncing, and transaction handling.
- Implements Coinbase API client and adapter for seamless integration.
- Supports ActiveRecord encryption for secure credential storage.
- Adds UI components for provider setup, account management, and synchronization.

* Localize Coinbase-related UI strings, refine account linking for security, and add timeouts to Coinbase API requests.

* Localize Coinbase account handling to support native currencies (USD, EUR, GBP, etc.) across balances, trades, holdings, and transactions.

* Improve Coinbase processing with timezone-safe parsing, native currency support, and immediate holdings updates.

* Improve trend percentage formatting and enhance race condition handling for Coinbase account linking.

* Fix log message wording for orphan cleanup

* Ensure `selected_accounts` parameter is sanitized by rejecting blank entries.

* Add tests for Coinbase integration: account, item, and controller coverage

- Adds unit tests for `CoinbaseAccount` and `CoinbaseItem` models.
- Adds integration tests for `CoinbaseItemsController`.
- Introduces Stimulus `select-all` controller for UI checkbox handling.
- Localizes UI strings and logging for Coinbase integration.

* Update test fixtures to use consistent placeholder API keys and secrets

* Refine `coinbase_item` tests to ensure deterministic ordering and improve scope assertions.

* Integrate `SyncStats::Collector` into Coinbase syncer to streamline statistics collection and enhance consistency.

* Localize Coinbase sync status messages and improve sync summary test coverage.

* Update `CoinbaseItem` encryption: use deterministic encryption for `api_key` and standard for `api_secret`.

* fix schema drift

* Beta labels to lower expectations

---------

Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-01-21 22:56:39 +01:00
luckyPipewrench
a75cb816c7 Centralize investment_contributions_category logic and update references for streamlined handling. 2026-01-20 17:51:36 -05:00
soky srm
d1b8d585ce FIX merchant regression (#659) 2026-01-15 13:14:10 +01:00
soky srm
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.
2026-01-09 19:38:04 +01:00
soky srm
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>
2026-01-09 13:03:40 +01:00
Ethan
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
2026-01-07 15:59:04 +01:00
Juan José Mata
bf90cad9a0 Add Recent Runs visibility for rule executions (#376)
* Add Recent Runs visibility for rule executions

Adds a comprehensive tracking system for rule execution history with the following features:

- Creates RuleRun model to track execution metadata:
  * Date/time of execution
  * Execution type (manual/scheduled)
  * Success/failure status
  * Rule reference
  * Transaction counts (processed and modified)
  * Error messages for failed runs

- Updates RuleJob to automatically record execution results:
  * Captures transaction processing statistics
  * Handles success/failure states
  * Stores error details for debugging

- Adds "Recent Runs" section to rules index page:
  * Paginated display (20 runs per page)
  * Columnar layout similar to LLM usage page
  * Visual status indicators (success/failed badges)
  * Error tooltips for failed runs
  * Responsive design with design system tokens

- Includes i18n translations for all user-facing strings

This provides users with visibility into rule execution history, making it easier to debug issues and monitor rule performance.

* Update schema.rb with rule_runs table definition

* Linter noise

* Separate transaction counts into Queued, Processed, and Modified

Previously, the code eagerly reported transactions as "processed" when they
were only queued for processing. This commit separates the counts into three
distinct metrics:

- Transactions Queued: Count of transactions matching the rule's filter
  conditions before any processing begins
- Transactions Processed: Count of transactions that were actually processed
  and modified by the rule actions
- Transactions Modified: Count of transactions that had their values changed
  (currently same as Processed, but allows for future differentiation)

Changes:
- Add transactions_queued column to rule_runs table
- Update RuleJob to track all three counts separately
- Update action executors to return count of modified transactions
- Update Rule#apply to aggregate modification counts from actions
- Add transactions_queued label to locales
- Update Recent Runs view to display new column
- Add validation for transactions_queued in RuleRun model

The tracking now correctly reports:
1. How many transactions matched the filter (queued)
2. How many were actually modified (processed/modified)
3. Distinguishes between matching and modifying transactions

* Add Pending status to track async rule execution progress

Introduced a new "pending" status for rule runs to properly track async
AI operations. The system now:

- Tracks pending async jobs with a counter that decrements as jobs complete
- Updates transactions_modified incrementally as each job finishes
- Only counts transactions that were actually modified (not just queued)
- Displays pending status with yellow badge in the UI
- Automatically transitions from pending to success when all jobs complete

This provides better visibility into long-running AI categorization and
merchant detection operations, showing real-time progress as Sidekiq
processes the batches.

* Fix migration version to 7.2 as per project standards

* Consolidate rule_runs migrations into single migration file

Merged three separate migrations (create, add_transactions_queued,
add_pending_jobs_count) into a single CreateRuleRuns migration.
This provides better clarity and maintains a clean migration history.

Changes:
- Updated CreateRuleRuns migration to include all columns upfront
- Removed redundant add_column migrations
- Updated schema version to 2025_11_24_000000

* Linter and test fixes

* Space optimization

* LLM l10n is better than no l10n

* Fix implementation for tags/AI rules

* Fix tests

* Use batch_size

* Consider jobs "unknown" status sometimes

* Rabbit suggestion

* Rescue block for RuleRun.create!

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-07 16:30:02 +01:00
soky srm
4a29d030af Initial enable banking implementation (#382)
* Initial enable banking implementation

* Handle multiple connections

* Amount fixes

* Account type mapping

* Add option to skip accounts

* Update schema.rb

* Transaction fixes

* Provider fixes

* FIX account identifier

* FIX support unlinking

* UI style fixes

* FIX safe redirect and brakeman issue

* FIX

- pagination max fix
- wrap crud in transaction logic

* FIX api uid access

- The Enable Banking API expects the UUID (uid from the API response) to fetch balances/transactions, not the identification_hash

* FIX add new connection

* FIX erb code

* Alert/notice box overflow protection

* Give alert/notification boxes room to grow (3 lines max)

* Add "Enable Banking (beta)" to `/settings/bank_sync`

* Make Enable Banking section collapsible like all others

* Add callback hint to error message

---------

Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2025-11-29 13:31:08 +01:00
soky srm
e290e3d4a1 Recurring transactions (#271)
* Implement recurring transactions support

* Amount fix

* Hide section when any filter is applied

* Add automatic identify feature

Automatic identification runs after:
  - CSV Import completes (TransactionImport, TradeImport, AccountImport, MintImport)
  - Plaid sync completes
  - SimpleFIN sync completes
  - LunchFlow sync completes
- Any new provider that we create.

* Fix linter and tests

* Fix address review

* FIX proper text sizing

* Fix further linter

Use circular distance to handle month-boundary wrapping

* normalize to a circular representation before computing the median

* Better tests validation

* Added some UI info

Fix pattern identification, last recurrent transaction needs to happened within the last 45 days.

* Fix styling

* Revert text subdued look

* Match structure of the other sections

* Styling

* Restore positive amounts styling

* Shorten label for UI styling

---------

Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2025-11-01 09:12:42 +01:00
soky srm
5eadfaad98 Lunchflow integration (#259)
* First pass lunch flow

* Fixes

- Fix apikey not being saved properly due to provider no reload support
- Fix proper messages if we try to link existing accounts.

* Fix better error handling

* Filter existing transactions and skip duplicates

* FIX messaging

* Branding :)

* Fix XSS and linter

* FIX provider concern

- also fix code duplication

* FIX md5 digest

* Updated determine_sync_start_date to be account-aware

* Review fixes

* Broaden error catch to not crash UI

* Fix buttons styling

* FIX process account error handling

* FIX account cap and url parsing

* Lunch Flow brand

* Found orphan i18n strings

* Remove per conversation with @sokie

---------

Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2025-10-30 14:07:16 +01:00
soky srm
bb364fab38 LLM cost estimation (#223)
* Password reset back button also after confirmation

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>

* Implement a filter for category (#215)

- Also implement an is empty/is null condition.

* Implement an LLM cost estimation page

Track costs across all the cost categories: auto categorization, auto merchant detection and chat.
Show warning with estimated cost when running a rule that contains AI.

* Update pricing

* Add google pricing

and fix inferred model everywhere.

* Update app/models/llm_usage.rb

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: soky srm <sokysrm@gmail.com>

* FIX address review

* Linter

* Address review

- Lowered log level
- extracted the duplicated record_usage method into a shared concern

* Update app/controllers/settings/llm_usages_controller.rb

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: soky srm <sokysrm@gmail.com>

* Moved attr_reader out of private

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Signed-off-by: soky srm <sokysrm@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-24 00:08:59 +02:00
Mark Hendriksen
5f97f2fc4d Add new date format and 10-year period option (#154)
Added 'YYYYMMDD' to supported date formats in Family model.
Introduced a 'last_10_years' period option in Period model with appropriate labels and date range.
2025-09-22 09:21:06 +02:00
Himmelschmidt
7e36b1c7c5 Feature/simplefin integration (#94)
* Add HTTParty gem for SimpleFin API integration

- Add HTTParty gem for making HTTP requests to SimpleFin API
- Required for SimpleFin protocol implementation

* Add SimpleFin database schema

- Create simplefin_items table for SimpleFin connections
- Create simplefin_accounts table for account metadata
- Add simplefin_account_id to accounts table for linking
- Add external_id to transactions for deduplication
- Enable encrypted storage of SimpleFin access URLs

* Implement SimpleFin API client and data models

- Add SimplefinItem model with sync capabilities and encryption
- Add SimplefinAccount model for account data mapping
- Implement Provider::Simplefin API client with token exchange
- Add SimpleFin protocol support with proper error handling
- Include sync jobs, importers, and processors for data flow
- Add family SimpleFin connectivity mixin

* Update core models for SimpleFin integration

- Add SimpleFin account creation methods to Account model
- Implement intelligent account type mapping from names
- Add SimpleFin linkable functionality to Account
- Include SimpleFin items in Family model associations
- Support account creation with user-selected types

* Add SimpleFin controllers and routing

- Create SimplefinItemsController with CRUD operations
- Add account setup flow with user type selection
- Include sync management and error handling
- Update AccountsController to display SimpleFin items
- Add routes for SimpleFin item management and setup

* Add SimpleFin user interface components

- Create SimpleFin connection management views
- Add account setup modal with type selection
- Include connection form with token input and instructions
- Update accounts index to display SimpleFin items
- Add SimpleFin option to account method selector
- Include SimpleFin in settings navigation

* Add user account type selection workflow

- Add pending_account_setup field to SimpleFin items
- Enable pausing sync for user account type selection
- Allow users to choose account types during import
- Prevent automatic account creation until user confirms

* Add tests for SimpleFin integration

- Add SimplefinItem model tests with fixtures
- Add SimplefinAccount model tests
- Add SimplefinItemsController tests
- Include test coverage for sync and account creation

* Fix account show page for SimpleFin accounts

- Update sync button routing to handle SimpleFin accounts
- Add SimpleFin item sync path alongside existing Plaid support
- Prevent NoMethodError when viewing SimpleFin-linked accounts
- Support proper sync routing for Plaid, SimpleFin, and manual accounts

* Complete subtype selection for SimpleFin accounts

- Add subtype database columns to all accountable models
- Create Stimulus controller for dynamic subtype dropdown interaction
- Add delegation from Account to accountable subtype for clean API access
- Update SimpleFin account setup form with working subtype selection
- Fix account display to show proper subtype labels instead of generic "Cash"

Users can now select both account type and subtype during SimpleFin import,
and the selected subtypes are properly saved and displayed in the UI.

* Fix dark mode compatibility for SimpleFin UI components

- Replace hardcoded colors with design system tokens throughout SimpleFin views
- Fix method selector hover states to use bg-surface instead of bg-gray-50
- Update SimpleFin form to use styled_form_with and standard form patterns
- Replace custom button styling with design system button components
- Fix info boxes and containers to use bg-surface and border-primary
- Replace hardcoded green/blue colors with text-primary, text-secondary, text-link
- Remove custom text area styling to allow form builder defaults (dark mode support)

All SimpleFin components now properly adapt to both light and dark themes
with correct contrast and visibility.

* Fix SimpleFin integration bugs and improve code quality

- Fix upsert method to handle string/symbol keys with indifferent access
- Add missing show route and view for SimpleFin items
- Fix test fixtures to use correct user references
- Update test data to match real-world JSON format (string keys, BigDecimal)
- Apply code formatting and linting fixes (rubocop, erb_lint)
- Ensure all SimpleFin tests pass (16/16 passing)

* Remove SimpleFin demo file with outdated setup token

* Update SimpleFin User-Agent to use Sure Finance branding

* Remove unused SimpleFin account type mapping logic

- Remove map_simplefin_type_to_accountable_type method (no longer needed)
- Remove create_from_simplefin_account method (manual setup only)
- Simplify account type selection UI to not pre-select defaults
- Update processor to log error if account missing (safety check)
- All account creation now goes through manual user selection flow

* Gate SimpleFin option behind US region check

SimpleFin is primarily for North American financial institutions,
so only show the option when US banking connections are available.

* Refactor SimpleFin controller to use model method

- Move SimpleFin item creation logic from controller to Family#create_simplefin_item!
- Remove duplication between controller and model
- Simplify controller to focus on web request/response handling
- Remove unused simplefin_provider method
- Follow Rails best practices for fat models, skinny controllers

* Fix critical data integrity issue in SimpleFin date parsing

- Remove fallback to Date.current when transaction dates fail to parse
- Raise ArgumentError instead to ensure data integrity
- Log detailed error messages for debugging
- Skip transactions with invalid dates rather than using incorrect dates
- Prevents hard-to-debug issues with balances and financial reports

* Address all Gemini code review feedback for SimpleFin integration

- Remove debug console.log statements from JavaScript controller
- Consolidate duplicate SimpleFin account creation methods into single method
- Refactor SimplefinItemsController to reduce complexity with helper methods
- Fix HTTParty thread-safety by moving SSL options to class level
- Remove redundant HTTParty options from individual requests
- Add proper error logging for invalid currency URIs
- Extract sync button path logic to AccountsHelper#sync_path_for method
- DRY up repeated subtype dropdown code with reusable partial and data structure

All SimpleFin tests passing (16/16). Code quality improvements maintain
backward compatibility while following Rails best practices.

* Fix tests for subtype delegation to accountable models

The subtype attribute was moved from Account to individual accountable models
to enable users to select specific subtypes during SimpleFin account import.
This change allows for better account categorization and more precise display
of account types (e.g., "HSA" instead of generic "Cash").

However, tests and the PlaidAccount processor weren't updated to work with
the new delegation pattern. This commit fixes:

- PlaidAccount::Processor now sets subtype on accountable and uses enrichable
  pattern to respect user locks
- PropertiesController updated to handle subtype via accountable_attributes
- Test fixtures corrected to set subtype on accountable models not Account
- Tests updated to work with the delegated subtype pattern

All originally failing tests now pass:
- PropertiesControllerTest#test_updates_property_overview
- PlaidAccount::ProcessorTest (2 failing tests)
- AccountTest#test_gets_short/long_subtype_label

* Fix trailing whitespace (rubocop auto-fix)

* Add option to "skip" adding an account

* Revert "Gate SimpleFin option behind US region check"

This reverts commit 43b339940b.

* Fix SimpleFin transaction syncing and clean up debug logging

- Fix transaction creation to use Entry/entryable pattern instead of creating Transaction directly
- Handle both string and symbol keys in transaction data using with_indifferent_access
- Fix amount parsing to use BigDecimal instead of converting to cents
- Use plaid_id field for external ID storage to prevent duplicates
- Remove excessive debug logging while keeping essential error logging

SimpleFin transaction sync now works correctly, creating proper Entry records
with accurate dollar amounts and preventing duplicate transactions.

* Not sure how skipping worked for me the first time

* Fix SimpleFin new account setup flow and UI dark mode issues

- Fix accounts showing as 'unknown' by displaying proper account type from Account model
- Fix new accounts in existing connections not triggering setup flow with correct query
- Fix dark mode colors throughout SimpleFin views using design system tokens
- Improve UI logic to show existing accounts alongside new account setup prompt
- Remove balance attribute error when creating CreditCard accounts
- Simplify CreditCard subtype selection (auto-default to credit_card)

* Fix linter issues (trailing whitespace and ERB formatting)

* Remove SimpleFin button from create accounts view

SimpleFin doesn't work like Plaid - no need for separate connection creation for new accounts, just refresh existing connection.

* Add missing SimpleFin attributes and fix balance attribute error

- Add balance_date field to SimpleFin accounts to capture balance timestamp from protocol
- Enhanced build_simplefin_accountable_attributes to set available_credit for CreditCard accounts
- Fixed model mismatch where balance was being set on accountable models instead of Account model
- Updated tests to verify balance_date parsing functionality

This addresses the balance attribute error from commit 6681537b and ensures we're capturing
all available SimpleFin protocol data properly.

* Store all SimpleFin protocol fields in JSONB following existing patterns

* Fix SimpleFin API date parameter format and improve error handling

- Change date parameters from string format to Unix timestamps as required by SimpleFin API
- Add better error handling for 400 Bad Request responses
- Add more detailed error logging for debugging failed API calls

This fixes the issue where SimpleFin was only returning recent transactions
instead of historical data when start_date was provided.

* Implement comprehensive historical transaction sync for SimpleFin

- Add start_date parameter to SimpleFin API calls for historical data
- Use 100-year lookback for first sync to capture all available history
- Use 7-day buffer for incremental syncs to catch late-posting transactions
- Fix transaction storage to prevent data loss during account updates
- Remove verbose logging for cleaner output

This ensures users get all their historical transactions on first sync,
not just recent ones.

* Fix SimpleFin transaction sign convention to match Maybe's format

- Negate SimpleFin amounts to convert from banking convention to Maybe's format
- SimpleFin: expenses negative, income positive (banking convention)
- Maybe: expenses positive, income negative (internal convention)
- Improve date parsing to handle multiple date formats (Unix timestamps, strings, Date objects)

This fixes the issue where expenses showed as negative in the UI instead of positive.

* Add SimpleFin account association and fix balance handling for liabilities

- Add belongs_to :simplefin_account association to Account model
- Fix balance handling for credit cards and loans (use absolute value)
- SimpleFin returns negative balances for liabilities, but Maybe expects positive

This enables displaying organization names and ensures correct balance display.

* Display organization names throughout SimpleFin interface

- Show institution names under SimpleFin connection titles
- Display organization names next to account names (e.g., "360 Checking • Capital One")
- Add organization info to all SimpleFin account displays:
  - Account setup page
  - SimpleFin item details page
  - Regular account lists for SimpleFin accounts
- Use org_data from SimpleFin accounts with fallback to institution_name

This improves account identification by showing which financial institution
each account belongs to throughout the SimpleFin workflow.

* Fix SimpleFin UI styling to match design system

- Replace custom styles with DS components (DS::FilledIcon, DS::Link, DS::Button)
- Use proper design system tokens instead of hardcoded colors
- Fix form select styling to match design system patterns
- Update empty states to use consistent styling
- Ensure all SimpleFin views follow the app's design system

This makes the SimpleFin interface consistent with the rest of the app.

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-12 02:59:16 +02:00
Vincent Teo
d04c87449d feat: split provider check and remove hardcoded synth check (#45) 2025-08-01 08:07:34 +02:00
Zach Gollwitzer
0329a5f211 Data exports (#2517)
* Import / export UI

* Data exports

* Lint fixes, brakeman update
2025-07-24 10:50:05 -04:00
Zach Gollwitzer
662f2c04ce Multi-step account forms + clearer balance editing (#2427)
* Initial multi-step property form

* Improve form structure, add optional tooltip help icons to form fields

* Add basic inline alert component

* Clean up and improve property form lifecycle

* Implement Account status concept

* Lint fixes

* Remove whitespace

* Balance editing, scope updates for account

* Passing tests

* Fix brakeman warning

* Remove stale columns

* data constraint tweaks

* Redundant property
2025-07-03 09:33:07 -04:00
Zach Gollwitzer
1aae00f586 perf(transactions): add kind to Transaction model and remove expensive Transfer joins in aggregations (#2388)
* add kind to transaction model

* Basic transfer creator

* Fix method naming conflict

* Creator form pattern

* Remove stale methods

* Tweak migration

* Remove BaseQuery, write entire query in each class for clarity

* Query optimizations

* Remove unused exchange rate query lines

* Remove temporary cache-warming strategy

* Fix test

* Update transaction search

* Decouple transactions endpoint from IncomeStatement

* Clean up transactions controller

* Update cursor rules

* Cleanup comments, logic in search

* Fix totals logic on transactions view

* Fix pagination

* Optimize search totals query

* Default to last 30 days on transactions page if no filters

* Decouple transactions list from transfer details

* Revert transfer route

* Migration reset

* Bundle update

* Fix matching logic, tests

* Remove unused code
2025-06-20 13:31:58 -04:00
Zach Gollwitzer
10ce2c8e23 Balance sheet cache layer, non-blocking sync UI (#2356)
* Balance sheet cache layer with cache-busting

* Update family cache timestamps during Sync

* Less blocking sync loaders

* Consolidate family data caching key logic

* Fix turbo stream broadcasts

* Remove dev delay

* Add back account group sorting
2025-06-10 18:20:06 -04:00
Josh Pigford
870b543640 Refactor syncing? method in Family model to optimize query performance. Moved visible scope to the beginning and adjusted joins and where conditions to leverage composite indexing for improved efficiency. 2025-06-01 06:30:38 -05:00
Zach Gollwitzer
9f13b5bb83 Handle stale syncs (#2257)
* Handle stale syncs

* Use `visible` sync logic in sidebar groups
2025-05-17 18:28:21 -04:00
Zach Gollwitzer
10dd9e061a Improve account sync performance, handle concurrent market data syncing (#2236)
* PlaidConnectable concern

* Remove bad abstraction

* Put sync implementations in own concerns

* Sync strategies

* Move sync orchestration to Sync class

* Clean up sync class, add state machine

* Basic market data sync cron

* Fix price sync

* Improve sync window column names, add timestamps

* 30 day syncs by default

* Clean up market data methods

* Report high duplicate sync counts to Sentry

* Add sync states throughout app

* account tab session

* Persistent account tab selections

* Remove manual sleep

* Add migration to clear stale syncs on self hosted apps

* Tweak sync states

* Sync completion event broadcasts

* Fix timezones in tests

* Cleanup

* More cleanup

* Plaid item UI broadcasts for sync

* Fix account ID namespace conflict

* Sync broadcasters

* Smoother account sync refreshes

* Remove test sync delay
2025-05-15 10:19:56 -04:00
Zach Gollwitzer
9e6e4b1ce6 Only run Plaid syncs via webhook after initial sync 2025-05-12 18:55:19 -04:00
Zach Gollwitzer
ab2cec55e7 Propagate child sync errors up to parent, fix sync status (#2232)
* Propagate child sync errors up to parent, fix sync status

* Remove testing error
2025-05-09 14:56:49 -04:00
Zach Gollwitzer
a07e9d40a3 Transactional locks for sync completions (#2219)
* Transactional locks for sync completions

* Lower sync display logic tolerance in UI
2025-05-07 16:28:58 -04:00
Zach Gollwitzer
5da4bb6dc3 Subscription tests and domain (#2209)
* Save work

* Subscriptions and trials domain

* Store family ID on customer

* Remove indirection of stripe calls

* Test simplifications

* Update brakeman

* Fix stripe tests in CI

* Update billing page to show subscription details

* Remove legacy columns

* Complete billing settings page

* Fix hardcoded plan name

* Handle subscriptions for self hosting mode

* Lint fixes
2025-05-06 14:05:21 -04:00
Zach Gollwitzer
a51c4d2cba New onboarding, trials, Stripe integration (#2185)
* New onboarding, trials, Stripe integration

* Fix tests

* Lint fixes

* Fix subscription endpoints
2025-05-01 16:47:14 -04:00
Zach Gollwitzer
90a9546f32 Pre-launch design sync with Figma spec (#2154)
* Add lookbook + viewcomponent, organize design system file

* Build menu component

* Button updates

* More button fixes

* Replace all menus with new ViewComponent

* Checkpoint: fix tests, all buttons and menus converted

* Split into Link and Button components for clarity

* Button cleanup

* Simplify custom confirmation configuration in views

* Finalize button, link component API

* Add toggle field to custom form builder + Component

* Basic tabs component

* Custom tabs, convert all menu / tab instances in app

* Gem updates

* Centralized icon helper

* Update all icon usage to central helper

* Lint fixes

* Centralize all disclosure instances

* Dialog replacements

* Consolidation of all dialog styles

* Test fixes

* Fix app layout issues, move to component with slots

* Layout simplification

* Flakey test fix

* Fix dashboard mobile issues

* Finalize homepage

* Lint fixes

* Fix shadows and borders in dark mode

* Fix tests

* Remove stale class

* Fix filled icon logic

* Move transparent? to public interface
2025-04-30 18:14:22 -04:00
Zach Gollwitzer
297a695d0f Transaction rules engine V1 (#1900)
* Domain model sketch

* Scaffold out rules domain

* Migrations

* Remove existing data enrichment for clean slate

* Sketch out business logic and basic tests

* Simplify rule scope building and action executions

* Get generator working again

* Basic implementation + tests

* Remove manual merchant management (rules will replace)

* Revert "Remove manual merchant management (rules will replace)"

This reverts commit 83dcbd9ff0aa7bbee211796b71aa48b71df5e57e.

* Family and Provider merchants model

* Fix brakeman warnings

* Fix notification loader

* Update notification position

* Add Rule action and condition registries

* Rule form with compound conditions and tests

* Split out notification types, add CTA type

* Rules form builder and Stimulus controller

* Clean up rule registry domain

* Clean up rules stimulus controller

* CTA message for rule when user changes transaction category

* Fix tests

* Lint updates

* Centralize notifications in Notifiable concern

* Implement category rule prompts with auto backoff and option to disable

* Fix layout bug caused by merge conflict

* Initialize rule with correct action for category CTA

* Add rule deletions, get rules working

* Complete dynamic rule form, split Stimulus controllers by resource

* Fix failing tests

* Change test password to avoid chromium conflicts

* Update integration tests

* Centralize all test password references

* Add re-apply rule action

* Rule confirm modal

* Run migrations

* Trigger rule notification after inline category updates

* Clean up rule styles

* Basic attribute locking for rules

* Apply attribute locks on user edits

* Log data enrichments, only apply rules to unlocked attributes

* Fix merge errors

* Additional merge conflict fixes

* Form UI improvements, ignore attribute locks on manual rule application

* Batch AI auto-categorization of transactions

* Auto merchant detection, ai enrichment in batches

* Fix Plaid merchant assignments

* Plaid category matching

* Cleanup 1

* Test cleanup

* Remove stale route

* Fix desktop chat UI issues

* Fix mobile nav styling issues
2025-04-18 11:39:58 -04:00
Zach Gollwitzer
8648f11413 Sync hierarchy updates (#2087)
* Add parent sync orchestration

* Pass sync object to dependents
2025-04-11 12:13:46 -04:00
Zach Gollwitzer
2f6b11c18f Personal finance AI (v1) (#2022)
* AI sidebar

* Add chat and message models with associations

* Implement AI chat functionality with sidebar and messaging system

- Add chat and messages controllers
- Create chat and message views
- Implement chat-related routes
- Add message broadcasting and user interactions
- Update application layout to support chat sidebar
- Enhance user model with initials method

* Refactor AI sidebar with enhanced chat menu and interactions

- Update sidebar layout with dynamic width and improved responsiveness
- Add new chat menu Stimulus controller for toggling between chat and chat list views
- Improve chat list display with recent chats and empty state
- Extract AI avatar to a partial for reusability
- Enhance message display and interaction styling
- Add more contextual buttons and interaction hints

* Improve chat scroll behavior and message styling

- Refactor chat scroll functionality with Stimulus controller
- Optimize message scrolling in chat views
- Update message styling for better visual hierarchy
- Enhance chat container layout with flex and auto-scroll
- Simplify message rendering across different chat views

* Extract AI avatar to a shared partial for consistent styling

- Refactor AI avatar rendering across chat views
- Replace hardcoded avatar markup with a reusable partial
- Simplify avatar display in chats and messages views

* Update sidebar controller to handle right panel width dynamically

- Add conditional width class for right sidebar panel
- Ensure consistent sidebar toggle behavior for both left and right panels
- Use specific width class for right panel (w-[375px])

* Refactor chat form and AI greeting with flexible partials

- Extract message form to a reusable partial with dynamic context support
- Create flexible AI greeting partial for consistent welcome messages
- Simplify chat and sidebar views by leveraging new partials
- Add support for different form scenarios (chat, new chat, sidebar)
- Improve code modularity and reduce duplication

* Add chat clearing functionality with dynamic menu options

- Implement clear chat action in ChatsController
- Add clear chat route to support clearing messages
- Update AI sidebar with dropdown menu for chat actions
- Preserve system message when clearing chat
- Enhance chat interaction with new menu options

* Add frontmatter to project structure documentation

- Create initial frontmatter for structure.mdc file
- Include description and configuration options
- Prepare for potential dynamic documentation rendering

* Update general project rules with additional guidelines

- Add rule for using `Current.family` instead of `current_family`
- Include new guidelines for testing, API routes, and solution approach
- Expand project-specific rules for more consistent development practices

* Add OpenAI gem and AI-friendly data representations

- Add `ruby-openai` gem for AI integration
- Implement `to_ai_readable_hash` methods in BalanceSheet and IncomeStatement
- Include Promptable module in both models
- Add savings rate calculation method in IncomeStatement
- Prepare financial models for AI-powered insights and interactions

* Enhance AI Financial Assistant with Advanced Querying and Debugging Capabilities

- Implement comprehensive AI financial query system with function-based interactions
- Add detailed debug logging for AI responses and function calls
- Extend BalanceSheet and IncomeStatement models with AI-friendly methods
- Create robust error handling and fallback mechanisms for AI queries
- Update chat and message views to support debug mode and enhanced rendering
- Add AI query routes and initial test coverage for financial assistant

* Refactor AI sidebar and chat layout with improved structure and comments

- Remove inline AI chat from application layout
- Enhance AI sidebar with more semantic HTML structure
- Add descriptive comments to clarify different sections of chat view
- Improve flex layout and scrolling behavior in chat messages container
- Optimize message rendering with more explicit class names and structure

* Add Markdown rendering support for AI chat messages

- Implement `markdown` helper method in ApplicationHelper using Redcarpet
- Update message view to render AI messages with Markdown formatting
- Add comprehensive Markdown rendering options (tables, code blocks, links)
- Enhance AI Financial Assistant prompt to encourage Markdown usage
- Remove commented Markdown CSS in Tailwind application stylesheet

* Missing comma

* Enhance AI response processing with chat history context

* Improve AI debug logging with payload size limits and internal message flag

* Enhance AI chat interaction with improved thinking indicator and scrolling behavior

* Add AI consent and enable/disable functionality for AI chat

* Upgrade Biome and refactor JavaScript template literals

- Update @biomejs/biome to latest version with caret (^) notation
- Refactor AI query and chat controllers to use template literals
- Standardize npm scripts formatting in package.json

* Add beta testing usage note to AI consent modal

* Update test fixtures and configurations for AI chat functionality

- Add family association to chat fixtures and tests
- Set consistent password digest for test users
- Enable AI for test users
- Add OpenAI access token for test environment
- Update chat and user model tests to include family context

* Simplify data model and get tests passing

* Remove structure.mdc from version control

* Integrate AI chat styles into existing prose pattern

* Match Figma design spec, implement Turbo frames and actions for chats controller

* AI rules refresh

* Consolidate Stimulus controllers, thinking state, controllers, and views

* Naming, domain alignment

* Reset migrations

* Improve data model to support tool calls and message types

* Tool calling tests and fixtures

* Tool call implementation and test

* Get assistant test working again

* Test updates

* Process tool calls within provider

* Chat UI back to working state again

* Remove stale code

* Tests passing

* Update openai class naming to avoid conflicts

* Reconfigure test env

* Rebuild gemfile

* Fix naming conflicts for ChatResponse

* Message styles

* Use OpenAI conversation state management

* Assistant function base implementation

* Add back thinking messages, clean up error handling for chat

* Fix sync error when security price has bad data from provider

* Add balance sheet function to assistant

* Add better function calling error visibility

* Add income statement function

* Simplify and clean up "thinking" interactions with Turbo frames

* Remove stale data definitions from functions

* Ensure VCR fixtures working with latest code

* basic stream implementation

* Get streaming working

* Make AI sidebar wider when left sidebar is collapsed

* Get tests working with streaming responses

* Centralize provider error handling

* Provider data boundaries

---------

Co-authored-by: Josh Pigford <josh@joshpigford.com>
2025-03-28 13:08:22 -04:00
Zach Gollwitzer
f65b93a352 Data provider simplification, tests, and documentation (#1997)
* Ignore env.test from source control

* Simplification of providers interface

* Synth tests

* Update money to use new find rates method

* Remove unused issues code

* Additional issue feature removals

* Update price data fetching and tests

* Update documentation for providers

* Security test fixes

* Fix self host test

* Update synth usage data access

* Remove AI pr schema changes
2025-03-17 11:54:53 -04:00