Initial WhatToDo app

Self-hosted personal task list: FastAPI + SQLite in Docker, mobile-friendly
PWA frontend, deadlines, priorities, categories, tags, notes, checklists,
recurring tasks, single-password login, and JSON export/import.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
goyban
2026-10-07 11:43:56 +02:00
commit c5b049edba
23 changed files with 2045 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
# WhatToDo
A small, self-hosted to-do app for one person. It works in a desktop browser and on a phone, and you can install it to your home screen.
- Tasks have an optional **deadline**, **priority** (none / low / medium / high), **category**, **tags**, **notes**, and a **checklist** of steps.
- **Recurring tasks** (every N days/weeks/months/years): completing one creates the next occurrence.
- Views: **Today** (overdue, due today, high priority), **Upcoming**, **All open**, **Done**, plus one view per category.
- You can rename, recolor, reorder, add, or delete categories in **Settings**. It starts with Work, Life, Personal, YouTube.
- **Export / import** of all data as JSON, from **Settings**.
- Login with a single password.
Stack: Python (FastAPI) + SQLite with a plain HTML/CSS/JS frontend and no build step. Everything runs in Docker.
## Run locally
Requirements: Docker with the Compose plugin. Nothing else is installed on the host.
```sh
cp .env.example .env # then edit .env: set APP_PASSWORD and SECRET_KEY
docker compose up -d --build
```
Open <http://localhost:8080> and log in with `APP_PASSWORD`.
The database lives in `./data/whattodo.db`, which is git-ignored.
Useful commands:
```sh
docker compose logs -f # follow logs
docker compose down # stop
docker compose up -d --build # rebuild after pulling changes
docker compose run --rm test # run the test suite (in Docker)
```
### Testing on your phone (same Wi-Fi)
Set `BIND_ADDR=0.0.0.0` in `.env`, run `docker compose up -d`, then open `http://<this-computer's-LAN-IP>:8080` on the phone.
Browsers only allow "Install app" / "Add to Home Screen" with offline support over **HTTPS** (or on `localhost`). Over plain LAN HTTP the app still works, but it won't install as a full app.
## Deploy to production
1. On the server, clone the repo and create `.env` from `.env.example`. Use a **new strong** `APP_PASSWORD` and `SECRET_KEY`, and set `COOKIE_SECURE=true`.
2. `docker compose up -d --build`. The app listens on `127.0.0.1:${PORT}`.
3. Put it behind a reverse proxy with HTTPS. For example, with Caddy:
```
todo.example.com {
reverse_proxy 127.0.0.1:8080
}
```
If the proxy runs in another container instead of on the host, set `BIND_ADDR`/networking to match and set `FORWARDED_ALLOW_IPS` to the proxy's IP. The app then sees the real client IP, which login rate limiting uses.
### Moving your data from this PC to production
1. Local app → **Settings → Export data**. This downloads `whattodo-export-YYYYMMDD-HHMM.json`.
2. Production app → **Settings → Import**, pick the file:
- **Replace** deletes everything on that install and loads the file. Use this for the first move to prod.
- **Merge** adds the file's tasks to what is already there. Categories with the same name are reused.
The export file contains your tasks. Keep it out of the repo (`whattodo-export-*.json` is git-ignored).
### Backups
Export regularly from Settings, or copy `./data/whattodo.db` while the app is stopped.
## Security notes
- `.env` and `data/` are git-ignored. Never commit them; the repository is public.
- Changing `APP_PASSWORD` or `SECRET_KEY` logs out all sessions.
- Failed logins are rate limited: 10 failures per 15 minutes per IP.
- Write requests require an `X-WhatToDo` header (CSRF protection). The app also sends a strict Content-Security-Policy.
## Project layout
```
app/main.py API: auth, tasks, categories, export/import
app/db.py SQLite schema and setup
app/static/ frontend (index.html, app.js, style.css, PWA files, icons)
tests/ API tests (run with: docker compose run --rm test)
tools/make_icons.py regenerates the PNG icons
```