chore: Release v0.10.0 (Reverse-Proxy-Tauglichkeit)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -61,7 +61,7 @@ systemd `--user`), Grafana OSS 12.1.0, Bash-Deployskript.
|
||||
`FB_SESSION_COOKIE_SECURE`, Default `False`). Bool-Parsing via Modul-Helfer
|
||||
`_env_bool(value: str) -> bool` (truthy: `1/true/yes/on`, case-insensitiv).
|
||||
|
||||
- [ ] **Step 1: Failing Tests schreiben** — an `finance/tests/test_config.py`
|
||||
- [x] **Step 1: Failing Tests schreiben** — an `finance/tests/test_config.py`
|
||||
anhängen (oben `import pytest` ergänzen, falls nicht vorhanden):
|
||||
|
||||
```python
|
||||
@@ -105,12 +105,12 @@ def test_session_cookie_secure_parsing(monkeypatch, val, expected):
|
||||
get_settings.cache_clear()
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Tests laufen lassen, Fehlschlag prüfen**
|
||||
- [x] **Step 2: Tests laufen lassen, Fehlschlag prüfen**
|
||||
|
||||
Run: `cd finance && .venv/bin/python -m pytest tests/test_config.py -q`
|
||||
Expected: FAIL (`AttributeError: ... 'grafana_public_url'` / `session_cookie_secure`).
|
||||
|
||||
- [ ] **Step 3: Implementieren** — `finance/app/config.py`. Bool-Helfer vor
|
||||
- [x] **Step 3: Implementieren** — `finance/app/config.py`. Bool-Helfer vor
|
||||
`get_settings` einfügen, zwei Felder ins `@dataclass Settings` und zwei
|
||||
Zeilen in den `Settings(...)`-Konstruktor:
|
||||
|
||||
@@ -142,17 +142,17 @@ In `get_settings()` in den `return Settings(...)`-Aufruf (nach
|
||||
session_cookie_secure=_env_bool(e("FB_SESSION_COOKIE_SECURE", "")),
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Tests grün**
|
||||
- [x] **Step 4: Tests grün**
|
||||
|
||||
Run: `cd finance && .venv/bin/python -m pytest tests/test_config.py -q`
|
||||
Expected: PASS.
|
||||
|
||||
- [ ] **Step 5: Volle Suite**
|
||||
- [x] **Step 5: Volle Suite**
|
||||
|
||||
Run: `cd finance && .venv/bin/python -m pytest -q`
|
||||
Expected: PASS (> 199).
|
||||
|
||||
- [ ] **Step 6: Fable-Gate + Commit**
|
||||
- [x] **Step 6: Fable-Gate + Commit**
|
||||
|
||||
```bash
|
||||
git add finance/app/config.py finance/tests/test_config.py
|
||||
@@ -173,7 +173,7 @@ git commit -m "feat: FB_GRAFANA_PUBLIC_URL + FB_SESSION_COOKIE_SECURE in Setting
|
||||
`secure`) auf: jetzt per Env konfigurierbar, Default unverändert (kein
|
||||
`secure` im Lokalbetrieb).
|
||||
|
||||
- [ ] **Step 1: Failing Tests** — an `finance/tests/test_auth.py` anhängen.
|
||||
- [x] **Step 1: Failing Tests** — an `finance/tests/test_auth.py` anhängen.
|
||||
Sicherstellen, dass oben importiert ist: `from app.config import get_settings`.
|
||||
Die Tests nutzen die vorhandene `client`-Fixture (setzt Passwort-Hash) und
|
||||
schalten das Flag zur Laufzeit um (Login liest `get_settings()` je Request):
|
||||
@@ -197,12 +197,12 @@ def test_login_cookie_not_secure_by_default(client, monkeypatch):
|
||||
assert "secure" not in r.headers["set-cookie"].lower()
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Fehlschlag prüfen**
|
||||
- [x] **Step 2: Fehlschlag prüfen**
|
||||
|
||||
Run: `cd finance && .venv/bin/python -m pytest tests/test_auth.py::test_login_cookie_secure_when_enabled -q`
|
||||
Expected: FAIL (`assert "secure" in ...`, Cookie hat noch kein secure-Flag).
|
||||
|
||||
- [ ] **Step 3: Implementieren** — in `finance/app/main.py` den
|
||||
- [x] **Step 3: Implementieren** — in `finance/app/main.py` den
|
||||
`set_cookie`-Aufruf im Login um `secure=` ergänzen:
|
||||
|
||||
```python
|
||||
@@ -219,17 +219,17 @@ def login(username: str = Form(...), password: str = Form(...)):
|
||||
return resp
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Tests grün**
|
||||
- [x] **Step 4: Tests grün**
|
||||
|
||||
Run: `cd finance && .venv/bin/python -m pytest tests/test_auth.py -q`
|
||||
Expected: PASS.
|
||||
|
||||
- [ ] **Step 5: Volle Suite**
|
||||
- [x] **Step 5: Volle Suite**
|
||||
|
||||
Run: `cd finance && .venv/bin/python -m pytest -q`
|
||||
Expected: PASS.
|
||||
|
||||
- [ ] **Step 6: Fable-Gate + Commit**
|
||||
- [x] **Step 6: Fable-Gate + Commit**
|
||||
|
||||
```bash
|
||||
git add finance/app/main.py finance/tests/test_auth.py
|
||||
@@ -254,7 +254,7 @@ git commit -m "feat: Session-Cookie secure-Flag per FB_SESSION_COOKIE_SECURE"
|
||||
`http://<request-host>:8097`. Templates hängen bei Bedarf `/d/finanzen/...`
|
||||
an — mit sub-path-URL ergibt das `.../grafana/d/finanzen/...`.
|
||||
|
||||
- [ ] **Step 1: Failing Tests** — an `finance/tests/test_gui.py` anhängen. Oben
|
||||
- [x] **Step 1: Failing Tests** — an `finance/tests/test_gui.py` anhängen. Oben
|
||||
`from app.config import get_settings` ergänzen, falls nicht vorhanden:
|
||||
|
||||
```python
|
||||
@@ -287,12 +287,12 @@ def test_grafana_links_fallback_to_host_port_when_unset(client, monkeypatch):
|
||||
get_settings.cache_clear()
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Fehlschlag prüfen**
|
||||
- [x] **Step 2: Fehlschlag prüfen**
|
||||
|
||||
Run: `cd finance && .venv/bin/python -m pytest tests/test_gui.py::test_grafana_links_use_public_url_when_set -q`
|
||||
Expected: FAIL (Templates nutzen noch `<host>:8097`, `:8097` ist im Text).
|
||||
|
||||
- [ ] **Step 3a: Jinja-Global implementieren** — `finance/app/routers/gui.py`.
|
||||
- [x] **Step 3a: Jinja-Global implementieren** — `finance/app/routers/gui.py`.
|
||||
Import ergänzen (bei den `from app...`-Imports):
|
||||
|
||||
```python
|
||||
@@ -319,7 +319,7 @@ def grafana_public_base(request: Request) -> str:
|
||||
templates.env.globals["grafana_public_base"] = grafana_public_base
|
||||
```
|
||||
|
||||
- [ ] **Step 3b: Templates umstellen.**
|
||||
- [x] **Step 3b: Templates umstellen.**
|
||||
|
||||
`finance/app/templates/base.html` Zeile 20:
|
||||
|
||||
@@ -342,22 +342,22 @@ templates.env.globals["grafana_public_base"] = grafana_public_base
|
||||
Kurven in <a href="{{ grafana_public_base(request) }}" target="_blank" rel="noopener">Grafana</a> ansehen.
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Tests grün**
|
||||
- [x] **Step 4: Tests grün**
|
||||
|
||||
Run: `cd finance && .venv/bin/python -m pytest tests/test_gui.py -q`
|
||||
Expected: PASS.
|
||||
|
||||
- [ ] **Step 5: Kontrollgriff — keine hartkodierten `:8097` mehr in Templates**
|
||||
- [x] **Step 5: Kontrollgriff — keine hartkodierten `:8097` mehr in Templates**
|
||||
|
||||
Run: `grep -rn ":8097" finance/app/templates`
|
||||
Expected: keine Treffer.
|
||||
|
||||
- [ ] **Step 6: Volle Suite**
|
||||
- [x] **Step 6: Volle Suite**
|
||||
|
||||
Run: `cd finance && .venv/bin/python -m pytest -q`
|
||||
Expected: PASS.
|
||||
|
||||
- [ ] **Step 7: Fable-Gate + Commit**
|
||||
- [x] **Step 7: Fable-Gate + Commit**
|
||||
|
||||
```bash
|
||||
git add finance/app/routers/gui.py finance/app/templates/base.html \
|
||||
@@ -381,7 +381,7 @@ git commit -m "feat: Grafana-Links aus FB_GRAFANA_PUBLIC_URL (Sub-Pfad-tauglich)
|
||||
nur an `127.0.0.1` gebunden ist und ausschließlich der lokale Traefik ihn
|
||||
erreicht (dokumentiert in docs/reverse-proxy.md, Task 6).
|
||||
|
||||
- [ ] **Step 1: Failing Test** — `finance/tests/test_entrypoint.py` anlegen:
|
||||
- [x] **Step 1: Failing Test** — `finance/tests/test_entrypoint.py` anlegen:
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
@@ -395,12 +395,12 @@ def test_entrypoint_enables_proxy_headers():
|
||||
assert "--forwarded-allow-ips" in text
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Fehlschlag prüfen**
|
||||
- [x] **Step 2: Fehlschlag prüfen**
|
||||
|
||||
Run: `cd finance && .venv/bin/python -m pytest tests/test_entrypoint.py -q`
|
||||
Expected: FAIL (Flags fehlen noch).
|
||||
|
||||
- [ ] **Step 3: Implementieren** — `finance/entrypoint.sh` vollständig:
|
||||
- [x] **Step 3: Implementieren** — `finance/entrypoint.sh` vollständig:
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
@@ -416,17 +416,17 @@ exec uvicorn app.main:app --host 0.0.0.0 --port 8000 \
|
||||
--proxy-headers --forwarded-allow-ips='*'
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Test grün + Shell-Syntaxcheck**
|
||||
- [x] **Step 4: Test grün + Shell-Syntaxcheck**
|
||||
|
||||
Run: `cd finance && .venv/bin/python -m pytest tests/test_entrypoint.py -q && sh -n entrypoint.sh && echo OK`
|
||||
Expected: PASS + `OK`.
|
||||
|
||||
- [ ] **Step 5: Volle Suite**
|
||||
- [x] **Step 5: Volle Suite**
|
||||
|
||||
Run: `cd finance && .venv/bin/python -m pytest -q`
|
||||
Expected: PASS.
|
||||
|
||||
- [ ] **Step 6: Fable-Gate + Commit**
|
||||
- [x] **Step 6: Fable-Gate + Commit**
|
||||
|
||||
```bash
|
||||
git add finance/entrypoint.sh finance/tests/test_entrypoint.py
|
||||
@@ -451,7 +451,7 @@ git commit -m "feat: uvicorn Proxy-Headers fuer Reverse-Proxy-Betrieb"
|
||||
`bash -n`, isolierten Test der Sub-Pfad-Extraktion und den Live-Redeploy in
|
||||
Task 7.
|
||||
|
||||
- [ ] **Step 1: Sub-Pfad-Berechnung einfügen** — in `create_pod_finance.sh`
|
||||
- [x] **Step 1: Sub-Pfad-Berechnung einfügen** — in `create_pod_finance.sh`
|
||||
VOR dem **API**-`podman run` (`podman run -d --name "$API_CTR_NAME" ...`)
|
||||
diesen Block einfügen. WICHTIG: nicht erst vor dem Grafana-Container — der
|
||||
API-Container läuft im Skript zuerst und verwendet bereits `${GF_SUBPATH}`
|
||||
@@ -481,7 +481,7 @@ if [ -n "${FB_GRAFANA_PUBLIC_URL:-}" ]; then
|
||||
fi
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Grafana-Container um die Sub-Pfad-Args ergänzen** — im
|
||||
- [x] **Step 2: Grafana-Container um die Sub-Pfad-Args ergänzen** — im
|
||||
`podman run -d --name "$GRAFANA_CTR_NAME" ...`-Aufruf eine Zeile
|
||||
einfügen (z.B. direkt nach `-e GF_SECURITY_COOKIE_SAMESITE=lax \`):
|
||||
|
||||
@@ -492,7 +492,7 @@ fi
|
||||
(Bei leerem Array expandiert das unter bash zu nichts — Lokalbetrieb
|
||||
unverändert.)
|
||||
|
||||
- [ ] **Step 3: API-Container um die drei Env-Durchreichungen ergänzen** — im
|
||||
- [x] **Step 3: API-Container um die drei Env-Durchreichungen ergänzen** — im
|
||||
`podman run -d --name "$API_CTR_NAME" ...`-Aufruf nach der Zeile
|
||||
`-e FB_UPLOADS_DIR=/data/uploads \` einfügen:
|
||||
|
||||
@@ -506,7 +506,7 @@ unverändert.)
|
||||
zum bisherigen Config-Default; im Sub-Pfad-Modus `http://localhost:3000/grafana`,
|
||||
damit die GUI-Passwortänderung die Grafana-Admin-API unter dem Präfix trifft.)
|
||||
|
||||
- [ ] **Step 4: Grafana-Health-Check-URL sub-path-bewusst machen** — die Zeile
|
||||
- [x] **Step 4: Grafana-Health-Check-URL sub-path-bewusst machen** — die Zeile
|
||||
|
||||
```bash
|
||||
CHECK_URL_GRAFANA="http://$HOST_LOCAL_IP:$GRAFANA_HOST_PORT/api/health"
|
||||
@@ -518,7 +518,7 @@ ersetzen durch:
|
||||
CHECK_URL_GRAFANA="http://$HOST_LOCAL_IP:$GRAFANA_HOST_PORT${GF_SUBPATH}/api/health"
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Statische Verifikation**
|
||||
- [x] **Step 5: Statische Verifikation**
|
||||
|
||||
Run: `bash -n create_pod_finance.sh && echo SYNTAX-OK`
|
||||
Expected: `SYNTAX-OK`.
|
||||
@@ -538,7 +538,7 @@ http://host.tld/g/ -> [/g]
|
||||
-> []
|
||||
```
|
||||
|
||||
- [ ] **Step 6: Fable-Gate (adversariale Skript-Review) + Commit**
|
||||
- [x] **Step 6: Fable-Gate (adversariale Skript-Review) + Commit**
|
||||
|
||||
Fable prüft insbesondere: Lokalbetrieb (leere Variable) ist echter No-Op
|
||||
(leeres Array, leerer Präfix, `FB_GRAFANA_URL=http://localhost:3000`);
|
||||
@@ -562,7 +562,7 @@ git commit -m "feat: create_pod_finance.sh Grafana-Sub-Pfad + interne URLs sub-p
|
||||
- Produces: Betriebsdoku für den Proxy-Umzug. Beispiel-Snippets sind
|
||||
Vorlagen — die eigentliche Proxy-Konfiguration macht der Nutzer.
|
||||
|
||||
- [ ] **Step 1: `docs/reverse-proxy.md` anlegen** mit folgendem Inhalt:
|
||||
- [x] **Step 1: `docs/reverse-proxy.md` anlegen** mit folgendem Inhalt:
|
||||
|
||||
````markdown
|
||||
# Reverse-Proxy-Betrieb (Ausbaustufe 10)
|
||||
@@ -658,7 +658,7 @@ Forwarded-Proto https` ist wichtig, damit uvicorn (mit `--proxy-headers`) das
|
||||
entfernen (oder leeren) und `./create_pod_finance.sh` erneut ausführen.
|
||||
````
|
||||
|
||||
- [ ] **Step 2: Verweis in `docs/ARCHITEKTUR.md`** — im Deployment-Abschnitt
|
||||
- [x] **Step 2: Verweis in `docs/ARCHITEKTUR.md`** — im Deployment-Abschnitt
|
||||
(Abschnitt 3) einen Hinweis auf die neue Doku ergänzen, z.B.:
|
||||
|
||||
```markdown
|
||||
@@ -668,10 +668,10 @@ entfernen (oder leeren) und `./create_pod_finance.sh` erneut ausführen.
|
||||
> Direktbetrieb unverändert.
|
||||
```
|
||||
|
||||
- [ ] **Step 3: `CLAUDE.md`** — im Abschnitt zur `.env` die zwei neuen
|
||||
- [x] **Step 3: `CLAUDE.md`** — im Abschnitt zur `.env` die zwei neuen
|
||||
Variablen kurz erwähnen (ein Satz), inkl. Verweis auf `docs/reverse-proxy.md`.
|
||||
|
||||
- [ ] **Step 4: Fable-Gate (Faktencheck gegen Skript/Config/Templates) + Commit**
|
||||
- [x] **Step 4: Fable-Gate (Faktencheck gegen Skript/Config/Templates) + Commit**
|
||||
|
||||
Fable prüft: Snippets stimmen mit dem tatsächlichen Verhalten aus Task 1–5
|
||||
überein (Ports 8096/8097, kein Prefix-Stripping, `serve_from_sub_path`,
|
||||
@@ -696,26 +696,26 @@ git commit -m "docs: Reverse-Proxy-Snippets (Traefik/Apache) + .env-Schalter"
|
||||
- Live-Verifikation, dass der **Lokalbetrieb** (leere Proxy-Variablen) mit
|
||||
v0.10.0 unverändert funktioniert.
|
||||
|
||||
- [ ] **Step 1: Version hochzählen**
|
||||
- [x] **Step 1: Version hochzählen**
|
||||
|
||||
`finance/VERSION`:
|
||||
```
|
||||
0.10.0
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Volle Suite**
|
||||
- [x] **Step 2: Volle Suite**
|
||||
|
||||
Run: `cd finance && .venv/bin/python -m pytest -q`
|
||||
Expected: PASS (> 199).
|
||||
|
||||
- [ ] **Step 3: Redeploy (Lokalbetrieb, `.env` OHNE Proxy-Variablen)**
|
||||
- [x] **Step 3: Redeploy (Lokalbetrieb, `.env` OHNE Proxy-Variablen)**
|
||||
|
||||
Run: `./create_pod_finance.sh`
|
||||
Expected: Läuft durch bis „API is reachable ... (200)" und „Grafana is
|
||||
reachable ... (200)"; Service enabled+active. Der Health-Check spricht ohne
|
||||
Präfix `:8097/api/health` (weil `FB_GRAFANA_PUBLIC_URL` leer).
|
||||
|
||||
- [ ] **Step 4: Live-Check Lokalbetrieb unverändert**
|
||||
- [x] **Step 4: Live-Check Lokalbetrieb unverändert**
|
||||
|
||||
```bash
|
||||
# Login → 303 + Cookie (Cookie OHNE Secure, da FB_SESSION_COOKIE_SECURE leer)
|
||||
@@ -737,12 +737,12 @@ Expected: Login `303` + `set-cookie: fb_session=...` **ohne** `Secure`;
|
||||
`/api/version` → `{"version":"0.10.0"}`; Grafana-Link enthält `:8097/d/finanzen`
|
||||
und **kein** `/grafana`; alle Seiten `200`; `grafana:200`.
|
||||
|
||||
- [ ] **Step 5: Plan-Haken + Ledger** — alle Task-Checkboxen dieses Plans
|
||||
- [x] **Step 5: Plan-Haken + Ledger** — alle Task-Checkboxen dieses Plans
|
||||
setzen; in `.superpowers/sdd/progress.md` einen A10-Abschluss-Eintrag
|
||||
ergänzen (Commit-Range, Fable-Befunde je Task, Live-Check-Ergebnis; **keine**
|
||||
echten Kontodaten/Domain-Secrets).
|
||||
|
||||
- [ ] **Step 6: Fable-Release-Gate + Commit**
|
||||
- [x] **Step 6: Fable-Release-Gate + Commit**
|
||||
|
||||
Fable verifiziert: Suite grün, Version live `0.10.0`, Lokalbetrieb im
|
||||
Live-Check unverändert (Cookie ohne Secure, Grafana-Fallback `:8097`),
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.9.0
|
||||
0.10.0
|
||||
|
||||
Reference in New Issue
Block a user