Files
tuio/CLAUDE.md
T
jbandClaude Opus 4.8 25137eb5da docs: add Portuguese docs and English CLAUDE.md
Add README.md, docs/ (fluxo, configuracao, arquitetura) in PT-BR and a
CLAUDE.md technical reference in English describing the installer flow,
generated files, containers and architecture.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:53:56 -03:00

145 lines
6.7 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.
# CLAUDE.md
Guidance for Claude Code when working in this repository.
> User-facing docs are in Portuguese (BR): [README.md](README.md) and [docs/](docs/).
> This file is in English and is the technical source of truth for how the code works.
## What this is
A terminal UI (TUI) **installer** for the "App do Dono" **client middleware**. The
middleware runs on a tenant's infrastructure and brokers communication between the
tenant's servers and davinTI's **central server**.
The installer is a guided wizard that: checks Docker → logs into the private registry
→ pulls images → (optionally) sets up a WireGuard tunnel (`vproxy`) when there is no
public IP → collects configuration via terminal forms → generates config files
(`config.toml`, `envs`) → runs the Docker containers.
It is **not** the middleware itself — it only provisions and launches it via `docker`.
## Tech stack
- **Go 1.25**
- **Bubble Tea v2** (`charm.land/bubbletea/v2`) — Elm-architecture TUI runtime.
- **Bubbles v2** — `textinput`, `spinner` components.
- **Lip Gloss v2** — styling.
- **BurntSushi/toml** — read existing `config.toml` for form defaults.
- Module path: `git.davinti.com.br/davinTI/app-dono/tui`.
## Layout
```
cmd/main.go Entry point; starts the Bubble Tea program.
internal/tui/
model.go Model struct, ConfigValues, loadConfig (defaults), InitialModel, Init.
steps.go step enum — the ordered wizard stages.
update.go Update: global keys + per-step dispatch (handlers).
view.go View: header + per-step body + help footer (AltScreen).
form.go Generic FormStep/FormField component (text/password/number/select).
cmds.go Msg types and async tea.Cmd wrappers around docker/file ops.
docker.go os/exec wrappers around the `docker` binary.
config.go Generates & writes config.toml and envs (+ numeric validation).
styles.go Lip Gloss palette/styles.
Makefile Multi-arch build + S3 publish.
```
## Architecture (Model–Update–View)
- **Model** ([model.go](internal/tui/model.go)) holds all state: `currentStep`,
progress/error flags, one `FormStep` per form, and `configValues` (`ConfigValues`)
which accumulates each form's `map[string]string` output by section.
- **Update** ([update.go](internal/tui/update.go)) handles global messages
(`Ctrl+C`, window size, spinner tick) then dispatches on `currentStep` to per-step
handlers. Step transitions happen when a form returns `done == true` or when an
async completion message arrives.
- **View** ([view.go](internal/tui/view.go)) renders per-step.
- **Commands** ([cmds.go](internal/tui/cmds.go)) wrap every blocking op (docker calls,
file writes) as a `tea.Cmd` returning a `Msg`: `DockerCheckedMsg`,
`ImageDownloadFinishedMsg`, `ConfigFileMsg`, `DockerRunMsg`, `TickMsg`.
## Wizard flow
`steps.go` defines the order. See [docs/fluxo.md](docs/fluxo.md) for full detail.
1. `StepCheckDocker` — `exec.LookPath("docker")`. Missing → `StepDockerInstall`
(instructs manual install and exits; **never auto-installs Docker**).
2. `StepDockerLogin` → `StepDownloadImage` — `docker login` + `pull` of the app image.
These registry credentials are **reused** later for the vproxy image.
3. `StepIPQuestion` — "public IP available?"
- **Yes** → jump to `StepAppConfig`.
- **No** → vproxy block: `StepWireguardConfig` → `StepGenerateWireguardFile`
(writes `envs`) → `StepDownloadWireguard` → `StepRunWireguard`.
4. Config forms: `StepAppConfig` → `StepServerConfig` → `StepDatabaseConfig` →
`StepCertConfig`.
5. `StepGenerateFile` — writes `config.toml` (validates numeric fields first).
6. `StepRunDocker` — runs `app-dono-cliente` container.
7. `StepDone`.
## Key constants
In [update.go](internal/tui/update.go):
- `imageName = hub.davinti.com.br:443/app-dono/app-cliente:latest`
- `wireguardImageName = hub.davinti.com.br:443/davinti-vproxy:latest`
- `configPath = config.toml`, `wireguardConfigPath = envs`
In [docker.go](internal/tui/docker.go): `networkName = app-dono_app` (all containers
join this network; created on demand).
## Generated files
- **`config.toml`** — app config, bind-mounted at `/app/config.toml`. If present at
startup it seeds form defaults via `loadConfig`. Generated by `GenerateConfigTOML`.
- **`envs`** — vproxy/WireGuard env vars, passed via `--env-file`. Generated only when
there is no public IP. By `GenerateWireguardConfig`.
Both are gitignored.
## Containers
| Container | Image | Notes |
| ------------------ | -------------------- | -------------------------------------------------------- |
| `app-dono-cliente` | app-cliente | `<host port>:8080`, mounts config.toml + cert dir, `--restart unless-stopped`, runs as host uid:gid. |
| `vproxy` | davinti-vproxy | `--cap-add=NET_ADMIN`, `/dev/net/tun`, `--env-file envs`, only without public IP. |
`seccomp=unconfined` is added to either container when the "Modo Compatibilidade"
(`seccomp_unconfined`) select is `"Sim"` — for old machines.
## Gotchas (read before editing)
- **Port:** `config.toml` always writes `port = 8080` (hardcoded in
`GenerateConfigTOML`). The form's "Porta" value only sets the **host-side** port in
the `docker run` mapping (`<port>:8080`); inside the container the app always listens
on 8080.
- **Network name** is the `networkName` constant (`app-dono_app`) in
[docker.go](internal/tui/docker.go); use it rather than re-typing the literal.
- **Registry credentials** are collected once (login form) and reused for the vproxy
pull — no second prompt.
- Containers run detached and are verified with `docker inspect` for `running`; on
failure the last 20 log lines are surfaced.
## Build & run
```bash
go run ./cmd # run from source
go build -o installer ./cmd # local binary
make build # multi-arch (linux/darwin/windows, amd64/arm64) → ./dist
make build VERSION=2.0.0
make clean
make push S3_BUCKET=<bucket> VERSION=<v> # sync dist/ to S3 (version + latest)
make release S3_BUCKET=<bucket> VERSION=<v> # per-binary copy with OS/arch naming
```
There is no test suite. Verify changes by running `go build ./...` and exercising the
TUI manually. Requires a working Docker daemon and registry access to fully run.
## Conventions
- User-facing strings in the TUI are **Portuguese (BR)**; keep new ones consistent.
- Keep code comments and identifiers matching the surrounding style (mixed
English identifiers, Portuguese user messages).
- When adding a wizard step: add it to `steps.go`, a handler in `update.go`, a render
branch in `view.go`, and any new `Msg`/`Cmd` in `cmds.go`.