Teil von „Design auffrischen“, unabhängig von den Teilen 1–7 umsetzbar (sinnvoll nach Teil 1, damit Schrift und Farben schon stehen). Den Prompt unten komplett an Claude Code geben.
Lies vorher CLAUDE.md und die dort verlinkten Dokumente, die für diese Aufgabe relevant sind
(mindestens docs/architektur.md und docs/redaktion.md). Halte dich an Coding und Documentation
Convention. Erst Plan vorstellen, auf mein OK warten, dann umsetzen.
Design-Leitplanken für alle Design-Aufgaben:
- Bestehende Tokens in wwwroot/app.css erweitern, keine Hardcode-Farben; jede neue Farbe mit
Dark-Mode-Variante im bestehenden prefers-color-scheme-Block; WCAG AA.
- Keine Hover-Bewegung (transform/translate) – bewusst entfernt in c67c71e. Hover = Farbe,
Schatten, Rahmen.
- Kommentarstil von app.css beibehalten (erklärt das Warum).
- Layout muss mit beliebigem Redaktions-Markdown und leeren/fehlenden Feldern funktionieren.
- UI-Texte deutsch, ohne Anglizismen.
- Tests: xUnit + Shouldly. Reine Logik als Unit-Test; Darstellung über RouteSmokeTests
(HTML der gerenderten Route prüfen) gegen den PocketBaseFixture. Keine neuen Test-Pakete
(bUnit, Playwright …) ohne Begründung und Rückfrage.
- KEINE Änderung am PocketBase-Datenmodell: keine neuen Collections, Felder, Select-Werte
oder Regeln, collections_schema.json bleibt unverändert. Grund: Es gibt noch keinen Weg,
Schemaänderungen nach Produktion zu übertragen. Wenn eine Lösung nur mit Schemaänderung
ginge: anhalten, Alternative ohne Schemaänderung vorschlagen und die Schema-Variante nur als
Notiz für später ausgeben. Neue Records im Dev-Seed und im Fixture sind erlaubt.
Aufgabe: Eigene Wartungsseite, wenn PocketBase nicht erreichbar ist.
Ist-Zustand: Fällt PocketBase aus, rendert die Startseite (Features/Home/Home.razor.cs)
bewusst nur den festen Kopftext ohne Embeds und mit Status 200; da auch das Menü aus
PocketBase kommt, wirkt die Seite leer. Die übrigen Inhaltsseiten setzen 503 über
Shared/SourceUnavailable und zeigen einen kurzen Hinweis im normalen Layout.
Ziel: Ist PocketBase nicht erreichbar, bekommt jede Seitenanfrage eine eigenständige
statische Wartungsseite mit HTTP 503 (plus Retry-After), statt einer halb leeren Seite.
1. wwwroot/maintenance.html anlegen (Entwurf steht unten im Issue). Eigenständig: keine
PocketBase-Daten, kein Menü, Styles inline (der Fingerprint-Name von app.css ist der
statischen Datei nicht bekannt), IGMH-Farben aus app.css übernehmen, Dark Mode,
keine externen Ressourcen. Nach Prompt 1 Schrift/Farben an die neuen Tokens angleichen.
2. Middleware in Program.cs vor MapRazorComponents: prüft PocketBaseClient.IsHealthyAsync,
Ergebnis kurz zwischenspeichern (z. B. 5–10 s, IMemoryCache oder ein kleiner
Singleton-Dienst mit Zeitstempel), damit nicht jede Anfrage PocketBase anpingt.
Bei „nicht gesund“: maintenance.html mit 503 ausliefern.
Ausgenommen: /health (muss weiter selbst 503 melden), /events.ics (liefert schon einen
leeren Kalender), statische Assets (MapStaticAssets), /maintenance.html selbst.
3. Prüfen, ob das bestehende Degradieren in Home/Embeds/Seiten danach noch gebraucht wird;
als zweite Sicherung (PocketBase fällt zwischen Prüfung und Abruf aus) behalten,
Kommentare anpassen.
4. Tests in RouteSmokeTests nach dem Muster von
Health_returns_503_when_PocketBase_is_unreachable: bei nicht erreichbarem PocketBase
liefern / und eine Inhaltsseite 503 mit dem Wartungstext; /health bleibt 503 mit
„PocketBase unreachable“; bei erreichbarem PocketBase unverändert 200.
5. Verhalten kurz in docs/architektur.md oder docs/deployment.md (Abschnitt Ausfall)
beschreiben.
Hintergrund: Ein früherer Versuch funktionierte nur lokal, weil Datei und Middleware nie
committet wurden; Produktion (gebaut aus main) kannte beides nicht.
Entwurf wwwroot/maintenance.html aus dem früheren Versuch (nie committet)
<!DOCTYPE html><!--
Static maintenance page shown when PocketBase is unreachable. A gate in Program.cs
serves this file with status 503 before any component renders, so it must stand on
its own: no menu, no PocketBase, and its styles are inlined rather than linked to
the fingerprinted app.css (whose hashed name this static file cannot know). The
IGMH colours are copied from app.css so the page still looks like the site.
--><htmllang="de"><head><metacharset="utf-8"/><metaname="viewport"content="width=device-width, initial-scale=1.0"/><title>Elternbeirat der IGMH – gerade nicht erreichbar</title><style>body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;background:#f4f6f4;color:#222;font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;line-height:1.6;padding:1.5rem;}main{max-width:32rem;background:#fff;border-radius:12px;box-shadow:01px3pxrgba(31,58,95,0.08),04px12pxrgba(31,58,95,0.06);padding:2rem;}h1{color:#2b6f9c;margin-top:0;font-size:1.5rem;}a{color:#1f5477;font-weight:600;}.contact{margin-top:1.5rem;padding-top:1.5rem;border-top:1pxsolid#e0e0e0;color:#555;}</style></head><body><main><h1>Die Seite ist gerade nicht erreichbar</h1><p>
Wir bitten um Entschuldigung. Die Website des Elternbeirats der IGMH ist im
Moment nicht verfügbar. Wir arbeiten daran – bitte versuchen Sie es in Kürze
noch einmal.
</p><pclass="contact">
In dringenden Fällen erreichen Sie den Elternbeirat per E-Mail:<br/><ahref="mailto:kontakt@elternbeirat-igmh.info">kontakt@elternbeirat-igmh.info</a></p></main></body></html>
Teil von „Design auffrischen“, unabhängig von den Teilen 1–7 umsetzbar (sinnvoll nach Teil 1, damit Schrift und Farben schon stehen). Den Prompt unten komplett an Claude Code geben.
```
Lies vorher CLAUDE.md und die dort verlinkten Dokumente, die für diese Aufgabe relevant sind
(mindestens docs/architektur.md und docs/redaktion.md). Halte dich an Coding und Documentation
Convention. Erst Plan vorstellen, auf mein OK warten, dann umsetzen.
Design-Leitplanken für alle Design-Aufgaben:
- Bestehende Tokens in wwwroot/app.css erweitern, keine Hardcode-Farben; jede neue Farbe mit
Dark-Mode-Variante im bestehenden prefers-color-scheme-Block; WCAG AA.
- Keine Hover-Bewegung (transform/translate) – bewusst entfernt in c67c71e. Hover = Farbe,
Schatten, Rahmen.
- Kommentarstil von app.css beibehalten (erklärt das Warum).
- Layout muss mit beliebigem Redaktions-Markdown und leeren/fehlenden Feldern funktionieren.
- UI-Texte deutsch, ohne Anglizismen.
- Tests: xUnit + Shouldly. Reine Logik als Unit-Test; Darstellung über RouteSmokeTests
(HTML der gerenderten Route prüfen) gegen den PocketBaseFixture. Keine neuen Test-Pakete
(bUnit, Playwright …) ohne Begründung und Rückfrage.
- KEINE Änderung am PocketBase-Datenmodell: keine neuen Collections, Felder, Select-Werte
oder Regeln, collections_schema.json bleibt unverändert. Grund: Es gibt noch keinen Weg,
Schemaänderungen nach Produktion zu übertragen. Wenn eine Lösung nur mit Schemaänderung
ginge: anhalten, Alternative ohne Schemaänderung vorschlagen und die Schema-Variante nur als
Notiz für später ausgeben. Neue Records im Dev-Seed und im Fixture sind erlaubt.
Aufgabe: Eigene Wartungsseite, wenn PocketBase nicht erreichbar ist.
Ist-Zustand: Fällt PocketBase aus, rendert die Startseite (Features/Home/Home.razor.cs)
bewusst nur den festen Kopftext ohne Embeds und mit Status 200; da auch das Menü aus
PocketBase kommt, wirkt die Seite leer. Die übrigen Inhaltsseiten setzen 503 über
Shared/SourceUnavailable und zeigen einen kurzen Hinweis im normalen Layout.
Ziel: Ist PocketBase nicht erreichbar, bekommt jede Seitenanfrage eine eigenständige
statische Wartungsseite mit HTTP 503 (plus Retry-After), statt einer halb leeren Seite.
1. wwwroot/maintenance.html anlegen (Entwurf steht unten im Issue). Eigenständig: keine
PocketBase-Daten, kein Menü, Styles inline (der Fingerprint-Name von app.css ist der
statischen Datei nicht bekannt), IGMH-Farben aus app.css übernehmen, Dark Mode,
keine externen Ressourcen. Nach Prompt 1 Schrift/Farben an die neuen Tokens angleichen.
2. Middleware in Program.cs vor MapRazorComponents: prüft PocketBaseClient.IsHealthyAsync,
Ergebnis kurz zwischenspeichern (z. B. 5–10 s, IMemoryCache oder ein kleiner
Singleton-Dienst mit Zeitstempel), damit nicht jede Anfrage PocketBase anpingt.
Bei „nicht gesund“: maintenance.html mit 503 ausliefern.
Ausgenommen: /health (muss weiter selbst 503 melden), /events.ics (liefert schon einen
leeren Kalender), statische Assets (MapStaticAssets), /maintenance.html selbst.
3. Prüfen, ob das bestehende Degradieren in Home/Embeds/Seiten danach noch gebraucht wird;
als zweite Sicherung (PocketBase fällt zwischen Prüfung und Abruf aus) behalten,
Kommentare anpassen.
4. Tests in RouteSmokeTests nach dem Muster von
Health_returns_503_when_PocketBase_is_unreachable: bei nicht erreichbarem PocketBase
liefern / und eine Inhaltsseite 503 mit dem Wartungstext; /health bleibt 503 mit
„PocketBase unreachable“; bei erreichbarem PocketBase unverändert 200.
5. Verhalten kurz in docs/architektur.md oder docs/deployment.md (Abschnitt Ausfall)
beschreiben.
Hintergrund: Ein früherer Versuch funktionierte nur lokal, weil Datei und Middleware nie
committet wurden; Produktion (gebaut aus main) kannte beides nicht.
```
<details>
<summary>Entwurf <code>wwwroot/maintenance.html</code> aus dem früheren Versuch (nie committet)</summary>
```html
<!DOCTYPE html>
<!--
Static maintenance page shown when PocketBase is unreachable. A gate in Program.cs
serves this file with status 503 before any component renders, so it must stand on
its own: no menu, no PocketBase, and its styles are inlined rather than linked to
the fingerprinted app.css (whose hashed name this static file cannot know). The
IGMH colours are copied from app.css so the page still looks like the site.
-->
<html lang="de">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Elternbeirat der IGMH – gerade nicht erreichbar</title>
<style>
body {
margin: 0;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #f4f6f4;
color: #222;
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
line-height: 1.6;
padding: 1.5rem;
}
main {
max-width: 32rem;
background: #fff;
border-radius: 12px;
box-shadow: 0 1px 3px rgba(31, 58, 95, 0.08), 0 4px 12px rgba(31, 58, 95, 0.06);
padding: 2rem;
}
h1 {
color: #2b6f9c;
margin-top: 0;
font-size: 1.5rem;
}
a {
color: #1f5477;
font-weight: 600;
}
.contact {
margin-top: 1.5rem;
padding-top: 1.5rem;
border-top: 1px solid #e0e0e0;
color: #555;
}
</style>
</head>
<body>
<main>
<h1>Die Seite ist gerade nicht erreichbar</h1>
<p>
Wir bitten um Entschuldigung. Die Website des Elternbeirats der IGMH ist im
Moment nicht verfügbar. Wir arbeiten daran – bitte versuchen Sie es in Kürze
noch einmal.
</p>
<p class="contact">
In dringenden Fällen erreichen Sie den Elternbeirat per E-Mail:<br/>
<a href="mailto:kontakt@elternbeirat-igmh.info">kontakt@elternbeirat-igmh.info</a>
</p>
</main>
</body>
</html>
```
</details>
Gehört zu #37.
Tom
added this to the Elternbeirat-Website milestone 2026-10-01 11:23:31 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Teil von „Design auffrischen“, unabhängig von den Teilen 1–7 umsetzbar (sinnvoll nach Teil 1, damit Schrift und Farben schon stehen). Den Prompt unten komplett an Claude Code geben.
Entwurf
wwwroot/maintenance.htmlaus dem früheren Versuch (nie committet)Gehört zu #37.