Single-user appointment scheduling. A public appointment page, an admin UI, calendar integration (Google + CalDAV), and email notifications — all configured through one YAML file.
"When" runs as two services that share a single when.yaml and data directory:
the web app (appointment page + admin) and a background worker that handles
calendar sync and sends appointment emails off the request path. The bundled
apps/web/docker-compose.yml runs both.
-
Copy
apps/web/config/when.example.ymltoapps/web/config/when.yamland fill it in. Point your editor at the bundled schema for autocomplete and validation — the example's first line already does this:# yaml-language-server: $schema=./config.schema.jsonSee
docs/config.mdfor the full configuration reference. -
Copy
apps/web/.env.exampletoapps/web/.envand fill it in — the compose file loads it into all three services. Generate the secret it asks for:openssl rand -base64 32 # -> AUTH_SECRETSet
ORIGINto the public URL you serve from; behind a reverse proxy, form submissions fail with a 403 without it. The full list of environment variables is indocs/deployment.md. -
Bring up both services:
docker compose -f apps/web/docker-compose.yml up -d
The appointment page is at
http://localhost:3000/and the admin UI at/admin. The container runs database migrations on boot. SQLite lives under/app/data; the bundled compose file mounts./dataso appointments survive restarts.
- Philosophy — what "When" is, and the principles behind it.
- Architecture — how the system is built.
- Configuration — the full
when.yamlreference. - Deployment — environment variables, Docker, running behind a reverse proxy, persistence, and operating endpoints.
- Development — running it locally, the scripts, testing, and coding conventions.