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
- Update BalanceSheet model to directly calculate account weights based on converted balances.
- Modify dashboard view to compute account weight as a percentage of classification total, enhancing clarity.
- Adjust group weight partial to handle effective weight, ensuring accurate rendering of weight representation.
- Add caching for classification groups and account groups in the BalanceSheet model to improve performance.
- Update views for accountable sparklines to utilize caching for rendered HTML, enhancing load times and reducing database queries.
- Implement caching for transaction totals to enhance performance, using a unique cache key based on family ID and search parameters.
- Adjust default date filter logic to use the user's preferred period when no explicit date filters are provided, reducing the load on the database for large datasets.
Note to self hosters:
If you started self hosting prior to this commit, you may have duplicate securities in your database.
This is usually not a problem, but if you'd like to clean things up, you can run the data migration
by opening a terminal on the machine you're hosting with and running:
```sh
rake data_migration:migrate_duplicate_securities
```
* Setup health check
* Security health checker cron
* Use resolver throughout codebase
* Use resolver for trade builder
* Add security health checks to schedule
* Handle no provider
* Lint fixes
* Add new chat button
* Tweak chat navigation
* Fix chat nav padding on new chat
* Make the button nicer
* Fix bad tailwind class
* Use menu icon instead of left
* Fix path
* Use rounded-full on budget allocation bar
* Fix backgrounds when balance sheet groups are open
* Add rulers between accounts and classification groups in balance sheet and account groups views.
* Update Security model to include country_code in the data definition.
* Modify Provider::SecurityConcept to define country_code for security.
* Enhance Provider::Synth to extract country_code from security data.
* Update Security::Provided to include country_code when creating security instances.
* Adjust Security::SynthComboboxOption to add country_code as an attribute.
* Revise combobox_security partial to conditionally display country flag and code.
* Create shared ruler view
* Use collection rendering/spacer templates for rules, and new shared_ruler
* Use shared ruler for all the places a ruler is used
* Use shared ruler for imports and balance sheet
* Fix brakeman by using a static partial with a defined collection
* Standardize & improve a bunch of corners, fix some backgrounds, fix merchants for dark mode
* Update balance sheet
* misc cleanup
* Fix import table
* Remove middot
* Create shared ruler view
* Use collection rendering/spacer templates for rules, and new shared_ruler
* Use shared ruler for all the places a ruler is used
* Use shared ruler for imports and balance sheet
* Fix brakeman by using a static partial with a defined collection
* Update balance sheet
* Enhance cash flow dashboard with new cash flow period handling and improved Sankey diagram rendering. Update D3 and related dependencies for better performance and features.
* Fix Rubocop offenses
* Refactor Sankey chart controller to use Number.parseFloat for value formatting and improve code readability by restructuring conditional logic for node shapes.
* Add ability to name a rule
* Add sorting by name and date,
* Improve rule page and form design
* Small header tweak
* Improve sorting click areas by including icon
* Fix brakeman
* Use icon helper instead of lucide_icon helper
* Fix double headers with new DialogComponent
* Use updated_at for sorting instead of created_at
* Use copy-plus icon for compound rules
* Remove icons and change IF/THEN/FOR font in edit form
* Use text-secondary on disabled rules
* First pass at redesigning the sorting menu
* New rule list
* Borders instead of shadows
* Apply proper text color to TO in edit form
* Improve dark mode with proper background color classes
* Use border-secondary
* Add touch: true to conditions and actions of a rule, so updated_at works as expected
* Fix db schema
* Change sort direction to be a LinkComponent outside of the form for better sort behavior
* Clean up dropdown design to match figma
* Match tags/categories design
* Fix name text color, add bg-divider background for dividers
* Fix family subscription tests (thanks zach!)
* Fix AND prefix on rule form
This new condition prefix data target is used to ensure the AND prefix is added/removed to additional conditions/groups when there aren't any saved conditions yet.
* Ensure the condition group "Add condition" button is type button to avoid form submission
* Add prefix update when removing a subcondition
* Use data condition to update the prefix on conditions, condition groups, and subconditions
* Use condition remove instead of element remove for condition groups so prefix logic runs
* Add back explicit show_prefixes to ensure subconditions never have a prefix
* Run the prefix update runs on a load of a form, which handles prefixes on an edit since no conditions change
* Ensure saved items that are marked for removal don't impact the index
* Simplify logic since we don't process subconditions
* Clean up comments
* Add primary_condition_title field to rule model
old config exposed the Redis server to the internet if the user had not configured a firewall to block port 6379
Signed-off-by: JIBSIL <40243545+JIBSIL@users.noreply.github.com>
* Fix category dark mode styles
* Fix sidebar account tab states
* Fix dashboard balance sheet group styles
* Fix budget dark mode styles
* Fix chart gradient split
* Fix prose styles in dark mode
* Add back chat nav id for tests
* 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
* Add change name rule for transaction
* Use HTML template in the ERB, clone and inject those templates from the stimulus controller
* Put back the ai_enabled check
* Update docs
* Example of what no case statement would look like
* Remove action_type and needs_value now that controller is injecting templates/hiding action target
* add "to" to template, improve no-option selection, ensure text box is cleared
* Onboarding redirect tests and trial status bar
* use helper method
* Fix time tolerance failure
* Update post-onboarding message to be generic
* Disable turbo frames on Trial start button
* Update flash notice in test
- Implemented checks for the existence of accounts before rendering links in the transfers partial.
- Added error messaging for missing accounts to improve user feedback and prevent broken links.
- Improved error handling for invalid institution URLs by rescuing URI::InvalidURIError and logging a warning.
- Refactored the method to use safe navigation and streamline the URL parsing process.
- Added a check to determine if a trial was started within the last few seconds, allowing for the assumption that onboarding was just completed even if the onboarded_at timestamp appears blank momentarily. This improves the user experience during onboarding transitions.
- Adjusted padding for mobile sidebar to account for safe area insets.
- Modified main content and bottom navigation styles to enhance layout consistency on mobile devices.
* Add lookbook + viewcomponent, organize design system file
* Build menu component
* Button updates
* More button fixes
* Replace all menus with new ViewComponent
* Checkpoint: fix tests, all buttons and menus converted
* Split into Link and Button components for clarity
* Button cleanup
* Simplify custom confirmation configuration in views
* Finalize button, link component API
* Add toggle field to custom form builder + Component
* Basic tabs component
* Custom tabs, convert all menu / tab instances in app
* Gem updates
* Centralized icon helper
* Update all icon usage to central helper
* Lint fixes
* Centralize all disclosure instances
* Dialog replacements
* Consolidation of all dialog styles
* Test fixes
* Fix app layout issues, move to component with slots
* Layout simplification
* Flakey test fix
* Fix dashboard mobile issues
* Finalize homepage
* Lint fixes
* Fix shadows and borders in dark mode
* Fix tests
* Remove stale class
* Fix filled icon logic
* Move transparent? to public interface
* Improve net worth hover
* Improve graph tooltip
* Use locales files for some text on net worth and account charts
* Consolidate and simplify trend change between net worth and account charts
* Fix test and self-review stuff
* Clean up some stuff on the holding sidebar
Changed transaction form to only display relevant categories based on transaction type (income or expense), improving usability and preventing misclassification. Created a shared transaction type tabs component for consistent navigation between expense, income, and transfer forms, providing a better user experience and reducing code duplication.
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
Co-authored-by: Zach Gollwitzer <zach@maybe.co>
* fix: improve dark mode readability across the app
* fix: improve dark mode support for asset percentage text
* fix: apply suggested patch for theme-related improvements
* chore: apply PR feedback – remove dark:, align with design tokens, update form builder
* chore: revert background token and restore original style for visual consistency
* chore: remove unnecessary class attributes from form fields using builder
* refactor: move number_field and date_field into metaprogramming block
* refactor: replace bg-divider-adaptive divs with <hr> and border-secondary
* fix: apply requested changes and linting fixes
* Add nice formatting for subtypes on account list
* Fix rubocop linting errors
* Implement better mapping
* Fix rubocop linting
* Add short and long versions of subtypes
* Simplify subtype reference
Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
Signed-off-by: Alex Hatzenbuhler <hatz@hey.com>
* Simplify reference logic, add a small test
* Fix test
* Fix tests
---------
Signed-off-by: Alex Hatzenbuhler <hatz@hey.com>
Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
* Fixes#2100: added 'text-primary' in class , this will fix the problem of text not visible in dark theme inside the modals
* added text-primary in class for form fields
---------
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
Co-authored-by: Zach Gollwitzer <zach@maybe.co>
* Domain model sketch
* Scaffold out rules domain
* Migrations
* Remove existing data enrichment for clean slate
* Sketch out business logic and basic tests
* Simplify rule scope building and action executions
* Get generator working again
* Basic implementation + tests
* Remove manual merchant management (rules will replace)
* Revert "Remove manual merchant management (rules will replace)"
This reverts commit 83dcbd9ff0.
* Family and Provider merchants model
* Fix brakeman warnings
* Fix notification loader
* Update notification position
* Add Rule action and condition registries
* Rule form with compound conditions and tests
* Split out notification types, add CTA type
* Rules form builder and Stimulus controller
* Clean up rule registry domain
* Clean up rules stimulus controller
* CTA message for rule when user changes transaction category
* Fix tests
* Lint updates
* Centralize notifications in Notifiable concern
* Implement category rule prompts with auto backoff and option to disable
* Fix layout bug caused by merge conflict
* Initialize rule with correct action for category CTA
* Add rule deletions, get rules working
* Complete dynamic rule form, split Stimulus controllers by resource
* Fix failing tests
* Change test password to avoid chromium conflicts
* Update integration tests
* Centralize all test password references
* Add re-apply rule action
* Rule confirm modal
* Run migrations
* Trigger rule notification after inline category updates
* Clean up rule styles
* Basic attribute locking for rules
* Apply attribute locks on user edits
* Log data enrichments, only apply rules to unlocked attributes
* Fix merge errors
* Additional merge conflict fixes
* Form UI improvements, ignore attribute locks on manual rule application
* Batch AI auto-categorization of transactions
* Auto merchant detection, ai enrichment in batches
* Fix Plaid merchant assignments
* Plaid category matching
* Cleanup 1
* Test cleanup
* Remove stale route
* Fix desktop chat UI issues
* Fix mobile nav styling issues
Previously, the symbol for the 'Uncategorized' segment defaulted to `$`, which is incorrect for non-USD budgets. This change ensures the correct currency symbol is shown based on the budget's currency.
Co-authored-by: Zach Gollwitzer <zach@maybe.co>
* 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>
* devContainer: Use Redis for ActiveJob and ActionCable
* devContainer: Simplify environment variables for services.
* devContainer: Remove version field as it's no longer required in Compose.
* Placeholder logic for missing prices
* Generate holdings properly for "offline" securities
* Separate forward and reverse calculators for holdings and balances
* Remove unnecessary currency conversion during sync
* Clearer sync process
* Move price caching logic to dedicated model
* Base holding calculator
* Base calculator for balances
* Finish balance calculators
* Better naming
* Logs cleanup
* Remove stale data type
* Remove stale test
* Fix price lookup logic for holdings sync
* Fix Plaid item sync regression
* Remove temp logging
* Calculate cash and holdings series
* Add holdings, cash, and balance series dropdown for investments
* Replaced data-action click event with data-action mousedown to prevent the modal from hiding on mouse up whenever mouse down starts within the modal
* Changed click events to mousedown within dialog elements to trigger the closing of the element
* Allow CSV imports to be configured to a single account or multiple accounts
* Initialize import directly from accounts page
* Fix brakeman warnings
* Fix schema
* Fix Synth check
* Do not show billing settings navbar item when self hosted
* Do not show billing settings navbar item when self hosted
* Add condition to settings helper
* Let Stripe::AuthenticationError bubble up
* Add breadcrumbs support across application
Fixes#1896
* Potential fix for tests
* Simplify breadcrumbs implementation
Remove complex breadcrumbs logic from controllers and concern, replacing with a simpler default approach that sets a basic breadcrumb based on the current controller name
* Refactor page header and breadcrumbs rendering
Remove complex breadcrumbs helper method and update layout to use more flexible content_for approach for page headers and breadcrumbs
* Add fallback breadcrumbs rendering to settings layout
linux/arm/v7 is not compatible with the latest Tailwind package + takes a significant amount of time when using buildx. Most Raspberry Pi OS now run on 64 bit ARM architecture, so we should still have significant coverage with linux/amd + linux/arm builds.
Signed-off-by: Zach Gollwitzer <zach@maybe.co>
Since the very first 0.1.0-alpha.1 release, we've been moving quickly to add new features to the Maybe app. In doing so, some parts of the codebase have become outdated, unnecessary, or overly-complex as a natural result of this feature prioritization.
Now that "core" Maybe is complete, we're moving into a second phase of development where we'll be working hard to improve the accuracy of existing features and build additional features on top of "core". This PR is a quick overhaul of the existing codebase aimed to:
- Establish the brand new and simplified dashboard view (pictured above)
- Establish and move towards the conventions introduced in Cursor rules and project design overview #1788
- Consolidate layouts and improve the performance of layout queries
- Organize the core models of the Maybe domain (i.e. Account::Entry, Account::Transaction, etc.) and break out specific traits of each model into dedicated concerns for better readability
- Remove stale / dead code from codebase
- Remove overly complex code paths in favor of simpler ones
* Add geist font
* Design system css file
* Add cursor ui/ux rules
* Add shadows and shadow borders
* Replace primitives with tokens for common text and backgrounds
* Organize css
* Update switch and checkbox class names
* Add back global color variables
* Enhance Plaid connection management with re-authentication and error handling
- Add support for Plaid item status tracking (good/requires_update)
- Implement re-authentication flow for Plaid connections
- Handle connection errors and provide user-friendly reconnection options
- Update Plaid link token generation to support item updates
- Add localization for new connection management states
* Remove redundant 'reconnect' localization for Plaid items
* Enhance security information retrieval and handling
- Add support for operating MIC codes in security info fetching
- Update security uniqueness validation to handle unknown securities
- Improve security creation and update logic in Plaid investment sync
- Update combobox and view components to handle operating MIC codes
- Add unknown flag for securities with incomplete information
* Update schema.rb
* Refactor the need for mic codes
* Don't fetch prices unless a security has the necessary mic code
* Deduplication
* Lint
* Update Securities and Plaid Investment Sync
- Modify PlaidInvestmentSync to return plaid_security for USD cash
- Add non-null constraint to Securities ticker column
- Update Securities fixture to use exchange_operating_mic instead of exchange_mic
---------
Signed-off-by: Josh Pigford <josh@joshpigford.com>
* feat(import): add currency and number format support for CSV imports
* feat(import): add currency and format for mint and trade
* fix(imports): remove currency field in favor of currency csv col
* fix(imports): remove validate column from import model
* test(import): add some tests for imports
* test(import): add some tests for generate_rows_from_csv
* fix: change method name for import model
* fix: change before validation
---------
Co-authored-by: danestves <danestves@users.noreply.github.com>
* Fix Account Holding validation and synchronization
Fixes#1781
- Add comprehensive validations for Account::Holding
- Implement validation to ensure amount matches qty * price
- Update Account::Syncer to include qty and price during synchronization
- Add database constraints for holding attributes and calculations
* Remove database check constraints for Account Holdings
Align with project convention of keeping complex validations in ActiveRecord
- Remove database-level check constraints for quantity, price, and amount
- Maintain database-level null and unique constraints
- Prepare for more flexible validation in the model layer
* feat: Add institution details to Plaid items
- Fetch and store institution URL, ID, and primary color for Plaid items
- Update PlaidItem model to retrieve and save institution metadata
- Add new method in Plaid provider to get institution details
- Update account logo view to use institution domain for logo generation
* Add institution domain method to Account model
- Extract institution domain logic from view to Account model
- Simplify logo view by using new institution_domain method
- Improve code reusability and separation of concerns
* Add scope to filter transactions from active accounts
* Add test for transfer match candidates with active accounts
* Refactor active account filtering for transactions and entries
* Refactor transaction enrichment to support batch processing
- Add method to enrich transactions in batches
- Implement job scheduling for unenriched transactions
- Improve logging and error handling for transaction enrichment
* Re-enable enrichment
* Fix transaction enrichment query to use correct table references
- Update queries to explicitly join and reference account_entries and account_transactions tables
- Remove unnecessary name presence check before enrichment
- Improve query precision for unenriched transaction selection
* Optimize transaction enrichment query joins
- Refactor database joins to use explicit table references
- Improve query performance for unenriched transaction selection
- Ensure correct table aliasing in enrichment methods
* Remove deprecated data enrichment job and method
- Delete EnrichDataJob as it's no longer used
- Remove `enrich_data_later` method from Account model
- Update Account::Syncer to directly call `enrich_data` instead of scheduling a job
- Add error handling for individual security price loading
- Log detailed error information for problematic securities
- Prevent single security errors from halting entire price loading process
- Enhance logging with more specific security identification details
* Fix: make date format year consistent overall
* chore: Consolidating all date formatting options
* adding disabled condition back to mint import
* chore: Moving formats from helper to models/family.rd
* Adding date_format_label to the en translation for import/configurations
* nit: making changes to use individual translations
* Initial pass at Plaid EU
* Add EU support to Plaid Items
* Lint
* Temp fix for rubocop isseus
* Merge cleanup
* Pass in region and get tests passing
* Use absolute path for translation
---------
Signed-off-by: Josh Pigford <josh@joshpigford.com>
* Change email address
* Email confirmation
* Email change test
* Lint
* Schema reset
* Set test email sender
* Select specific user fixture
* Refactor/cleanup
* Remove unused email_confirmation_token
* Current user would never be true
* Fix translation test failures
* feat: add validation to require consistent category color
* feat: reflect color requirement in new category form
* refactor: move logic inline over shared component
* rubocop
* tests: fix breaking and add case for new validation
* feat: hide color selector when parent category selected
* feat: override color with parent color in model
* tests: remove case for unnecessary validation
---------
Signed-off-by: Julien Bertazzo Lambert <42924425+JLambertazzo@users.noreply.github.com>
* Improve category level limit validation
* Set categories list only for non parents
* Disable select field
* Add info about the disabled select
* Don’t render a select input for parent categories
* Handle correctly turbo_stream request format
* Add turbo_stream format to requests on create and update action's tests
* Remove no_content status from update action
* Revert "Remove no_content status from update action"
This reverts commit 866140c196.
* Revert "Add turbo_stream format to requests on create and update action's tests"
This reverts commit c6bf21490f.
* Add correct redirect url for both html and turbo_stream formats
* Remove useless turbo_frame_tag
Add where statement to account_transactions overview to only give transactions and not valuations
Signed-off-by: Jasper Delahaije <47220315+Repsay@users.noreply.github.com>
* Transfer data model migration
* Transfers and payment modeling and UI improvements
* Fix CI
* Transfer matching flow
* Better UI for transfers
* Auto transfer matching, approve, reject flow
* Mark transfers created from form as confirmed
* Account filtering
* Excluded rejected transfers from calculations
* Calculation tweaks with transfer exclusions
* Clean up migration
* Add data enrichment
* Make data enrichment optional for self-hosters
* Add categories to data enrichment
* Only update category and merchant if nil
* Fix name overrides
* Lint fixes
* Fix bug: Loan % doesn't allow exact rate
Fixes#1487
Change the step of the interest rate field to 0.005.
It's unlikely that we'll see interest rates in smaller increments.
* step 0.005
* migration for loan interest rates precision
* add new line
* Basic plaid data model and linking
* Remove institutions, add plaid items
* Improve schema and Plaid provider
* Add webhook verification sketch
* Webhook verification
* Item accounts and balances sync setup
* Provide test encryption keys
* Fix test
* Only provide encryption keys in prod
* Try defining keys in test env
* Consolidate account sync logic
* Add back plaid account initialization
* Plaid transaction sync
* Sync UI overhaul for Plaid
* Add liability and investment syncing
* Handle investment webhooks and process current day holdings
* Remove logs
* Remove "all" period select for performance
* fix amount calc
* Remove todo comment
* Coming soon for investment historical data
* Document Plaid configuration
* Listen for holding updates
* Initial pass at Synth-based ticker selection
* Update _tickers.turbo_stream.erb
* Functional combobox display
* A few cleanup steps
* Linter
* Prevent long strings
* Another step towards functional combobox
* Deprecated files
* Custom Combobox implementation
* Lint
* Test suite fixes
* Lint
* Make direct use of mic codes
* Update splits
* Update trades_test.rb
* First pass at security price reference
* Data cleanup
* Synth security fetching does better with a mic_code
* Update test suite
😭
* Update schema.rb
* Update generator.rb
* Initial pass at stock filtering
* Rough in filter
* Cleaning up security listing
* Tweak to search function
* Combobox tweaks
* Clean up search query
* Update trades test with combobox
* Update securities.yml
* Adds custom debounce timeout to autosubmit form controller
- There's a default debounce timeout based on element type
- You can parameterize debounce timeout on a data-attribute
* Adds corrections based on js_lint
* Restores sleep on test
---------
Co-authored-by: Nicolás Galdámez <nicolas.galdamez@unagisoftware.com>
* Move accountable partials
* Split accountables into separate view partials
* Fix test
* Add form to permitted partials
* Fix failing system tests
* Update new account modal views
* New sync algorithm implementation
* Update account system test assertions to match new behavior
* Fix off by 1 date error
* Revert new balance sync algorithm
* Add missing account overviews
* chore: add formatting and linting for javascript code relates to #1295
* use spaces instaed
* add to recommended extensions
* only enforce lint
* auto save
* Add additional subtypes and allow for None
* Add parens for consistency on 401
* Remove cryptocurrency investment subtype
* Handle nil value
* Use objects current subtype as the initial selection
* Remove "None" option to default to helper prompt
* Fix blank/none selection
* Only include blank if subtype is present
* Simplify investment subtype dropdown
* Improve depository subtype
* Stubbing in early access
* Styling
* Title tweak
* Early access tweaks
Also removed the allow_browser helper as it tends to cause more headaches than we really care about at this point
* Lint
Having by default `PORT=` only assigns to that variable `0`, which is
interpreted by puma to start the web app in a random port when `bin/dev`
is called.
* Remove stale 1.0 import logic and model
* Fresh start
* Checkpoint before removing nav
* First working prototype
* Add trade, account, and mint import flows
* Basic working version with tests
* System tests for each import type
* Clean up mappings flow
* Clean up PR, refactor stale code, tests
* Add back row validations
* Row validations
* Fix import job test
* Fix import navigation
* Fix mint import configuration form
* Currency preset for new accounts
* add col_sep to import model
* add validation for col_sep column
* add col_sep option to csv import model
* make use of col_sep option in import model
* add column separator field to new/edit action of an import
* add col_sep parameter to create/update action
* fix spacing between fields
Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
Signed-off-by: Alexander Schrot <alexander@axs-labs.com>
---------
Signed-off-by: Alexander Schrot <alexander@axs-labs.com>
Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
* Rough draft of issue system
* Simplify design
* Remove stale files from merge conflicts
* STI for issues
* Cleanup
* Improve Synth api key flow
* Stub api key for test
* Consolidate modal form structure into partial + helper
* Scaffold out trade transaction form
* Normalize translations
* Add buy and sell trade form with tests
* Move entryable lists to dedicated controllers
* Delegate entry group contents rendering
* More cleanup
* Extract transaction and valuation update logic from entries controller
* Delegate edit and show actions to entryables
* Trade builder
* Update paths for transaction updates
This rule serves as high-level documentation for how you should write code for the Maybe codebase.
## Project Tech Stack
- Web framework: Ruby on Rails
- Minitest + fixtures for testing
- Propshaft for asset pipeline
- Hotwire Turbo/Stimulus for SPA-like UI/UX
- TailwindCSS for styles
- Lucide Icons for icons
- OpenAI for AI chat
- Database: PostgreSQL
- Jobs: Sidekiq + Redis
- External
- Payments: Stripe
- User bank data syncing: Plaid
- Market data: Synth (our custom API)
## Project conventions
These conventions should be used when writing code for Maybe.
### Convention 1: Minimize dependencies, vanilla Rails is plenty
Dependencies are a natural part of building software, but we aim to minimize them when possible to keep this open-source codebase easy to understand, maintain, and contribute to.
- Push Rails to its limits before adding new dependencies
- When a new dependency is added, there must be a strong technical or business reason to add it
- When adding dependencies, you should favor old and reliable over new and flashy
### Convention 2: Leverage POROs and concerns over "service objects"
This codebase adopts a "skinny controller, fat models" convention. Furthermore, we put almost _everything_ directly in the `app/models/` folder and avoid separate folders for business logic such as `app/services/`.
- Organize large pieces of business logic into Rails concerns and POROs (Plain ole' Ruby Objects)
- While a Rails concern _may_ offer shared functionality (i.e. "duck types"), it can also be a "one-off" concern that is only included in one place for better organization and readability.
- When concerns are used for code organization, they should be organized around the "traits" of a model; not for simply moving code to another spot in the codebase.
- When possible, models should answer questions about themselves—for example, we might have a method, `account.balance_series` that returns a time-series of the account's most recent balances. We prefer this over something more service-like such as `AccountSeries.new(account).call`.
- Native HTML is always preferred over JS-based components
- Example 1: Use `<dialog>` element for modals instead of creating a custom component
- Example 2: Use `<details><summary>...</summary></details>` for disclosures rather than custom components
- Leverage Turbo frames to break up the page over JS-driven client-side solutions
- Example 1: A good example of turbo frame usage is in [application.html.erb](mdc:app/views/layouts/application.html.erb) where we load [chats_controller.rb](mdc:app/controllers/chats_controller.rb) actions in a turbo frame in the global layout
- Leverage query params in the URL for state over local storage and sessions. If absolutely necessary, utilize the DB for persistent state.
- Use Turbo streams to enhance functionality, but do not solely depend on it
- Format currencies, numbers, dates, and other values server-side, then pass to Stimulus controllers for display only
- Keep client-side code for where it truly shines. For example, @bulk_select_controller.js is a case where server-side solutions would degrade the user experience significantly. When bulk-selecting entries, client-side solutions are the way to go and Stimulus provides the right toolset to achieve this.
- Always use the `icon` helper in [application_helper.rb](mdc:app/helpers/application_helper.rb) for icons. NEVER use `lucide_icon` helper directly.
The Hotwire suite (Turbo/Stimulus) works very well with these native elements and we optimize for this.
### Convention 4: Optimize for simplicitly and clarity
All code should maximize readability and simplicity.
- Prioritize good OOP domain design over performance
- Only focus on performance for critical and global areas of the codebase; otherwise, don't sweat the small stuff.
- Example 1: be mindful of loading large data payloads in global layouts
- Example 2: Avoid N+1 queries
### Convention 5: Use Minitest + Fixtures for testing, minimize fixtures
Due to the open-source nature of this project, we have chosen Minitest + Fixtures for testing to maximize familiarity and predictability.
- Always use Minitest and fixtures for testing.
- Keep fixtures to a minimum. Most models should have 2-3 fixtures maximum that represent the "base cases" for that model. "Edge cases" should be created on the fly, within the context of the test which it is needed.
- For tests that require a large number of fixture records to be created, use Rails helpers such as [entries_test_helper.rb](mdc:test/support/entries_test_helper.rb) to act as a "factory" for creating these. For a great example of this, check out [forward_calculator_test.rb](mdc:test/models/account/balance/forward_calculator_test.rb)
- Take a minimal approach to testing—only test the absolutely critical code paths that will significantly increase developer confidence
### Convention 6: Use ActiveRecord for complex validations, DB for simple ones, keep business logic out of DB
- Enforce `null` checks, unique indexes, and other simple validations in the DB
- ActiveRecord validations _may_ mirror the DB level ones, but not 100% necessary. These are for convenience when error handling in forms. Always prefer client-side form validation when possible.
- Complex validations and business logic should remain in ActiveRecord
description: This rule explains the system architecture and data flow of the Rails app
globs: *
alwaysApply: true
---
This file outlines how the codebase is structured and how data flows through the app.
This is a personal finance application built in Ruby on Rails. The primary domain entities for this app are outlined below. For an authoritative overview of the relationships, [schema.rb](mdc:db/schema.rb) is the source of truth.
## App Modes
The Maybe app runs in two distinct "modes", dictated by `Rails.application.config.app_mode`, which can be `managed` or `self_hosted`.
- "Managed" - in managed mode, the Maybe team operates and manages servers for users
- "Self Hosted" - in self hosted mode, users host the Maybe app on their own infrastructure, typically through Docker Compose. We have an example [docker-compose.example.yml](mdc:docker-compose.example.yml) file that runs [Dockerfile](mdc:Dockerfile) for this mode.
## Families and Users
- `Family` - all Stripe subscriptions, financial accounts, and the majority of preferences are stored at the [family.rb](mdc:app/models/family.rb) level.
- `User` - all [session.rb](mdc:app/models/session.rb) happen at the [user.rb](mdc:app/models/user.rb) level. A user belongs to a `Family` and can either be an `admin` or a `member`. Typically, a `Family` has a single admin, or "head of household" that manages finances while there will be several `member` users who can see the family's finances from varying perspectives.
## Currency Preference
Each `Family` selects a currency preference. This becomes the "main" currency in which all records are "normalized" to via [exchange_rate.rb](mdc:app/models/exchange_rate.rb) records so that the Maybe app can calculate metrics, historical graphs, and other insights in a single family currency.
## Accounts
The center of the app's domain is the [account.rb](mdc:app/models/account.rb). This represents a single financial account that has a `balance` and `currency`. For example, an `Account` could be "Chase Checking", which is a single financial account at Chase Bank. A user could have multiple accounts at a single institution (i.e. "Chase Checking", "Chase Credit Card", "Chase Savings") or an account could be a standalone account, such as "My Home" (a primary residence).
### Accountables
In the app, [account.rb](mdc:app/models/account.rb) is a Rails "delegated type" with the following subtypes (separate DB tables). Each account has a `classification` or either `asset` or `liability`. While the types are a flat hierarchy, below, they have been organized by their classification:
- Asset accountables
- [depository.rb](mdc:app/models/depository.rb) - a typical "bank account" such as a savings or checking account
- [investment.rb](mdc:app/models/investment.rb) - an account that has "holdings" such as a brokerage, 401k, etc.
- [crypto.rb](mdc:app/models/crypto.rb) - an account that tracks the value of one or more crypto holdings
- [property.rb](mdc:app/models/property.rb) - an account that tracks the value of a physical property such as a house or rental property
- [vehicle.rb](mdc:app/models/vehicle.rb) - an account that tracks the value of a vehicle
- [other_asset.rb](mdc:app/models/other_asset.rb) - an asset that cannot be classified by the other account types. For example, "jewelry".
- Liability accountables
- [credit_card.rb](mdc:app/models/credit_card.rb) - an account that tracks the debt owed on a credit card
- [loan.rb](mdc:app/models/loan.rb) - an account that tracks the debt owed on a loan (i.e. mortgage, student loan)
- [other_liability.rb](mdc:app/models/other_liability.rb) - a liability that cannot be classified by the other account types. For example, "IOU to a friend"
### Account Balances
An account [balance.rb](mdc:app/models/account/balance.rb) represents a single balance value for an account on a specific `date`. A series of balance records is generated daily for each account and is how we show a user's historical balance graph.
- For simple accounts like a "Checking Account", the balance represents the amount of cash in the account for a date.
- For a more complex account like "Investment Brokerage", the `balance` represents the combination of the "cash balance" + "holdings value". Each accountable type has different components that make up the "balance", but in all cases, the "balance" represents "How much the account is worth" (when `classification` is `asset`) or "How much is owed on the account" (when `classification` is `liability`)
All balances are calculated daily by [balance_calculator.rb](mdc:app/models/account/balance_calculator.rb).
### Account Holdings
An account [holding.rb](mdc:app/models/holding.rb) applies to [investment.rb](mdc:app/models/investment.rb) type accounts and represents a `qty` of a certain [security.rb](mdc:app/models/security.rb) at a specific `price` on a specific `date`.
For investment accounts with holdings, [base_calculator.rb](mdc:app/models/holding/base_calculator.rb) is used to calculate the daily historical holding quantities and prices, which are then rolled up into a final "Balance" for the account in [base_calculator.rb](mdc:app/models/account/balance/base_calculator.rb).
### Account Entries
An account [entry.rb](mdc:app/models/entry.rb) is also a Rails "delegated type". `Entry` represents any record that _modifies_ an `Account` [balance.rb](mdc:app/models/account/balance.rb) and/or [holding.rb](mdc:app/models/holding.rb). Therefore, every entry must have a `date`, `amount`, and `currency`.
The `amount` of an [entry.rb](mdc:app/models/entry.rb) is a signed value. A _negative_ amount is an "inflow" of money to that account. A _positive_ value is an "outflow" of money from that account. For example:
- A negative amount for a credit card account represents a "payment" to that account, which _reduces_ its balance (since it is a `liability`)
- A negative amount for a checking account represents an "income" to that account, which _increases_ its balance (since it is an `asset`)
- A negative amount for an investment/brokerage trade represents a "sell" transaction, which _increases_ the cash balance of the account
There are 3 entry types, defined as [entryable.rb](mdc:app/models/entryable.rb) records:
- `Valuation` - an account [valuation.rb](mdc:app/models/valuation.rb) is an entry that says, "here is the value of this account on this date". It is an absolute measure of an account value / debt. If there is an `Valuation` of 5,000 for today's date, that means that the account balance will be 5,000 today.
- `Transaction` - an account [transaction.rb](mdc:app/models/transaction.rb) is an entry that alters the account balance by the `amount`. This is the most common type of entry and can be thought of as an "income" or "expense".
- `Trade` - an account [trade.rb](mdc:app/models/trade.rb) is an entry that only applies to an investment account. This represents a "buy" or "sell" of a holding and has a `qty` and `price`.
### Account Transfers
A [transfer.rb](mdc:app/models/transfer.rb) represents a movement of money between two accounts. A transfer has an inflow [transaction.rb](mdc:app/models/transaction.rb) and an outflow [transaction.rb](mdc:app/models/transaction.rb). The Maybe system auto-matches transfers based on the following criteria:
- Must be from different accounts
- Must be within 4 days of each other
- Must be the same currency
- Must be opposite values
There are two primary forms of a transfer:
- Regular transfer - a normal movement of money between two accounts. For example, "Transfer $500 from Checking account to Brokerage account".
- Debt payment - a special form of transfer where the _receiver_ of funds is a [loan.rb](mdc:app/models/loan.rb) type account.
Regular transfers are typically _excluded_ from income and expense calculations while a debt payment is considered an "expense".
## Plaid Items
A [plaid_item.rb](mdc:app/models/plaid_item.rb) represents a "connection" maintained by our external data provider, Plaid in the "hosted" mode of the app. An "Item" has 1 or more [plaid_account.rb](mdc:app/models/plaid_account.rb) records, which are each associated 1:1 with an internal Maybe [account.rb](mdc:app/models/account.rb).
All relevant metadata about the item and its underlying accounts are stored on [plaid_item.rb](mdc:app/models/plaid_item.rb) and [plaid_account.rb](mdc:app/models/plaid_account.rb), while the "normalized" data is then stored on internal Maybe domain models.
## "Syncs"
The Maybe app has the concept of a [syncable.rb](mdc:app/models/concerns/syncable.rb), which represents any model which can have its data "synced" in the background. "Syncables" include:
- `Account` - an account "sync" will sync account holdings, balances, and enhance transaction metadata
- `PlaidItem` - a Plaid Item "sync" fetches data from Plaid APIs, normalizes that data, stores it on internal Maybe models, and then finally performs an "Account sync" for each of the underlying accounts created from the Plaid Item.
- `Family` - a Family "sync" loops through the family's Plaid Items and individual Accounts and "syncs" each of them. A family is synced once per day, automatically through [auto_sync.rb](mdc:app/controllers/concerns/auto_sync.rb).
Each "sync" creates a [sync.rb](mdc:app/models/sync.rb) record in the database, which keeps track of the status of the sync, any errors that it encounters, and acts as an "audit table" for synced data.
Below are brief descriptions of each type of sync in more detail.
### Account Syncs
The most important type of sync is the account sync. It is orchestrated by the account's `sync_data` method, which performs a few important tasks:
- Auto-matches transfer records for the account
- Calculates daily [balance.rb](mdc:app/models/account/balance.rb) records for the account from `account.start_date` to `Date.current` using [base_calculator.rb](mdc:app/models/account/balance/base_calculator.rb)
- Balances are dependent on the calculation of [holding.rb](mdc:app/models/holding.rb), which uses [base_calculator.rb](mdc:app/models/account/holding/base_calculator.rb)
- Enriches transaction data if enabled by user
An account sync happens every time an [entry.rb](mdc:app/models/entry.rb) is updated.
### Plaid Item Syncs
A Plaid Item sync is an ETL (extract, transform, load) operation:
1. [plaid_item.rb](mdc:app/models/plaid_item.rb) fetches data from the external Plaid API
2. [plaid_item.rb](mdc:app/models/plaid_item.rb) creates and loads this data to [plaid_account.rb](mdc:app/models/plaid_account.rb) records
3. [plaid_item.rb](mdc:app/models/plaid_item.rb) and [plaid_account.rb](mdc:app/models/plaid_account.rb) transform and load data to [account.rb](mdc:app/models/account.rb) and [entry.rb](mdc:app/models/entry.rb), the internal Maybe representations of the data.
### Family Syncs
A family sync happens once daily via [auto_sync.rb](mdc:app/controllers/concerns/auto_sync.rb). A family sync is an "orchestrator" of Account and Plaid Item syncs.
## Data Providers
The Maybe app utilizes several 3rd party data services to calculate historical account balances, enrich data, and more. Since the app can be run in both "hosted" and "self hosted" mode, this means that data providers are _optional_ for self hosted users and must be configured.
Because of this optionality, data providers must be configured at _runtime_ through [registry.rb](mdc:app/models/provider/registry.rb) utilizing [setting.rb](mdc:app/models/setting.rb) for runtime parameters like API keys:
There are two types of 3rd party data in the Maybe app:
1. "Concept" data
2. One-off data
### "Concept" data
Since the app is self hostable, users may prefer using different providers for generic data like exchange rates and security prices. When data is generic enough where we can easily swap out different providers, we call it a data "concept".
Each "concept" has an interface defined in the `app/models/provider/concepts` directory.
```
app/models/
exchange_rate/
provided.rb # <- Responsible for selecting the concept provider from the registry
provider.rb # <- Base provider class
provider/
registry.rb <- Defines available providers by concept
concepts/
exchange_rate.rb <- defines the interface required for the exchange rate concept
synth.rb # <- Concrete provider implementation
```
### One-off data
For data that does not fit neatly into a "concept", an interface is not required and the concrete provider may implement ad-hoc methods called directly in code. For example, the [synth.rb](mdc:app/models/provider/synth.rb) provider has a `usage` method that is only applicable to this specific provider. This should be called directly without any abstractions:
```rb
class SomeModel < Application
def synth_usage
Provider::Registry.get_provider(:synth)&.usage
end
end
```
## "Provided" Concerns
In general, domain models should not be calling [registry.rb](mdc:app/models/provider/registry.rb) directly. When 3rd party data is required for a domain model, we use the `Provided` concern within that model's namespace. This concern is primarily responsible for:
- Choosing the provider to use for this "concept"
- Providing convenience methods on the model for accessing data
For example, [exchange_rate.rb](mdc:app/models/exchange_rate.rb) has a [provided.rb](mdc:app/models/exchange_rate/provided.rb) concern with the following convenience methods:
This exposes a generic access pattern where the caller does not care _which_ provider has been chosen for the concept of exchange rates and can get a predictable response:
```rb
def access_patterns_example
# Call exchange rate provider directly
ExchangeRate.provider.fetch_exchange_rate(from: "USD", to: "CAD", date: Date.current)
# Call convenience method
ExchangeRate.sync_provider_rates(from: "USD", to: "CAD", start_date: 2.days.ago.to_date)
end
```
## Concrete provider implementations
Each 3rd party data provider should have a class under the `Provider::` namespace that inherits from `Provider` and returns `with_provider_response`, which will return a `Provider::ProviderResponse` object:
```rb
class ConcreteProvider < Provider
def fetch_some_data
with_provider_response do
ExampleData.new(
example: "data"
)
end
end
end
```
The `with_provider_response` automatically catches provider errors, so concrete provider classes should raise when valid data is not possible:
```rb
class ConcreteProvider < Provider
def fetch_some_data
with_provider_response do
data = nil
# Raise an error if data cannot be returned
raise ProviderError.new("Could not find the data you need") if data.nil?
- You are writing styles in a JavaScript Stimulus controller
## Rules for AI (mandatory)
The codebase uses TailwindCSS v4.x (the newest version) with a custom design system defined in [maybe-design-system.css](mdc:app/assets/tailwind/maybe-design-system.css)
- Always start by referencing [maybe-design-system.css](mdc:app/assets/tailwind/maybe-design-system.css) to see the base primitives, functional tokens, and component tokens we use in the codebase
- Always prefer using the functional "tokens" defined in @maybe-design-system.css when possible.
- Example 1: use `text-primary` rather than `text-white`
- Example 2: use `bg-container` rather than `bg-white`
- Example 3: use `border border-primary` rather than `border border-gray-200`
- Never create new styles in [maybe-design-system.css](mdc:app/assets/tailwind/maybe-design-system.css) or [application.css](mdc:app/assets/tailwind/application.css) without explicitly receiving permission to do so
# Optional: Synth API Key for exchange rates + stock prices
# (you can also set this in your self-hosted settings page)
# Get it here: https://synthfinance.com/
SYNTH_API_KEY=
# Custom port config
# For users who have other applications listening at 3000, this allows them to set a value puma will listen to.
PORT=
# Exchange Rate API
# This is used to convert between different currencies in the app. We use Synth, which is a Maybe product. You can sign up for a free account at synthfinance.com.
SYNTH_API_KEY=
PORT=3000
# SMTP Configuration
# This is only needed if you intend on sending emails from your Maybe instance (such as for password resets or email financial reports).
@@ -15,7 +35,7 @@ SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_TLS_ENABLED=true
# Email Configuration
# Address that emails are sent from
EMAIL_SENDER=
# Database Configuration
@@ -28,61 +48,30 @@ POSTGRES_USER=postgres
# This is the domain that your Maybe instance will be hosted at. It is used to generate links in emails and other places.
APP_DOMAIN=
## Error and Performance Monitoring
# The app uses Sentry to monitor errors and performance. In reality, you likely don't need this unless you're deploying Maybe to many users.
SENTRY_DSN=
# If enabled, an invite code generated by `rake invites:create` is required to sign up as a new user.
# This is useful for controlling who can sign up for your Maybe instance.
REQUIRE_INVITE_CODE=false
# Enables self hosting features
SELF_HOSTING_ENABLED=false
# The hosting platform used to deploy the app (e.g. "render")
# `localhost` (or unset) is used for local development and testing
HOSTING_PLATFORM=localhost
# Secret key used to encrypt credentials (https://api.rubyonrails.org/v7.1.3.2/classes/Rails/Application.html#method-i-secret_key_base)
# Has to be a random string, generated eg. by running `openssl rand -hex 64`
# UPGRADES_ENABLED: Enables Upgrader class functionality.
# UPGRADES_MODE: Controls how the app will upgrade. `manual` means the user must manually upgrade the app. `auto` means the app will upgrade automatically (great for self-hosting)
# UPGRADES_TARGET: Controls what the app will upgrade to. `release` means the app will upgrade to the latest release. `commit` means the app will upgrade to the latest commit.
#
UPGRADES_ENABLED=false # unless editing the flow, you should keep this `false` locally in development
about: Open a bug report when you experience broken functionality within the latest
version of the Maybe app
title: 'Bug: [Add descriptive title here]'
labels: ''
assignees: ''
---
**Describe the bug**
## Before you start (required)
### General checklist
- [ ] I have removed personal / sensitive data from screenshots and logs
- [ ] I have searched [existing issues](https://github.com/maybe-finance/maybe/issues?q=is:issue) and [discussions](https://github.com/maybe-finance/maybe/discussions) to ensure this is not a duplicate issue
### How are you using Maybe?
- [ ] I am a paying Maybe customer (hosted version)
- Paying Maybe users can also open requests in Intercom (if there is sensitive info involved)
- [ ] I am a self-hosted user
### Self hoster checklist
_Paying, hosted users should delete this entire section._
If you are a self-hosted user, please complete all of the information below. Issues with incomplete information will be marked as `Needs Info` to help our small team prioritize bug fixes.
- Self hosted app commit SHA (find in user menu): [enter commit sha here]
- [ ] I have confirmed that my app's commit is the latest version of Maybe
- Where are you hosting?
- [ ] Render
- [ ] Docker Compose
- [ ] Umbrel
- [ ] Other (please specify)
---
## Bug description
A clear and concise description of what the bug is.
**To Reproduce**
### To Reproduce
Be as specific as possible so Maybe maintainers can quickly reproduce the bug you're experiencing.
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
### Expected behavior
**Screenshots / Recordings**
If applicable, add screenshots or short video recordings to help show the bug in more detail.
What is the intended behavior that you would expect?
**Additional context**
Add any other context about the problem here.
### Screenshots and/or recordings
We highly recommend providing additional context with screenshots and/or screen recordings. This will _significantly_ improve the chances of the bug being addressed and fixed quickly.
- Is this a feature request? Please [open a feature request discussion](https://github.com/maybe-finance/maybe/discussions/new?category=feature-requests).
- Do you need help or have a question? Please [open a discussion](https://github.com/maybe-finance/maybe/discussions/new/choose) or [join our Discord](https://link.maybe.co/discord) and post to the "help" channel.
### Is this a bug?
----------------------
A bug is _broken functionality_ of the app (i.e. it prevents you from using the app). For bugs, please use the ["Bug Report" template](https://github.com/maybe-finance/maybe/issues) instead.
**Is this issue related to a problem? Please describe.**
### Is this a bug with _sensitive info_?
**Describe the work that needs to be done to address this issue**
If you are a _paying_ Maybe user, you can open a support request in Intercom.
**Additional context**
### Is this a feature request?
A feature request is functionality that you would like that is not already on our [Roadmap](https://github.com/maybe-finance/maybe/wiki/Roadmap).
All feature requests should be opened in a [Feature request Discussion](https://github.com/maybe-finance/maybe/discussions/categories/feature-requests).
Be sure to search existing discussions prior to opening a new feature request.
### Is this related to Docker and/or hosting for self hosting?
If you are having a Docker configuration issue, please do not open a Github issue unless you've identified a bug in our Dockerfile. To get help with self hosting, there are several options:
- **First**: Read our [Docker hosting guide](https://github.com/maybe-finance/maybe/tree/main/docs/hosting/docker.md) and follow it step-by-step
- Open a [Docker Discussion](https://github.com/maybe-finance/maybe/discussions/categories/docker-compose-hosting)
---
## Issue description
If your issue does not fall into the categories above, please provide a **descriptive and complete** overview of your issue.
@@ -4,6 +4,8 @@ It means so much that you're interested in contributing to Maybe! Seriously. Tha
## House Rules
- Before contributing, familiarize yourself with our project conventions. You should read through our [Project Conventions Rule](https://github.com/maybe-finance/maybe/.cursor/rules/project-conventions.mdc), which is intended for LLMs, but is also an excellent primer on how we write code for Maybe.
- While totally optional, consider using Cursor + VSCode as it will automatically apply our project conventions to your code via the `.cursor/rules` directory.
- Before contributing, please check if it already exists in [issues](https://github.com/maybe-finance/maybe/issues) or [PRs](https://github.com/maybe-finance/maybe/pulls)
- Given the speed at which we're moving on the codebase, we don't assign issues or "give" issues to anyone.
- When multiple PRs are submitted for the same issue, we take the one that most succinctly & efficiently solves a given problem and stays within the scope of work.
<sup><i>(Note: The image above is a mockup of what we're working towards. We're rapidly approaching the functionality shown, but not all of the parts are ready just yet.)</i></sup>
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.