Νόμιsync Personal Accounting System Design
1. Introduction
One more personal accounting system. Not even locked to any finance tracking, you can keep any virtual points on bonuses. The system just keeps a track of numbers so your νόμισμα is always in sync.
3. Background
4. Features
[X]Self-hosted support[X]Multi-user[ ]Shared accounts[ ]RBAC[ ]Client-Server[ ]Standalone[X]Multi-currency[X]Double book-keep[X]Splits[ ]Online integration[ ]ofx/qif import/export[ ]receipt recognition[ ]web/cli/mobile/desktop[ ]rules/schedule/scripts[ ]crypto integration[ ]smart contracts[X]account tree[X]tags[ ]inbox[ ]egui-based UI
5. Key points
5.1. Double entry bookkeeping
That's the common ground for any reasonable financial accounting: there's no reason not to use the system which worked perfectly since the XIV century.
5.2. Absolute accuracy
The system uses rationals to store all the finance information: that's not a unique feature but this allows to avoid any rounding and loosing even the smallest fraction of your asset in accounting.
This is especially important when working with modern crypto-currencies which use tiny fractions as minimal values. You'll never have your gas Ethereum gas payment mismatch in the report.
5.3. Native multi-currency support
Many accounting systems support multiple currencies and currency conversions, but unfortunately the implementation is not always perfect: usually the user has to choose a "base currency" and all the rest of computations is done based on it. But now in the era of travels and even some special user categories like digital nomads the multi-currency should be implemented in a way that allows switching a base currency any time.
The second point here is decentralization: crypto-currencies, international brokers, investments into assets all over the world using different ways is a usual situation, so all these assets must be handled appropriately.
5.4. Easy-to-use tag system
There is a tagging system that allows an accounting configuration of arbitrary flexibility: bills, categories, users, comments, any marks. You define your way to go with finance.
5.5. WASM-based scripting
The universal bytecode and simple API allow you to manage your finances the way you like with just a simple combination of tag and script.
Automatic categorization, automated bill payments' accounting, automated budgeting, and so on.
6. Usage
6.1. Run
For running use:
cargo run -- --loglevel Debug -d 'postgres://ray@localhost/nomisynctestdb' --setopt locale=en
7. Changelog
All notable changes to this project will be documented in this file.
7.1. [unreleased]
7.1.1. 🚀 Features
- (db,config) Add sqlx and i18n
- (db) Add support for actual db
- (sqlite) Force the connection pool to work
- (config) Add ConfigOption support
- (config) Make configuration storage work
- (config) Load locale from configuration
- (db) Add pool configuration
- (cli) Add cli create and move the server to lib
- (sql) Init the tables for finance
- (finance) Add account, commodity, and transaction
- (web) Add web server
- (web) Fix the login process
- (scripting) Add wasm-based scripting
- (scripting) Migrate from Wasmer to WasmTime
- (finance) Add builder to Account
- (scrtiping) Add string-based interaction with WASM
- (finance) Add Tag support
- (server) Add commoditytags support
- (server) Implement getting tags for commodity
- (scripting) Add tag export to scripts
- (build) Add Dockerfile and Drone config
- (web) Enable logging
- (build) Pull cache explicitly
- (doc) Render the disdoc into html and publish it
- (finance) Add createtransaction
- (finance) Add TransactionTicket and DB management
- (finance) Add Split insertion for Transaction
- (finance) Add single-currency Transaction support
- (web) Add /api/version endpoint
- (finance) Support the multi-currency transactions
- (finance) Add Split::commit()
- (finance) Add Tag::commit()
- (server) Add Command and infrastructure
- (build) Add check to Drone pipeline
- (cli) Add first simple UI
- (cli) Show logs in UI
- (cli) Add param completion
- (cli) Add first command
- (cli) Add working /config/get
- (server,cli) Add SetConfig
- (cli) Add Version command
- (cli) Fix part of backspace processing
- (server) Add GetVersion command
- (command,cli) Add selcol command for debug
- (server) Add CommodityCreate command
- (cli) Add CommodityCreate command
- (server) Add support for returning finance entities
- (server,cli) Add ListCommodities and CliListCommodities
- (cli) Add support for quotes in parameters
- (server) Add CreateAccount and ListAccount
- (web) Add CommodityList support
- (server) Migrate the TaggedEntities to HashMap
- (cli) Add CliAccountCreate command
- (cli) Add Commodity completion for Accounts
- (server) Add CreateAccount internals
- Add placeholder comment for implementing CliAccountList command
- Implement CliAccountList for listing accounts
- (cli) Add ListAccounts
- Add placeholder comment for implementing accounttable function
- Implement accounttable handler with template and view logic
- (web) Add Accounts listing
- Add CreateTransaction command with split handling
- Implement CreateTransaction command with split creation and test
- (cli) Add Transaction creation
- Add Transaction listing support
- Add optional note for CreateTransaction
- (server) Add ListSplits command
- (cli) Add /account/balance command
- (web) Add balance to account listing
- (server) Add UserContext
- (web) Add favicon
- (web) Implement Commodity creation and listing
- (web) Implement Account listing and creation
- (web) Add index page
- (web) First attempt to add transaction
- (web) Fix the Transaction and Account listing
- (web) Add Account listing to the Transaction list
- (build) Update Rust to 1.86
- (web) Add check for currency in transaction creation
- (web) Add currency conversion support
- (web) Add home link to all pages
- (web) Migrate to JWT user handling
- (macro) Implement first args macro version based on HashMap
- (macro) Implement the compile-time checking macro
- Migrate to commodity-free accounts
- Support multi-currency balances
- (web) Redirect to login page on token expiry
- (db) Support tags tagging
- (web) Pretty-print the balance on the main page
- (server) Add the UpdateTransaction command
- (web) Support transactions editing
- (server) Add DeleteTransaction command
- (web) Add the Delete link for transaction
- (web) Add tag management page
- (web) Add transaction tag management
- (web) Add autocompletion for transaction tags
- (web) Add split tag management
7.1.2. 🐛 Bug Fixes
- (main) Stop translating db request
- (server) Update config sql queries
- (finance) Remove quantity from split as not needed
- (scripting) Export functions via linker
- (server) Detect a dockerized build and don't try to run emacs
- (scripting) Enable tags usage and update from the WASM scripts
- (build) Set up correct caching in Dockerfile
- (build) Fix path to static files in docker
- (web) Fix the build error related to Path conversion
- (web) Fix build by removing unneeded import
- (web) Remove logger to prevent conflict
- (build) Add docker socket to build step
- (web) Fix the web page to match with handler
- (hook) Add .sqlx directory on commit
- (web) Check the Redis connection on start
- Cleanup the Account type to get rid of links
- Cleanup the Split type and migrate it to Uuid
- Cleanup the Price and the rest of dependent types
- Add Trasaction creation process
- (server) Migrate to UserPool instead of UserContext
- (cli) Fix the cli commands to create accounts and transactions
- (web) Fix the multi-split transactions
- (web) Fix the transaction split validation
- (web) Fix the js to tag transactions correctly
7.1.3. 🚜 Refactor
- (server) Migrate Account to User support
- (server) Migrate Commodity to User support
- (server) Fix the tests
- (cli) Provide userid for commands
- (cli) Migrate commands in cli to User
- (web) Migrate the web part to User and context
7.1.4. 📚 Documentation
- Update the README.md to use cli and cargo run
- Add main doc and hook for automated readme
- Fix the git-cliff config and hook
- Add workspace documentation
- Update feature plan
- (server) Generate migrations from the docs
- (finance) Update the finance table and add descriptions
- Add tasklist and bugtracker
- Update the coverage link
7.1.5. 🧪 Testing
- (db) Add sqlite tests
- (config) Stabilize test runs
- (config) Fix the doctests
- (server) Fix tests to work with Postgres
- (server) Fix DBPOOL for multi-threaded tests
- (server) Rework tests and simplify the db connection
- (finance) Commit the transaction in tests
- (server) Add C++ example of wasm script
- (commodity) Add panic to scripting to find the issue
- (finance) Add draft for the Transaction creation test
- (server) Add test for ListCommodities
- Support coverage collection
- (web) Add the first part of web tests
- (web) Add pages tests
- (web) Reexport the web internals for test
- (server) Fix the arguments for gettag
- (web) Add test for ListCommodities
7.1.6. ⚙️ Miscellaneous Tasks
- (build) Migrate to Cargo Workspace
- Apply cargo fix
- (config) Move sql requests to separate files
- Migrate to Postgres
- (server) Update the SQL queries and save them to files
- (hook) Cleanup temporary file after doc generation
- Add .projectile file
- (web) Eliminate copying
- (scripting) Support WAT for scripts
- (scripting) Generalize wrappers
- (server) Rework wasm build procedure
- (macro) Add builder macro for builders autogeneration
- (macro) Support lifetimes in Builder
- (macro) Migrate to syn-2
- (sql) SQLX statements prepared
- (build) Add builder creation step to drone.yml
- (build) Remove unneeded build step
- (finance) Remove ACTION from split
- (finance) Unify Split with other entities
- (build) Switch Drone to Kaniko
- (build) Fix the image name in Drone deployment
- (build) Set lto to "fat"
- (build) Fix tag for Drone
- (build) Fix the path to disdoc.html
- (build) Fix the Drone secret
- (doc) Add build status badge into Status section
- (build) Update Dockerfile to rust-1.83
- (hook) Cleanup the hook and fix the codestyle
- (repo) Add .gitignore
- (finance) Cleanup the tests and ensure they pass
- (web) Rename loginrouter to publicrouter
- (web) Update logging
- (drone) Switch to another k8s plugin
- (finance) Migrate to universal Connection
- (finance) Migrate from text fields in tables to tags
- (finance) Cleanup a Split accordingly to clippy
- (server) Cleanup the error log
- (cli) Rework input so completion works as intended
- (cli) Set correct start state
- (cli) Migrate to HashMap for arguments
- (server) Migrate to HashMap for arguments
- (cli) Move from debug! to trace!
- (finance) Migrate from refs to uuids for Account
- (build) Fix the Drone CI pipeline
- (cli,server) Migrate to returning CmdResult from commands
- (cli) Fix output of the commodity list
- Migrate to Rust 1.85
- (web) Fix the handler type
- (web) Update css
- (web) Migrate to own htmx
- (web) Group components by category
- (web) Regroup the endpoints
- (web) Fix the mobile css
- (web) Create transaction with split
- (web) Fix the error on submitting a transaction
- (web) Add time to the Transaction input date
- (web) Apply the styles for mobile device
- (web) Set column layout for mobile devices
- (web) Fix minor css font size
- (docker) Update rust version
- (web) Fix the path format
- (doc) Add the rustdoc and doc link
- Add CLAUDE.md
- Fix the cargo test flags
- (web) Restore the version information on the login page
- (web) Fix the Account status display and update dashboard
- Apply if-let chaining style
- (server) Accept the accountid argument as Uuid
- (macro) Cleanup and remove the HashMap
- (server) Migrate GetVersion to new macro
- (server) Migrate GetConfig to new macro
- (server) Migrate SetConfig to new macro
- (server) Migrate SelectColumn to new macro
- (server) Migrate CreateCommodity to new macro
- (web) Create structure for tests
- (server) Migrate ListCommodities to new macro
- (server) Migrate CreateAccount to new macro
- (macro) Migrate from keyword to attribute
- (server) Migrate ListAccounts to new macro
- (server) Migrate GetAccount to new macro
- (server) Migrate CreateTransaction to new macro
- (server) Migrate ListTransactions to new macro
- (server) Migrate ListSplits to new macro
- (server) Migrate GetCommodity to new macro and cleanup
- (web) Add script for regular token refresh
- (web) Cleanup the logout and relogin
- (sql) Rename fields to fix sqlfluff and refactor the code
- (build) Generate version info in Drone build
- (ci) Fix the Drone CI and Dockerfile
- (ci) Fix the Drone CI Analyze stage
- (web) Remove the "Commodity" field from "Create Account" page
- (ci) Disable miri isolation
- (web) Update the jsonwebtoken to version 10
- (web) Cleanup all the templates and apply prettier
- (web) Fix the redirect loop
- (web) Print build date together with version
- (sql) Update the sqxl requests
- (web) Fix the argument validation path
- (ci) Disable mandatory sql check
- (sql) Update the sqlx prepared queries
- (web) Simplify the transaction listings for accounts
- (web) Rearrange the main page layout
- (web) Remove useless header
- (web) Rework the JS massively
- (web) Redesign the transaction creation form
- (web) Update css to align the sizes
- (web) Clean up the transaction list
- (web) Reduce the version block size
- (web) Update the transaction list to display name and balance
- (web) Parse the balances correctly in js
- (web) Fix the rational formatting everywhere
- (web) Cleanup the transaction display
- (server) Sort the accounts by latest transaction by default
- (web) Add the "Spend" button to transaction list
- (web) Trim the account name in autocompletion
7.1.7. Build
- Update Rust to 1.87
- Update Rust to 1.88 and bump deps
- Update Rust to 1.89 and bump deps
- Bump wasmtime to 35
- Update Rust to 1.90 and bump deps
- Bump deps
- Bump Rust to 1.91 and update deps
- Bump deps
7.1.8. Finance
- Module created
7.1.9. Naming
- Thus it shall be called - Nomisync
7.1.10. Web
- Duplicate the "to currency" from "from currency" by default
8. Copying
Νόμιsync is the personal accounting system for a wide variety of commodities. Copyright (C) 2025 Slava Barinov <rayslava@rayslava.com>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.
10. Coverage info
A tarpaulin report is available at coverage.