Goals

The basic idea and goals of this project.

  • feature-rich and simple to use App (Desktop, Mobile, Web)
  • easy to use and understand API
  • easy to self-host => you own your data

Features

General Features

  • Budgets
  • Categories
  • Accounts
  • Transactions
  • Reports
  • custom currencies
  • Import/Export
  • Family (or multiple users) Accounts
  • scan bills and add to transaction

Other specific features

For frontend specific features see Frontend Features
For backend specific features see Backend Features

Frontend

Features that are specific to the frontend.

  • (MAYBE) fully offline support without any backend
  • Localization

Backend

Features that are specific to the backend.

  • API
  • compression (brotli, zstd, gzip => in this order!)
  • handling of trailing slashes for the API

Easy Deployment

  • provide docker image
  • provide good installation instructions
  • reduce external dependencies
    • we only need our databases PostgreSQL & redis
    • integrated rate limiter -> no need for an external one

API

Stage

The stage gets wiped on every deploy!!!
For development use only!!!

Url: https://api-stage.financrr.app/swagger-ui/

API Error

We provide a custom error object that is utilized throughout the library.

Error and HTTP Codes

We employ semantic HTTP codes to signify the type of error that occurred, enabling more precise error handling.
If HTTP codes lack granularity, we offer a custom error code for more specific error handling scenarios. By default, HTTP codes are used.

Custom Error Codes

Custom error codes come into play when HTTP codes lack granularity. For instance, if you need to handle a particular error in a specific manner, custom error codes allow for such tailored handling.
Custom error codes always consist of at least four digits to prevent conflicts with HTTP codes.
We call these custom error codes Api Codes.

Api Codes

CodeDescription
1000Invalid Session
1002Invalid credentials provided
1003Unauthorized
1004No bearer token provided

User-causes errors

CodeDescription
1100Resource not found
1101Serialization error
1102Missing permissions
1103Error while parsing to cron

Validation errors

CodeDescription
1200Validation error!

Internal server errors

CodeDescription
1300DB-Entitiy error
1301Database error
1302Redis error
1303Cron builder error
1304An internal time-error
1305An internal error that occurs when a snowflake could not be generated!

Misc errors

CodeDescription
9000Actix error
9999Unknown error

Validation Codes

Validation codes are just like Api Codes but instead of just a number, they contain String code and a message.
They are used to provide more detailed information about the validation-error that occurred.

Recurring rule

A recurring rule is a rule that defines when and how often a recurring transaction should be executed.
Structure of a recurring rule:

{
    "cron_pattern": {
        "day_of_month": "*",
        "month": "*",
        "day_of_week": "*"
    }
}

This rule will execute the transaction every day.

  • day_of_month: The day of the month when the transaction should be executed.
    • *: Every day of the month.
    • 1-31: The day of the month.
  • month: The month when the transaction should be executed.
    • *: Every month.
    • 1-12: The month.
  • day_of_week: The day of the week when the transaction should be executed.
    • *: Every day of the week.
    • 1-7: The day of the week. (1 is Monday, ..., 6 is Saturday, 7 is Sunday)

We use croner-rust to parse the recurring rule.
Check out their repository to see what is supported.

Special rules

There are some special rules that can be used instead of the cron pattern.
The special rules are:

  • @yearly: Execute the transaction every year.
  • @annually: Execute the transaction every year.
  • @monthly: Execute the transaction every month.
  • @weekly: Execute the transaction every week.
  • @daily: Execute the transaction every day.

How to use it easily

You should be able to use a cron builder to create the recurring rule.
Simply build the cron and extract the day_of_month, month, and day_of_week from the cron string.

Examples

repeat every day

{
    "cron_pattern": {
        "day_of_month": "*",
        "month": "*",
        "day_of_week": "*"
    }
}

repeat every 4th day

{
    "cron_pattern": {
        "day_of_month": "*",
        "month": "*",
        "day_of_week": "*/4"
    }
}

repeat every 2nd week on monday and friday

{
    "cron_pattern": {
        "day_of_month": "*",
        "month": "*",
        "day_of_week": "1,5"
    }
}

repeat every month

{
    "special": "@monthly"
}

repeat every 3rd month on the 2nd monday

{
    "cron_pattern": {
        "day_of_month": "*",
        "month": "*/3",
        "day_of_week": "1#2"
    }
}

repeat every year on january and august

{
    "cron_pattern": {
        "day_of_month": "*",
        "month": "1,8",
        "day_of_week": "*"
    }
}

Database

Model

erDiagram
    User {
        int id PK
        string username UK
        string email UK "Nullable"
        string password UK "Hashed and salted Password"
        timestamp created_at
        bool is_admin
    }

    Currency {
        int id PK
        string name
        string symbol
        string iso_code
        int decimal_places
        User user FK "Nullable"
    }
    Currency }|--|| User: "many to one"

    Account {
        int id PK
        string name
        string description "Nullable"
        string iban UK "Nullable"
        int balance
        Currency currency FK
        timestamp created_at
    }

    UserAccount {
        User user PK "References User.id"
        Account account PK "References Account.id"
    }
    UserAccount ||--|{ User: "one to many"
    UserAccount ||--|{ Account: "one to many"

    Transaction {
        int id PK
        Account source FK "Nullable"
        Account destination FK "Nullable"
        int amount
        Currency currency FK
        string description "Nullable"
        Budget budget FK "Nullable"
        timestamp created_at
        timestamp executed_at
    }
    Transaction ||--|| Account: "one to one"
    Transaction ||--|| Budget: "one to one"

    Budget {
        int id PK
        User user FK
        int amount
        string name
        string description "Nullable"
        timestamp created_at
    }
    Budget ||--|| User: "one to one" 

SQL

You can find the SQL script here.

Developers

This section is intended for contributors or developers.

Stage system

We provide a stage system for testing purposes.

Please note that this system is not intended for production use and may be reset at any time.