getfin 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- getfin-1.0.0/.gitignore +23 -0
- getfin-1.0.0/LICENSE +133 -0
- getfin-1.0.0/PKG-INFO +499 -0
- getfin-1.0.0/README.md +324 -0
- getfin-1.0.0/pyproject.toml +82 -0
- getfin-1.0.0/src/fin/__init__.py +0 -0
- getfin-1.0.0/src/fin/audit.py +305 -0
- getfin-1.0.0/src/fin/cache.py +167 -0
- getfin-1.0.0/src/fin/categorize.py +338 -0
- getfin-1.0.0/src/fin/classifier.py +598 -0
- getfin-1.0.0/src/fin/cli.py +2885 -0
- getfin-1.0.0/src/fin/close_books.py +659 -0
- getfin-1.0.0/src/fin/config.py +116 -0
- getfin-1.0.0/src/fin/credentials.py +163 -0
- getfin-1.0.0/src/fin/csv_import.py +364 -0
- getfin-1.0.0/src/fin/dates.py +354 -0
- getfin-1.0.0/src/fin/db.py +1310 -0
- getfin-1.0.0/src/fin/demo.py +250 -0
- getfin-1.0.0/src/fin/integrity.py +136 -0
- getfin-1.0.0/src/fin/legacy_analysis.py +851 -0
- getfin-1.0.0/src/fin/legacy_classify.py +2356 -0
- getfin-1.0.0/src/fin/log.py +11 -0
- getfin-1.0.0/src/fin/models.py +21 -0
- getfin-1.0.0/src/fin/money.py +295 -0
- getfin-1.0.0/src/fin/normalize.py +204 -0
- getfin-1.0.0/src/fin/planner.py +429 -0
- getfin-1.0.0/src/fin/projections.py +555 -0
- getfin-1.0.0/src/fin/reconciliation.py +580 -0
- getfin-1.0.0/src/fin/refund_matching.py +446 -0
- getfin-1.0.0/src/fin/report_service.py +293 -0
- getfin-1.0.0/src/fin/reporting.py +371 -0
- getfin-1.0.0/src/fin/reporting_models.py +271 -0
- getfin-1.0.0/src/fin/simplefin_client.py +221 -0
- getfin-1.0.0/src/fin/static/css/fin_drilldown.css +206 -0
- getfin-1.0.0/src/fin/static/js/fin_api.js +37 -0
- getfin-1.0.0/src/fin/static/js/fin_drilldown.js +500 -0
- getfin-1.0.0/src/fin/static/js/fin_ui.js +133 -0
- getfin-1.0.0/src/fin/status_commands.py +512 -0
- getfin-1.0.0/src/fin/templates/audit.html +510 -0
- getfin-1.0.0/src/fin/templates/base.html +3638 -0
- getfin-1.0.0/src/fin/templates/budget.html +554 -0
- getfin-1.0.0/src/fin/templates/commitments.html +461 -0
- getfin-1.0.0/src/fin/templates/connect.html +1003 -0
- getfin-1.0.0/src/fin/templates/dashboard.html +1391 -0
- getfin-1.0.0/src/fin/templates/dashboard_v2.html +1767 -0
- getfin-1.0.0/src/fin/templates/insights.html +187 -0
- getfin-1.0.0/src/fin/templates/plan.html +18 -0
- getfin-1.0.0/src/fin/templates/subs.html +466 -0
- getfin-1.0.0/src/fin/templates/sync-log.html +276 -0
- getfin-1.0.0/src/fin/tls.py +214 -0
- getfin-1.0.0/src/fin/transfer_pairing.py +426 -0
- getfin-1.0.0/src/fin/versioning.py +84 -0
- getfin-1.0.0/src/fin/view_models.py +479 -0
- getfin-1.0.0/src/fin/web.py +4067 -0
- getfin-1.0.0/tests/__init__.py +1 -0
- getfin-1.0.0/tests/conftest.py +482 -0
- getfin-1.0.0/tests/test_analysis.py +345 -0
- getfin-1.0.0/tests/test_audit.py +151 -0
- getfin-1.0.0/tests/test_backup_export.py +411 -0
- getfin-1.0.0/tests/test_classifier.py +379 -0
- getfin-1.0.0/tests/test_cli_integration.py +484 -0
- getfin-1.0.0/tests/test_commitments.py +972 -0
- getfin-1.0.0/tests/test_credentials.py +354 -0
- getfin-1.0.0/tests/test_csv_import.py +312 -0
- getfin-1.0.0/tests/test_dashboard_metrics.py +154 -0
- getfin-1.0.0/tests/test_dates.py +290 -0
- getfin-1.0.0/tests/test_duplicate_detection.py +469 -0
- getfin-1.0.0/tests/test_insights_route.py +191 -0
- getfin-1.0.0/tests/test_known_subscriptions.py +239 -0
- getfin-1.0.0/tests/test_money.py +336 -0
- getfin-1.0.0/tests/test_no_legacy_engine.py +402 -0
- getfin-1.0.0/tests/test_period_selection.py +248 -0
- getfin-1.0.0/tests/test_reconciliation.py +338 -0
- getfin-1.0.0/tests/test_refund_matching.py +287 -0
- getfin-1.0.0/tests/test_reporting.py +237 -0
- getfin-1.0.0/tests/test_simplefin_setup.py +144 -0
- getfin-1.0.0/tests/test_sketchy_detection.py +482 -0
- getfin-1.0.0/tests/test_transfer_pairing.py +357 -0
- getfin-1.0.0/tests/test_txn_type_overrides.py +190 -0
- getfin-1.0.0/tests/test_web_functional.py +628 -0
getfin-1.0.0/.gitignore
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
.env
|
|
2
|
+
|
|
3
|
+
data/
|
|
4
|
+
exports/
|
|
5
|
+
|
|
6
|
+
__pycache__/
|
|
7
|
+
.pytest_cache/
|
|
8
|
+
*.egg-info/
|
|
9
|
+
dist/
|
|
10
|
+
build/
|
|
11
|
+
*.log
|
|
12
|
+
*.pyc
|
|
13
|
+
*.pyo
|
|
14
|
+
*.pyd
|
|
15
|
+
*.sqlite
|
|
16
|
+
*.db
|
|
17
|
+
*.test_backup
|
|
18
|
+
.vscode/
|
|
19
|
+
|
|
20
|
+
# Local files
|
|
21
|
+
.claude/
|
|
22
|
+
BACKLOG.md
|
|
23
|
+
buglist.txt
|
getfin-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# PolyForm Noncommercial License 1.0.0
|
|
2
|
+
|
|
3
|
+
<https://polyformproject.org/licenses/noncommercial/1.0.0>
|
|
4
|
+
|
|
5
|
+
Required Notice: Copyright Arclight Engineering (http://www.arclighteng.com)
|
|
6
|
+
|
|
7
|
+
## Acceptance
|
|
8
|
+
|
|
9
|
+
In order to get any license under these terms, you must agree
|
|
10
|
+
to them as both strict obligations and conditions to all
|
|
11
|
+
your licenses.
|
|
12
|
+
|
|
13
|
+
## Copyright License
|
|
14
|
+
|
|
15
|
+
The licensor grants you a copyright license for the
|
|
16
|
+
software to do everything you might do with the software
|
|
17
|
+
that would otherwise infringe the licensor's copyright
|
|
18
|
+
in it for any permitted purpose. However, you may
|
|
19
|
+
only distribute the software according to [Distribution
|
|
20
|
+
License](#distribution-license) and make changes or new works
|
|
21
|
+
based on the software according to [Changes and New Works
|
|
22
|
+
License](#changes-and-new-works-license).
|
|
23
|
+
|
|
24
|
+
## Distribution License
|
|
25
|
+
|
|
26
|
+
The licensor grants you an additional copyright license
|
|
27
|
+
to distribute copies of the software. Your license
|
|
28
|
+
to distribute covers distributing the software with
|
|
29
|
+
changes and new works permitted by [Changes and New Works
|
|
30
|
+
License](#changes-and-new-works-license).
|
|
31
|
+
|
|
32
|
+
## Notices
|
|
33
|
+
|
|
34
|
+
You must ensure that anyone who gets a copy of any part of
|
|
35
|
+
the software from you also gets a copy of these terms or the
|
|
36
|
+
URL for them above, as well as copies of any plain-text lines
|
|
37
|
+
beginning with `Required Notice:` that the licensor provided
|
|
38
|
+
with the software. For example:
|
|
39
|
+
|
|
40
|
+
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
41
|
+
|
|
42
|
+
## Changes and New Works License
|
|
43
|
+
|
|
44
|
+
The licensor grants you an additional copyright license to
|
|
45
|
+
make changes and new works based on the software for any
|
|
46
|
+
permitted purpose.
|
|
47
|
+
|
|
48
|
+
## Patent License
|
|
49
|
+
|
|
50
|
+
The licensor grants you a patent license for the software that
|
|
51
|
+
covers patent claims the licensor can license, or becomes able
|
|
52
|
+
to license, that you would infringe by using the software.
|
|
53
|
+
|
|
54
|
+
## Noncommercial Purposes
|
|
55
|
+
|
|
56
|
+
Any noncommercial purpose is a permitted purpose.
|
|
57
|
+
|
|
58
|
+
## Personal Uses
|
|
59
|
+
|
|
60
|
+
Personal use for research, experiment, and testing for
|
|
61
|
+
the benefit of public knowledge, personal study, private
|
|
62
|
+
entertainment, hobby projects, amateur pursuits, or religious
|
|
63
|
+
observance, without any anticipated commercial application,
|
|
64
|
+
is use for a permitted purpose.
|
|
65
|
+
|
|
66
|
+
## Noncommercial Organizations
|
|
67
|
+
|
|
68
|
+
Use by any charitable organization, educational institution,
|
|
69
|
+
public research organization, public safety or health
|
|
70
|
+
organization, environmental protection organization,
|
|
71
|
+
or government institution is use for a permitted purpose
|
|
72
|
+
regardless of the source of funding or obligations resulting
|
|
73
|
+
from the funding.
|
|
74
|
+
|
|
75
|
+
## Fair Use
|
|
76
|
+
|
|
77
|
+
You may have "fair use" rights for the software under the
|
|
78
|
+
law. These terms do not limit them.
|
|
79
|
+
|
|
80
|
+
## No Other Rights
|
|
81
|
+
|
|
82
|
+
These terms do not allow you to sublicense or transfer any of
|
|
83
|
+
your licenses to anyone else, or prevent the licensor from
|
|
84
|
+
granting licenses to anyone else. These terms do not imply
|
|
85
|
+
any other licenses.
|
|
86
|
+
|
|
87
|
+
## Patent Defense
|
|
88
|
+
|
|
89
|
+
If you make any written claim that the software infringes or
|
|
90
|
+
contributes to infringement of any patent, your patent license
|
|
91
|
+
for the software granted under these terms ends immediately. If
|
|
92
|
+
your company makes such a claim, your patent license ends
|
|
93
|
+
immediately for work on behalf of your company.
|
|
94
|
+
|
|
95
|
+
## Violations
|
|
96
|
+
|
|
97
|
+
The first time you are notified in writing that you have
|
|
98
|
+
violated any of these terms, or done anything with the software
|
|
99
|
+
not covered by your licenses, your licenses can nonetheless
|
|
100
|
+
continue if you come into full compliance with these terms,
|
|
101
|
+
and take practical steps to correct past violations, within
|
|
102
|
+
32 days of receiving notice. Otherwise, all your licenses
|
|
103
|
+
end immediately.
|
|
104
|
+
|
|
105
|
+
## No Liability
|
|
106
|
+
|
|
107
|
+
***As far as the law allows, the software comes as is, without
|
|
108
|
+
any warranty or condition, and the licensor will not be liable
|
|
109
|
+
to you for any damages arising out of these terms or the use
|
|
110
|
+
or nature of the software, under any kind of legal claim.***
|
|
111
|
+
|
|
112
|
+
## Definitions
|
|
113
|
+
|
|
114
|
+
The **licensor** is the individual or entity offering these
|
|
115
|
+
terms, and the **software** is the software the licensor makes
|
|
116
|
+
available under these terms.
|
|
117
|
+
|
|
118
|
+
**You** refers to the individual or entity agreeing to these
|
|
119
|
+
terms.
|
|
120
|
+
|
|
121
|
+
**Your company** is any legal entity, sole proprietorship,
|
|
122
|
+
or other kind of organization that you work for, plus all
|
|
123
|
+
organizations that have control over, are under the control of,
|
|
124
|
+
or are under common control with that organization. **Control**
|
|
125
|
+
means ownership of substantially all the assets of an entity,
|
|
126
|
+
or the power to direct its management and policies by vote,
|
|
127
|
+
contract, or otherwise. Control can be direct or indirect.
|
|
128
|
+
|
|
129
|
+
**Your licenses** are all the licenses granted to you for the
|
|
130
|
+
software under these terms.
|
|
131
|
+
|
|
132
|
+
**Use** means anything you do with the software requiring one
|
|
133
|
+
of your licenses.
|
getfin-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: getfin
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Local-first personal finance — sync with your bank, detect subscriptions, track spending. All data stays on your machine.
|
|
5
|
+
Project-URL: Homepage, https://github.com/arclighteng/fin
|
|
6
|
+
Project-URL: Documentation, https://github.com/arclighteng/fin#readme
|
|
7
|
+
Author-email: Arclight Engineering <hello@arclighteng.com>
|
|
8
|
+
License: # PolyForm Noncommercial License 1.0.0
|
|
9
|
+
|
|
10
|
+
<https://polyformproject.org/licenses/noncommercial/1.0.0>
|
|
11
|
+
|
|
12
|
+
Required Notice: Copyright Arclight Engineering (http://www.arclighteng.com)
|
|
13
|
+
|
|
14
|
+
## Acceptance
|
|
15
|
+
|
|
16
|
+
In order to get any license under these terms, you must agree
|
|
17
|
+
to them as both strict obligations and conditions to all
|
|
18
|
+
your licenses.
|
|
19
|
+
|
|
20
|
+
## Copyright License
|
|
21
|
+
|
|
22
|
+
The licensor grants you a copyright license for the
|
|
23
|
+
software to do everything you might do with the software
|
|
24
|
+
that would otherwise infringe the licensor's copyright
|
|
25
|
+
in it for any permitted purpose. However, you may
|
|
26
|
+
only distribute the software according to [Distribution
|
|
27
|
+
License](#distribution-license) and make changes or new works
|
|
28
|
+
based on the software according to [Changes and New Works
|
|
29
|
+
License](#changes-and-new-works-license).
|
|
30
|
+
|
|
31
|
+
## Distribution License
|
|
32
|
+
|
|
33
|
+
The licensor grants you an additional copyright license
|
|
34
|
+
to distribute copies of the software. Your license
|
|
35
|
+
to distribute covers distributing the software with
|
|
36
|
+
changes and new works permitted by [Changes and New Works
|
|
37
|
+
License](#changes-and-new-works-license).
|
|
38
|
+
|
|
39
|
+
## Notices
|
|
40
|
+
|
|
41
|
+
You must ensure that anyone who gets a copy of any part of
|
|
42
|
+
the software from you also gets a copy of these terms or the
|
|
43
|
+
URL for them above, as well as copies of any plain-text lines
|
|
44
|
+
beginning with `Required Notice:` that the licensor provided
|
|
45
|
+
with the software. For example:
|
|
46
|
+
|
|
47
|
+
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
48
|
+
|
|
49
|
+
## Changes and New Works License
|
|
50
|
+
|
|
51
|
+
The licensor grants you an additional copyright license to
|
|
52
|
+
make changes and new works based on the software for any
|
|
53
|
+
permitted purpose.
|
|
54
|
+
|
|
55
|
+
## Patent License
|
|
56
|
+
|
|
57
|
+
The licensor grants you a patent license for the software that
|
|
58
|
+
covers patent claims the licensor can license, or becomes able
|
|
59
|
+
to license, that you would infringe by using the software.
|
|
60
|
+
|
|
61
|
+
## Noncommercial Purposes
|
|
62
|
+
|
|
63
|
+
Any noncommercial purpose is a permitted purpose.
|
|
64
|
+
|
|
65
|
+
## Personal Uses
|
|
66
|
+
|
|
67
|
+
Personal use for research, experiment, and testing for
|
|
68
|
+
the benefit of public knowledge, personal study, private
|
|
69
|
+
entertainment, hobby projects, amateur pursuits, or religious
|
|
70
|
+
observance, without any anticipated commercial application,
|
|
71
|
+
is use for a permitted purpose.
|
|
72
|
+
|
|
73
|
+
## Noncommercial Organizations
|
|
74
|
+
|
|
75
|
+
Use by any charitable organization, educational institution,
|
|
76
|
+
public research organization, public safety or health
|
|
77
|
+
organization, environmental protection organization,
|
|
78
|
+
or government institution is use for a permitted purpose
|
|
79
|
+
regardless of the source of funding or obligations resulting
|
|
80
|
+
from the funding.
|
|
81
|
+
|
|
82
|
+
## Fair Use
|
|
83
|
+
|
|
84
|
+
You may have "fair use" rights for the software under the
|
|
85
|
+
law. These terms do not limit them.
|
|
86
|
+
|
|
87
|
+
## No Other Rights
|
|
88
|
+
|
|
89
|
+
These terms do not allow you to sublicense or transfer any of
|
|
90
|
+
your licenses to anyone else, or prevent the licensor from
|
|
91
|
+
granting licenses to anyone else. These terms do not imply
|
|
92
|
+
any other licenses.
|
|
93
|
+
|
|
94
|
+
## Patent Defense
|
|
95
|
+
|
|
96
|
+
If you make any written claim that the software infringes or
|
|
97
|
+
contributes to infringement of any patent, your patent license
|
|
98
|
+
for the software granted under these terms ends immediately. If
|
|
99
|
+
your company makes such a claim, your patent license ends
|
|
100
|
+
immediately for work on behalf of your company.
|
|
101
|
+
|
|
102
|
+
## Violations
|
|
103
|
+
|
|
104
|
+
The first time you are notified in writing that you have
|
|
105
|
+
violated any of these terms, or done anything with the software
|
|
106
|
+
not covered by your licenses, your licenses can nonetheless
|
|
107
|
+
continue if you come into full compliance with these terms,
|
|
108
|
+
and take practical steps to correct past violations, within
|
|
109
|
+
32 days of receiving notice. Otherwise, all your licenses
|
|
110
|
+
end immediately.
|
|
111
|
+
|
|
112
|
+
## No Liability
|
|
113
|
+
|
|
114
|
+
***As far as the law allows, the software comes as is, without
|
|
115
|
+
any warranty or condition, and the licensor will not be liable
|
|
116
|
+
to you for any damages arising out of these terms or the use
|
|
117
|
+
or nature of the software, under any kind of legal claim.***
|
|
118
|
+
|
|
119
|
+
## Definitions
|
|
120
|
+
|
|
121
|
+
The **licensor** is the individual or entity offering these
|
|
122
|
+
terms, and the **software** is the software the licensor makes
|
|
123
|
+
available under these terms.
|
|
124
|
+
|
|
125
|
+
**You** refers to the individual or entity agreeing to these
|
|
126
|
+
terms.
|
|
127
|
+
|
|
128
|
+
**Your company** is any legal entity, sole proprietorship,
|
|
129
|
+
or other kind of organization that you work for, plus all
|
|
130
|
+
organizations that have control over, are under the control of,
|
|
131
|
+
or are under common control with that organization. **Control**
|
|
132
|
+
means ownership of substantially all the assets of an entity,
|
|
133
|
+
or the power to direct its management and policies by vote,
|
|
134
|
+
contract, or otherwise. Control can be direct or indirect.
|
|
135
|
+
|
|
136
|
+
**Your licenses** are all the licenses granted to you for the
|
|
137
|
+
software under these terms.
|
|
138
|
+
|
|
139
|
+
**Use** means anything you do with the software requiring one
|
|
140
|
+
of your licenses.
|
|
141
|
+
License-File: LICENSE
|
|
142
|
+
Classifier: Development Status :: 4 - Beta
|
|
143
|
+
Classifier: Environment :: Console
|
|
144
|
+
Classifier: Environment :: Web Environment
|
|
145
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
146
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
147
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
148
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
149
|
+
Requires-Python: >=3.12
|
|
150
|
+
Requires-Dist: fastapi
|
|
151
|
+
Requires-Dist: filelock>=3.13.0
|
|
152
|
+
Requires-Dist: httpx>=0.27.0
|
|
153
|
+
Requires-Dist: jinja2>=3.1.0
|
|
154
|
+
Requires-Dist: keyring>=25.0.0
|
|
155
|
+
Requires-Dist: numpy>=1.24.0
|
|
156
|
+
Requires-Dist: pydantic>=2.7.0
|
|
157
|
+
Requires-Dist: python-dateutil>=2.9.0
|
|
158
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
159
|
+
Requires-Dist: python-multipart>=0.0.9
|
|
160
|
+
Requires-Dist: rich>=13.7.0
|
|
161
|
+
Requires-Dist: slowapi>=0.1.9
|
|
162
|
+
Requires-Dist: tenacity>=8.2.0
|
|
163
|
+
Requires-Dist: typer>=0.12.0
|
|
164
|
+
Requires-Dist: tzdata>=2024.1
|
|
165
|
+
Requires-Dist: uvicorn
|
|
166
|
+
Provides-Extra: dev
|
|
167
|
+
Requires-Dist: httpx>=0.27.0; extra == 'dev'
|
|
168
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
169
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
|
|
170
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
171
|
+
Provides-Extra: ml
|
|
172
|
+
Requires-Dist: sentence-transformers>=2.2.0; extra == 'ml'
|
|
173
|
+
Requires-Dist: torch>=2.0.0; extra == 'ml'
|
|
174
|
+
Description-Content-Type: text/markdown
|
|
175
|
+
|
|
176
|
+
# fin
|
|
177
|
+
|
|
178
|
+
A local-first personal finance tool. Syncs with your bank accounts via SimpleFIN or import CSV directly—analyzes spending patterns, detects subscriptions, and keeps your data local with encrypted backups.
|
|
179
|
+
|
|
180
|
+
## Features
|
|
181
|
+
|
|
182
|
+
**Security & Privacy**
|
|
183
|
+
- **Local-Only Data**: All data stays on your machine in SQLite. No cloud sync, no tracking.
|
|
184
|
+
- **System Keyring**: Credentials stored in OS secure storage (Keychain, Credential Manager, Secret Service)
|
|
185
|
+
- **Encrypted Backups**: Age encryption for portable, audited backup files
|
|
186
|
+
|
|
187
|
+
**Accuracy & Trust**
|
|
188
|
+
- **Known Service Detection**: 150+ subscription services recognized instantly (Netflix, Spotify, etc.)
|
|
189
|
+
- **Pattern Validation**: `fin audit-subs` verifies detection accuracy—no false positives
|
|
190
|
+
- **Manual Override**: Correct any miscategorization; your choice persists
|
|
191
|
+
|
|
192
|
+
**Analysis**
|
|
193
|
+
- **Dashboard**: Visual overview of income, spending, alerts, and subscriptions
|
|
194
|
+
- **Smart Categorization**: Automatic transaction categorization with manual override
|
|
195
|
+
- **Subscription Detection**: Finds recurring charges and separates subscriptions from utility bills
|
|
196
|
+
- **Alerts**: Detects duplicate charges, unusual amounts, price increases
|
|
197
|
+
- **Bundle Detection**: Flags potential duplicate subscriptions (Disney+/Hulu/ESPN+ overlap)
|
|
198
|
+
|
|
199
|
+
**Interface**
|
|
200
|
+
- **Web Dashboard**: Full-featured UI at localhost
|
|
201
|
+
- **CLI Tools**: Complete command-line interface for automation
|
|
202
|
+
- **Mobile Responsive**: Works on phone, tablet, and desktop
|
|
203
|
+
- **Dark Mode**: Easy on the eyes
|
|
204
|
+
|
|
205
|
+
## Getting Started
|
|
206
|
+
|
|
207
|
+
> **Two install paths are in progress.** A guided installer (no Python required, wizard-based setup) is under active development. The manual path below is current and stable.
|
|
208
|
+
|
|
209
|
+
### Manual Install (Python required)
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# 1. Create virtual environment
|
|
213
|
+
python -m venv .venv
|
|
214
|
+
.venv\Scripts\activate # Windows
|
|
215
|
+
# source .venv/bin/activate # Mac/Linux
|
|
216
|
+
|
|
217
|
+
# 2. Install
|
|
218
|
+
pip install -e .
|
|
219
|
+
|
|
220
|
+
# 3. Start the web dashboard
|
|
221
|
+
fin web
|
|
222
|
+
# Browser opens automatically to http://127.0.0.1:8000/dashboard
|
|
223
|
+
# If no data exists, demo data loads with a "Connect your bank" banner
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
The database is stored automatically at:
|
|
227
|
+
- **Windows**: `%APPDATA%\fin\fin.db`
|
|
228
|
+
- **macOS/Linux**: `~/.local/share/fin/fin.db`
|
|
229
|
+
|
|
230
|
+
Override with `FIN_DB_PATH` if needed.
|
|
231
|
+
|
|
232
|
+
### Connecting Your Bank
|
|
233
|
+
|
|
234
|
+
From the dashboard, click **"Connect your bank"** to open the setup page. Two options:
|
|
235
|
+
|
|
236
|
+
**Import CSV** (easiest — no account required)
|
|
237
|
+
1. Log into your bank and download a transaction export (CSV)
|
|
238
|
+
2. Drag and drop it onto the import page
|
|
239
|
+
3. fin detects the format automatically for Chase, BofA, Amex, Wells Fargo, and Capital One; shows a preview before importing
|
|
240
|
+
|
|
241
|
+
**SimpleFIN** (automatic daily sync, ~$1.50/month)
|
|
242
|
+
1. Go to [SimpleFIN Bridge](https://beta-bridge.simplefin.org/), subscribe, and link your bank
|
|
243
|
+
2. Copy your Setup Token
|
|
244
|
+
3. Paste it into the SimpleFIN section on the connect page
|
|
245
|
+
|
|
246
|
+
See [docs/SIMPLEFIN_SETUP.md](docs/SIMPLEFIN_SETUP.md) for detailed SimpleFIN instructions.
|
|
247
|
+
|
|
248
|
+
### Docker
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
# 1. Configure
|
|
252
|
+
cp .env.example .env
|
|
253
|
+
# Edit .env with your SimpleFIN access URL
|
|
254
|
+
|
|
255
|
+
# 2. Build & run
|
|
256
|
+
docker compose build
|
|
257
|
+
docker compose run --rm fin sync
|
|
258
|
+
docker compose run --rm fin web
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Security
|
|
262
|
+
|
|
263
|
+
Your financial data is sensitive. fin is designed with security as a priority.
|
|
264
|
+
|
|
265
|
+
### Credential Storage
|
|
266
|
+
|
|
267
|
+
**Recommended: System Keyring**
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
fin credentials set
|
|
271
|
+
# Prompted for SimpleFIN Access URL, stored securely
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Credentials are stored in:
|
|
275
|
+
- **Windows**: Credential Manager
|
|
276
|
+
- **macOS**: Keychain
|
|
277
|
+
- **Linux**: Secret Service (GNOME Keyring, KWallet)
|
|
278
|
+
|
|
279
|
+
Check status: `fin credentials status`
|
|
280
|
+
|
|
281
|
+
**Alternative: Environment File**
|
|
282
|
+
|
|
283
|
+
Create a `.env` file (gitignored):
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
SIMPLEFIN_ACCESS_URL=https://your-access-url-from-simplefin
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Keyring takes priority over .env if both are configured.
|
|
290
|
+
|
|
291
|
+
### Data Protection
|
|
292
|
+
|
|
293
|
+
**Full-Disk Encryption (Recommended)**
|
|
294
|
+
|
|
295
|
+
Enable your OS's built-in encryption:
|
|
296
|
+
|
|
297
|
+
| OS | Solution |
|
|
298
|
+
|----|----------|
|
|
299
|
+
| Windows | BitLocker (Pro/Enterprise) or VeraCrypt |
|
|
300
|
+
| macOS | FileVault |
|
|
301
|
+
| Linux | LUKS |
|
|
302
|
+
|
|
303
|
+
This protects your database at rest with zero configuration in fin.
|
|
304
|
+
|
|
305
|
+
**Encrypted Backups**
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
# Create encrypted backup with passphrase
|
|
309
|
+
fin export-backup -p
|
|
310
|
+
|
|
311
|
+
# Or with age public key (for automated backups)
|
|
312
|
+
fin export-backup -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
|
|
313
|
+
|
|
314
|
+
# Decrypt later
|
|
315
|
+
age -d -o fin.db fin_backup_20260123.finbak
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Requires `age`: `winget install FiloSottile.age` (Windows) / `brew install age` (macOS) / `apt install age` (Linux).
|
|
319
|
+
|
|
320
|
+
### Why This Architecture?
|
|
321
|
+
|
|
322
|
+
We chose OS-level encryption + encrypted exports over SQLCipher because:
|
|
323
|
+
1. Zero configuration for users who already have FileVault/BitLocker enabled
|
|
324
|
+
2. No additional dependencies or build complexity
|
|
325
|
+
3. `age` is a modern, audited tool with better key management
|
|
326
|
+
4. You control when encryption happens (backups) vs always-on overhead
|
|
327
|
+
|
|
328
|
+
## Web Dashboard
|
|
329
|
+
|
|
330
|
+
The dashboard displays your financial overview in a 5-card responsive layout.
|
|
331
|
+
|
|
332
|
+
### Card 1: Cash Flow (Hero)
|
|
333
|
+
Shows income vs expenses side-by-side with a big "Kept $X" or "Over $X" number, savings rate, and a 3-month rolling comparison. Mid-month pacing projection appears if you're still in the current month. Pending transactions show a warning if they exceed the typical threshold.
|
|
334
|
+
|
|
335
|
+
### Card 2: Monthly Commitments
|
|
336
|
+
Lists detected subscriptions and utility bills (using pattern detection over 400 days). Click any item to see all transactions from that merchant. Shows total committed this month as a percentage of income with a color-coded bar (green under 50%, yellow 50-70%, red over 70%). Inline price change alerts flag recent increases. Footer breaks down subscription vs bill totals.
|
|
337
|
+
|
|
338
|
+
### Card 3: Spending Breakdown
|
|
339
|
+
Top 7 spending categories with horizontal bars and 3-month averages. Click any category to drill down to merchants and transactions. Outlier badges (+X%) highlight categories that exceed their 3-month average. Footer shows total vs 3-month comparison.
|
|
340
|
+
|
|
341
|
+
### Card 4: Heads Up
|
|
342
|
+
Shows unusual charges with dismiss actions ("Looks fine" / "Flag it"), multi-month spending trends, and bill deviation alerts. When empty, displays "Nothing unusual this month."
|
|
343
|
+
|
|
344
|
+
### Card 5: Your Trend
|
|
345
|
+
6-month bar chart of net cash flow (kept vs over). Green bars for positive months, red for negative. Current month shown as dashed outline. Click any bar to navigate to that month. Footer shows 6-month average.
|
|
346
|
+
|
|
347
|
+
### Navigation & Controls
|
|
348
|
+
- **Month navigation**: Previous/next buttons with current month indicator dot
|
|
349
|
+
- **Account filter**: Multi-select dropdown to focus on specific accounts
|
|
350
|
+
- **Transaction search**: Live results dropdown—type a merchant name or amount to find transactions
|
|
351
|
+
- **Keyboard accessible**: Tab navigation, Enter to select, Escape to close dropdowns
|
|
352
|
+
|
|
353
|
+
### Drilldown System
|
|
354
|
+
Click any number, bar, category, or merchant to open a modal with the full transaction list. Sortable columns, account filtering, and scopes including income, spend, recurring, discretionary, net, merchant, and category.
|
|
355
|
+
|
|
356
|
+
## Other Pages
|
|
357
|
+
|
|
358
|
+
**Connect** (`/connect`)
|
|
359
|
+
Import CSV files or connect via SimpleFIN. Drag-and-drop CSV upload with automatic format detection for major banks.
|
|
360
|
+
|
|
361
|
+
**Recurring Charges** (`/subs`)
|
|
362
|
+
Dedicated page for subscriptions and utility bills. Filter by account, see payment history, toggle between subscription and bill types, and export to CSV.
|
|
363
|
+
|
|
364
|
+
**Budget** (`/budget`)
|
|
365
|
+
Set spending targets by category. Compare targets vs actual spending with visual indicators.
|
|
366
|
+
|
|
367
|
+
**Audit** (`/audit`)
|
|
368
|
+
Review and correct transaction categorization. Manages override history for future reference.
|
|
369
|
+
|
|
370
|
+
## Subscription Detection
|
|
371
|
+
|
|
372
|
+
fin uses a two-tier approach to find subscriptions:
|
|
373
|
+
|
|
374
|
+
### Known Services (Instant)
|
|
375
|
+
|
|
376
|
+
150+ well-known services are recognized immediately, even with just one charge:
|
|
377
|
+
- Streaming: Netflix, Hulu, Disney+, HBO Max, YouTube TV, Spotify
|
|
378
|
+
- Software: Adobe, Microsoft 365, GitHub, ChatGPT, 1Password
|
|
379
|
+
- Fitness: Peloton, Planet Fitness, Strava
|
|
380
|
+
- And many more...
|
|
381
|
+
|
|
382
|
+
### Pattern Detection (3+ charges)
|
|
383
|
+
|
|
384
|
+
Unknown merchants are detected via:
|
|
385
|
+
- Consistent amounts (low variance)
|
|
386
|
+
- Regular intervals (weekly, monthly, annual)
|
|
387
|
+
- Recurring payment indicators
|
|
388
|
+
|
|
389
|
+
### Verifying Accuracy
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
# Audit what's being detected
|
|
393
|
+
fin audit-subs
|
|
394
|
+
|
|
395
|
+
# Show all detected (including pattern-based)
|
|
396
|
+
fin audit-subs --all
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Bundle Detection
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
fin bundle-check
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Flags vendor families where you might be paying twice (Disney+/Hulu/ESPN+, Apple services, etc.)
|
|
406
|
+
|
|
407
|
+
## CLI Commands
|
|
408
|
+
|
|
409
|
+
### Everyday Use
|
|
410
|
+
|
|
411
|
+
| Command | Description |
|
|
412
|
+
|---------|-------------|
|
|
413
|
+
| `fin sync` | Pull latest transactions from bank |
|
|
414
|
+
| `fin web` | Start the web dashboard (browser opens automatically) |
|
|
415
|
+
| `fin web --no-browser` | Start without auto-opening browser |
|
|
416
|
+
| `fin status` | Financial status at a glance (CLI) |
|
|
417
|
+
| `fin trend` | Monthly trend over time |
|
|
418
|
+
|
|
419
|
+
### Analysis & Audit
|
|
420
|
+
|
|
421
|
+
| Command | Description |
|
|
422
|
+
|---------|-------------|
|
|
423
|
+
| `fin drill recurring` | All recurring expenses |
|
|
424
|
+
| `fin drill one-offs` | Discretionary spending |
|
|
425
|
+
| `fin drill alerts` | All alerts with details |
|
|
426
|
+
| `fin drill income` | Income sources |
|
|
427
|
+
| `fin audit-subs` | Verify subscription detection accuracy |
|
|
428
|
+
| `fin bundle-check` | Find duplicate/overlapping subscriptions |
|
|
429
|
+
| `fin dashboard-cli` | Full CLI dashboard with alerts |
|
|
430
|
+
|
|
431
|
+
### Export & Backup
|
|
432
|
+
|
|
433
|
+
| Command | Description |
|
|
434
|
+
|---------|-------------|
|
|
435
|
+
| `fin export-csv` | Export all data to CSV files |
|
|
436
|
+
| `fin export-backup -p` | Encrypted backup with passphrase |
|
|
437
|
+
| `fin export-backup -r age1...` | Encrypted backup to recipient key |
|
|
438
|
+
| `fin export-summary` | Income vs spend summary with rolling averages |
|
|
439
|
+
| `fin export-duplicates` | Export duplicate subscription groups |
|
|
440
|
+
| `fin import-csv FILE` | Import transactions from CSV (CLI) |
|
|
441
|
+
|
|
442
|
+
### Credentials & Setup
|
|
443
|
+
|
|
444
|
+
| Command | Description |
|
|
445
|
+
|---------|-------------|
|
|
446
|
+
| `fin setup TOKEN` | Exchange SimpleFIN setup token for access URL |
|
|
447
|
+
| `fin credentials set` | Store credentials in system keyring |
|
|
448
|
+
| `fin credentials status` | Show credential source (keyring/env/none) |
|
|
449
|
+
| `fin credentials clear` | Remove credentials from keyring |
|
|
450
|
+
|
|
451
|
+
## Sync Options
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
# Daily sync (14 days) - catches new transactions
|
|
455
|
+
fin sync --quick
|
|
456
|
+
|
|
457
|
+
# Weekly sync (30 days) - default, covers statement cycle
|
|
458
|
+
fin sync
|
|
459
|
+
|
|
460
|
+
# After vacation/absence (120 days)
|
|
461
|
+
fin sync --full
|
|
462
|
+
|
|
463
|
+
# January annual (400 days) - finds yearly subscriptions
|
|
464
|
+
fin sync --annual-bootstrap
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## Troubleshooting
|
|
468
|
+
|
|
469
|
+
### "No transactions found"
|
|
470
|
+
Run `fin sync --full` to pull more history, or import a CSV from `/connect`.
|
|
471
|
+
|
|
472
|
+
### Categories are wrong
|
|
473
|
+
Click the category in the dashboard, then click the edit icon to override.
|
|
474
|
+
|
|
475
|
+
### Subscription showing as Bill (or vice versa)
|
|
476
|
+
Click the type badge on the Recurring page to toggle.
|
|
477
|
+
|
|
478
|
+
### Suspicious subscription detection
|
|
479
|
+
Run `fin audit-subs` to verify what's being detected.
|
|
480
|
+
|
|
481
|
+
### Alerts not showing expected transactions
|
|
482
|
+
Use the date pickers to select a custom range, or click the month navigation to reset to the current month.
|
|
483
|
+
|
|
484
|
+
## Development
|
|
485
|
+
|
|
486
|
+
```bash
|
|
487
|
+
# Install with dev dependencies
|
|
488
|
+
pip install -e ".[dev]"
|
|
489
|
+
|
|
490
|
+
# Run tests
|
|
491
|
+
FIN_DB_PATH=/tmp/test.db pytest
|
|
492
|
+
|
|
493
|
+
# Type checking
|
|
494
|
+
mypy src/fin
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
## License
|
|
498
|
+
|
|
499
|
+
PolyForm Noncommercial 1.0.0
|