diff --git a/.cursor/rules/project-conventions.mdc b/.cursor/rules/project-conventions.mdc index 835451c28..8e1f15dde 100644 --- a/.cursor/rules/project-conventions.mdc +++ b/.cursor/rules/project-conventions.mdc @@ -3,7 +3,7 @@ description: globs: alwaysApply: true --- -This rule serves as high-level documentation for how you should write code for the Maybe codebase. +This rule serves as high-level documentation for how you should write code in this codebase. ## Project Tech Stack @@ -22,7 +22,7 @@ This rule serves as high-level documentation for how you should write code for t ## Project conventions -These conventions should be used when writing code for Maybe. +These conventions should be used when writing code for the project. ### Convention 1: Minimize dependencies, vanilla Rails is plenty diff --git a/.cursor/rules/project-design.mdc b/.cursor/rules/project-design.mdc index 3c4ea3471..0b87e0a4f 100644 --- a/.cursor/rules/project-design.mdc +++ b/.cursor/rules/project-design.mdc @@ -10,10 +10,10 @@ This is a personal finance application built in Ruby on Rails. The primary doma ## App Modes -The Maybe app runs in two distinct "modes", dictated by `Rails.application.config.app_mode`, which can be `managed` or `self_hosted`. +The codebase 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. +- "Managed" - in managed mode, a team operates and manages servers for users +- "Self Hosted" - in self hosted mode, users host the codebase 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 @@ -22,7 +22,7 @@ The Maybe app runs in two distinct "modes", dictated by `Rails.application.confi ## 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. +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 app can calculate metrics, historical graphs, and other insights in a single family currency. ## Accounts @@ -77,7 +77,7 @@ There are 3 entry types, defined as [entryable.rb](mdc:app/models/entryable.rb) ### 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: +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 codebase auto-matches transfers based on the following criteria: - Must be from different accounts - Must be within 4 days of each other @@ -93,16 +93,16 @@ Regular transfers are typically _excluded_ from income and expense calculations ## 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). +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 app [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. +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 app 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: +The codebase 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. +- `PlaidItem` - a Plaid Item "sync" fetches data from Plaid APIs, normalizes that data, stores it on internal app 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. @@ -126,7 +126,7 @@ 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. +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 codebase representations of the data. ### Family Syncs @@ -134,11 +134,11 @@ A family sync happens once daily via [auto_sync.rb](mdc:app/controllers/concerns ## 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. +The codebase 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: +There are two types of 3rd party data in the codebase: 1. "Concept" data 2. One-off data diff --git a/.cursor/rules/testing.mdc b/.cursor/rules/testing.mdc index 9fc95f82f..0377c459c 100644 --- a/.cursor/rules/testing.mdc +++ b/.cursor/rules/testing.mdc @@ -3,7 +3,7 @@ description: globs: test/** alwaysApply: false --- -Use this rule to learn how to write tests for the Maybe codebase. +Use this rule to learn how to write tests for the codebase. Due to the open-source nature of this project, we have chosen Minitest + Fixtures for testing to maximize familiarity and predictability. diff --git a/CLAUDE.md b/CLAUDE.md index e67a52e61..96ed7ade0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -66,9 +66,9 @@ Only proceed with pull request creation if ALL checks pass. ## High-Level Architecture ### Application Modes -The Maybe app runs in two distinct modes: -- **Managed**: The Maybe team operates and manages servers for users (Rails.application.config.app_mode = "managed") -- **Self Hosted**: Users host the Maybe app on their own infrastructure, typically through Docker Compose (Rails.application.config.app_mode = "self_hosted") +The codebase runs in two distinct modes: +- **Managed**: A team operates and manages servers for users (Rails.application.config.app_mode = "managed") +- **Self Hosted**: Users host the codebase on their own infrastructure, typically through Docker Compose (Rails.application.config.app_mode = "self_hosted") ### Core Domain Model The application is built around financial data management with these key relationships: