Task trees with real progress.
Do It List is a small web app for breaking work into nested tasks and watching parent and root progress roll up automatically from the leaves. Optional weighting lets you say "this subtask is worth 30% of its parent" without forcing the user to set weights for everything.
Do It List grows milestone by milestone. The execution dashboard lives in
docs/PLAN.md; the canonical product spec lives in
docs/ProductSpec.md. The first shipped milestone
is M01-BaseApp (docs/milestones/m01-baseapp/m01-baseapp.md).
- Phoenix LiveView 1.1 (Elixir 1.18)
- PostgreSQL 16
- Tailwind + DaisyUI for styling
- Bcrypt for password hashing
The whole development environment is containerised. The only host-level requirements are Docker and Docker Compose.
docker compose up --buildThen open http://localhost:4000. Register an account, create an Initiative, and start adding lists and nested tasks.
The first boot is slow — Elixir, Hex, and the JS asset toolchain are all
pulled into the image. Subsequent runs use the cached _build, deps, and
node_modules named volumes.
compose.yaml ships with sensible defaults that need no configuration. To
override them, copy .env.example to .env and edit:
| Variable | Default | Purpose |
|---|---|---|
WEB_PORT |
4000 |
Port mapped from the host to the web app. |
DB_USERNAME |
postgres |
PostgreSQL user. |
DB_PASSWORD |
postgres |
PostgreSQL password. |
DB_DATABASE |
doit_dev |
PostgreSQL database name. |
Database data lives in the named Docker volume doit_pgdata, so it survives
docker compose down. docker compose down -v wipes everything.
The test suite (notably the progress roll-up unit tests) runs inside the container too:
docker compose run --rm \
-e MIX_ENV=test \
-e DB_DATABASE=doit \
web mix testThis creates a doit_test database alongside doit_dev. The pure-Elixir
progress tests in test/doit/tasks/progress_test.exs do not touch the database
at all and are the fastest signal that the roll-up math is correct.
Canonical definitions live in docs/ProductSpec.md. Quick reference:
- Initiative — the top-level container, has members and many Lists.
- Task — any node in the tree.
- List — informal name for a root task (a task whose
parent_idisnull). An Initiative usually has multiple Lists, each with its own tree. - Roll-up progress —
computed_progresson a task: the weighted average of its children's rolled-up progress. - Weight — how much a child contributes to its parent's roll-up. Default
is
1; users only have to touch it when they want non-equal contributions. - Initiative member — a
(user, initiative, role)triple. Roles areowner,editor,viewer.
The principle and formula live in docs/ProductSpec.md;
detailed edge cases live in docs/milestones/m01-baseapp/m01-baseapp.md.
Pure implementation lives in DoIt.Tasks.Progress and is exercised by
test/doit/tasks/progress_test.exs.
leaf task → manual_progress (clamped 0..100)
status == "done" → 100
branch task → sum(child_progress * child_weight) / sum(child_weight)
Children with non-positive weight are ignored. Marking a task done snaps its
progress to 100; reopening lets the user move it back down. Whenever a task
changes, DoIt.Tasks recomputes its ancestors recursively.
lib/doit/accounts/— user registration / login / password hashing.lib/doit/initiatives/— initiatives and initiative membership.lib/doit/tasks/— tasks, comments, activity events, and the pure-ElixirProgressmodule.lib/doit_web/live/—InitiativeIndexLiveandInitiativeShowLive. The latter subscribes toinitiative:<id>PubSub topics so other browsers see updates promptly. Last writer wins; no conflict resolution.lib/doit_web/user_auth.ex— session-based auth plug + LiveView mount hooks.
Activity events are recorded on task creation, deletion, comment, and field changes (title, status, progress, weight, assignee, parent, priority) and are shown in the task editor sidebar.
- No drag-and-drop reordering.
sort_orderis set on creation and editable only via the JSON form field. - No conflict resolution: simultaneous edits to the same field follow last-writer-wins.
- No notifications, attachments, kanban, calendar, or AI features.
- No password reset / email confirmation flow yet — registration logs you straight in.
mix release/ production Dockerfile are out of scope for M01-BaseApp; the shipped image runsmix phx.serverindevmode.