docs(quick-260916-dcz): Betriebshandbuch Kapitel 9 (Changelog-Schritt, Gitea-Release, Seite Was ist neu), Anwender-, Entwicklungs- und CI-Handbuch
Tessera CI/CD / Lint & Type Check (push) Successful in 45s
Tessera CI/CD / Tests (push) Successful in 1m0s
Tessera CI/CD / Build & Publish Images (push) Successful in 2m51s

- Betrieb Kapitel 9: Vorschritt CHANGELOG.md vor dem Tag, automatischer Gitea-Release samt Verhalten bei fehlendem Abschnitt, Erstfreigabe v1.0.0 in der Vergangenheit, vierter Erkennungsweg "Was ist neu"
- Anwender: Satz zur Versionszeile in "Aufbau der Oberflaeche", neuer Abschnitt "Was ist neu" vor den Stolpersteinen, Inhaltsverzeichnis; Abschnitt "Dashboard" (dyv) unangetastet
- Entwicklung: Regel "Aenderungsliste" unter Konventionen und Fallstricke (Bauzeit-Einbettung, Importdisziplin, Kanalregel, Release-Skript)
- CI-Setup (ASCII): REGISTRY_TOKEN mit repository: write, vier Schritte im Job publish, Release je Tag, API-Basis im Job-Container

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018N9CD3ebPKm1b32bPpBknY
This commit is contained in:
2026-09-16 11:25:10 +02:00
parent 6940bd05a1
commit c5f4adeeed
4 changed files with 62 additions and 12 deletions
+9 -2
View File
@@ -17,7 +17,8 @@ Diese Anleitung richtet sich an alle Kolleginnen und Kollegen, die Tessera im Ar
- [Domaincheck](#domaincheck) - [Domaincheck](#domaincheck)
7. [Persönliche Einstellungen](#persönliche-einstellungen) 7. [Persönliche Einstellungen](#persönliche-einstellungen)
8. [Einen Fehler melden](#einen-fehler-melden) 8. [Einen Fehler melden](#einen-fehler-melden)
9. [Häufige Stolpersteine](#häufige-stolpersteine) 9. [Was ist neu](#was-ist-neu)
10. [Häufige Stolpersteine](#häufige-stolpersteine)
--- ---
@@ -52,7 +53,7 @@ Links steht das Tessera-Logo, in der Mitte der aktuelle Seitentitel. Rechts find
**Seitenleiste (links)** **Seitenleiste (links)**
Ganz oben stehen zwei feste Einträge: **Dashboard** (Ihre Startseite) und **Marktplatz**. Darunter folgt ein Suchfeld „Module suchen…", mit dem Sie die Modulliste filtern können, und darunter die Liste der für Sie freigegebenen Module, gruppiert nach **Kategorien**. Ein Klick auf eine Kategorie klappt sie auf und zeigt die einzelnen Module darin. Sind für Sie noch keine Module aktiv, steht dort „Keine Module". Ganz oben stehen zwei feste Einträge: **Dashboard** (Ihre Startseite) und **Marktplatz**. Darunter folgt ein Suchfeld „Module suchen…", mit dem Sie die Modulliste filtern können, und darunter die Liste der für Sie freigegebenen Module, gruppiert nach **Kategorien**. Ein Klick auf eine Kategorie klappt sie auf und zeigt die einzelnen Module darin. Sind für Sie noch keine Module aktiv, steht dort „Keine Module".
Unten in der Seitenleiste finden Sie die Sprachumschaltung (Deutsch/English) sowie Ihren Namen mit Rolle. Über den Pfeil-Button am unteren Rand können Sie die Seitenleiste ein- und wieder ausklappen — im eingeklappten Zustand bleiben nur die Symbole sichtbar, das spart Platz auf kleineren Bildschirmen. Unten in der Seitenleiste finden Sie die Sprachumschaltung (Deutsch/English) sowie Ihren Namen mit Rolle. Über den Pfeil-Button am unteren Rand können Sie die Seitenleiste ein- und wieder ausklappen — im eingeklappten Zustand bleiben nur die Symbole sichtbar, das spart Platz auf kleineren Bildschirmen. Ganz unten steht die Versionsnummer von Tessera; ein Klick darauf öffnet die Seite [Was ist neu](#was-ist-neu).
## Dashboard ## Dashboard
@@ -169,6 +170,12 @@ Mit **Senden** gehen folgende Angaben als E-Mail an Ihren Administrator: das Bil
Nach dem Senden erscheint „Vielen Dank, die Meldung wurde gesendet." Falls das nicht klappt, sagt Ihnen Tessera, warum: Entweder ist noch kein Postfach für Fehlermeldungen eingerichtet (dann sprechen Sie Ihren Administrator an), oder Sie haben in kurzer Zeit zu viele Meldungen geschickt (höchstens fünf in zehn Minuten), oder die E-Mail konnte gerade nicht gesendet werden (dann versuchen Sie es später noch einmal). Mit **Abbrechen** oder der Escape-Taste schließen Sie das Fenster, ohne etwas zu senden. Nach dem Senden erscheint „Vielen Dank, die Meldung wurde gesendet." Falls das nicht klappt, sagt Ihnen Tessera, warum: Entweder ist noch kein Postfach für Fehlermeldungen eingerichtet (dann sprechen Sie Ihren Administrator an), oder Sie haben in kurzer Zeit zu viele Meldungen geschickt (höchstens fünf in zehn Minuten), oder die E-Mail konnte gerade nicht gesendet werden (dann versuchen Sie es später noch einmal). Mit **Abbrechen** oder der Escape-Taste schließen Sie das Fenster, ohne etwas zu senden.
## Was ist neu
Ein Klick auf die Versionsnummer ganz unten in der Seitenleiste öffnet die Seite **Was ist neu**. Sie zeigt die Änderungsliste von Tessera: Für jede Version steht dort in einfachen Worten, was neu hinzugekommen ist, was sich geändert hat und was behoben wurde — gegliedert in die Gruppen **Neu**, **Geändert** und **Behoben**. Die neueste Version steht oben.
Auf dem Live-System sehen Sie nur freigegebene Versionen. Auf der Beta erscheint zusätzlich der Abschnitt **Noch nicht freigegeben (Beta)** mit einem gelben Hinweis: Diese Punkte sind in der Beta bereits enthalten, aber noch nicht als Version freigegeben.
## Häufige Stolpersteine ## Häufige Stolpersteine
- **Die Anmeldung schlägt fehl, obwohl Passwort und E-Mail stimmen.** Prüfen Sie, ob Sie im Feld „Benutzername" tatsächlich Ihren Benutzernamen eingegeben haben — nicht Ihre E-Mail-Adresse. Das ist mit Abstand der häufigste Grund für eine scheinbar kaputte Anmeldung. - **Die Anmeldung schlägt fehl, obwohl Passwort und E-Mail stimmen.** Prüfen Sie, ob Sie im Feld „Benutzername" tatsächlich Ihren Benutzernamen eingegeben haben — nicht Ihre E-Mail-Adresse. Das ist mit Abstand der häufigste Grund für eine scheinbar kaputte Anmeldung.
+25 -5
View File
@@ -432,6 +432,11 @@ Zeilen einmal ergänzt.
Das Freigeben erledigt Claude; Sie sagen nur „Version X freigeben“. Zur Einordnung, Das Freigeben erledigt Claude; Sie sagen nur „Version X freigeben“. Zur Einordnung,
was dabei passiert: was dabei passiert:
1. **Änderungsliste abschließen:** In `CHANGELOG.md` wird der Abschnitt
„Unveröffentlicht“ in „X.Y.Z – JJJJ-MM-TT“ umbenannt, darüber ein neues, leeres
„Unveröffentlicht“ angelegt, und das Ganze auf `main` committet und gepusht.
Erst dann wird zusammengeführt und getaggt:
```bash ```bash
git checkout live git checkout live
git merge --ff-only main git merge --ff-only main
@@ -445,6 +450,14 @@ weigert, ist eine frühere Korrektur (siehe Hotfix, Schritt 5) noch nicht zurüc
Zweig `live` wird nur geprüft, der Tag `vX.Y.Z` wird gebaut und als `live` und Zweig `live` wird nur geprüft, der Tag `vX.Y.Z` wird gebaut und als `live` und
`vX.Y.Z` abgelegt. Das dauert etwa vier bis sechs Minuten. `vX.Y.Z` abgelegt. Das dauert etwa vier bis sechs Minuten.
Beim Tag legt die Pipeline zusätzlich einen **Release in Gitea** an: Name
„Tessera X.Y.Z“, Text ist der Abschnitt dieser Version aus `CHANGELOG.md`. Sie
finden ihn im Repository unter „Releases“. Fehlt der Abschnitt in der
Änderungsliste, schlägt genau dieser letzte Schritt fehl – die Abbilder sind dann
trotzdem gebaut und abgelegt. Der Release wird nachgeholt, sobald der Abschnitt
nachgetragen ist: entweder durch erneutes Auslösen des Tag-Laufs oder lokal per
Skript (`.gitea/scripts/publish-release.sh --tag vX.Y.Z`).
Danach spielen Sie die Version auf dem Live-Server ein – Kapitel 4 gilt unverändert: Danach spielen Sie die Version auf dem Live-Server ein – Kapitel 4 gilt unverändert:
```bash ```bash
@@ -452,10 +465,12 @@ docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d --force-recreate api web docker compose -f docker-compose.prod.yml up -d --force-recreate api web
``` ```
**Erstfreigabe v1.0.0:** Den Zweig `live` gibt es noch nicht. Er entsteht beim **Erstfreigabe v1.0.0:** Die erste Freigabe ist erfolgt. Der Zweig `live`
ersten Mal aus `main` (`git checkout -b live main`), bekommt den Tag `v1.0.0` und entstand am 2026-09-14 aus `main` (`git checkout -b live main`), bekam den Tag
wird zusammen mit dem Tag gepusht. Das erfolgt, sobald der Knopf „Fehler melden“ `v1.0.0` und wurde zusammen mit dem Tag gepusht; seit 2026-09-15 läuft diese
eingebaut ist – nicht in diesem Durchlauf. Version auf dem Live-Server. Der Release „Tessera 1.0.0“ in Gitea wurde
nachträglich mit dem Skript angelegt, weil die Änderungsliste erst danach
eingeführt wurde.
### Einen Fehler auf Live beheben (Hotfix) ### Einen Fehler auf Live beheben (Hotfix)
@@ -483,7 +498,7 @@ eine Datenbankänderung, wird sie als reguläre Version über `main` freigegeben
### Woran Sie erkennen, welche Version läuft ### Woran Sie erkennen, welche Version läuft
Drei Wege, vom einfachsten zum genauesten: Vier Wege, vom einfachsten zum genauesten:
1. **In der Oberfläche:** Unten in der Seitenleiste steht `v1.0.0 · Live` bzw. 1. **In der Oberfläche:** Unten in der Seitenleiste steht `v1.0.0 · Live` bzw.
`v1.0.0-12-gabc1234 · Beta`. Wenn Sie die Maus darüber halten, erscheinen die `v1.0.0-12-gabc1234 · Beta`. Wenn Sie die Maus darüber halten, erscheinen die
@@ -505,6 +520,11 @@ Drei Wege, vom einfachsten zum genauesten:
``` ```
Zeigt die Startzeile `Tessera API v1.0.0 (live) abc1234` (siehe Kapitel 7). Zeigt die Startzeile `Tessera API v1.0.0 (live) abc1234` (siehe Kapitel 7).
4. **Was sich geändert hat:** Ein Klick auf die Versionszeile unten in der
Seitenleiste öffnet die Seite „Was ist neu“ mit der Änderungsliste. Auf Live
sehen Sie nur freigegebene Versionen; auf der Beta steht zusätzlich der
Abschnitt „Noch nicht freigegeben (Beta)“ mit dem, was seit der letzten
Freigabe dazugekommen ist.
### Den neuen Live-Server einrichten ### Den neuen Live-Server einrichten
+15
View File
@@ -437,6 +437,21 @@ dokumentiert das an jeder betroffenen Stelle explizit im Kommentar (`source-conf
jedem neuen `@Get(':id')`/`@Put(':id')`/`@Delete(':id')` in einem Controller mit weiteren statischen jedem neuen `@Get(':id')`/`@Put(':id')`/`@Delete(':id')` in einem Controller mit weiteren statischen
GET-Routen: statische Routen zuerst deklarieren. GET-Routen: statische Routen zuerst deklarieren.
**Änderungsliste (`CHANGELOG.md`):** Jede Änderung, die Anwender oder Betrieb bemerken, wird sofort
im selben Auftrag in `CHANGELOG.md` unter „Unveröffentlicht“ eingetragen — in Alltagssprache für
Anwender, Sie-Form, echte Umlaute, gegliedert in „Neu“, „Geändert“ und „Behoben“; keine Dateinamen,
keine Commit-Kürzel, keine unerklärten Fachbegriffe. Bei der Freigabe wird der Abschnitt in
„X.Y.Z – JJJJ-MM-TT“ umbenannt und darüber ein neues leeres „Unveröffentlicht“ angelegt (siehe
Betriebshandbuch Kapitel 9). Die Seite „Was ist neu“ (`apps/web/src/app/(portal)/changelog/page.tsx`)
liest den Text zur Bauzeit aus `env.TESSERA_CHANGELOG_MD`, das `apps/web/next.config.ts` aus der
Datei befüllt — deshalb steht `COPY CHANGELOG.md ./` im Web-Dockerfile und `!CHANGELOG.md` als
Ausnahme in `.dockerignore`. Nur `page.tsx` darf `@/lib/changelog` importieren, damit der Text im
Server-Bundle bleibt und nicht in öffentlich abrufbare Client-Chunks gelangt. Die Kanalregel (Live
ohne „Unveröffentlicht“, Beta/Entwicklung mit „Noch nicht freigegeben (Beta)“) liegt in
`filterChangelogForChannel` (`apps/web/src/lib/changelog.ts`) mit Tests. Beim Tag `vX.Y.Z`
schneidet `.gitea/scripts/publish-release.sh` den Abschnitt der Version heraus und legt daraus den
Gitea-Release an — fehlt der Abschnitt, bricht dieser CI-Schritt mit Exit 1 ab.
**i18n — Schlüsselparität zwischen de.json und en.json:** Jeder benutzersichtbare Text gehört in **i18n — Schlüsselparität zwischen de.json und en.json:** Jeder benutzersichtbare Text gehört in
beide Sprachdateien, `apps/web/src/messages/de.json` und `apps/web/src/messages/en.json`. Ein beide Sprachdateien, `apps/web/src/messages/de.json` und `apps/web/src/messages/en.json`. Ein
strukturelle Wächter-Test, `apps/web/src/messages/tenderRadar-parity.spec.ts`, prüft für den strukturelle Wächter-Test, `apps/web/src/messages/tenderRadar-parity.spec.ts`, prüft für den
+13 -5
View File
@@ -85,7 +85,7 @@ fuer die Pipeline konfiguriert. Benoetigt wird genau eines:
| Secret | Beschreibung | | Secret | Beschreibung |
|--------|--------------| |--------|--------------|
| `REGISTRY_TOKEN` | Gitea-Zugangstoken (Access Token) mit Schreibrecht auf Pakete (`package: write`). Wird im Job `publish` fuer `docker login localhost:3002 --password-stdin` verwendet. | | `REGISTRY_TOKEN` | Gitea-Zugangstoken (Access Token) mit Schreibrecht auf Pakete (`package: write`) und zusaetzlich auf das Repository (`repository: write`, fuer Releases). Wird im Job `publish` fuer `docker login localhost:3002 --password-stdin` verwendet und im Release-Schritt ueber `env` als `GITEA_TOKEN` an `.gitea/scripts/publish-release.sh` gereicht -- nie als Argument. |
Das Token erscheint nie im Log: es wird per `--password-stdin` uebergeben und Das Token erscheint nie im Log: es wird per `--password-stdin` uebergeben und
Gitea maskiert Secret-Werte in der Job-Ausgabe. Das Veroeffentlichungs-Skript Gitea maskiert Secret-Werte in der Job-Ausgabe. Das Veroeffentlichungs-Skript
@@ -118,10 +118,18 @@ aus drei aufeinander aufbauenden Jobs:
veroeffentlichen veroeffentlichen
Ablauf: `quality` -> `test` -> `publish` (jeder Job nur bei Erfolg des Ablauf: `quality` -> `test` -> `publish` (jeder Job nur bei Erfolg des
vorherigen). Der Job `publish` besteht aus drei Schritten: `actions/checkout@v4` vorherigen). Der Job `publish` besteht aus vier Schritten: `actions/checkout@v4`
mit `fetch-depth: 0` (volle Historie samt Tags, sonst liefert `git describe` mit `fetch-depth: 0` (volle Historie samt Tags, sonst liefert `git describe`
nichts), Login in die Registry (siehe Abschnitt 3) und der Aufruf von nichts), Login in die Registry (siehe Abschnitt 3), der Aufruf von
`.gitea/scripts/publish-images.sh`. `.gitea/scripts/publish-images.sh` und der Aufruf von
`.gitea/scripts/publish-release.sh` (legt bei Tags `v*` den Gitea-Release aus dem
CHANGELOG-Abschnitt an; auf `main` endet er mit "nichts zu tun").
Das Release-Skript spricht die Gitea-API ueber `GITHUB_API_URL` bzw.
`GITHUB_SERVER_URL/api/v1` an -- im Job-Container ist das
`https://git.vicolab.de`; `localhost:3002` ist von dort NICHT erreichbar (nur der
Docker-Daemon des Hosts erreicht die Registry so). Lokal laesst sich das Skript
mit `--dry-run --tag vX.Y.Z` pruefen, ohne Netzaufruf und ohne Token.
### Zwei Kanaele: Etiketten je Anlass ### Zwei Kanaele: Etiketten je Anlass
@@ -131,7 +139,7 @@ Das Skript `.gitea/scripts/publish-images.sh` entscheidet allein anhand
| Anlass | Kanal (`APP_CHANNEL`) | Etiketten in der Registry | | Anlass | Kanal (`APP_CHANNEL`) | Etiketten in der Registry |
|--------|----------------------|---------------------------| |--------|----------------------|---------------------------|
| Push auf `main` | `beta` | `beta` und `latest` (`latest` ist nur ein Alias fuer `beta` und entfaellt spaeter) | | Push auf `main` | `beta` | `beta` und `latest` (`latest` ist nur ein Alias fuer `beta` und entfaellt spaeter) |
| Tag `vX.Y.Z` | `live` | `live` und `vX.Y.Z` | | Tag `vX.Y.Z` | `live` | `live` und `vX.Y.Z` + Gitea-Release `Tessera X.Y.Z` mit dem CHANGELOG-Abschnitt |
| Push auf `live` ohne Tag | -- | keine; der Lauf prueft nur (`quality`, `test`), das Skript endet mit "nichts zu tun" | | Push auf `live` ohne Tag | -- | keine; der Lauf prueft nur (`quality`, `test`), das Skript endet mit "nichts zu tun" |
Das Kanalmodell fuer den Betrieb (welcher Server welches Etikett zieht, Freigabe, Das Kanalmodell fuer den Betrieb (welcher Server welches Etikett zieht, Freigabe,