-
Latest Go release (go 1.27 today). Module path go.xvii.network/<repo>. CGO_ENABLED=0 builds,
static binaries for linux/amd64 and linux/arm64 (servers) and darwin too for the CLI.
-
Layout of a service repo:
cmd/<service>d/ main: config, wiring, HTTP server, workers
internal/<domain>/ one package per domain concept (store, api, …)
apiv1/ the API contract, a nested module go.xvii.network/<service>/apiv1 (ADR 0027):
operations, wire types, openapi.json; also the Go client, used by the CLI and
other services (it replaces client/ as a service migrates)
client/ public Go client of the API, in services without apiv1 yet
cli/ the `xvii <service>` command group, registered by the cli repo
migrations/ SQL migrations (embedded)
queries/ sqlc queries; generated code in internal/db
panel/ the React panel; dist/ embedded by embed.go
deploy/ systemd unit and service manifest for xvii-node
-
Standard library first (net/http routing with patterns, log/slog, encoding/json). Dependencies need
a reason: pgx, sqlc, go-webauthn are fine; frameworks (gin, echo, ORMs) are not.
-
Config: KEY=VALUE file plus XVII_<SERVICE>_<KEY> env overrides, through kit/config. Secrets
never in flags.
-
Errors wrap with %w and context; APIs map them to the error shape in api.md. No panics
across package boundaries.
-
Logging: slog JSON to stdout (journald), request id on every line, no secrets or tokens.
-
Tests: go test ./... must pass without network; database tests use a throwaway PostgreSQL through
kit/dbtest (skipped with a clear message when none is available). Table tests for parsers and
rules; API tests through httptest against the real handler.
-
gofmt and go vet clean. Comments explain why; package comments say what the package is.