Metadata-Version: 2.3
Name: money-tracker
Version: 0.3.0
Summary: A reliable command-line money tracker
Author: robeth
Author-email: robeth <robethrahmatullah@gmail.comm>
Requires-Dist: alembic>=1.13,<2
Requires-Dist: click>=8.1,<9
Requires-Dist: flask>=3.1,<4
Requires-Dist: flask-wtf>=1.2,<2
Requires-Dist: gunicorn>=23,<24
Requires-Dist: platformdirs>=4,<5
Requires-Dist: rich>=13,<14
Requires-Dist: sqlalchemy>=2.0,<3
Requires-Dist: tomli-w>=1,<2
Requires-Dist: tomli>=2,<3 ; python_full_version < '3.11'
Requires-Python: >=3.10
Description-Content-Type: text/markdown

deferred to Phase 2.
# Money Tracker

Money Tracker is a Python application for tracking household accounts,
payees, transactions, category budgets, and reports in SQLite. It provides
both a command-line interface and a password-protected, server-rendered web
interface for household use.

## Quick start

Run the published executable without a global installation:

```bash
uvx money-tracker db init --user Alice --currency USD
uvx money-tracker account add --name Wallet --type cash
uvx money-tracker payee add --name Market --kind merchant
uvx money-tracker tx expense \
  --account Wallet --amount 24.95 \
  --payee Market --category Groceries --date 2026-09-20
uvx money-tracker tx list --json
```

Use `--json` when another program or an AI agent will parse the result.
Names are case-insensitive and unique within a database, so names are usually
easier than numeric IDs. Run `context --json` before a complex command to see
available users, accounts, balances, and categories. Context does not list
payees; use `payee list` or `payee show` when a payee reference is needed.

`db init` seeds these categories:

- `Income` (`income`)
- `Car` (`expense`) with `Fuel`, `Maintenance`, and `Upgrade` children
- `Groceries`, `Shopping`, and `Dining` (`expense`)

## Common usage

### Inspect the tracker

```bash
uvx money-tracker context --json
uvx money-tracker doctor --json
uvx money-tracker user list
uvx money-tracker account list
uvx money-tracker payee list
uvx money-tracker category list
```

`context` is the compact helicopter view for reference discovery. Human
output has separate Users, Accounts, and Categories sections; JSON has
`users`, `accounts`, and `categories` members. Use `--tree` to render
categories hierarchically, including nested `children` arrays in JSON.

Reference lists show active records by default. Use `--all` to include
archived/inactive records; human output then adds an `Active` column. JSON
always includes `is_active`. Audit fields (`created_at`, `created_by`,
`updated_at`, and `updated_by`) are hidden by default and can be requested
with `--include-audit`.

`doctor` is read-only and reports the selected database path, path source,
resolved path, parent directory, configuration path, permissions, SQLite
health, schema tables, Alembic revision, current executor, and package/runtime
checks. Use it first when a command appears to use the wrong database.

### Users and current executor

```bash
uvx money-tracker user add --name Bob --email bob@example.com
uvx money-tracker user edit Bob --email new@example.com
uvx money-tracker user use Bob
uvx money-tracker user current
uvx money-tracker user archive Bob
```

The current executor is stored in the local configuration file. Transaction
ownership is inferred from the account owner; transaction commands do not
take a separate user argument.

### Accounts, payees, and categories

```bash
uvx money-tracker account add \
  --name Checking --type checking --opening-balance 1000.00
uvx money-tracker account edit Checking \
  --type savings --owner Bob --opening-balance 1250.00
uvx money-tracker account archive Checking

uvx money-tracker payee add --name Acme --kind utility
uvx money-tracker payee edit Acme --kind merchant

uvx money-tracker category add \
  --name Fuel --type expense --parent Car
uvx money-tracker category edit Fuel --name Petrol
uvx money-tracker category archive Petrol
uvx money-tracker category list --tree
```

Valid account types are `cash`, `checking`, `savings`, `credit_card`,
`investment`, `loan`, and `other`. Valid category types are `income` and
`expense`. Invalid enum values are rejected with the valid values in the
error message.

### Transactions

Income, expense, transfer, account, budget, and report amounts use decimal
major units at the CLI boundary. For example, `123` is stored as `12300`
minor units. Human output and JSON use a two-decimal string plus an exact
minor-unit field:

```json
{"amount": "123.00", "amount_minor": 12300}
```

```bash
uvx money-tracker tx income \
  --account Checking --amount 2500.00 --date 2026-09-30 \
  --payee Employer --category Income
uvx money-tracker tx expense \
  --account Wallet --amount 42.50 --date 2026-09-20 \
  --payee Market --category Groceries --note "Weekly shopping"
uvx money-tracker tx transfer \
  --from Checking --to Wallet --amount 100.00 --date 2026-09-20
```

Transfers are stored as two legs sharing one event ID. Financial identity
(type, amount, and account legs) is not editable. Edit metadata when needed:

```bash
uvx money-tracker tx edit EVENT_ID \
  --date 2026-09-21 --category Dining --note "Corrected note"
uvx money-tracker tx reverse EVENT_ID \
  --date 2026-09-22 --note "Posted in error"
```

Transaction listing is paginated by default to keep agent output bounded.
Pagination counts logical events, not individual transfer legs:

```bash
uvx money-tracker tx list --json
uvx money-tracker tx list \
  --page 2 --page-size 25 --sort created_asc \
  --account Wallet --type expense --json
```

The JSON result has only `items` and `metadata` at the top level:

```json
{
  "items": [],
  "metadata": {
    "pagination": {
      "page": 2,
      "page_size": 25,
      "offset": 25,
      "total": 123,
      "shown": 25,
      "pages": 5,
      "has_previous": true,
      "has_next": true
    },
    "sort": {"field": "created", "direction": "asc"},
    "filter": {"account": "Wallet", "type": "expense"}
  }
}
```

Unset filters are omitted. Read `metadata.pagination` before requesting
another page. Human output prints the same page, offset, shown/total, sort,
and active-filter context above the table.

Valid transaction types are `income`, `expense`, and `transfer`.

### Budgets and reports

```bash
uvx money-tracker budget add \
  --name "Grocery budget" --category Groceries --amount 500.00 \
  --period monthly --start 2026-09-01 --recurring
uvx money-tracker budget edit "Grocery budget" \
  --category Dining --period yearly --start 2026-01-01
uvx money-tracker budget status "Grocery budget" \
  --from 2026-09-01 --to 2026-10-01 --json
```

Valid budget periods are `monthly` and `yearly`. Budgets must use an
`expense` category. Recurring budgets generate periods through the requested
report range.

```bash
uvx money-tracker report summary \
  --from 2026-01-01 --to 2027-01-01 \
  --granularity month --breakdown user \
  --breakdown account --breakdown category --json
```

Report ranges use the half-open interval `[from, to)`. Supported
granularities are `month`, `quarter`, and `year`; supported breakdowns are
`user`, `account`, and `category`.

## Command reference

| Command | Purpose |
| --- | --- |
| `db init` | Create the SQLite database, run Alembic migrations, create the first user, and seed categories |
| `doctor` | Read-only database, migration, runtime, and package diagnostics |
| `context` | Show users, accounts, balances, and categories for reference discovery |
| `user` | Add, list, show, edit, archive, select, and inspect the current executor |
| `account` | Add, list, show, edit, and archive accounts |
| `payee` | Add, list, show, edit, and archive payees/merchants |
| `category` | Add, list, show, edit, and archive categories |
| `tx` | Record income, expenses, transfers; list/show/edit/reverse events |
| `budget` | Add, list, show, edit, archive, and evaluate category budgets |
| `report summary` | Aggregate transactions over dynamic date ranges |

Every list/show/edit command accepts `--json` either after the command or as a
root option. References can be numeric IDs or unique names.

## Database and application configuration

Database selection precedence is:

1. `--db PATH`
2. `MONEY_TRACKER_DB`
3. `~/.money-tracker/data.db`

Normal workflows can omit all three. Use an explicit path when operating on
multiple independent household/tenant databases:

```bash
uvx money-tracker --db ./travel.db context --json
MONEY_TRACKER_DB=./home.db uvx money-tracker context --json
```

Each SQLite file is an independent configuration. Separate files provide
Phase 1 tenant isolation; this is not an organization, authentication, or
authorization system. `doctor --json` exposes the selected path, source
(`flag`, `environment`, or `default`), resolved path, and relevant parent
directory details to troubleshoot selection.

The current executor is stored in:

```text
~/.money-tracker/config.toml
```

The file contains only the selected user name. Use `user use NAME` to update
it. `MONEY_TRACKER_DB` selects a database file and does not select or
authenticate a user.

## Development

Install dependencies and run tests from the checkout:

```bash
uv sync --dev
uv run pytest -q
uv run money-tracker --help
```

`uv run` executes the local project in editable mode, so normal Python source
changes do not require recompilation. `uvx money-tracker` resolves the
published package and is best for package-install smoke tests.

Alembic migrations are used from day one. Database commands apply migrations
before opening an application session; do not edit the schema manually.

## Releasing

GitHub Actions runs the quality gates (`pytest`, chart tests, generated-CSS
freshness, package build smoke) on every pull request and push to `master`.
Publishing happens only for version tags:

```bash
# 1. set the new version in pyproject.toml and commit it to master
# 2. tag that commit and push the tag
git tag v0.2.0
git push origin v0.2.0
```

The tag must match `pyproject.toml`'s `version` or the publish workflow stops
before uploading anything. A matching tag publishes the `money-tracker`
package to PyPI and pushes the `robeth/money-tracker` image to Docker Hub
(tags `X.Y.Z`, `X.Y`, and `latest`).

One-time repository setup (documented in
`docs/superpowers/specs/2026-10-11-ci-cd-design.md`):

- PyPI and TestPyPI Trusted Publishers for `robeth/money-tracker` pointing at
  `publish.yml` / `publish-testpypi.yml` with the `pypi` / `testpypi`
  GitHub Environments (OIDC — no API tokens).
- Repository secrets `DOCKERHUB_USERNAME` and `DOCKERHUB_TOKEN`.
- Manual dry runs go to TestPyPI via the "Publish to TestPyPI" workflow.

## Local Web Demo

Install the development environment, then start the loopback-only web demo:

```bash
uv sync --dev
./scripts/run_local_web_demo.sh
```

Open `http://127.0.0.1:18765` and sign in with `money-tracker-local-test`.
After sign-in, choose `Calendar month` and `March 2026` in the dashboard
period controls to see sample activity. The ignored `.local/` directory holds
`web-demo.db` and its selected-user config. The database uses the deterministic
Q1 2026 household scenario from `tests/test_household_scenario.py`: three
users, five accounts, budgets, and 300 income, expense, and transfer events.
Its dates are fixed to January through March 2026.

The launcher binds only to `127.0.0.1`. Its fixed password and secret key are
for local testing only; do not expose this server to your network or the
internet. Stop it with `Ctrl+C`.

To reset all demo transactions and references, stop the server and remove
`.local/web-demo.db`, then run the launcher again. Existing demo databases are
migrated but never reseeded or overwritten automatically.

## Home-Network Web Interface

The web interface is intended for a trusted home network. Its sample Compose
configuration publishes the service on all host interfaces so a phone on the
same Wi-Fi can connect. The example uses plain HTTP and is not safe for public
internet exposure; remote access needs TLS and an explicit access-control
design.

Copy the environment template and replace both placeholders with unique,
strong values before starting the service:

```bash
cp .env.example .env
```

Initialize the persistent database and its first user explicitly. Replace
`NAME` and `USD` with the household's executor name and base currency:

```bash
docker compose -f compose.example.yaml run --rm web money-tracker db init --user NAME --currency USD
docker compose -f compose.example.yaml up -d
```

Schema upgrades are also explicit:

```bash
docker compose -f compose.example.yaml run --rm web money-tracker db upgrade
```

Open `http://<computer-lan-address>:8000` from a device on the same trusted
Wi-Fi. Find the computer's LAN address in its network settings or with the
operating system's IP address command. The dashboard and all data routes
require the configured web password. The database and current-user
configuration persist in the named `money_tracker_data` volume.

To bind to a particular host interface or port, set `MONEY_TRACKER_HOST` or
`MONEY_TRACKER_PORT` in `.env`. Keep `.env` private; it is excluded from git.
