* Add admin family management features and tests
- Implement FamiliesController with destroy action to delete unused families.
- Add localization for success and error messages related to family deletion.
- Create FamiliesControllerTest to ensure proper functionality of family deletion.
- Update UserPolicyTest to include permissions for super admins to delete users.
- Enhance UsersControllerTest with tests for user family management, including moving users between families and creating new families.
* feat(users): enhance user management with family transfer validation and improved delete warnings
* Simplify user management actions column and combine family options
Move heavy user edit forms from table rows into a DS::Popover action
menu, add role badges to the user column, combine family migration and
creation inputs with a Stimulus controller, enable self-family
transfer for super admins, and add safety guards against demoting the
last super admin in the system.
* feat: add authentication type pills to admin user index to display SSO and local login status
* Add set password feature for local users in admin user management
- Add password field in action popover for users with local password login
- Enforce all registration password criteria (min 8 chars, mixed case, digit, special char)
- Block simultaneous family and password updates with clear error
- Show descriptive success notifications (role, password, both, family)
- Ignore password param for SSO-only users
- Add comprehensive tests for all password validation paths
* Resolve DS Drift Patrol findings and CI scan failures
- Wrap auth-type pills in DS::Tooltip instead of native title= attribute
- Add actions.manage_user key to locale and drop redundant default: fallbacks
- Fix RuboCop style offenses in Admin::UsersController
- Update Brakeman ignore entry fingerprint for Admin::UsersController#user_params
* fix: update badge query to target DS::Pill structure
* Fix DS::Tooltip misuse hiding SSO auth-type pill in admin users view
The SSO pill was passed as a block to DS::Tooltip, which caused it to
render inside the hidden div[role="tooltip"] instead of being visible.
The text: option ("SSO Provider: ...") was also silently ignored because
tooltip_content returns content (the block) over @text when a block is
given.
Fix: render the SSO/Local+SSO pill directly as visible content and pass
DS::Tooltip with no block so text: is used as the tooltip popup. An info
icon now appears next to the pill and shows the provider name on hover.
Fixes test: Admin::UsersControllerTest#test_index_renders_auth_type_pills_for_local_and_sso_users
* Remove redundant default: fallback from role pill i18n lookup
All admin.users.index.roles.{guest,member,admin,super_admin} keys are
defined in the locale file and used elsewhere in the same view without
a default:. The fallback was redundant for every valid role and would
silently mask a missing or renamed key instead of raising in
development.
Drop the default: user.role.humanize argument so that any future
missing key surfaces immediately as I18n::MissingTranslationData.
* Revert unrelated JS/schema/split churn; fix transfer_to_family! default role
- Revert 62 JS files (Biome formatter and unrelated controller changes)
- Revert db/schema.rb dump churn (no new migrations in this branch)
- Revert unrelated split transaction view changes (edit/new.html.erb)
- Fix User#transfer_to_family! role default: role: role evaluates to nil
when omitted; use explicit self.role to read model attribute
Keeps the PR focused on user/family management (~18-20 files).
* Fix last login and session count in admin user management
Store last_login_at and sessions_count directly on the users table
so they remain accurate after a user logs out.
- Add migration to add last_login_at (datetime) and sessions_count
(integer, default 0) columns to users, with backfill from sessions
- Add counter_cache: :sessions_count to Session#belongs_to :user so
the count auto-increments/decrements on session create/destroy
- Add after_create callback on Session to stamp user.last_login_at
- Update Admin::UsersController to read both values from users table
instead of aggregating Session rows (which disappear on logout)
* Fix user management PR pending CI items
* Keep test current session after sign in
* Address PR review comments for user transfers
* refactor: update user removal label to "Delete User" and standardize component attribute naming
* Address PR Review Feedback for User Management
* test: Fix families and users controller tests for user management PR
* Limit PR 2868 schema diff
* Fix PR 2868 user management CI failures
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: sure-admin <sure-admin@splashblot.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
* perf(dashboard): streamline investment activity totals
* fix(dashboard): skip empty investment totals cache writes
Short-circuit empty investment account totals before cache fetch and move the new SQL query capture regression helper into test/support.
* refactor(dashboard): address review on investment totals query
- Drop defensive ArgumentError guards in InvestmentStatement::Totals#initialize.
The sole caller (totals_query) always passes correct types, and the
empty_result early-return already handles the zero-accounts case.
- Remove the redundant accounts JOIN and its family_id/status filters from the
aggregation SQL. account_ids is already scoped to the family's visible
(draft/active) investment accounts, so the join back to accounts is
unnecessary work in the query plan. Drop the now-unused family_id param.
- Add a regression assertion that the aggregate no longer joins accounts.
* feat(mobile): standardize money typography and semantic amount color
Add a brightness-aware SureColors theme extension and a MoneyText/SureMoney
primitive (semantic success/destructive/subdued tokens + tabular figures for
column-aligned digits), then migrate the transaction lists and balance cards
off raw Colors.green/red/grey.
Step 2 of the mobile design-system sequence (#2235), after #2237's theme
foundation. Primitive-first: screens consume shared tokens/typography.
* fix: review feedback — brightness-aware token fallback, de-flake Setting tests, Pipelock localhost FP
- SureColors.of falls back to the palette matching the active brightness (not
always light) when the extension is missing, so dark surfaces stay correct.
- Clear the rails-settings-cached cache before each test; its in-memory cache
survives the per-test transaction rollback, leaking Setting.* across tests and
flaking Settings::HostingsControllerTest (stale empty string vs nil).
Full unit suite: 4952 runs, 0 failures.
- Suppress the localhost test-DB DATABASE_URL false positive with line-level
`# pipelock:ignore` in ci.yml + llm-evals.yml instead of excluding whole files,
so those workflows stay scanned for real secrets.
* feat(statements): add account statement vault
Add web-only statement uploads, account linking, duplicate detection, and per-account coverage/reconciliation checks without mutating transactions. Extend ActiveStorage authorization and targeted tests for family/account scoping.
* fix(statements): return deleted account statements to inbox
Preserve linked statement records when an account is deleted by moving them back to the unmatched inbox, then expand coverage for upload validation, sanitized parser metadata, unavailable reconciliation, and missing-month coverage.
* fix(statements): harden vault upload review flows
Address review and security findings in the statement vault by preserving sanitized parser metadata, failing closed on orphaned statement blobs, avoiding account_id mass assignment permits, and adding regression coverage for link/delete edge cases.
* fix(statements): harden vault upload and access controls
* fix(statements): address vault hardening review
* fix(statements): address vault review feedback
Prioritize SHA-256 duplicate detection while preserving MD5 fallback for legacy rows.
Remove free-form account notes from statement matching, document direct account-destroy unlinking, and add year-selectable historical coverage with muted out-of-range months.
* fix(statements): harden vault review follow-ups
Clarify legacy MD5 checksum use, whitelist statement balance helper dispatch, and preserve sanitized parser metadata.
Hide statement management controls from read-only viewers while keeping server-side authorization unchanged.
* fix(statements): repair settings system coverage
Allow the changelog provider lookup in the self-hosting settings system test, include Statement Vault in settings navigation coverage, and align the feature title casing. Update the devcontainer so ActiveStorage and parallel system tests can run in the documented environment.
* fix(statements): move vault beside accounts
Place Statement Vault with account settings instead of between Imports and Exports. Keep settings footer ordering and system navigation coverage aligned, including the non-admin visibility guard.
* fix(statements): address vault review cleanup
Resolve CodeRabbit review feedback for statement upload validation, duplicate race handling, account statement matching semantics, metadata detection, ActiveStorage authorization tests, and small UI/style cleanups.
* fix(statements): address vault cleanup review
* fix(statements): deduplicate vault style helpers
* fix(statements): close vault review follow-ups
* fix(statements): refresh schema after upstream rebase
* fix(statements): process vault uploads sequentially
* fix(statements): close vault review follow-ups
* fix(statements): scope vault index to accessible accounts
* fix(statements): harden statement vault readiness
Squash the statement vault migration hardening into the feature migration, tighten Active Storage authorization edge cases, bound CSV metadata detection, and add real PDF fixture coverage for stored statements.
Validation: targeted statement/auth/controller/provider tests, full Rails suite, system tests, RuboCop, Biome, Brakeman, Zeitwerk, importmap audit, npm audit, ERB lint, CodeRabbit, and Codex Security all passed locally.
* fix(statements): close vault review follow-ups
Move statement unlinking to after account destroy commit, keep Kraken account creation on the shared crypto helper, and add statement metadata length limits with DB checks.
Validation: fresh devcontainer with fresh DB via db:prepare, focused account/statement/Kraken/Binance tests, RuboCop, Brakeman, Zeitwerk, git diff --check, CodeRabbit, and Codex Security passed before commit.
* fix(statements): address vault scan follow-ups
Move statement tab data setup out of the ERB partial, harden reconciliation labels and coverage initialization, and tighten statement schema constraints.
Validation: CodeRabbit and Codex Security reviewed the current PR diff; Rails focused tests, full Rails tests, system tests, RuboCop, Brakeman, Zeitwerk, ERB lint, npm lint, importmap audit, npm audit, and git diff --check passed.
* fix(statements): defer vault tab loading
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
* 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
* 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>
Multi-provider SSO support:
- Database-backed SSO provider management with admin UI
- Support for OpenID Connect, Google OAuth2, GitHub, and SAML 2.0
- Flipper feature flag (db_sso_providers) for dynamic provider loading
- ProviderLoader service for YAML or database configuration
Admin functionality:
- Admin::SsoProvidersController for CRUD operations
- Admin::UsersController for super_admin role management
- Pundit policies for authorization
- Test connection endpoint for validating provider config
User provisioning improvements:
- JIT (just-in-time) account creation with configurable default role
- Changed default JIT role from admin to member (security)
- User attribute sync on each SSO login
- Group/role mapping from IdP claims
SSO identity management:
- Settings::SsoIdentitiesController for users to manage connected accounts
- Issuer validation for OIDC identities
- Unlink protection when no password set
Audit logging:
- SsoAuditLog model tracking login, logout, link, unlink, JIT creation
- Captures IP address, user agent, and metadata
Advanced OIDC features:
- Custom scopes per provider
- Configurable prompt parameter (login, consent, select_account, none)
- RP-initiated logout (federated logout to IdP)
- id_token storage for logout
SAML 2.0 support:
- omniauth-saml gem integration
- IdP metadata URL or manual configuration
- Certificate and fingerprint validation
- NameID format configuration
* Add OpenID Connect login support
* Add docs for OIDC config with Google Auth
* Use Google styles for log in
- Add support for linking existing account
- Force users to sign-in with passoword first, when linking existing accounts
- Add support to create new user when using OIDC
- Add identities to user to prevent account take-ver
- Make tests mocking instead of being integration tests
- Manage session handling correctly
- use OmniAuth.config.mock_auth instead of passing auth data via request env
* Conditionally render Oauth button
- Set a config item `configuration.x.auth.oidc_enabled`
- Hide button if disabled
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Signed-off-by: soky srm <sokysrm@gmail.com>
Co-authored-by: sokie <sokysrm@gmail.com>
* Remove Synth Finance integration
* Linter noise
* Fix failing (old) test, use it for Twelve Data
---------
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Breaks our Plaid sync process out into more manageable classes. Notably, this moves the sync process to a distinct, 2-step flow:
1. Import stage - we first make API calls and import Plaid data to "mirror" tables
2. Processing stage - read the raw data, apply business rules, build internal domain models and sync balances
This provides several benefits:
- Plaid syncs can now be "replayed" without fetching API data again
- Mirror tables provide better audit and debugging capabilities
- Eliminates the "all or nothing" sync behavior that is currently in place, which is brittle
* 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
* 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>
* User tickers as primary lookup symbol instead of isin
* Add security price provider
* Fetch security prices in bulk to improve sync performance
* Fetch prices in bulk, better mocking for tests
An overhaul and cleanup of the transactions feature including:
- Simplification of transactions search and filtering
- Consolidation of account sync logic after transaction change
- Split sidebar modal and modal into "drawer" and "modal" concepts
- Refactor of transaction partials and folder organization
- Cleanup turbo frames and streams for transaction updates, including new Transactions::RowsController for inline updates
- Refactored and added several integration and systems tests
* Add climate_control gem and test helper
* Replace ENV mods in upgrades test
* Replace ENV mods in registrations test
* Remove ENV references in hostings controller
* Update ENV refs in mailer test
* ActiveStorage cleanup
* Consolidate queue config so appropriate adapter runs in test environment
* Make test environment more explicit
* Centralize self hosting config
* Remove flaky system test
* Implement Synth as an exchange rate provider
* Add assertions to provider interface test
* Assert the correct provider error is raised
* Remove unnecessary parens