# Gardomatic administration CLI The CLI connects directly to PostgreSQL and is implemented in `cmd/cli`. ## Configuration `GARDOMATIC_DB_DSN` is required for every database command. The following variables are optional: | Variable | Default | Purpose | | --- | --- | --- | | `GARDOMATIC_ENV` | `development` | Enables confirmations for risky production operations | | `GARDOMATIC_WEB_BASE_URL` | `http://localhost:4040` | Base URL for activation links | | `GARDOMATIC_DEMO_RESET_ENABLED` | `false` | Explicitly enables destructive demo resets | | `GARDOMATIC_SMTP_MODE` | `file` | Mail delivery mode (`file` or `smtp`) | | `GARDOMATIC_SMTP_HOST` | empty | SMTP server hostname | | `GARDOMATIC_SMTP_PORT` | `25` | SMTP server port | | `GARDOMATIC_SMTP_USERNAME` | empty | SMTP username | | `GARDOMATIC_SMTP_PASSWORD` | empty | SMTP password | | `GARDOMATIC_SMTP_SENDER` | `gardomatic@localhost` | Sender address | | `GARDOMATIC_SMTP_FILE_PATH` | `/tmp/gardomatic-mails.log` | Development mail output | Global flags can override the DSN, environment, and public URL. Global flags must appear before the command. Use `--json` for machine-readable output and `--yes` to confirm an explicitly configured production operation. ## Examples Create an invited user and print a generated initial password: ```sh go run ./cmd/cli users create \ --name "Alice Example" \ --email alice@example.com \ --invite \ --generate-password ``` Create the initial active application administrator atomically: ```sh go run ./cmd/cli users create \ --name "Initial Admin" \ --email admin@example.com \ --role application:admin \ --active \ --generate-password ``` Create an active development user and read the password without exposing it in the process list: ```sh printf '%s\n' 'correct horse battery staple' | \ go run ./cmd/cli users create \ --name "Development User" \ --email dev@example.com \ --active \ --password-stdin ``` Without `--password-stdin` or `--generate-password`, the CLI securely prompts for the password twice. An invitation is printed by default; add `--send-email` to deliver it using the configured mail backend. Other common operations: ```sh go run ./cmd/cli users list go run ./cmd/cli users show --email alice@example.com go run ./cmd/cli users invite --email alice@example.com --send-email go run ./cmd/cli users activate --email alice@example.com go run ./cmd/cli users deactivate --email alice@example.com go run ./cmd/cli users reset-password --email alice@example.com --generate-password go run ./cmd/cli users set-role --email alice@example.com --role application:admin go run ./cmd/cli gardens add-user --garden-id 3 --email alice@example.com --role admin go run ./cmd/cli db ping ``` `users create` requires exactly one of `--active` and `--invite` and accepts `application:user` or `application:admin` as `--role`. User creation, its role, and its activation token are committed in one database transaction. Password reset invalidates existing bearer and password reset tokens. The CLI never accepts passwords as command-line arguments. Application roles (`application:user`, `application:admin`) are independent of garden roles (`owner`, `admin`, `member`, `viewer`, `worker`). `gardens add-user` uses `member` when `--role` is omitted. ## Demo data `demo reset` atomically removes all sessions, users, gardens, categories, and their dependent content and replaces them with a fresh `Sonnengarten`. It contains three members, a pending invitation, a custom garden role, eight hierarchical locations, twelve richly described species with care instructions and task templates, sixteen plants (including one without a species and several lifecycle states), sixteen current, recurring, completed, and generated tasks, tags, six journal or pinboard entries, and a reusable image library. Task due dates and journal dates are calculated relative to the reset, so the data remains useful over time. The command is deliberately guarded twice. It only runs when `GARDOMATIC_DEMO_RESET_ENABLED=true`, and it additionally requires the global `--yes` flag. Never enable it for a database containing real data. The password must be supplied via standard input: ```sh systemd-ask-password 'Demo password:' | \ GARDOMATIC_DEMO_RESET_ENABLED=true \ go run ./cmd/cli --yes demo reset \ --email demo@example.com \ --password-stdin ``` Concurrent resets are serialized with a PostgreSQL advisory transaction lock. The old data remains visible until the complete replacement commits; existing login sessions are invalidated by every reset.