Captures the brainstormed design for a dev-environment banner shown app-wide, plus the height-compensation needed so it doesn't reintroduce the double-scrollbar class of bug just fixed in Shell/public pages.
5.8 KiB
Umgebungs-Indikator (Entwicklungsumgebung-Banner)
Status: approved Datum: 2026-08-05
Kontext
Beim Arbeiten und Testen kann leicht unklar sein, ob man gerade in der lokalen
Entwicklungsumgebung (ng serve, environment.development.ts) oder in der echten,
produktiven App unterwegs ist — beide sehen optisch identisch aus. Ziel: ein visueller
Indikator, der überall in der App sofort erkennbar macht, wenn man sich in der
Entwicklungsumgebung befindet, damit man sich beim Testen nicht vertut.
Entscheidungen aus dem Brainstorming
- Betroffene Umgebungen: Es gibt drei Angular-Build-Konfigurationen
(
myteamwallet_frontend_modern/angular.json):production(Standard,environment.ts, echte API auf myteamwallet.de),development(environment.development.ts, nur lokal viang serve,localhost:3999) undcontainer(environment.container.ts,npm run build:container). Dercontainer-Build ist der reguläre Deploy-Weg der echten Produktion (z. B. self-hosted per Docker) — kein Staging-System — und setzt bereits selbstproduction: true. Der Indikator muss also nurenvironment.production === falseerkennen; kein neues Feld in den Environment-Dateien nötig. - Darstellung: dünner Banner-Streifen ganz oben über der gesamten App (nicht nur im Header), warme Warnfarbe (Amber/Orange, bewusst nicht das App-Grün), Text „⚠ Entwicklungsumgebung", zentriert, klein, kein Dismiss-Button (der Zweck ist ja gerade, ihn nicht wegzuklicken und zu vergessen).
- Inhalt: nur der Umgebungsname, keine zusätzlichen technischen Details (API-URL o. ä.).
- Platzierung im Code: einmalig in
app.htmlvor<router-outlet />, statt in jeder Seite einzeln — automatisch auf jeder Route (Shell, Public-Seiten, Login, Register, Users, Logs, …) sichtbar, single source of truth.
Architektur / Komponenten
1. Neue Komponente EnvBanner
Ordner: myteamwallet_frontend_modern/src/app/shared/env-banner/
Standalone-Komponente nach dem Muster bestehender Shared-Komponenten (context-help,
skeleton) — kein Modul/Barrel, keine Inputs.
env-banner.ts: importiertenvironmentaus../../../environments/environmentund exponiertprotected readonly showBanner = !environment.production;. Exportiert außerdem die Konstanteexport const ENV_BANNER_HEIGHT_PX = 28;(wird vonAppfür die Höhen-Kompensation wiederverwendet, siehe unten — ein einziger Ort für die Pixel-Zahl).env-banner.html:@if (showBanner) { <div class="env-banner" role="status">⚠ Entwicklungsumgebung</div> }— rendert in Produktion buchstäblich nichts (kein leeres DOM-Element).env-banner.scss:.env-banner { height: 28px; display:flex; align-items:center; justify-content:center; background: #f4a300; color:#20251F; font-weight:700; font-size: 0.75rem; letter-spacing:0.04em; text-transform:uppercase; flex-shrink:0; }(die28pxmüssen mitENV_BANNER_HEIGHT_PXübereinstimmen — als Kommentar im SCSS vermerkt).env-banner.spec.ts: rendert Text wennenvironment.production === false, rendert nichts wenntrue(Environment-Objekt im Test gemockt/überschrieben).
2. Einbau in app.html / app.ts
app.html bekommt vor <router-outlet /> ein <app-env-banner />. App importiert
EnvBanner in seine imports-Liste.
3. Höhen-Kompensation für height: 100dvh-Layouts
Der Banner nimmt echten Platz im normalen Fluss ein. Für Seiten, die nur min-height:100dvh
nutzen und sich auf bodys eigenen Scrollbar verlassen (Login, Register,
Forgot/Reset-Password, Confirm-Email, Users, Logs), ist das unproblematisch — body gleicht
das automatisch aus, kein Änderungsbedarf.
Aber shell.scss, public-team.scss und public-player.scss nutzen height: 100dvh
als feste Zusage „genau ein Bildschirm hoch" (siehe
docs/superpowers/plans/-Historie zum Doppel-Scrollbar-Fix vom selben Tag). Ohne Anpassung
würde die Shell/Public-Seite exakt um die Banner-Höhe über den sichtbaren Bereich
hinausragen (Bottom-Nav leicht abgeschnitten) — derselbe Bugtyp wie der kürzlich gefixte.
Fix: App (Root-Komponente) bindet eine CSS-Custom-Property auf ihr eigenes
Host-Element. Host-Bindings werten Ausdrücke gegen die Komponenten-Instanz aus, daher als
Instanz-Property vorhalten:
host: {
'[style.--env-banner-height.px]': 'bannerHeight',
}
// ...
protected readonly bannerHeight = environment.production ? 0 : ENV_BANNER_HEIGHT_PX;
Da <app-root> ein gemeinsamer Vorfahre von EnvBanner und allen Routen-Komponenten
(Shell, Public-Seiten, …) ist, vererbt sich die Property automatisch nach unten. Die drei
betroffenen SCSS-Dateien ändern:
// vorher: height: 100dvh;
height: calc(100dvh - var(--env-banner-height, 0px));
In Produktion ist die Property 0px, calc(100dvh - 0px) verhält sich identisch zu vorher
— keine Verhaltensänderung außerhalb der Entwicklungsumgebung.
Testing
env-banner.spec.ts(neu): Sichtbarkeit abhängig vonenvironment.production.app.spec.ts: Erweiterung um Assertion, dass--env-banner-heightkorrekt0pxbzw.28pxauf dem Host gesetzt wird (je nach gemocktemenvironment.production).- Bestehende Tests (
shell.spec.ts,public-team.spec.ts,public-player.spec.ts) bleiben unverändert grün — diecalc()-Änderung ist rein visuell/CSS, keine Verhaltensänderung. - Manuelle Verifikation:
ng serve(development) zeigt den Banner,ng build(production) undng build --configuration=containerzeigen ihn nicht; Shell/Public-Seiten scrollen mit Banner weiterhin korrekt ohne abgeschnittene Bottom-Nav (per Chrome DevTools nachprüfen).
Out of Scope
- Kein neues
environmentName-Feld in den Environment-Dateien (nicht nötig, siehe oben). - Kein Dismiss/Ausblenden des Banners.
- Keine Anzeige zusätzlicher technischer Details (API-URL, Build-Hash) im Banner-Text.