subalineado/README.md
2026-10-12 16:34:29 -03:00

149 lines
6.4 KiB
Markdown

# Subalineado
Go API and SolidJS + TypeScript webapp in one repository. No database is required.
## Start in development
Install Docker with Compose **2.32+** and [Task v3](https://taskfile.dev/docs/installation). Task is a standalone binary. With Node installed, use `npm install --global @go-task/cli`; other installation options are linked above. Then run:
```sh
task dev
```
Open http://localhost:5173. The API is at http://localhost:8080.
If a port is occupied, prefix the command with `API_PORT=18080 DEV_WEB_PORT=15173` (or `WEB_PORT=13000` for production).
Ctrl+C stops both services; remove their containers with:
```sh
task dev:down
```
Compose Watch syncs webapp source into Vite for hot reload and rebuilds the Go service on changes. Dependency and Vite configuration changes rebuild the webapp. Go module and compilation caches persist through BuildKit cache mounts. After a broken Go build, fix and save the source to trigger another build. Dockerfile changes require restarting with `--build`.
## Discover and extend commands
```sh
task # List commands with descriptions
task --list # Same list, explicitly
task --summary dev # Read usage details for development
task dev:status # See running services
task dev:logs # Follow their logs
task install # Install native Go and webapp dependencies
task check # Go vet, Biome and TypeScript checks
task test # Go race tests and Vitest tests
task format # Go formatting and safe Biome fixes
task build # Build both production Docker images
```
`install`, `check`, `test`, and `format` use your native Go/Node/pnpm tools. `dev`, `dev:*`, and `build` use Docker. Individual commands such as `task server:test` and `task webapp:check` are also listed. Tasks stop when a command fails.
All commands live in the root `Taskfile.yml`. Add a named task with `desc` and `cmds`; use `dir` for commands in a service directory and `summary` for detailed usage. Task finds the file from repository subdirectories too.
```yaml
webapp:build:
desc: Build the webapp locally
dir: webapp
cmds:
- pnpm build
```
Compose remains the source of truth for services and watch rules. Task supplies short, discoverable command names. The underlying development command is still available:
```sh
docker compose -f compose.yaml -f compose.dev.yaml up --build --watch
```
## Run production images locally
```sh
docker compose up --build -d --wait
```
Open http://localhost:3000. Nginx serves the compiled webapp and proxies `/api/*` and `/health` to Go. Both runtime containers run as non-root users and expose health checks. Ports bind to loopback for local use.
```sh
docker compose down
```
## Native development and checks
Use Node **24**, pnpm **10.28.2**, and Go **1.27.2**. `.tool-versions` pins the native Node and Go versions for asdf; the Go module also requires Go 1.27.2. Install pnpm with `npm install --global pnpm@10.28.2`.
In one terminal:
```sh
cd server
go mod download
go run ./cmd/api
```
In another:
```sh
cd webapp
pnpm install --frozen-lockfile
pnpm dev
```
Native Go development requires restarting `go run` after edits; Compose Watch automates this in the container workflow.
Server checks:
```sh
cd server
go test -race ./...
go vet ./...
go build -o bin/api ./cmd/api
```
Webapp checks:
```sh
cd webapp
pnpm check
pnpm test
pnpm build
```
`pnpm format` applies Biome formatting and safe fixes; `pnpm test:watch` runs Vitest interactively.
## Continuous integration
`.gitlab-ci.yml` runs two jobs in parallel on every push and merge request:
- Server: `go vet ./...` and `go test -race ./...` with Go 1.27.2.
- Webapp: `pnpm check` (Biome and TypeScript) and `pnpm test` (Vitest) with Node 24 and pnpm 10.28.2. Dependencies use the frozen lockfile.
When a branch has an open merge request, its pushes run the merge request pipeline instead of a duplicate branch pipeline. All checks run even for documentation-only changes. A GitLab runner supporting container images (Docker or Kubernetes executor) must be available to the project; no deployment credentials are needed.
## Structure and API
- `server/cmd/api`: process startup, HTTP timeouts, signal handling and graceful shutdown.
- `server/internal/httpapi`: router, HTTP handlers and endpoint tests.
- `webapp/src`: page, typed API client and component tests.
- `Taskfile.yml`: discoverable development, dependency, formatting and verification commands.
- `compose.yaml`: production images and service dependencies.
- `compose.dev.yaml`: development overrides and file-watch rules.
| Request | Response |
| --- | --- |
| `GET /health` | `200 {"status":"ok"}` |
| `GET /api/test` | `200 {"message":"API connection successful"}` |
Responses use `application/json`. Other methods return 405; unknown routes return 404. `HTTP_ADDR` configures the API listener (default `:8080`). Vite reads `API_PROXY_TARGET` (default `http://localhost:8080`); Compose sets it to the server service. This is a server-side proxy setting, not a browser URL.
## Tooling choices
[Chi](https://github.com/go-chi/chi) keeps route groups and middleware readable while using standard `net/http` handlers. Add related routes under `r.Route(...)`; extract feature handlers as the app grows. A larger framework is unnecessary for the current two endpoints.
[Vite](https://vite.dev/guide/) provides SolidJS compilation, development hot reload and production builds. Biome handles formatting and linting; TypeScript checks types; Vitest and Solid Testing Library verify rendered success, errors and retry behavior.
[Task](https://taskfile.dev/docs/reference/schema) provides language-independent commands in YAML, with descriptions via `task --list` and detailed help via `task --summary`. [Compose Watch](https://docs.docker.com/compose/how-tos/file-watch/) manages service startup and reloads underneath `task dev`.
Alternatives considered: [Just](https://just.systems/man/en/) is a concise command runner with Make-inspired syntax; [mise](https://mise.jdx.dev/tasks/toml-tasks.html) offers TOML tasks alongside runtime and environment management. Task fits the declarative YAML style already used by Compose and leaves the existing asdf runtime setup in place.
The Docker images use explicit Go and Node major/version selections, frozen pnpm dependencies and a Go checksum file. Runtime base tags receive upstream updates; pin image digests if reproducible deployment images become a requirement.