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.
71 lines
4.1 KiB
Markdown
71 lines
4.1 KiB
Markdown
# Onboarding — becoming a full contributor to Thermograph
|
|
|
|
This is the developer onboarding path for the `Jinemi/thermograph` monorepo: what
|
|
the product is, how the code is shaped, how to run it, what will break silently
|
|
if you get it wrong, and how a change actually travels from your editor to
|
|
`thermograph.org`.
|
|
|
|
**Scope.** This covers *working in this repo*. Cross-cutting architecture
|
|
decision records and operator runbooks live in the separate `thermograph-docs`
|
|
repo (reachable through Centralis's `docs_search`) — this set links out rather
|
|
than duplicating them. Where a fact is owned by a `CLAUDE.md`, that file stays
|
|
the source of truth and this set explains the context around it.
|
|
|
|
## Reading order
|
|
|
|
| # | Doc | Read it when |
|
|
|---|-----|--------------|
|
|
| 1 | [Orientation](01-orientation.md) | First. What the product actually claims, the estate, the four non-negotiable rules. |
|
|
| 2 | [Local setup](02-setup.md) | Before you touch anything. Toolchain, verified run/test recipes for every service. |
|
|
| 3 | [Repo map](03-repo-map.md) | To find things. Every domain and directory, and which files matter. |
|
|
| 4 | [Backend deep dive](04-backend.md) | Before your first backend change. Data pipeline, grading, caching, roles, daemon. |
|
|
| 5 | [Frontend deep dive](05-frontend.md) | Before your first frontend change. The Go SSR service, static assets, design system. |
|
|
| 6 | [Cross-service contracts](06-contracts.md) | **Before any change that touches both.** These break silently and in production. |
|
|
| 7 | [CI and release](07-ci-and-release.md) | Before you open a PR. Nine workflows, three branches, three environments. |
|
|
| 8 | [Infra and secrets](08-infra-secrets.md) | Before you touch deploy, compose, or a secret. |
|
|
| 9 | [Observability](09-observability.md) | When something is wrong and you need to see it. |
|
|
| 10 | [Recipes](10-recipes.md) | Task-shaped walkthroughs for the things you'll actually do. |
|
|
| 11 | [Traps and stale docs](11-traps.md) | **Skim early, re-read often.** Which docs in this repo currently lie, and why. |
|
|
|
|
## The short version
|
|
|
|
Thermograph grades how unusual today's weather is at any point on Earth against
|
|
~45 years of that exact location's own history. Percentiles, never thermometer
|
|
readings.
|
|
|
|
- **`backend/`** — Python 3.12 / FastAPI. Owns all climate data, grading, the
|
|
API, accounts, notifications, plus a Go daemon (`backend/daemon/`) that owns
|
|
the Discord gateway and recurring timers. Ships as `jinemi/thermograph/backend`.
|
|
- **`frontend/`** — **Go** SSR service (`frontend/server/`) plus every static
|
|
asset. No climate data, no database, no compute. Ships as
|
|
`jinemi/thermograph/frontend`. (The Python implementation at `frontend/*.py` is
|
|
the superseded original — see [traps](11-traps.md).)
|
|
- **`infra/`** — compose and Swarm files, deploy scripts, the SOPS secrets
|
|
vault, Terraform, ops query tooling.
|
|
- **`observability/`** — Loki + Grafana on vps1, an Alloy agent per node.
|
|
|
|
Branches stage environments: PR → `dev` (vps1, mesh-only) → `main` (beta, vps2)
|
|
→ `release` (prod, vps2). The two app domains build and deploy
|
|
**independently** — that independence is the whole reason the split-then-reunify
|
|
history exists, and [contracts](06-contracts.md) is the list of things that
|
|
keep it safe.
|
|
|
|
## Your first day
|
|
|
|
1. Read [Orientation](01-orientation.md) and [Traps](11-traps.md).
|
|
2. Work through [Local setup](02-setup.md) until `make test` is green in both
|
|
`backend/` and `frontend/server/`.
|
|
3. Read [Repo map](03-repo-map.md) with the tree open beside it.
|
|
4. Pick something small in the domain you're least afraid of, and follow
|
|
[Recipes](10-recipes.md) end to end — including opening the PR.
|
|
|
|
## Your first week
|
|
|
|
- Read [Contracts](06-contracts.md) properly. Every item on that list has
|
|
already cost someone a production incident somewhere in this project's
|
|
history; that's why each one is written down.
|
|
- Get Centralis wired up (see [Local setup](02-setup.md)) and ask it
|
|
`fleet_status`, `logs_overview`, `deployed_version`. You cannot debug this
|
|
estate blind, and the boxes are not reachable from a laptop off the
|
|
WireGuard mesh.
|
|
- Read the `CLAUDE.md` for each domain. They are terse, current, and binding.
|