flowtrack/README.md
rope bb19bc0aeb Push notifications: period soon/late reminders, test button
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 09:43:41 +01:00

77 lines
2.9 KiB
Markdown

# Flowtrack
A private, self-hosted period tracker. It logs period days with flow and
symptoms, predicts the next six periods, and estimates the fertile window.
It installs on a phone home screen as a web app.
The app has no runtime dependencies beyond the Python standard library, and it
stores everything in one SQLite file. Nginx and Authelia provide the access
boundary.
## Predictions
- Periods are runs of logged period days. Spotting doesn't count, and one
missing day inside a run doesn't split it.
- The cycle length is a weighted average of up to the last 12 cycles, with
recent cycles counting more. Cycles shorter than 15 days or longer than 60
are left out because they usually mean a log was missed.
- Each prediction is a range of ± the cycle's standard deviation (at least 2
days, or 4 with fewer than three cycles). The range widens with √n for later
cycles.
- Ovulation is estimated 14 days before the next period. The fertile window
runs from 5 days before ovulation to 1 day after. These are estimates, not
contraception.
- Once the expected day passes, the next period is expected from tomorrow,
and later predictions move with it.
The logic lives in `static/cycle.js` and is tested in `tests/test_cycle.js`.
## Notifications
Web Push, sent by `notify.js` (Node, no dependencies: built-in crypto and
SQLite). It reuses `static/cycle.js`, so reminders always match the app.
- `flowtrack-notify daily` runs once a day. It sends "period expected soon"
once per cycle, `remindDays` (1-7, default 2) before the predicted start,
and "period is late" once per cycle after the expected day passes.
- The owner turns notifications on per device in Settings, where there is
also a test button. On iPhone this only works from the Home Screen app
(iOS 16.4 or later).
- The VAPID key pair is created on first start and stored in the database.
Replacing it invalidates every subscription.
- The server only accepts subscriptions on Apple, Google, Mozilla and
Microsoft push hosts, because it POSTs to whatever endpoint it stores.
Enable it with `--push-contact https://your.site` (the NixOS module does
this through `push.contact`).
## Access
Nginx must overwrite `Remote-User` with the Authelia username. Users listed
with `--editor` can log and export. Users listed with `--viewer` see period
days and predictions only. They also see flow and symptoms if the owner turns
on sharing in Settings. Everyone else gets 403.
## Run locally
```sh
python3 app.py --database /tmp/flowtrack.sqlite3 --editor me --dev-user me
```
Then open `http://127.0.0.1:8093`.
## NixOS module
```nix
services.flowtrack = {
enable = true;
editors = [ "kayla" ];
viewers = [ "fred" ];
backup.directory = "/mnt/disk2/backups/flowtrack"; # nightly, keeps 30
push.contact = "https://flowtrack.example.org";
push.time = "*-*-* 09:00:00 Europe/London";
};
```
`python3 app.py --database DB --backup-to DIR --keep N` takes a consistent
snapshot by hand.