mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-19 05:09:38 +02:00
Cursor rules and project design overview (#1788)
* Add cursor rules directory * Complete project design rules
This commit is contained in:
parent
f57fa526af
commit
2a338eb01b
5 changed files with 222 additions and 73 deletions
|
@ -1,64 +0,0 @@
|
||||||
<!-- Copy this file to .cursorrules in the root of the project on your local machine if you'd like to use these rules with Cursor. -->
|
|
||||||
|
|
||||||
You are an expert in Ruby, Ruby on Rails, Postgres, Tailwind, Stimulus, Hotwire and Turbo and always use the latest stable versions of those technologies.
|
|
||||||
|
|
||||||
**Code Style and Structure**
|
|
||||||
- Write concise, technical Ruby code with accurate examples.
|
|
||||||
- Prefer iteration and modularization over code duplication.
|
|
||||||
- Use descriptive variable names with auxiliary verbs (e.g., is_loading, has_error).
|
|
||||||
- Structure files: models, controllers, views, helpers, services, jobs, mailers.
|
|
||||||
|
|
||||||
**Naming Conventions**
|
|
||||||
- Use snake_case for file names and directories (e.g., app/models/user_profile.rb).
|
|
||||||
- Use CamelCase for classes and modules (e.g., UserProfile).
|
|
||||||
|
|
||||||
**Ruby on Rails Usage**
|
|
||||||
- Use Rails conventions for MVC structure.
|
|
||||||
- Favor scopes over class methods for queries.
|
|
||||||
- Use strong parameters for mass assignment protection.
|
|
||||||
- Use partials to DRY up views.
|
|
||||||
|
|
||||||
**Syntax and Formatting**
|
|
||||||
- Use two spaces for indentation.
|
|
||||||
- Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements.
|
|
||||||
- Use descriptive method names and keep methods short.
|
|
||||||
|
|
||||||
**Commenting Code**
|
|
||||||
- Write clear, concise comments to explain the purpose of individual functions and methods.
|
|
||||||
- Use comments to describe the intent and functionality of complex logic.
|
|
||||||
- Avoid redundant comments that state the obvious.
|
|
||||||
|
|
||||||
**UI and Styling**
|
|
||||||
- Use Tailwind CSS for styling.
|
|
||||||
- Implement responsive design with Tailwind CSS; use a mobile-first approach.
|
|
||||||
- Use Stimulus for JavaScript behavior.
|
|
||||||
- Use Turbo for asynchronous actions and updates.
|
|
||||||
|
|
||||||
**Performance Optimization**
|
|
||||||
- Use eager loading to avoid N+1 queries.
|
|
||||||
- Cache expensive queries and partials where appropriate.
|
|
||||||
- Use background jobs for long-running tasks.
|
|
||||||
- Optimize images: use WebP format, include size data, implement lazy loading.
|
|
||||||
|
|
||||||
**Database Querying & Data Model Creation**
|
|
||||||
- Use ActiveRecord for data querying and model creation.
|
|
||||||
- Favor database constraints and indexes for data integrity and performance.
|
|
||||||
- Use migrations to manage schema changes.
|
|
||||||
|
|
||||||
**Key Conventions**
|
|
||||||
- Follow Rails best practices for RESTful routing.
|
|
||||||
- Optimize for performance and security.
|
|
||||||
- Use environment variables for configuration.
|
|
||||||
- Write tests for models, controllers, and features.
|
|
||||||
|
|
||||||
**AI Guidelines**
|
|
||||||
- Follow the user’s requirements carefully & to the letter.
|
|
||||||
- Confirm, then write code!
|
|
||||||
- Suggest solutions that I didn't think about—anticipate my needs
|
|
||||||
- Focus on readability over being performant.
|
|
||||||
- Fully implement all requested functionality.
|
|
||||||
- Leave NO todo’s, placeholders or missing pieces.
|
|
||||||
- Don't say things like "additional logic can be added here" — instead, add the logic.
|
|
||||||
- Be concise. Minimize any other prose.
|
|
||||||
- Consider new technologies and contrarian ideas, not just the conventional wisdom
|
|
||||||
- If I ask for adjustments to code, do not repeat all of my code unnecessarily. Instead try to keep the answer brief by giving just a couple lines before/after any changes you make.
|
|
77
.cursor/rules/project-conventions.mdc
Normal file
77
.cursor/rules/project-conventions.mdc
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
---
|
||||||
|
description: This rule explains the project's tech stack and code conventions
|
||||||
|
globs: *
|
||||||
|
---
|
||||||
|
This rule serves as high-level documentation for how the Maybe codebase is structured.
|
||||||
|
|
||||||
|
## Rules for AI
|
||||||
|
|
||||||
|
- Use this file to understand how the codebase works
|
||||||
|
- Treat this rule/file as your "source of truth" when making code recommendations
|
||||||
|
|
||||||
|
## 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
|
||||||
|
- Database: PostgreSQL
|
||||||
|
- Jobs: GoodJob
|
||||||
|
- 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 possible, models should answer questions about themselves—for example, we might have a method, `account.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`.
|
||||||
|
|
||||||
|
### Convention 3: Prefer server-side solutions over client-side solutions
|
||||||
|
|
||||||
|
- When possible, leverage Turbo frames over complex, JS-driven client-side solutions
|
||||||
|
- When writing a client-side solution, use Stimulus controllers and keep it simple!
|
||||||
|
- Especially when dealing with money and currencies, calculate + format server-side and then pass that to the client to display
|
||||||
|
- Keep client-side code for where it truly shines. For example, [bulk_select_controller.js](mdc:app/javascript/controllers/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.
|
||||||
|
|
||||||
|
### Convention 4: Sacrifice performance, optimize for simplicitly and clarity
|
||||||
|
|
||||||
|
This codebase is still young. We are still rapidly iterating on domain designs and features. Because of this, code should be optimized for simplicitly and clarity over performance.
|
||||||
|
|
||||||
|
- Focus on good OOP design first, performance second
|
||||||
|
- Be mindful of large performance bottlenecks, but don't sweat the small stuff
|
||||||
|
|
||||||
|
### Convention 5: Prefer semantic, native HTML features
|
||||||
|
|
||||||
|
The HTML spec has improved tremendously over the years and offers a ton of functionality out of the box. We prefer semantic, native HTML solutions over JS-based ones. A few examples of this include:
|
||||||
|
|
||||||
|
- Using the `dialog` element for modals
|
||||||
|
- Using `summary` / `details` elements for disclosures (or `popover` attribute)
|
||||||
|
|
||||||
|
The Hotwire suite (Turbo/Stimulus) works very well with these native elements and we optimize for this.
|
||||||
|
|
||||||
|
### Convention 6: 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/account/entries_test_helper.rb) to act as a "factory" for creating these. For a great example of this, check out [balance_calculator_test.rb](mdc:test/models/account/balance_calculator_test.rb)
|
||||||
|
|
134
.cursor/rules/project-design.mdc
Normal file
134
.cursor/rules/project-design.mdc
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
---
|
||||||
|
description: This rule explains the system architecture and data flow of the Rails app
|
||||||
|
globs: *
|
||||||
|
---
|
||||||
|
|
||||||
|
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/account/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, [holding_calculator.rb](mdc:app/models/account/holding_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 [balance_calculator.rb](mdc:app/models/account/balance_calculator.rb).
|
||||||
|
|
||||||
|
### Account Entries
|
||||||
|
|
||||||
|
An account [entry.rb](mdc:app/models/account/entry.rb) is also a Rails "delegated type". `Account::Entry` represents any record that _modifies_ an `Account` [balance.rb](mdc:app/models/account/balance.rb) and/or [holding.rb](mdc:app/models/account/holding.rb). Therefore, every entry must have a `date`, `amount`, and `currency`.
|
||||||
|
|
||||||
|
The `amount` of an [entry.rb](mdc:app/models/account/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/account/entryable.rb) records:
|
||||||
|
|
||||||
|
- `Account::Valuation` - an account [valuation.rb](mdc:app/models/account/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 `Account::Valuation` of 5,000 for today's date, that means that the account balance will be 5,000 today.
|
||||||
|
- `Account::Transaction` - an account [transaction.rb](mdc:app/models/account/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".
|
||||||
|
- `Account::Trade` - an account [trade.rb](mdc:app/models/account/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/account/transaction.rb) and an outflow [transaction.rb](mdc:app/models/account/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 [syncer.rb](mdc:app/models/account/syncer.rb), and performs a few important tasks:
|
||||||
|
|
||||||
|
- Auto-matches transfer records for the account
|
||||||
|
- Calculates holdings and balances for the account
|
||||||
|
- Enriches transaction data
|
||||||
|
- Converts account balances that are not in the family's preferred currency to the preferred currency
|
||||||
|
|
||||||
|
An account sync happens every time an [entry.rb](mdc:app/models/account/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/account/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.
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ It means so much that you're interested in contributing to Maybe! Seriously. Tha
|
||||||
|
|
||||||
## House Rules
|
## 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)
|
- 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.
|
- 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.
|
- 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.
|
||||||
|
|
18
README.md
18
README.md
|
@ -33,6 +33,15 @@ There are 3 primary ways to use the Maybe app:
|
||||||
2. [One-click deploy](docs/hosting/one-click-deploy.md)
|
2. [One-click deploy](docs/hosting/one-click-deploy.md)
|
||||||
3. [Self-host with Docker](docs/hosting/docker.md)
|
3. [Self-host with Docker](docs/hosting/docker.md)
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Before contributing, you'll likely find it helpful
|
||||||
|
to [understand context and general vision/direction](https://github.com/maybe-finance/maybe/wiki).
|
||||||
|
|
||||||
|
Once you've done that, please visit
|
||||||
|
our [contributing guide](https://github.com/maybe-finance/maybe/blob/main/CONTRIBUTING.md)
|
||||||
|
to get started!
|
||||||
|
|
||||||
## Local Development Setup
|
## Local Development Setup
|
||||||
|
|
||||||
**If you are trying to _self-host_ the Maybe app, stop here. You
|
**If you are trying to _self-host_ the Maybe app, stop here. You
|
||||||
|
@ -107,15 +116,6 @@ In development, we use `letter_opener` to automatically open emails in your
|
||||||
browser. When an email sends locally, a new browser tab will open with a
|
browser. When an email sends locally, a new browser tab will open with a
|
||||||
preview.
|
preview.
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Before contributing, you'll likely find it helpful
|
|
||||||
to [understand context and general vision/direction](https://github.com/maybe-finance/maybe/wiki).
|
|
||||||
|
|
||||||
Once you've done that, please visit
|
|
||||||
our [contributing guide](https://github.com/maybe-finance/maybe/blob/main/CONTRIBUTING.md)
|
|
||||||
to get started!
|
|
||||||
|
|
||||||
## Repo Activity
|
## Repo Activity
|
||||||
|
|
||||||

|

|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue