Files
todo-hetzner/AGENTS.md
T
cole-maxwell1 dd60bd4a3e chore: align repository and Ansible configuration
Relocate group variable examples beside the inventory for automatic discovery.

Refresh repository guidance, ignore local tooling artifacts, and disable Ansible cows.
2026-08-07 09:52:47 -05:00

35 lines
3.6 KiB
Markdown

# Repository Guide
## Boundaries
- `app/` is the Go 1.22 module. The server entrypoint is `app/cmd/server/main.go`; handlers own HTTP behavior, `internal/db` owns xorm persistence, and `app/web` embeds templates plus compiled CSS into the binary.
- `infra/` is one OpenTofu root module and one shared state for both production and staging. `infra/environments/*` contain input files, not independent stacks.
- `ansible/playbooks/setup-node.yml` configures both hosts; `deploy-app.yml` pulls and restarts the rootless Podman/Quadlet app. Environment-specific behavior is selected by generated inventory groups and `deployment_environment`.
- Staging restores unchanged production data. Treat staging, backups, logs, real tfvars, Vault files, and state as production-sensitive; inspect examples instead of secret-bearing files.
## Commands
- Run repository checks with `make validate`: Go tests, `go vet`, OpenTofu validation, then both Ansible syntax checks.
- Run one Go test from `app/`: `go test ./internal/handler -run '^TestName$'` or `go test ./internal/db -run '^TestStoreLifecycle$'`.
- `internal/db` integration tests silently skip unless `TEST_DATABASE_URL` points to PostgreSQL. Normal `make test` needs no database.
- Format Go and OpenTofu files with `make format`; it runs `gofmt` and recursive `tofu fmt` (including real ignored tfvars), but does not format YAML or templates.
- Build the embedded app with `make build-app`. This first runs Tailwind and writes `app/web/static/app.css`; `make css` performs only that asset step.
- Build the deployment image with `docker build -t todo:local app`. Its CSS stage is self-contained and does not use the local `app/tailwindcss` binary.
## Generated And Runtime Behavior
- Edit Tailwind source in `app/web/input.css` and templates under `app/web/templates/`; regenerate the tracked `app/web/static/app.css` with `make css` after class or style changes.
- The standalone Tailwind binary is downloaded at pinned version `v3.4.17` to ignored `app/tailwindcss`.
- The server requires `DATABASE_URL`, defaults `APP_ADDR` to `:8080`, and runs xorm `Sync2` for the `todos` table during startup. Keep `xorm.io/xorm` paired with `github.com/lib/pq` in this stack.
- `make generate-inventory` reads applied OpenTofu output and overwrites ignored `ansible/inventory/hosts.yml`; rerun it after server replacement or address changes.
## Infrastructure And Deployment
- OpenTofu commands must use both var files against the root stack, for example `tofu -chdir=infra plan -var-file=environments/prod/prod.tfvars -var-file=environments/staging/staging.tfvars`. The staging file only supplies staging-specific overrides.
- Prefer `TF_VAR_hcloud_token`, `TF_VAR_s3_access_key`, and `TF_VAR_s3_secret_key`; values in `*.tfvars` override those environment variables.
- Keep the AWS provider on `~> 5.69.0`: newer releases wait for an AWS-only response header absent from Hetzner Object Storage.
- Run Ansible from `ansible/`, as the Make targets do, or set `ANSIBLE_CONFIG=ansible/ansible.cfg`; otherwise the repository role path is not loaded.
- `make deploy-ansible` is an operational deployment, not a verification command. It regenerates inventory, runs host setup before app deployment, requires decryptable Vault files, and acts on both production and staging.
- The Quadlet uses `Pull=never`; `deploy-app.yml` intentionally pulls `app_image` before restarting `app-todo.service`.
- Production WAL-G archives under a prefix ending in `/prod`. Staging's scheduled `db-sync` destructively replaces `/var/lib/pgsql/data` from `LATEST` and leaves the app stopped on failure; do not weaken its path/prefix guards or use it as a routine test.