Fix: Media-Symlinks beim Start, Sitter-Datenschutztext, Recalls Dark-Mode, Ausweis neuer Tab, SW by-v600

This commit is contained in:
rene 2026-05-02 10:09:06 +02:00
parent 2677cff882
commit b47a54db39
6 changed files with 47 additions and 24 deletions

View file

@ -48,6 +48,7 @@ async def lifespan(app: FastAPI):
init_db() init_db()
from routes.movies import seed_movies from routes.movies import seed_movies
seed_movies() seed_movies()
_link_prod_media()
logger.info(f"KI-Modus: {ki.KI_MODE}") logger.info(f"KI-Modus: {ki.KI_MODE}")
sched.start() sched.start()
yield yield
@ -280,25 +281,25 @@ app.mount("/img", StaticFiles(directory=f"{STATIC_DIR}/img"), name="img")
# User-generierte Medien (Fotos aus Tagebuch, Giftköder-Alarm, etc.) # User-generierte Medien (Fotos aus Tagebuch, Giftköder-Alarm, etc.)
MEDIA_DIR = os.getenv("MEDIA_DIR", "/data/media") MEDIA_DIR = os.getenv("MEDIA_DIR", "/data/media")
PROD_MEDIA_DIR = os.getenv("PROD_MEDIA_DIR", "") # Staging-only: Fallback auf Prod-Media PROD_MEDIA_DIR = os.getenv("PROD_MEDIA_DIR", "") # Staging-only: Production-Media einlinken
os.makedirs(MEDIA_DIR, exist_ok=True) os.makedirs(MEDIA_DIR, exist_ok=True)
app.mount("/media", StaticFiles(directory=MEDIA_DIR), name="media")
if PROD_MEDIA_DIR:
# Staging: erst eigenes media-Verzeichnis, dann Prod-Fallback
from pathlib import Path as _Path
from starlette.responses import FileResponse as _FileResponse
@app.get("/media/{path:path}") def _link_prod_media():
async def serve_media(path: str): """Staging: symlinkt Production-Media-Verzeichnisse in das Staging-Media-Verzeichnis."""
p = _Path(MEDIA_DIR) / path if not PROD_MEDIA_DIR or not os.path.isdir(PROD_MEDIA_DIR):
if p.is_file(): return
return _FileResponse(str(p)) import pathlib
pp = _Path(PROD_MEDIA_DIR) / path staging = pathlib.Path(MEDIA_DIR)
if pp.is_file(): for item in pathlib.Path(PROD_MEDIA_DIR).iterdir():
return _FileResponse(str(pp)) link = staging / item.name
raise HTTPException(404, "Media not found") if not link.exists() and not link.is_symlink():
else: try:
app.mount("/media", StaticFiles(directory=MEDIA_DIR), name="media") link.symlink_to(item)
logger.info(f"Prod-Media verlinkt: {link}{item}")
except OSError as e:
logger.warning(f"Symlink fehlgeschlagen {link}: {e}")
@app.get("/robots.txt") @app.get("/robots.txt")
async def robots(): async def robots():

View file

@ -6924,3 +6924,26 @@ svg.empty-state-icon {
margin-top: var(--space-1); margin-top: var(--space-1);
line-height: 1.4; line-height: 1.4;
} }
/* Rückrufe — Warnbanner (Dark-Mode-sicher) */
.recalls-warning-banner {
background: var(--c-danger-subtle);
border: 1px solid var(--c-danger);
border-radius: var(--radius-md);
padding: var(--space-3) var(--space-4);
margin-bottom: var(--space-4);
display: flex;
align-items: flex-start;
gap: var(--space-2);
}
.recalls-warning-icon {
color: var(--c-danger);
flex-shrink: 0;
margin-top: 2px;
}
.recalls-warning-text {
margin: 0;
font-size: var(--text-sm);
color: var(--c-text);
line-height: 1.5;
}

View file

@ -3,7 +3,7 @@
Router, State-Management, Navigation, Initialisierung. Router, State-Management, Navigation, Initialisierung.
============================================================ */ ============================================================ */
const APP_VER = '599'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const APP_VER = '600'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VERSION = '1.2.1'; // ← semantische Version, wird bei make release gesetzt const APP_VERSION = '1.2.1'; // ← semantische Version, wird bei make release gesetzt
const IS_STAGING = location.hostname === 'staging.banyaro.app'; const IS_STAGING = location.hostname === 'staging.banyaro.app';

View file

@ -213,7 +213,8 @@ window.Page_dog_profile = (() => {
<div style="padding:var(--space-4);border-bottom:1px solid var(--c-border)"> <div style="padding:var(--space-4);border-bottom:1px solid var(--c-border)">
<div style="font-weight:600">Sitter-Zugang</div> <div style="font-weight:600">Sitter-Zugang</div>
<div style="font-size:var(--text-xs);color:var(--c-text-secondary)"> <div style="font-size:var(--text-xs);color:var(--c-text-secondary)">
Gib einem Freund temporären Schreibzugang für diesen Hund Gib einem Freund temporären Schreibzugang für diesen Hund.
Deine bestehenden Daten und Medien bleiben unsichtbar und privat der Sitter kann nur neue Einträge anlegen.
</div> </div>
</div> </div>
<div id="dp-sitting-access" style="padding:var(--space-4)">Lade</div> <div id="dp-sitting-access" style="padding:var(--space-4)">Lade</div>

View file

@ -38,13 +38,11 @@ window.Page_recalls = (() => {
async function _render() { async function _render() {
_container.innerHTML = ` _container.innerHTML = `
<!-- Warnbanner --> <!-- Warnbanner -->
<div style="background:#fef2f2;border:1px solid #fca5a5;border-radius:var(--radius-md); <div class="recalls-warning-banner">
padding:var(--space-3) var(--space-4);margin-bottom:var(--space-4); <svg class="ph-icon recalls-warning-icon" aria-hidden="true">
display:flex;align-items:flex-start;gap:var(--space-2)">
<svg class="ph-icon" aria-hidden="true" style="color:#dc2626;flex-shrink:0;margin-top:2px">
<use href="/icons/phosphor.svg#warning"></use> <use href="/icons/phosphor.svg#warning"></use>
</svg> </svg>
<p style="margin:0;font-size:var(--text-sm);color:#991b1b;line-height:1.5"> <p class="recalls-warning-text">
<strong>Hinweis:</strong> Prüfe immer das Mindesthaltbarkeitsdatum und die Chargen-Nummer <strong>Hinweis:</strong> Prüfe immer das Mindesthaltbarkeitsdatum und die Chargen-Nummer
bevor du ein gemeldetes Produkt entsorgst oder zurückgibst. bevor du ein gemeldetes Produkt entsorgst oder zurückgibst.
</p> </p>

View file

@ -3,7 +3,7 @@
Offline-Cache + Push Notifications + Tile-Cache Offline-Cache + Push Notifications + Tile-Cache
============================================================ */ ============================================================ */
const CACHE_VERSION = 'by-v599'; const CACHE_VERSION = 'by-v600';
const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_STATIC = `${CACHE_VERSION}-static`;
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache