fix(backend): Neustart gegen die eigene Datenbank, /info als Lebendprobe

Der Dienst lief einmal und stuerzte danach in einer Schleife: MODE=PostgreSQL
laesst H2 unquotierte Bezeichner klein anlegen, Liquibase sucht seine
Verwaltungstabellen gross, findet nichts, legt sie an — "Table
databasechangelog already exists". Der erste Start ging, jeder weitere nicht.
Gemessen mit dem echten Jar: ohne den Modus laufen beide. Liquibase auf
Kleinschreibung zu konfigurieren half nicht, es korrigiert den Namen selbst
zurueck — deshalb weicht der Modus ganz.

Die Testsuite konnte das nicht finden (jeder Test bekommt eine frische
In-Memory-DB), und der Regressionstest dafuer hat zweimal gelogen: erst reichte
er die URL als Default-Property herein, die die application.yaml ueberstimmt;
dann als Argument, aber damit pruefte er eine URL, die er sich selbst
ausgedacht hatte. Jetzt hat die URL einen Regler (werkbaum.data-dir), der Test
ueberschreibt nur den, und die Gegenprobe faellt.

Dieselbe Sorte Fehler eine Ebene hoeher: Die Testkonfiguration hiess
application.yaml und verdeckte damit die Hauptkonfiguration vollstaendig. Sie
ist jetzt eine Profil-Ueberlagerung.

Dazu GET /api/v1/info mit Name, Version und Bauzeitpunkt. Die Lebendprobe
erwartete bisher eine 404 von einem Dokument, das es nicht gibt — ein
erwarteter Fehler ist eine schlechte Zusicherung, dieselbe 404 liefert auch ein
falsch konfigurierter Proxy.

138 Backend-Tests. Gegenprobe: MODE=PostgreSQL zurueck -> genau der
Neustart-Test faellt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-08-26 19:02:51 +02:00
co-authored by Claude Opus 5
parent 78901793f0
commit dea904814b
17 changed files with 436 additions and 52 deletions
+10 -2
View File
@@ -270,9 +270,15 @@ The backend is a separate deploy, because it is a service rather than files:
```bash
scripts/install-jdk.sh # once: a JDK 21 into the server's home
scripts/deploy-backend.sh # build, upload, systemd user unit, restart
scripts/reset-password.sh # asks for the master password, hashes it there
scripts/deploy-prod.sh # the editor — also writes the /api/ proxy rule
```
`GET /api/v1/info` answers with name, version and build time — that is the
liveness check, for the deploy and for monitoring. Expecting a **404** from a
document that does not exist would be a poor assurance: a misconfigured proxy
returns one too.
Configuration lives in the git-ignored `.env` (template `.env.example`):
`BACKEND_SSH`, and optionally `BACKEND_DIR`, `BACKEND_JDK_DIR`, `BACKEND_PORT`,
`BACKEND_XMX`.
@@ -292,8 +298,10 @@ Configuration lives in the git-ignored `.env` (template `.env.example`):
- **The master password never leaves the server.** It goes into
`<BACKEND_DIR>/env` (mode 600), which the deploy creates empty on the first
run. Until a hash is in it, the document list stays locked — deliberately.
Generate it **interactively** (`htpasswd -nBC 12 ''`, no `-b`): a password on
a command line lands in the shell history, and the shell mangles it on the
`scripts/reset-password.sh` asks for it, sends it to the server over
**stdin** (never as an argument — those show up in the process list) and
verifies afterwards that hash and password match. Never put a password on a
command line: it lands in the shell history, and the shell mangles it on the
way — `ge$heim` becomes `ge`. What gets hashed is then not what you type
later, and the server answers 401 while everything looks right.
- **Memory is the scarce resource on that host**, not CPU. The JVM flags are