* feat(api): allow creating categories via API Adds POST /api/v1/categories so external integrations (e.g. bulk classification scripts that import already-categorized data from another system) can create categories without going through the web UI. Mirrors the existing tags create endpoint: requires the read_write scope, accepts name/color/icon/parent_id, auto-suggests an icon when omitted, and rejects parent_ids from other families. Also adds Minitest behavioural coverage, an rswag docs spec, a CategoryCreateRequest schema, and regenerates docs/api/openapi.yaml. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(api): address review feedback on POST /api/v1/categories - Re-raise ActionController::ParameterMissing in #create so the BaseController rescue_from handles it as a 400 instead of the generic 500 from the broad rescue inside the action. - Add a 403 'insufficient scope' response block to the rswag POST example so the generated OpenAPI documents read-only key rejection. - Switch the new create-action Minitest cases to API key auth via X-Api-Key + api_headers (using the existing api_keys fixtures), matching the project's API endpoint consistency rule. - Add Minitest coverage for two more 4xx paths: rejecting third-level nesting (parent_id pointing at a depth-2 subcategory) and rejecting requests without the category payload (400). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(test): migrate categories API index/show tests to X-Api-Key The pre-existing index and show tests in this file authenticated via Doorkeeper bearer tokens. Per the project's API endpoint consistency rule (CLAUDE.md, .cursor/rules/api-endpoint-consistency.mdc) Minitest controller tests under test/controllers/api/v1/ must use ApiKey + X-Api-Key auth. Drops the Doorkeeper application/access-token setup and routes every request through the existing api_keys fixtures and the api_headers helper, matching the create-action tests already in this file (and the pattern used in sync/users/family_settings tests). No behavioural change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(api): address second-round review on POST /api/v1/categories - Add a 400 response block to the POST rswag example so the generated OpenAPI documents the missing-category-payload contract that BaseController#handle_bad_request already returns. Regenerate docs/api/openapi.yaml. - Replace fixture-backed read_write_api_key / read_only_api_key helpers with explicit ApiKey.create! calls (matching the pattern in sync_controller_test, users_controller_test, and family_settings_controller_test). Setup now destroys active keys for the test user so the one-active-key-per-source validation does not collide with fixtures. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(api): tighten 422 create-category cases - Pass color and icon explicitly in the duplicate-name and third-level-nesting tests so each case is self-documenting about which validation it isolates (the model's color presence check is satisfied by the column default today, but reviewers — human and bot — flagged the implicit reliance). - Assert the JSON error envelope (error key + present message) on every 422 path so the response shape stays consistent and a regression in the rendered error body is caught uniformly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(api): tighten POST /api/v1/categories per review - Drop the no-op `rescue ActionController::ParameterMissing; raise` and the broad `rescue => e` from the create action. The BaseController already has rescue_from ActionController::ParameterMissing → 400, and unexpected exceptions are best left to Rails' default 500 handling (which logs identically). Keeps the action focused on its happy path and the two real error branches. - Stop accepting `lucide_icon` as a request key. The OpenAPI schema documents only `icon`; the dual permit was undocumented and pointless. `icon` is now the single canonical request key, mapped to `lucide_icon` on the model in category_params. - Migrate the Minitest helpers to the project's documented API key pattern: ApiKey.generate_secure_key + api_key.plain_key in the X-Api-Key header (matching the rswag spec in this PR and the rule in .cursor/rules/api-endpoint-consistency.mdc), instead of hand-built display_key strings. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Botched conflict merge --------- Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: Juan José Mata <jjmata@jjmata.com>
Deutsch | Español | Français | 日本語 | 한국어 | Português | Русский | 中文
Sure: The personal finance app for everyone
Get involved: Discord • Website • Issues
Important
This repository is a community fork of the now-abandoned Maybe Finance project.
Learn more in their final release doc.
Backstory
The Maybe Finance team spent most of 2021–2022 building a full-featured personal finance and wealth management app. It even included an “Ask an Advisor” feature that connected users with a real CFP/CFA — all included with your subscription.
The business end of things didn't work out, and so they stopped developing the app in mid-2023.
After spending nearly $1 million on development (employees, contractors, data providers, infra, etc.), the team open-sourced the app. Their goal was to let users self-host it for free — and eventually launch a hosted version for a small fee.
They actually did launch that hosted version … briefly.
That also didn’t work out — at least not as a sustainable B2C business — so now here we are: hosting a community-maintained fork to keep the codebase alive and see where this can go next.
Join us!
Hosting Sure
Sure is a fully working personal finance app that can be self hosted with Docker.
Forking and Attribution
This repo is a community fork of the archived Maybe Finance repo. You’re free to fork it under the AGPLv3 license — but we’d love it if you stuck around and contributed here instead.
To stay compliant and avoid trademark issues:
- Be sure to include the original AGPLv3 license and clearly state in your README that your fork is based on Maybe Finance but is not affiliated with or endorsed by Maybe Finance Inc.
- "Maybe" is a trademark of Maybe Finance Inc. and therefore, use of it is NOT allowed in forked repositories (or the logo)
Performance Issues
With data-heavy apps, inevitably, there are performance issues. We've set up a public dashboard showing the problematic requests seen on the demo site, along with the stacktraces to help debug them.
https://www.skylight.io/app/applications/s6PEZSKwcklL/recent/6h/endpoints
Any contributions that help improve performance are very much welcome.
Local Development Setup
If you are trying to self-host the app, read this guide to get started.
The instructions below are for developers to get started with contributing to the app.
Requirements
- See
.ruby-versionfile for required Ruby version - PostgreSQL >9.3 (latest stable version recommended)
- Redis > 5.4 (latest stable version recommended)
Getting Started
cd sure
cp .env.local.example .env.local
bin/setup
bin/dev
# Optionally, load demo data
rake demo_data:default
Visit http://localhost:3000 to view the app.
If you loaded the optional demo data, log in with these credentials:
- Email:
user@example.com - Password:
Password1!
For further instructions, see guides below.
Setup Guides
- Mac dev setup
- Linux dev setup
- Windows dev setup
- Dev containers - visit this guide
One-click Install
Managed OpenClaw for Sure Finances
License and Trademarks
Maybe and Sure are both distributed under an AGPLv3 license.
- "Maybe" is a trademark of Maybe Finance, Inc.
- "Sure" is not, and refers to this community fork.
