Files
whattodo/README.md
T
goyban 509b1a1320 Add optional time ranges and a calendar day view
Tasks can now have a start/end time on their deadline date. The new
Calendar view shows a day as a timeline (with a week strip and projected
repeats of recurring tasks), and the task form lists what is already
planned that day and flags overlaps. Existing databases are migrated to
schema v2 automatically, with a backup copy taken first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:08:09 +02:00

85 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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** with an optional **time range** (e.g. 10:00–12:00), **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.
- When you pick a date and time, the task form lists what else is planned that day and warns about overlaps.
- Views: **Today** (overdue, due today, high priority), **Upcoming**, **Calendar** (day timeline with week strip; tap an hour to add a task there), **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
```