|
Some checks failed
secrets-guard / encrypted (push) Successful in 24s
shell-lint / shellcheck (push) Successful in 26s
Deploy frontend to LAN dev server / build (push) Successful in 2m11s
Build + push frontend image (Forgejo registry) / build-push (push) Successful in 2m20s
Build + push backend image (Forgejo registry) / build-push (push) Successful in 2m28s
Deploy backend to LAN dev server / build (push) Successful in 2m45s
PR build (required check) / changes (pull_request) Successful in 16s
secrets-guard / encrypted (pull_request) Successful in 16s
shell-lint / shellcheck (pull_request) Successful in 15s
PR build (required check) / build-frontend (pull_request) Has been skipped
PR build (required check) / validate-observability (pull_request) Has been skipped
Deploy frontend to LAN dev server / deploy (push) Successful in 39s
PR build (required check) / build-backend (pull_request) Successful in 1m21s
PR build (required check) / gate (pull_request) Successful in 3s
Deploy backend to LAN dev server / deploy (push) Failing after 2m31s
|
||
|---|---|---|
| .. | ||
| internal | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| README.md | ||
thermograph-frontend (Go)
The SSR frontend service, ported from the Python implementation one directory
up (app.py / content.py / api_client.py / format.py): server-rendered
content pages, the interactive tool's SPA shells, and every static asset. It
is I/O-bound glue over the backend's /content/* JSON API — no climate maths,
no database, no auth.
Layout
go.mod module thermograph/frontend (Go 1.26)
main.go config + mux + static + graceful shutdown
internal/config/ every env var the service reads (same names,
defaults and required/optional split as the
Python — see config.go's field docs)
internal/contentapi/ backend /content/* client: TTL cache, bounded
LRU, per-key single-flight, origin forwarding;
typed payloads in types.go
internal/render/ html/template engine over an embed.FS +
response ETag helpers (W/"sha1[:20]",
If-None-Match handling)
internal/render/templates/ the page templates (embedded; *.tmpl)
internal/contentdata/ glossary.yaml / pages.yaml loader (fail-loud
validation, file order preserved)
Dependencies: stdlib plus gopkg.in/yaml.v3 — the committed SSR copy in
frontend/content/*.yaml is shared with the rest of the repo and uses block/
folded scalars, so a YAML parser is genuinely required.
Run locally
cd frontend/server
go build -o thermograph-frontend .
cd .. # static/ and content/ resolve relative to the working dir
THERMOGRAPH_API_BASE_INTERNAL=http://127.0.0.1:8137 \
THERMOGRAPH_BASE=/thermograph \
./server/thermograph-frontend
THERMOGRAPH_API_BASE_INTERNAL is required — the boot fails loudly without it,
same as the Python raised at import. Other env vars (all optional):
THERMOGRAPH_BASE (default /thermograph; the image sets /),
THERMOGRAPH_API_VERSION (default v2 — bump only per the API-version pinning
contract in frontend/CLAUDE.md), THERMOGRAPH_API_BASE_PUBLIC,
THERMOGRAPH_SSR_CACHE_TTL (seconds, default 600),
THERMOGRAPH_GOOGLE_VERIFY / THERMOGRAPH_BING_VERIFY, and PORT
(default 8080).
The process expects static/ and content/ in its working directory
(frontend/ locally, /app in the image). Templates are embedded in the
binary; static assets and the YAML copy are read from disk.
Test / verify
cd frontend/server
go build ./... && go vet ./... && go test ./...
The deployed binary is /usr/local/bin/thermograph-frontend inside the
emi/thermograph/frontend image; the image name, frontend-* CI workflows and
deploy path are unchanged from the Python service.