mirror of
https://github.com/we-promise/sure.git
synced 2026-04-06 22:11:23 +00:00
main
2356 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
48ae618316 |
Update ruby-lsp-rails 0.4.6 → 0.4.8 and ruby-lsp 0.24.1 → 0.26.9 (#1389)
* Update ruby-lsp-rails 0.4.6 → 0.4.8 and ruby-lsp 0.24.1 → 0.26.9 Relaxes the strict ruby-lsp dependency from (>= 0.24.0, < 0.25.0) to (>= 0.26.0, < 0.27.0). Also drops the no-longer-needed sorbet-runtime transitive dependency. https://claude.ai/code/session_01JeygD1gvjJ4eh9SmpW7xGf * Broad-ignore Pipelock check for now --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
616c363b3e |
Enable selenium service in devcontainer for system tests (#1340)
Co-authored-by: Pedro J. Aramburu <pedro@joakin.dev> |
||
|
|
246cd00cbb |
collect transaction stats after sync in EnableBanking provider (#1388)
* collect transaction stats after sync in EnableBanking provider * update logic to follow the pattern used by other bank providers * fix n+1 issue * fix N+1 issues |
||
|
|
38d2ac21d0 |
Fix version number of v0.7.0-alpha-* builds
|
||
|
|
78b334277c |
QIF imports: Add date format auto-detection and manual override (#1368)
* feat: improve QIF import date format selection - Added a reusable date format auto-detection method. - Show a live preview of the first parsed date that updates client-side as the user changes the dropdown selection, via a new qif-date-format Stimulus controller. - Show an error alert and disable the submit button when no supported date format can parse the file's dates. * A few polishing fixes: - Missing return on redirects Stale REASONABLE_DATE_RANGE constant. - Replaced the frozen constant with a class method Bare inline rescue — Replaced Date.strptime(s, fmt) rescue nil with an explicit begin/rescue catching. - save!(validate: false) in controller — Changed to update_column(:column_mappings, ...) in qif_category_selections_controller.rb:22, matching the pattern used in detect_and_set_qif_date_format!. - Unescaped JSON in HTML attribute — Replaced the raw <div> with tag.div ... do block in show.html.erb:16, letting Rails properly escape the data attribute value. * fix: address review feedback for QIF date format feature - Add missing `return` after redirect for non-QIF imports - Pass date_format to parse_opening_balance in will_adjust_opening_anchor? - Return empty array when no usable date sample exists for format preview - Add sr-only label to date format select for accessibility - Consolidate duplicate try_parse_date/parse_qif_date into single method - Remove misleading ambiguity scoring comment from detect_date_format - Skip redundant sync_mappings when date format already triggered a sync Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use %{product_name} interpolation in locale strings --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
a76aa340d5 |
fix: prevent NoMethodError in foreign_account? when account family is nil (#1376)
Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com> |
||
|
|
7f3b12107b |
fix: resolve flaky chats system test race condition (#1375)
Wait for the chat to fully load after click before triggering a page refresh, ensuring last_viewed_chat is persisted server-side. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
281197f918 |
Fix opacity for excluded transactions and implement keyboard navigation (#1332)
* Make category selection menus opaque for excluded transactions * Allow keyboard navigation in category selection menu * Fix category transparency on mobile * Make checkbox opaque * Remove text-secondary from amount container * Submit form directly * Handle aria labels |
||
|
|
94e7f7f0a0 | fix: enhance text contrast for headings, and paragraphs in blockquotes in dark mode on the Guide page (#1369) | ||
|
|
c26bf484fb | fix(ui): move repeat icon to the center (#1365) | ||
|
|
0dd3990502 | fix: preserve wrapped rule import json values (#1358) | ||
|
|
6d7ae0aa8a |
Fix: target="_blank" to contact button (#1359)
Co-authored-by: yunwei-zh <tspl.fin.guru@gmail.com> |
||
|
|
185d624889 | Bump version to next iteration after v0.7.0-alpha.1 release | ||
|
|
d6183be1ae |
fix: instantiate RuleImport before generating rows (#1354)
* fix: instantiate RuleImport before generating rows * test: use API keys in imports controller testsv0.7.0-alpha.1 |
||
|
|
d49e74b854 |
Restore monotonic Android versionCode for mobile releases (#1348)
* Initial plan * fix: bump Android mobile versionCode Agent-Logs-Url: https://github.com/we-promise/sure/sessions/c7b35fa9-a638-489b-803f-a935ccd7a301 Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> * Versioning YYYMMDD * Remove (new) brittle test --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> Co-authored-by: Juan José Mata <jjmata@jjmata.com> |
||
|
|
9a1cd1130a |
Update _form.html.erb (#1343)
@dosubots suggested fix Signed-off-by: Derek Brown <browndw4@gmail.com> |
||
|
|
ea49c988b9 |
Update Docker Compose file for AI optional features (#1349)
* Guard docs workflow to upstream repo Agent-Logs-Url: https://github.com/jjmata/sure/sessions/230a651a-b564-49fa-9563-4986fc5f2c13 Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> * Limit docs workflow token permissions Agent-Logs-Url: https://github.com/jjmata/sure/sessions/230a651a-b564-49fa-9563-4986fc5f2c13 Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> * Add OpenClaw service to AI compose example * Adjust OpenClaw compose and Pipelock defaults * Keep OpenClaw gateway running when unconfigured * Include Ollama in external-assistant profile * Tidy up language/simplify names * Make `profile` name more explicit (local-ai) * Clarify `local-ai` is included in OpenClaw profile * Correct internal roting for OpenClaw --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> |
||
|
|
8ed69132cf |
fix: add hex color validation to Category model and form (to solve #1247) (#1341)
- Added server-side validation to Category model to enforce 6-digit hex format for colors. - Added HTML pattern attribute to category form for client-side validation. - Updated tests to cover validation and fixed existing tests using shorthand hex colors. |
||
|
|
a90f9b7317 |
Add CoinStats exchange portfolio sync and normalize linked investment charts (#1308)
* [FEATURE] Add CoinStats exchange portfolios and normalize linked investment charts * [BUGFIX] Fix CoinStats PR regressions * [BUGFIX] Fix CoinStats PR review findings * [BUGFIX] Address follow-up CoinStats PR feedback * [REFACTO] Extract CoinStats exchange account helpers * [BUGFIX] Batch linked CoinStats chart normalization * [BUGFIX] Fix CoinStats processor lint --------- Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: Juan José Mata <juanjo.mata@gmail.com> |
||
|
|
f63630c0fa |
Fix NoMethodError on nil accountable for logo color (#1334)
Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com> |
||
|
|
43d617661f |
Missing translation fallback for account subtypes (#1325)
* Fix missing translation fallback for account subtypes in LunchFlow and Mercury The translate_subtypes lambda called t() without a default: fallback, causing "Translation missing" for the ~39 investment subtypes not in the locale files. Now falls back to the :long label from the model's SUBTYPES hash (e.g. "457(b)", "SEP IRA", "UGMA Custodial Account"), matching the pattern used by Accountable#subtype_label_for. https://claude.ai/code/session_01HBJzNkvpky8mKrLkzv83Mm * Default to single-column dashboard --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
8970211476 | LunchFlow referral codes | ||
|
|
861a2d2d91 |
Fix NoMethodError on nil entryable in account activity feed (#1316)
* Fix NoMethodError when entry has nil entryable Guard against orphaned entries where the entryable record has been deleted but the entry still exists, preventing a crash on the account show page. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add dependent: :destroy to Entryable has_one :entry The polymorphic has_one :entry association lacked a dependent option, meaning if a Transaction/Trade/Valuation was ever deleted directly (bypassing the Entry), the Entry would be left orphaned with a nil entryable — causing NoMethodError in the activity feed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add nil entryable guard to _split_group.html.erb Same defensive check as _entry.html.erb for consistency. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
c14ba6d0c9 |
FIX (#1315)
- split transaction mobile input - privacy for day totals |
||
|
|
ab9b97639b |
Record dividends and interest as Trades in investment accounts (#1311)
* Record dividends and interest as Trades in investment accounts
All investment income (dividends and interest) is now modeled as a
Trade with qty: 0 and price: 0, keeping security_id NOT NULL on trades
intact. Dividends require a security; interest falls back to a
per-account synthetic cash security (kind: "cash", offline: true) when
none is selected, matching how brokerages handle uninvested cash
internally.
- Add `kind` column to securities ("standard" | "cash") with DB check
constraint; `Security.cash_for(account)` lazily finds or creates the
synthetic cash security; `scope :standard` excludes synthetic
securities from user-facing pickers
- Trade::CreateForm: new `dividend` type (security required); `interest`
now creates a Trade instead of a Transaction
- Trade form: Dividend and Interest in the type dropdown with a security
combobox (required for dividend, optional for interest)
- transactions table: untouched
* UI fixes
* HealthChecker — both scopes now chain .standard to exclude cash securities from provider health checks.
DB query moved to model — Account#traded_standard_securities in app/models/account.rb, view uses account.traded_standard_securities.
DRY income creation — create_income_trade(sec:, label:, name:) extracted as shared private method; create_dividend_income and create_interest_income delegate to it.
show.html.erb blocks merged — single unless trade.qty.zero? block covers qty/price/fee fields.
Test extended — assert_response :unprocessable_entity added after the assert_no_difference block.
* Hide cash account ticker from no-security trade detail
* Fix CodeRabbit review issues from PR #1311
- Remove duplicate YAML keys in translation files (de, es, fr)
- Add error handling for security resolution in create_dividend_income
- Extract income trade check to reduce duplication in header template
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* Include holdings in dividend/interest security picker
The security picker for dividend/interest trades should include all securities
in holdings, not just those with trade history. This fixes the issue where
accounts with imported holdings (e.g., SimpleFIN) but no trades would have an
empty picker and be unable to record dividends.
Uses UNION to combine securities from both trades and holdings.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* scope picker to holdings only (a trade creates a holding anyway)
---------
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
|
||
|
|
cc7d675500 |
Add transaction fee support to trades (#1248)
Add an optional fee field (decimal, precision: 19, scale: 4) to trades. Fee is included in the total amount calculation (qty * price + fee) for both create and update flows. The fee field appears on both the create and edit forms, defaults to 0, and auto-submits like other trade fields. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
005d2fac20 |
Fix/issue 954 enable banking duplicate transactions (#988)
* fix: deduplicate Enable Banking API transactions with different entry_reference IDs (#954) Enable Banking API sometimes returns the same logical transaction multiple times with different entry_reference values in a single response. This causes duplicate entries because the existing ID-based deduplication treats them as distinct transactions. Add content-based deduplication that compares (date, amount, currency, creditor, debtor, remittance_information, status) to detect and remove these API-level duplicates before storing them. The first occurrence is kept. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: add Enable Banking processor and importer deduplication tests (#954) Add tests for: - EnableBankingEntry::Processor: verifies entry_reference fallback for external_id, idempotent re-processing, string key handling - EnableBankingItem::Importer: verifies content-based deduplication removes API-level duplicates while preserving legitimate distinct transactions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: handle nil values in remittance_information array for dedup key (#954) Call compact and map(&:to_s) before sort.join when remittance_information is an array, preventing ArgumentError when it contains nil elements. Also document the known limitation of content-based deduplication collapsing genuinely distinct identical transactions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: add coverage for nil values in remittance_information array (#954) Verify that deduplication handles remittance_information arrays containing nil elements without raising ArgumentError, and correctly treats arrays with different nil positions but same non-nil content as duplicates. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: prefer transaction_id over content-based dedup to preserve legit duplicates (#954) When transaction_id is present, use it as the dedup key instead of falling back to content-based deduplication. This preserves legitimately distinct transactions with identical content (e.g. two laundromat payments of the same amount on the same day) while still deduplicating the Enable Banking duplicate entry_reference issue when transaction_id is nil. Addresses review feedback from @jjmata about legitimate duplicate transactions being incorrectly collapsed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: use composite key for dedup instead of transaction_id alone (#954) Per the Enable Banking API docs, transaction_id is not guaranteed to be unique. Include it as one component of the composite content key rather than using it as the sole dedup criterion. This preserves transactions with non-unique transaction_ids but different content, while still deduplicating true API-level duplicates. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: add value_date fallback coverage for dedup key (#954) build_transaction_content_key falls back to value_date when booking_date is absent. This test exercises that path. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: document known limitation of content-based dedup (#954) When transaction_id is nil for both transactions, pure content comparison applies, which could theoretically collapse two genuinely distinct transactions with identical fields. Document this trade-off inline for future maintainers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: add credit_debit_indicator to dedup composite key (#954) transaction_amount.amount is always positive in the Enable Banking API, with direction encoded separately in credit_debit_indicator (CRDT/DBIT). Without it in the composite key, a payment and a same-day refund of the same amount to the same merchant would produce identical keys, silently dropping one transaction. - Add credit_debit_indicator to build_transaction_content_key - Add test for payment + same-day refund scenario - Update docstring to document the rationale Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
e7af0ad99b |
Added ca_file option to use the SSL_CA_FILE specified file if present (#1302)
* Added ca_file option to use the SSL_CA_FILE specified file if present * Per AI suggestion changed to reading env var directly` |
||
|
|
6a6548de64 |
feat(mobile): Add animated TypingIndicator for AI chat responses (#1269)
* feat(mobile): Add animated TypingIndicator widget for AI chat responses Replaces the static CircularProgressIndicator + "AI is thinking..." text with an animated TypingIndicator showing pulsing dots while the AI generates a response. Respects the app color scheme so it works in light and dark themes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix: Normalize stagger progress to [0,1) in TypingIndicator to prevent negative opacity Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(mobile): fix typing indicator visibility and run pub get The typing indicator was only visible for the duration of the HTTP POST (~instant) because it was tied to `isSendingMessage`. It now tracks the full AI response lifecycle via a new `isWaitingForResponse` state that stays true through polling until the response stabilises. - Add `isWaitingForResponse` to ChatProvider; set on poll start, clear on poll stop with notifyListeners so the UI reacts correctly - Move TypingIndicator inside the ListView as an assistant bubble so it scrolls naturally with the conversation - Add provider listener that auto-scrolls on every update while waiting for a response - Redesign TypingIndicator: 3-dot sequential bounce animation (classic chat style) replacing the simultaneous fade * feat(mobile): overhaul new-chat flow and fix typing indicator bugs chat is created lazily on first send, eliminating all pre-conversation flashes and crashes - Inject user message locally into _currentChat immediately on createChat so it renders before the first poll completes - Hide thinking indicator the moment the first assistant content arrives (was waiting one extra 2s poll cycle before disappearing) - Fix double-spinner on new chat: remove manual showDialog spinner and use a local _isCreating flag on the FAB instead * fix(mboile) : address PR review — widget lifecycle safety and new-chat regression * Fic(mobile): Add mounted check in post-frame callback --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
b1fd8bbc99 |
Mobile: Add theme selection (light/dark/system) to settings (#1213)
* Feature: Add Theme selection in Settings page * Fix: Theme provider exception handling. * feat(mobile): Show theme selection option in settings screen. * BuildID version 9 --------- Co-authored-by: Juan José Mata <juanjo.mata@gmail.com> |
||
|
|
f42b593b9e |
Show inflow/outflow totals for transfer filter (#1134)
* Show inflow/outflow totals when filtering by transfers When filtering transactions by "Transfer" type, the summary bar previously showed $0 for both Income and Expenses because transfers were excluded from those sums. Now computes transfer inflow/outflow in the same SQL pass and switches labels to "Inflow"/"Outflow" when transfer amounts are non-zero. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add mixed filter comment and transfer-only test coverage Document the intentional mixed filter behavior where transfer amounts are excluded from the summary bar when non-transfer types are present. Add test exercising Inflow/Outflow label switching for transfer-only results. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
f1991eaefe |
Recurring scoping implementation (#1300)
* Recurring scoping implementation * FIX tests and reviews |
||
|
|
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 |
||
|
|
1627cf197b |
Sort import account dropdown alphabetically (#1290)
Co-authored-by: r-jeffries <r-jeffries@users.noreply.github.com> |
||
|
|
1527611239 |
Default production SSO provider source to YAML to avoid boot-time schema errors (#1278)
* Initial plan * Default production SSO provider source to YAML Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> Agent-Logs-Url: https://github.com/we-promise/sure/sessions/d3a36ca8-e936-4687-a466-9b4c93c19150 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> |
||
|
|
eb34a2f9de | Added option to skip TLS verification for mailer (#1291) | ||
|
|
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. |
||
|
|
6cf7d20010 |
Perf: Index Balance::SyncCache lookups by date to eliminate O(N×D) scans (#1081)
* Perf: Index Balance::SyncCache lookups by date to eliminate O(N×D) scans Each call to get_holdings(date) and get_entries(date) previously did a linear scan over the full converted_holdings / converted_entries arrays. The balance calculators call these once per day across the full account history, making the overall complexity O(N×D) where N is the total number of holding/entry rows and D is the number of days in the account history. For a typical investment account (20 securities, 2 years of history): - Holdings: 20 × 730 = 14,600 rows - Balance loop: 730 date iterations - Comparisons: 14,600 × 730 ≈ 10.7 million per materialise run This change builds a hash index (grouped by date) once on first access and reuses it for all subsequent lookups, reducing per-call complexity to O(1). Total complexity becomes O(N) — load once, look up cheaply. Observed wall-clock improvement on a real account: ~36 s → ~5 s for a full Balance::Materializer run. The nightly sync benefits equally. No behavioural change: get_holdings, get_entries, and get_valuation return identical data — they are now just fetched via a hash key rather than a repeated array scan. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix: Return defensive copy from get_holdings to prevent cache mutation get_holdings was returning a direct reference to the internal cached array from holdings_by_date. A caller appending to the result (e.g. via <<) would silently corrupt the cache for all subsequent date lookups in the same materialise run. Use &.dup to return a shallow copy of the group array. Callers only read from the result (sum, map, etc.) so this has no behavioural impact and negligible performance cost. get_entries is already safe — Array#select always returns a new array. get_valuation returns a single object, not an array, so no issue there. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Remove unnecessary dup in get_holdings for consistency No caller mutates the returned array (only .sum is called), so the defensive copy is unnecessary overhead. This aligns get_holdings with get_entries and get_valuation which also return cached references directly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
b78944ed6f |
Fix selected account and Transaction/Transfer Tabs changes (#1220)
* Fix Dialog selected attribute had no effect * Fix New Transaction/Transfer Dialog * Update transfers_controller.rb --------- Co-authored-by: sokiee <sokysrm@gmail.com> |
||
|
|
fc987ededb |
Add Kosovo to country list (#1066)
Kosovo was missing from the COUNTRY_MAPPING in LanguagesHelper. Added Kosovo with ISO 3166-1 alpha-2 code XK and flag emoji 🇽🇰. The entry is placed in alphabetical order between Kuwait (KW) and Kyrgyzstan (KG) to maintain consistency with the existing list. Fix Investment account subtype not saving on creation (#1039) * Add permitted_accountable_attributes for investments * Include fields_for for accountable subtype selection feat: Add tag badge in filter window (#1038) * feat: Add tag badge in filter window * fix: validate Tag color attribute as hex format and increase transparency mix in border color * fix: use fallback for tag color fix/qol: Add Callback URL the Enable Banking Instructions (#1060) * fix/qol: Add wich Callback URL to use to the Enable Banking Instructions * CodeRabbit suggestion * CodeRabbit suggestion * Skip CI failure on findings --------- fix: Update PWA icons to use current logo (#1052) * fix: Update PWA icons to use current logo (#997) Replace outdated android-chrome-192x192.png and logo-pwa.png with the current logo. The old icons showed the previous branding (cyan border / old logomark) which appeared when creating web shortcuts on smartphones. Also add the 192x192 icon entry to the PWA manifest for better Android home screen icon support. * fix: Replace transparent background with solid #F9F9F9 in 192x192 PWA icon The android-chrome-192x192.png had an RGBA transparent background which can cause display issues on Android home-screen shortcuts. Regenerated with a solid #F9F9F9 background to match theme_color/background_color in the PWA manifest and the 512x512 icon. --------- Bump version to next iteration after v0.6.8-alpha.13 release Use Langfuse client trace upsert API (#1041) Replace direct trace.update calls with client trace upserts so OpenAI provider is compatible with langfuse-ruby 0.1.6 behavior. Add richer warning logs that include full exception details for trace creation, trace upserts, and generation logging failures. Add tests for client-based trace upserts and detailed error logging. Add build ID to Flutter app version display Add MCP server endpoint for external AI assistants (#1051) * Add MCP server endpoint for external AI assistants Expose Sure's Assistant::Function tools via JSON-RPC 2.0 at POST /mcp, enabling external AI clients (Claude, GPT, etc.) to query financial data through the Model Context Protocol. - Bearer token auth via MCP_API_TOKEN / MCP_USER_EMAIL env vars - JSON-RPC 2.0 with proper id threading, notification handling (204) - Transient session (sessions.build) to prevent impersonation leaks - Centralize function_classes in Assistant module - Docker Compose example with Pipelock forward proxy - 18 integration tests with scoped env (ClimateControl) * Update compose for full Pipelock MCP reverse proxy integration Use Pipelock's --mcp-listen/--mcp-upstream flags (PR #127) to run bidirectional MCP scanning in the same container as the forward proxy. External AI clients connect to port 8889, Pipelock scans requests (DLP, injection, tool policy) and responses (injection, tool poisoning) before forwarding to Sure's /mcp endpoint. This supersedes the standalone compose in PR #1050. * Fix compose --preset→--mode, add port 3000 trust comment, notification test Review fixes: - pipelock run uses --mode not --preset (would prevent stack startup) - Document port 3000 exposes /mcp directly (auth still required) - Add version requirement note for Pipelock MCP listener support - Add test: tools/call sent as notification does not execute 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 --------- Add Pipelock agent security scan to CI (#1049) * Add Pipelock agent security scan to CI Scans PR diffs for leaked secrets and agent security risks. Zero config, runs on every PR to main. * Retrigger CI (v1 action tag now available) * Harden checkout: persist-credentials false Pipelock only reads local git history for diff scanning, no auth token needed in .git/config. Improvements to Flutter client (#1042) * Chat improvements * Delete/reset account via API for Flutter app * Fix tests. * Add "contact us" to settings * Update mobile/lib/screens/chat_conversation_screen.dart * Improve LLM special token detection * Deactivated user shouldn't have API working * Fix tests * API-Key usage * Flutter app launch failure on no network * Handle deletion/reset delays * Local cached data may become stale * Use X-Api-Key correctly! --------- Skip unnecessary sync when account balance unchanged on update (#1040) The update action was calling set_current_balance (which triggers sync_later internally) on every form submission, even when the balance hadn't changed. This caused the account to enter a syncing state, replacing the visible balance with a pulsing skeleton placeholder until the sync completed. Now we compare the submitted balance against the current value and only call set_current_balance when it actually differs. Also removes a redundant sync_later call that duplicated the one already inside set_current_balance. feat: Add merchant logo in filter selection (#1037) * feat: Add merchant logo in filter selection * fix: move external div outside of if statement Sync Helm chart and Rails app versions in CI and release workflows (#1030) * Sync Helm chart and Rails app versions in CI and release workflows - values.yaml: default image.tag to "" so it uses Chart.appVersion (was hardcoded to stale "0.6.6" while app was at 0.6.8-alpha.13) - chart-ci.yml: add version-sync job that fails if version.rb, Chart.yaml version, and Chart.yaml appVersion diverge; trigger on version.rb changes too - chart-release.yml: derive chart version from version.rb (single source of truth) instead of auto-incrementing independent chart-v* tags https://claude.ai/code/session_01Eq3WHBn3Uwjezxb6ctdjMB * Default to `false` AI_DEBUG_MODE * Apply suggestions from CodeRabbit --------- Fix mobile-build using tag name instead of branch for filenames When workflow_dispatch is triggered from a tag (e.g. v0.6.7) instead of a branch, github.ref_name returns the tag name, causing filenames like sure-v0.6.7-{stamp}.apk instead of sure-main-{stamp}.apk. Guard against this by checking github.ref_type and falling back to the repository's default branch when a tag is selected. https://claude.ai/code/session_01TDfNkNxQ6uWxQxLAwJY5Qa Add workflow to build mobile apps from main without tagging (#1028) * Add workflow to build mobile apps from main without tagging Adds a new `mobile-main-build.yml` workflow that can be triggered manually via workflow_dispatch to build Android APK and iOS unsigned builds from the main branch. Uses a `main-YYYYMMDDHHMI` stamp for versioning (e.g. sure-main-202602181259.apk) and updates the gh-pages README.md MOBILE_DOWNLOADS section with direct download links. https://claude.ai/code/session_01TDfNkNxQ6uWxQxLAwJY5Qa * Rename to mobile-build.yml and support any branch Instead of hardcoding "main", derive the branch name from github.ref_name, sanitise it for filenames/tags (slashes → hyphens), and use it throughout: version, tag, release notes, and gh-pages README. The checkout step now explicitly pins ref: ${{ github.ref }} so the tag always matches the dispatched branch. Example artifacts from main: sure-main-202602181259.apk Example from feature/foo: sure-feature-foo-202602181259.apk https://claude.ai/code/session_01TDfNkNxQ6uWxQxLAwJY5Qa * Add continue-on-error to artifact download steps If either the Android or iOS build fails, the download step would hard-fail and abort the release job before the conditional logic in "Prepare release assets" could handle the partial result. Adding continue-on-error lets the workflow proceed so a release can still be created with whichever artifacts succeeded. https://claude.ai/code/session_01TDfNkNxQ6uWxQxLAwJY5Qa * Fix in-place replacement of MOBILE_DOWNLOADS section in README The previous logic stripped the marker block then appended the new section at the end of the file, causing it to drift to the bottom on every run. Now writes the section to a temp file and uses awk to replace the block between the markers in-place, preserving the section's original position in the README. https://claude.ai/code/session_01TDfNkNxQ6uWxQxLAwJY5Qa --------- Bump version to next iteration after v0.6.8-alpha.12 release Enable inclusion of hidden files in helm chart package Remove OPENAI_URI_BASE and OPENAI_MODEL from Helm secret values (#1025) These are optional app configuration values (not secrets), and listing them in rails.secret.values alongside required keys like SECRET_KEY_BASE makes users think they must be specified. Users who need them can set them via rails.extraEnv or rails.settings instead. https://claude.ai/code/session_01BP8Nr2cZWDdu9zGL9vD8Mw fix: Enable Banking DNS issues and provide better UI sync feedback (#1021) * fix(docker): add explicit DNS config to fix enable banking sync * fix(enable-banking): surface sync errors in the UI * fix: add spaces inside array brackets for RuboCop * fix(enable-banking): surface sync errors and partial failures in UI chore(deps): bump nokogiri from 1.18.9 to 1.19.1 (#1024) Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.18.9 to 1.19.1. - [Release notes](https://github.com/sparklemotion/nokogiri/releases) - [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md) - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.18.9...v1.19.1) --- updated-dependencies: - dependency-name: nokogiri dependency-version: 1.19.1 dependency-type: indirect ... Refactor GitHub Actions workflows (#1023) * Unify release workflows and add chart/mobile wrappers * Update chart CI to kube 1.25 * Fetch tagged commit before pushing release branch * Old `azure/setup-helm` * Base chart dispatch version on existing chart tags * `grep` failure with `pipefail` bypasses the user-friendly error message * `gh-pages` push lacks retry logic * Auto-incremented chart tag collision * `grep -Ev` pipeline will crash * Missed one feat: New tag creation UI (#1014) * feat: Update tag creation UI * fix: remove unused target * fix: remove connect/disconnect functions * fix: remove unnecessary target Fix crypto subtype for trades api (#1022) * fix: crypto subtype not persisted by permitting :subtype in CryptosController * Backfill crypto subtype for existig accounts so Trades API works * fix: backfill only unlinked cryptos; use raw SQL in migration; deterministic redirect in test * Update schema.rb for BackfillcryptoSubtypeForTrades migration --------- fix: add logic to skip future pending transactions and add cleanup ta… (#1011) * fix: add logic to skip future pending transactions and add cleanup task for stuck entries * Update lib/tasks/cleanup_stuck_pending_lunchflow.rake * Update app/models/lunchflow_entry/processor.rb * fix(coderabbit): assertions use entryable instead of transaction for pending state checks * chore(codex): add comments to clarify handling of pending transactions, exclude self in cleanup task * fix(coderabbit): memoize external_id --------- fix: show Edit button in account view bulk selection bar (#1002) Fix foreign currency accounts using wrong exchange rate in balance sheet totals (#1010) Balance sheet totals and accountable type summaries used a SQL JOIN on exchange_rates matching only today's date, which returned NULL (defaulting to 1:1) when no rate existed for that exact date. This caused foreign currency accounts to show incorrect totals. Changes: - Refactor BalanceSheet::AccountTotals to batch-fetch exchange rates via ExchangeRate.rates_for, with provider fallback, instead of a SQL join - Refactor Accountable.balance_money to use the same batch approach - Add ExchangeRate.rates_for helper for deduplicated rate lookups - Fix net worth chart query to fall back to the nearest future rate when no historical rate exists for a given date - Add composite index on accounts (family_id, status, accountable_type) - Reuse nearest cached exchange rate within a 5-day lookback window before calling the provider, preventing redundant API calls on weekends and holidays when providers return prior-day rates https://claude.ai/code/session_01GyssBJxQqdWnuYofQRjUu8 Syntax error in workflow Bump version to next iteration after v0.6.8-alpha.11 release Default tap on URL opens settings No credentials = no TestFlight Upload to TestFlight after `release` / fix version name Fix Android icon color Add demo account to Flutter client also Default login for Flutter client beta Wire TestFlight up to mobile releases iOS build fixes/prep for TestFlight LLC is Sure Finances, keep it the same New icon set and name Safe area around icon Add flutter_export_environment.sh to .gitignore Ignore changes in `mobile/` directory for publish workflow Enhance mobile release workflow with dispatch and script Added workflow_dispatch trigger and updated GitHub Release step to use a script for release notes and asset uploads. New icons New icon Fix version number for Android Version number in Gradle build Version number to bundle files More .gitignore noise chore(deps): bump rack from 3.1.18 to 3.1.20 (#1013) Bumps [rack](https://github.com/rack/rack) from 3.1.18 to 3.1.20. - [Release notes](https://github.com/rack/rack/releases) - [Changelog](https://github.com/rack/rack/blob/main/CHANGELOG.md) - [Commits](https://github.com/rack/rack/compare/v3.1.18...v3.1.20) --- updated-dependencies: - dependency-name: rack dependency-version: 3.1.20 dependency-type: indirect ... Update Flutter iOS run command in `mobile/README.md` fix: Remove additional padding from JS controller and add directly as a class (#1007) PDF ai import (#1006) Add support to review transactions for AI pdf import Bump version to next iteration after v0.6.8-alpha.10 release Improve tests Add new columns and sorting to admin users list (#1004) * Add trial end date to admin users list * Add new columns * Regression feat: Update gh-pages README with latest mobile release links (#1003) Add steps to the mobile-release workflow that checkout the gh-pages branch and update its README.md with direct download links to the latest Flutter mobile clients (Android APK, debug APK, iOS unsigned build). Uses HTML comment markers for idempotent updates on subsequent releases. https://claude.ai/code/session_01GuUjjmMzxvdSwfvhrjvJr1 Fix: Handle missing category in SetTransactionCategory executor (#1001) fix: Transfers were not syncing between accounts (#987) * fix: Include investment_contribution in transfer? check and protect transfer entries from sync Transfer transactions with kind "investment_contribution" were not recognized as transfers by the UI, causing missing +/- indicators, "Transfer" labels, and showing regular transaction forms instead of transfer details. Also adds user_modified: true to entries created via TransferMatchesController and SetAsTransferOrPayment rule action to protect them from provider sync overwrites, matching the existing behavior in Transfer::Creator. https://claude.ai/code/session_019BZ5Z1aqKSK3cRdR81P5Jg * fix: Centralize transfer/budget kind constants for consistent investment_contribution handling Define TRANSFER_KINDS and BUDGET_EXCLUDED_KINDS on Transaction to eliminate hard-coded kind lists scattered across filters, rules, and analytics code. investment_contribution is now consistently treated as a transfer in search filters, rule conditions, and UI display (via TRANSFER_KINDS), while budget analytics correctly continue treating it as an expense (via BUDGET_EXCLUDED_KINDS). https://claude.ai/code/session_019BZ5Z1aqKSK3cRdR81P5Jg * fix: Update tests for consistent investment_contribution as transfer kind - search_test: loan_payment is now in TRANSFER_KINDS, so uncategorized filter correctly excludes it (same as funds_movement/cc_payment) - condition_test: investment_contribution is now a transfer kind, so it matches the transfer filter rather than expense filter https://claude.ai/code/session_019BZ5Z1aqKSK3cRdR81P5Jg * fix: Eliminate SQL injection warnings in Transaction::Search Replace string-interpolated SQL with parameterized queries: - totals: use sanitize_sql_array with ? placeholders - apply_category_filter: pass TRANSFER_KINDS as bind parameter - apply_type_filter: use where(kind:)/where.not(kind:) and parameterized IN (?) for compound OR conditions - Remove unused transfer_kinds_sql helper https://claude.ai/code/session_019BZ5Z1aqKSK3cRdR81P5Jg --------- feat: Display dashboard as a 2-columns grid on big screens (#1000) * feat: display 2 columns grid in dashboard for wide screens * fix: update sortable controller to consider X/Y coordinates * fix: lint issues + missing variable init Flutter title and icon alignment fixes Small Flutter UI tweaks Intro mode in Flutter client fixes Replace text-tertiary with text-subdued in views (#999) * Replace text-tertiary with text-subdued in views Replace usages of the text-tertiary utility with text-subdued across several view partials to standardize subdued text styling because text-tertiary does not exist in the design system (reports, doorkeeper auth, simplefin items). Also adjust the net worth empty-liabilities markup to use a grid layout for consistent spacing, and update the related controller test selector to match the new CSS class. * Standardize empty net worth message markup Replace inconsistent markup and classes for empty asset/liability sections in the net worth partial. Swap text-secondary/p-2/text-center for text-subdued with unified padding (py-3 px-4 lg:px-6), and simplify the liabilities block from a grid/div to a single paragraph for consistent styling and spacing. Fix separators in breakdown table view (#996) * Fix separators in breakdown table view Correct conditional logic for rendering column separators (rulers) in the reports breakdown table. The top-level check now compares idx to groups.size instead of group.size, and the subcategory check compares idx to group[:subcategories].size. This ensures separators are shown between categories and subcategories correctly, avoiding missing or extra rulers. * Fix subcategory index variable name in partial Rename the inner loop index from `idx` to `sub_idx` in app/views/reports/_breakdown_table.html.erb to avoid shadowing the outer `idx`. This ensures the conditional that renders the separator (`shared/ruler`) uses the correct index for subcategories, preventing incorrect rendering of separators between subcategory rows. * Fix conditional block order in breakdown table Reorder ERB tags to properly nest the subcategory conditional and the ruler render in the reports breakdown partial. This ensures the divider is only rendered between subcategories and prevents mismatched ERB/end tags that could break template rendering. fix: Viewport issue in PWA (#995) * fix: move safe-area padding from body/HTML to navbars. Add script to compute app height dynamically. * fix: Initialize sankey tooltip with top-0 to avoid overflow * fix: add fallback to HTML height * fix: properly set bottom spacing and use position fixed for bottom navbar * fix: move viewport controller initialization 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. * 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 --------- fix: prevent New rule modal from closing when removing conditions or actions (#991) fix: prevent value overflow in Assets vs Liabilities card (#992) * fix: prevent value overflow in Assets vs Liabilities card Fixes issue where large asset/liability values overflow the container when AI side panel is open and reduces horizontal space. Changes: - Added flex-wrap to allow values to wrap to next line if needed - Added break-all to both asset and liability values for long numbers - Added shrink-0 to minus sign to prevent it from shrinking Fixes #976 * refactor: use break-words instead of break-all per code review Changed from break-all to break-words for currency values to prevent awkward mid-number breaks (e.g., $1,234,5 / 67.89). break-words only breaks when content overflows and keeps values intact when possible, providing cleaner line breaks while still preventing overflow. --------- fix: inverted Buy/Sell type selection by changing amount.negative to amount.positive in trade edit views (#952) Bump version to next iteration after v0.6.8-alpha.9 release Show disabled import options when no accounts exist (#977) * Show disabled import options before accounts exist Keep account-dependent import choices visible on /imports/new and render them as disabled with guidance when no accounts are available. * Refactor disabled import options: extract partial, fix accessibility (#986) - Extract _import_option partial to eliminate duplicated enabled/disabled markup across TransactionImport, TradeImport, and MintImport (also used by AccountImport, CategoryImport, RuleImport for consistency) - Replace misleading chevron-right with lock icon in disabled state - Add aria-disabled="true" for screen reader accessibility - Remove redundant default: parameter from t() call - Fix locale key ordering (requires_account after import_* keys) - Fix extra blank line in test file - Add assertion for aria-disabled attribute in test https://claude.ai/code/session_016j9tDYEBfWX9Dzd99rAYjX * Tailwind fixes --------- Expose ui_layout and ai_enabled to mobile clients and add enable_ai endpoint (#983) * Wire ui layout and AI flags into mobile auth Include ui_layout and ai_enabled in mobile login/signup/SSO payloads, add an authenticated endpoint to enable AI from Flutter, and gate mobile navigation based on intro layout and AI consent flow. * Linter * Ensure write scope on enable_ai * Make sure AI is available before enabling it * Test improvements * PR comment * Fix review issues: test assertion bug, missing coverage, and Dart defaults (#985) - Fix login test to use ai_enabled? (method) instead of ai_enabled (column) to match what mobile_user_payload actually serializes - Add test for enable_ai when ai_available? returns false (403 path) - Default aiEnabled to false when user is null in AuthProvider to avoid showing AI as available before authentication completes - Remove extra blank lines in auth_provider.dart and auth_service.dart https://claude.ai/code/session_01LEYYmtsDBoqizyihFtkye4 --------- fix: Handle empty compound conditions on rules index (#965) * fix: Handle empty compound conditions on rules index * fix: avoid contradictory rule condition summary on /rules * refactor: move rules condition display logic from view to model * fix: localize rule title fallback and preload conditions in rules index Document merchants API endpoints (#980) Add rswag request specs for merchants index/show and define a MerchantDetail schema used by the docs. Update the generated OpenAPI document with merchants paths and schema. 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 --------- Disable Turbo prefetch on dashboard outflow category links Hovering over category links in the outflow donut chart triggered Turbo 8's default link prefetching, which made a real request to the transactions controller. The controller's store_params! before_action saved those filter params (category + date range) to the session. When the user later navigated to /transactions via the nav menu, the stored params were restored, showing an unexpected filtered view. Adding data-turbo-prefetch="false" prevents the prefetch on hover while preserving the intended click-to-navigate behavior. https://claude.ai/code/session_01Na7AF1wyidPwFdPq5w8oaw Flutter login polish (#973) * Skip config screen by setting demo site default * Small copy edits * Login page polish Mobile-only GitHub workflow builds (#975) * Mobile build only * Fix copy on debug * PR review comments Bump version to next iteration after v0.6.8-alpha.8 release Bring back `/reports` link Fix flaky expectations in import-related tests (#963) Fix tests Generalize from PDF import to just files Index all PDF imports into vector store with type metadata Update backend table with status and requirements Clarify status of non-OpenAI vector store 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 * PR comments * More PR comments --------- Fix property subtype not persisting on edit (#930) * Fix property subtype not persisting on edit * Add regression test for property subtype persistence This change introduces model specs and factories to cover property subtype persistence on update. FactoryBot setup and test dependencies were adjusted to support the new specs. * Add regression test for property subtype persistence * remove unused FactoryBot factories and test * remove FactoryBot in Gemfile.lock * Fix no-op regression test for property subtype update * Delete no-op property_test * add pimary_residence in properties fixtures * add capybara system test for property subtype persistence * fix spelling and indent * rename test to "can persist property subtype" --------- Bump version to next iteration after v0.6.8-alpha.7 release fix: restore drawer positioning for transaction modals on desktop (#857) (#896) * feat: Add responsive dialog behavior for transaction modals Add responsive option to DS::Dialog component that switches between: - Mobile (< 1024px): Modal style (centered) with inline close button - Desktop (≥ 1024px): Drawer style (right side panel) with header close button Update transaction, transfer, holding, trade, and valuation views to use responsive behavior, maintaining mobile experience while reverting desktop to drawer style like budget categories. Changes: - app/components/DS/dialog.rb: Add responsive parameter and helper methods - app/components/DS/dialog.html.erb: Apply responsive styling - app/views/*/show.html.erb: Add responsive: true and hide close icons on mobile * fix: Enhance close button accessibility in dialog components * fix: Refactor dialog component to improve close button handling and accessibility Include newer providers in automatic family sync (#934) * Include newer providers in automatic family sync Coinbase, CoinStats, Mercury, and SnapTrade all implement Syncable and have Syncer classes but were not listed in child_syncables, meaning their data only refreshed on manual sync button clicks. * refactor(syncer): Open/Closed principle for provider sync - Adding new providers requires modifying child_syncables (violates O/C) - plaid_items missing .active scope (bug: syncs deleted items) - snaptrade_items can exist without user registration → fails on sync - Scattered knowledge about 'ready to sync' logic 1. **Registry pattern**: SYNCABLE_ITEM_ASSOCIATIONS constant lists all provider associations that participate in family sync 2. **Encapsulated sync-readiness**: Each item model defines its own `syncable` scope that knows when it's ready for auto-sync: - Most providers: `syncable = active` (not scheduled for deletion) - SnapTrade: `syncable = active + user_registered` (has API creds) 3. **Single loop**: child_syncables iterates the registry, calling `.syncable` on each association - Adding a provider = add to registry + define syncable scope - Each model owns its 'ready to sync' business logic - Fixes plaid_items bug (now uses .active via .syncable) - Fixes snaptrade auto-sync failures (filters unregistered items) - Easy to extend with new conditions per provider - family/syncer.rb: Registry + dynamic collection - *_item.rb (7 files): Add `scope :syncable, -> { active }` - snaptrade_item.rb: Add syncable with user_registered filter * Fix rubocop bracket spacing in SnaptradeItem syncable scope fix: keep nav bar sticky at top (#943) * fix: keep nav bar sticky at top * fix: sticky on settings page * fix: keep padding in settings page * fix: make all settings page title sticky * fix: make buttons sticky with title * fix: set header bar min height * fix: mobile responsive * fix: reduce header bar feat: Add LLM prompt for API endpoint consistency (#949) * Add LLM prompt for API endpoint consistency (fixes #944) - Add .cursor/rules/api-endpoint-consistency.mdc: checklist that applies when editing app/controllers/api/v1, spec/requests/api/v1, or test/controllers/api/v1. Enforces (1) Minitest-only behavioral coverage for new endpoints, (2) rswag docs-only (no expect/assert), (3) same API key auth pattern in all rswag specs. - Reference the rule in AGENTS.md under API Development Guidelines. * Add tests for API endpoint consistency implementation - Minitest: test/api_endpoint_consistency_rule_test.rb checks rule file exists, globs, and all three sections (Minitest, rswag docs-only, API key auth) plus AGENTS.md reference. - Standalone: test/support/verify_api_endpoint_consistency.rb runs same checks without loading Rails (use when app fails to boot). - Rule: add mdc: links for Cursor, note valuations_spec OAuth outlier. * Address review: add --compliance check, CLAUDE.md section - Verification script: --compliance scans current APIs and reports rswag OAuth vs API key, missing Minitest for controllers, expect/assert. - CLAUDE.md: add Post-commit API consistency subsection under API Development Guidelines (links to rule, documents script + --compliance). --------- Remove Flipper and replace with ENV-driven FeatureFlags (#957) * Presence of valid DEFAULT_UI_LAYOUT is sufficient * Linter Normalize legacy SSO icon values before validation (#955) chore(deps): bump faraday from 2.13.2 to 2.14.1 (#953) Bumps [faraday](https://github.com/lostisland/faraday) from 2.13.2 to 2.14.1. - [Release notes](https://github.com/lostisland/faraday/releases) - [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md) - [Commits](https://github.com/lostisland/faraday/compare/v2.13.2...v2.14.1) --- updated-dependencies: - dependency-name: faraday dependency-version: 2.14.1 dependency-type: direct:production ... Bump version to next iteration after v0.6.8-alpha.6 release Remove reference to nonexistent Sidekiq::Throttled gem (#950) The sidekiq-throttled gem is not in the Gemfile, so including Sidekiq::Throttled::Job causes an uninitialized constant NameError at boot time, breaking production builds. https://claude.ai/code/session_01Bj7xgndJt28BcUHW1v1M9S Bump version to next iteration after v0.6.8-alpha.5 release Forgot to make test Flipper-conditional Add Intro UI feature flag First cut of a simplified "intro" UI layout (#265) * First cut of a simplified "intro" UI layout * Linter * Add guest role and intro-only access * Fix guest role UI defaults (#940) Use enum predicate to avoid missing role helper. * Remove legacy user role mapping (#941) Drop the unused user role references in role normalization and SSO role mapping forms to avoid implying a role that never existed. Refs: #0 * Remove role normalization (#942) Remove role normalization Roles are now stored directly without legacy mappings. * Revert role mapping logic * Remove `normalize_role_settings` * Remove unnecessary migration * Make `member` the default * Broken `.erb` --------- 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. --------- Add REST API for holdings and trades (Discussion #905) (#918) * Add REST API for holdings and trades (Discussion #905) - Trades: GET index (filter by account_id, account_ids, start_date, end_date), GET show, POST create (buy/sell with security_id or ticker), PATCH update, DELETE destroy. Create restricted to accounts that support trades (investment or crypto exchange). Uses existing Trade::CreateForm for creation. - Holdings: GET index (filter by account_id, account_ids, date, start_date, end_date, security_id), GET show. Read-only; scoped to family. - Auth: read scope for index/show; write scope for create/update/destroy. - Responses: JSON via jbuilder (trade: id, date, amount, qty, price, account, security, category; holding: id, date, qty, price, amount, account, security, avg_cost). Pagination for index endpoints (page, per_page). * API v1 holdings & trades: validation, docs, specs - Holdings: validate date params, return 400 for invalid dates (parse_date!) - Trades: validate start_date/end_date, return 422 for invalid dates - Trades: accept buy/sell and inflow/outflow in update (trade_sell_from_type_or_nature?) - Trades view: nil guard for trade.security - Trades apply_filters: single join(:entry) when filtering - OpenAPI: add Trade/TradeCollection schemas, ErrorResponse.errors - Add spec/requests/api/v1/holdings_spec.rb and trades_spec.rb (rswag) - Regenerate docs/api/openapi.yaml * CI: fix Brakeman and test rate-limit failures - Disable Rack::Attack in test (use existing enabled flag) so parallel API tests no longer hit 429 from shared api_ip throttle - Add Brakeman ignore for trades_controller trade_params mass-assignment (account_id/security_id validated in create/update) - Trades/holdings API and OpenAPI spec updates * Trades: partial qty/price update fallback; fix PATCH OpenAPI schema - Fall back to existing trade qty/price when only one is supplied so sign normalisation and amount recalculation always run - OpenAPI: remove top-level qty, price, investment_activity_label, category_id from PATCH body; document entryable_attributes only * Trades: fix update/DELETE OpenAPI and avoid sell-trade corruption - Only run qty/price normalisation when client sends qty or price; preserve existing trade direction when type/nature omitted - OpenAPI: remove duplicate PATCH path param; add 422 for PATCH; document DELETE 200 body (DeleteResponse) * API: flat trade update params, align holdings errors, spec/OpenAPI fixes - Trades update: accept flat params (qty, price, type, etc.), build entryable_attributes in build_entry_params_for_update (match transactions) - Holdings: ArgumentError → 422 validation_failed; parse_date!(value, name) with safe message; extract render_validation_error, log_and_render_error - Specs: path id required (trades, holdings); trades delete 200 DeleteResponse; remove holdings 500; trades update body flat; holdings 422 invalid date - OpenAPI: PATCH trade request body flat * OpenAPI: add 422 invalid date filter to holdings index * API consistency and RSwag doc-only fixes - Trades: use render_validation_error in all 4 validation paths; safe_per_page_param case/when - Holdings: set_holding to family.holdings.find; price as Money.format in API; safe_per_page_param case/when - Swagger: Holding qty/price descriptions (Quantity of shares held, Formatted price per share) - RSwag: trades delete and valuations 201 use bare run_test! (documentation only, no expect) * Fix index-vs-show visibility inconsistencies and preserve custom activity labels - Add account status filter to set_holding to match index behavior - Add visible scope to set_trade to match index behavior - Preserve existing investment_activity_label when updating qty/price * Trades: clearer validation for non-numeric qty/price Return 'must be valid numbers' when qty or price is non-numeric (e.g. abc) instead of misleading 'must be present and positive'. --------- Add "Link to existing" option in SnapTrade Setup Accounts modal (#935) * Add account linking functionality for SnapTrade items - Introduced UI to link existing accounts when setting up SnapTrade items, preventing duplicate account creation. - Updated controller to fetch linkable accounts. - Added tests to verify proper filtering of accounts and linking behavior. * Add `snaptrade_item_id` to account linking flow for SnapTrade items - Updated controller to allow specifying `snaptrade_item_id` when linking accounts. - Adjusted form and views to include `snaptrade_item_id` as a hidden field. - Enhanced tests to validate behavior with the new parameter. Add tests for SnapTrade error handling and refine unlink behavior (#931) - Introduced new tests to cover SnapTrade decryption and connection errors in `SnaptradeItemsControllerTest`. - Updated error messages for improved user clarity. - Modified `unlink` functionality to preserve `SnaptradeAccount` records while ensuring proper detachment of associated holdings. Auto-categorize investment contributions across all transfer paths (#924) * Ensure investment contributions are auto-categorized with proper kind and category creation. * Retrigger CI Fix SSO provider warning timing (#927) Warn after providers are registered to avoid false empty state. fix: loan transfer kind assignment to use destination account (#874) * fix: loan transfer kind assignment to use destination account * fix: update system test to use depository account instead of investment account Bump version to next iteration after v0.6.8-alpha.4 release Protect demo API key from deletion (#919) * feat: Protect demo monitoring API key from deletion - Add DEMO_MONITORING_KEY constant to ApiKey model - Add `demo_monitoring_key?` method to identify the monitoring key - Add `visible` scope to exclude monitoring key from UI queries - Update controller to use `visible` scope, hiding the monitoring key - Prevent revocation of the monitoring key with explicit error handling - Update Demo::Generator to use the shared constant Users on the demo instance can still create their own API keys, but cannot see or delete the monitoring key used for uptime checks. https://claude.ai/code/session_01RQFsw39K7PB5kztboVdBdB * Linter * Protect demo monitoring API key from deletion * Use monitoring source for demo API key * Add test for demo monitoring revoke guard * Disable Rack::Attack in test and development --------- feat: Allow to create rules to mark transactions as transfers or payments (#920) * feat: Allow to create rules to define transfer or payments * fix: lint issues * Update app/models/rule/action_executor/set_as_transfer_or_payment.rb * fix: indentation issue * fix: add explicit return * fix: add guard on target_account * fix: use local variable for transfer and revert explicit return as it doesn't work * fix: Adjust transaction naming --------- fix: allow refreshes from the same source for cost basis updates (#917) * fix: allow refreshes from the same source for cost basis updates * test: update cost basis priority expectations Fix mobile login "Record not found" for unseeded instances (#916) * Auto-create mobile OAuth application when missing (#912) Self-hosted users who set up their instance without running `db:seed` (or reset their database) got "Record not found" on mobile login because `MobileDevice.shared_oauth_application` used `find_by!` which raises when the "Sure Mobile" Doorkeeper application does not exist. Switch to `find_or_create_by!` so the record is created transparently on first use, matching the attributes from the seed file. * Nice Claude Code suggestion --------- feat: add SSL_CA_FILE and SSL_VERIFY environment variables to support… (#894) * feat: add SSL_CA_FILE and SSL_VERIFY environment variables to support self-signed certificates in self-hosted environments * fix: NoMethodError by defining SSL helper methods before configure block executes * refactor: Refactor SessionsController to use shared SslConfigurable module and simplify SSL initializer redundant checks * refactor: improve SSL configuration robustness and error detection accuracy * fix:HTTParty SSL options, add file validation guards, prevent Tempfile GC, and redact URLs in error logs * fix: Fix SSL concern indentation and stub Simplefin POST correctly in tests * fix: normalize ssl_verify to always return boolean instead of nil * fix: solve failing SimpleFin test * refactor: trim unused error-handling code from SslConfigurable, replace Tempfile with fixed-path CA bundle, fix namespace pollution in initializers, and add unit tests for core SSL configuration and Langfuse CRL callback. * fix: added require ileutils in the initializer and require ostruct in the test file. * fix: solve autoload conflict that broke provider loading, validate all certs in PEM bundles, and add missing requires. Fix OIDC household invitation (issue #900) (#904) * Fix OIDC household invitation (issue #900) - Auto-add existing user when inviting by email (no invite email sent) - Accept page: choose 'Create account' or 'Sign in' (supports OIDC) - Store invitation token in session on sign-in; accept after login (password, OIDC, OIDC link, OIDC JIT, MFA) - Invitation#accept_for!(user): add user to household and mark accepted - Defensive guards: nil/blank user, token normalization, accept_for! return check * Address PR review: rename accept_for! to accept_for, i18n OIDC notice, test fixes, stub Rails.application.config * Fix flaky system test: assert only configure step, not flash message --------- fix: Preserve tags on bulk edits (take 3) (#889) * fix: handle tags separately from entryable_attributes in bulk updates Tags use a join table (taggings) rather than a direct column, which means empty tag_ids clears all tags rather than meaning "no change". This caused bulk category-only edits to accidentally clear existing tags. This fix: - Removes tag_ids from entryable_attributes in Entry.bulk_update! - Adds update_tags parameter to explicitly control tag updates - Uses params.key?(:tag_ids) in controller to detect explicit tag changes - Preserves existing tags when tag_ids is not provided in the request This is a cleaner architectural solution compared to tracking "touched" state in the frontend, as it properly acknowledges the semantic difference between column attributes and join table associations. https://claude.ai/code/session_014CsmTwjteP4qJs6YZqCKnY * fix: handle tags separately in API transaction updates Apply the same pattern to the API endpoint: tags are now handled separately from entryable_attributes to distinguish between "not provided" (preserve existing tags) and "explicitly set to empty" (clear all tags). This allows API consumers to: - Update other fields without affecting tags (omit tag_ids) - Clear all tags (send tag_ids: []) - Set specific tags (send tag_ids: [id1, id2]) https://claude.ai/code/session_014CsmTwjteP4qJs6YZqCKnY * Proposed fix * fix: improve tag handling in bulk updates for transactions * fix: allow bulk edit to clear/preserve tags by omitting hidden multi-select field * PR comments * Dumb copy/paste error * Linter --------- Fix flash message persistence in drag-and-drop CSV import (#915) * Initial plan * Disable Turbo on drag-and-drop import form to fix flash message display --------- Bump version to next iteration after v0.6.8-alpha.3 release Add Google Sign-In (SSO) support to Flutter mobile app (#860) * Add mobile SSO support to sessions controller Add /auth/mobile/:provider route and mobile_sso_start action that captures device params in session and renders an auto-submitting POST form to OmniAuth (required by omniauth-rails_csrf_protection). Modify openid_connect callback to detect mobile_sso session, issue Doorkeeper tokens via MobileDevice, and redirect to sureapp://oauth/callback with tokens. Handles MFA users and unlinked accounts with error redirects. Validates provider name against configured SSO providers and device info before proceeding. * Add SSO auth flow to Flutter service and provider Add buildSsoUrl() and handleSsoCallback() to AuthService for constructing the mobile SSO URL and parsing tokens from the deep link callback. Add startSsoLogin() and handleSsoCallback() to AuthProvider for launching browser-based SSO and processing the redirect. * Register deep link listener for SSO callback Listen for sureapp://oauth/* deep links via app_links package, handling both cold start (getInitialLink) and warm (uriLinkStream) scenarios. Routes callbacks to AuthProvider.handleSsoCallback(). * Add Google Sign-In button to Flutter login screen Add "or" divider and outlined Google Sign-In button that triggers browser-based SSO via startSsoLogin('google_oauth2'). Add app_links and url_launcher dependencies to pubspec.yaml. * Fix mobile SSO failure handling to redirect back to app When OmniAuth fails during mobile SSO flow, redirect to sureapp://oauth/callback with the error instead of the web login page. Cleans up mobile_sso session data on failure. * Address PR review feedback for mobile SSO flow - Use strong params for device info in mobile_sso_start - Guard against nil session data in handle_mobile_sso_callback - Add error handling for AppLinks initialization and stream - Handle launchUrl false return value in SSO login - Use user-friendly error messages instead of exposing exceptions - Reject empty token strings in SSO callback validation * Consolidate mobile device token logic into MobileDevice model Extract duplicated device upsert and token issuance code from AuthController and SessionsController into MobileDevice. Add CALLBACK_URL constant and URL builder helpers to eliminate repeated deep-link strings. Add mobile SSO integration tests covering the full flow, MFA rejection, unlinked accounts, and failure handling. * Fix CI: resolve Brakeman redirect warnings and rubocop empty line Move mobile SSO redirect into a private controller method with an inline string literal so Brakeman can statically verify the target. Remove unused URL builder helpers from MobileDevice. Fix extra empty line at end of AuthController class body. * Use authorization code exchange for mobile SSO and add signup error handling Replace passing plaintext tokens in mobile SSO redirect URLs with a one-time authorization code pattern. Tokens are now stored server-side in Rails.cache (5min TTL) and exchanged via a secure POST to /api/v1/auth/sso_exchange. Also wraps device/token creation in the signup action with error handling and sanitizes device error messages. * Add error handling for login device registration and blank SSO code guard * Address PR #860 review: fix SSO race condition, add OpenAPI spec, and cleanup - Fix race condition in sso_exchange by checking Rails.cache.delete return value to ensure only one request can consume an authorization code - Use strong parameters (params.require) for sso_exchange code param - Move inline HTML from mobile_sso_start to a proper view template - Clear stale session[:mobile_sso] flag on web login paths to prevent abandoned mobile flows from hijacking subsequent web SSO logins - Add OpenAPI/rswag spec for all auth API endpoints * Fix mobile SSO test to match authorization code exchange pattern The test was asserting tokens directly in the callback URL, but the code uses an authorization code exchange pattern. Updated to exchange the code via the sso_exchange API endpoint. Also swaps in a MemoryStore for this test since the test environment uses null_store which discards writes. * Refactor mobile OAuth to use single shared application Replace per-device Doorkeeper::Application creation with a shared "Sure Mobile" OAuth app. Device tracking uses mobile_device_id on access tokens instead of oauth_application_id on mobile_devices. --------- Normalize whitespace in text rule matching (#890) Normalize whitespace in text-based rule filters so transaction names with irregular spacing still match. Refs #886 Add mailer subject tests and refine i18n keys (#910) * Add mailer subject tests and refine i18n keys * Linter * Fix test * More fixes * More fixes --------- 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 --------- Add encryption support to provider account models (#815) * Enable encryption for raw payloads in account models. * Add backfill support for Snaptrade, Coinbase, Coinstats, and Mercury accounts. API v1: add amount_cents + signed_amount_cents to transactions (#899) * feat(api): add amount_cents + signed_amount_cents to transactions * fix: use currency.minor_unit_conversion for amount_cents - Replace hardcoded *100 with currency.minor_unit_conversion - Handles JPY (0 decimals), KWD/BHD (3 decimals), etc. correctly - Add assert_amount_cents_fields helper to validate sign/scale invariants Update Romanian localization for profile subtitle placeholder (#885) Use `dependent: :purge_later` for ActiveRecord attachments (#882) * Use dependent: :purge_later for user profile_image cleanup This is a simpler alternative to PR #787's callback-based approach. Instead of adding a custom callback and method, we use Rails' built-in `dependent: :purge_later` option which is already used by FamilyExport and other models in the codebase. This single-line change ensures orphaned ActiveStorage attac… Signed-off-by: Josh Pigford <josh@joshpigford.com>v0.6.9-alpha.9 |
||
|
|
65f439e4da | Add appearance setting for 2 column layout (#1285) | ||
|
|
66c1f62691 | Lock connection_pool gem (#1284) | ||
|
|
a3203989b1 | Bump version to next iteration after v0.6.9-alpha.9 release | ||
|
|
8dc5c92282 |
Merge pull request #1210 from lolimmlost/fix/dashboard-touch-hold
Fix dashboard mobile: require press-and-hold to reorder sections |
||
|
|
dbc104dc5d |
Fix missing privacy blur on split transaction amounts in drawer (#1275)
* Initial plan * Fix privacy blur missing on split transaction amounts in drawer Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> Agent-Logs-Url: https://github.com/we-promise/sure/sessions/658e35ef-e82a-4446-bd11-19b9b67c54a7 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> |
||
|
|
1ddc427fd5 |
chore(helm): bump pipelock to v2.0.0 with trusted domains and redirect profiles (#1266)
* chore(helm): bump pipelock to v2.0.0 with trusted domains and redirect profiles - Bump pipelock image tag from 1.5.0 to 2.0.0 - Add first-class Helm values for trustedDomains and mcpToolPolicy.redirectProfiles - Update CI GitHub Action from @v1 to @v2 - Update compose example, config reference, and docs with v2.0 features * Releasing this today in `alpha` form --------- Co-authored-by: Juan José Mata <jjmata@jjmata.com> |
||
|
|
f3ed07f96b |
Updated list of Canadian registered accounts (#1265)
* Added FHSA, RDSP, and DPSP to app/models/investment.rb * Update investment.rb Signed-off-by: Geoffrey <79559478+CYBRXT@users.noreply.github.com> * Fixed RDSP tax treatment (tax-deferred -> tax-advantaged) Signed-off-by: Geoffrey <79559478+CYBRXT@users.noreply.github.com> * Added non-registered account to the list (taxable) Signed-off-by: Geoffrey <79559478+CYBRXT@users.noreply.github.com> * Reordering Signed-off-by: Geoffrey <79559478+CYBRXT@users.noreply.github.com> --------- Signed-off-by: Geoffrey <79559478+CYBRXT@users.noreply.github.com> Co-authored-by: Geoffrey <geoffrey@github.worker> |
||
|
|
a292d93835 |
chore(deps): bump activestorage from 7.2.2.2 to 7.2.3.1 (#1263)
* chore(deps): bump activestorage from 7.2.2.2 to 7.2.3.1 Bumps [activestorage](https://github.com/rails/rails) from 7.2.2.2 to 7.2.3.1. - [Release notes](https://github.com/rails/rails/releases) - [Changelog](https://github.com/rails/rails/blob/v8.1.2.1/activestorage/CHANGELOG.md) - [Commits](https://github.com/rails/rails/compare/v7.2.2.2...v7.2.3.1) --- updated-dependencies: - dependency-name: activestorage dependency-version: 7.2.3.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * Fix flaky trades system tests racing with Turbo form submission (#1270) * Initial plan * Fix flaky trades system tests by waiting for form submission to complete Add assert_text "Entry created" after click_button "Add transaction" to ensure the Turbo form submission completes before navigating to the activity tab. Without this wait, the visit call could interrupt the in-flight Turbo request, causing the trade to never be created. Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> Agent-Logs-Url: https://github.com/we-promise/sure/sessions/45455cc4-e81e-41aa-bce6-9f67b982e81f --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> |
||
|
|
a9e1c221a5 |
Fix: use interaction state instead of device capability for drag guard
isTouchDevice() blocked mouse/trackpad drag on touch-capable laptops (e.g. Windows with touchscreen). Now checks if a touch interaction is actually in progress instead. Also adds touchcancel binding to clean up hold timer state when the OS interrupts a touch (notifications, palm rejection, etc). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
9642856b0d | Fix import flow regression. |