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>
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
# 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`.
|
||||
Reference in New Issue
Block a user