64 lines
3.0 KiB
Markdown
64 lines
3.0 KiB
Markdown
# The console
|
|
|
|
Vite + React + TypeScript + Tailwind, built into `internal/web/dist` and served
|
|
by the Go binary from an `//go:embed`. There is no separate deployment: the
|
|
binary *is* the console.
|
|
|
|
## Day-to-day
|
|
|
|
```sh
|
|
make web-check # npx tsc -b --noEmit && npm run build (what CI runs)
|
|
make web-dev # Vite dev server, proxying /api to 127.0.0.1:8080
|
|
make web # production build into internal/web/dist
|
|
```
|
|
|
|
For `make web-dev` to show anything, a `fancy-dns` has to be listening on
|
|
127.0.0.1:8080 with the API key the console sends. `deploy/config.example.yaml`
|
|
binds there, but on port 53; rewrite the ports (or use `make smoke`, which does
|
|
it for you) before starting it.
|
|
|
|
Two traps that have cost time, both from `AGENTS.md`:
|
|
|
|
- **`tsc -b` replays cached diagnostics** from `node_modules/.tmp/*.tsbuildinfo`.
|
|
After a large edit `rm -f node_modules/.tmp/*.tsbuildinfo`, or you will read
|
|
errors that no longer exist and miss ones that do.
|
|
- **`npm run build` empties `internal/web/dist` and deletes its `.gitkeep`.**
|
|
Restore it (`git checkout -- internal/web/dist/.gitkeep`). The Go build still
|
|
works while the directory is empty, so a console rebuild in the middle of
|
|
someone else's `go build` is not fatal — but the commit is.
|
|
|
|
## The API contract
|
|
|
|
`src/lib/types.ts` is a **hand-written mirror** of the Go `json` tags in
|
|
`internal/api` and `internal/app/hooks.go`. `apiFetch` ends in
|
|
`JSON.parse(text) as T`, so the compiler checks the console against its own
|
|
declarations and nothing else: a field that loses its `json` tag, or a response
|
|
a struct never had, shows up as an empty table in a browser and nowhere else.
|
|
That is not hypothetical — a round of this found the Sources table, the ACL
|
|
group cards and both Save buttons broken exactly that way.
|
|
|
|
So, when you touch either side:
|
|
|
|
- **Go**: add or keep the `json` tag. `internal/app` has contract tests that
|
|
assert the exact key set of every admin endpoint; they are the spec, and a
|
|
rename fails them.
|
|
- **Console**: change the interface in the same commit. If the server is wrong,
|
|
fix the server — do not "adapt" in the client, and do not paper a mismatch
|
|
over with `as any`, an optional field or a `?? 0` default. Those casts are
|
|
precisely what hides drift.
|
|
- Never rename a field on one side only. The dashboard, the ServiceMonitor
|
|
queries and the Grafana panels are consumers of the same JSON.
|
|
|
|
The durable fix is to generate `types.ts` from the Go structs, or to publish an
|
|
OpenAPI document from the server and generate from that. It is in the plan at
|
|
the end of `STATUS.md`.
|
|
|
|
## What is checked
|
|
|
|
`npx tsc -b --noEmit` (strict, with `noUnusedLocals`) and `oxlint` (two rules:
|
|
`react/rules-of-hooks` and `react/only-export-components`). There is **no test
|
|
runner** and no component test — the console's correctness rests entirely on its
|
|
types, which are only as good as the mirror above. Adding vitest and a handful
|
|
of tests for `lib/format.ts` (the percent/latency/duration formatters, which
|
|
have already shipped a units bug) is cheap and worth doing.
|