|
All checks were successful
PR build (required check) / changes (pull_request) Successful in 6s
secrets-guard / encrypted (pull_request) Successful in 4s
shell-lint / shellcheck (pull_request) Successful in 6s
PR build (required check) / validate-observability (pull_request) Successful in 20s
PR build (required check) / build-frontend (pull_request) Successful in 37s
PR build (required check) / build-backend (pull_request) Successful in 51s
PR build (required check) / gate (pull_request) Successful in 1s
Repos moved to the Jinemi org; the container packages did not follow, since
Forgejo does not transfer packages with a repo. The deploy path still resolved
`emi/thermograph/*` — a user_redirect to admin_emi — while build-push.yml
derives its push path from ${github.repository}, now jinemi/thermograph. The
next backend or frontend build would have published somewhere no deploy looks.
Point the image paths at jinemi/thermograph/* (lowercase: OCI references admit
no uppercase, which is why build-push.yml already pipes through tr), the clone
URLs at Jinemi/thermograph, and the registry logins at admin_emi — the account
that actually owns the tokens, rather than the redirect.
The live tags and both ci-runner tags were copied into the Jinemi namespace
first, so the switch has something to pull. thermograph-infra,
thermograph-observability and the retired */app packages stay under admin_emi;
they did not move.
|
||
|---|---|---|
| .. | ||
| 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
jinemi/thermograph/frontend image; the image name, frontend-* CI workflows and
deploy path are unchanged from the Python service.