Fix: Media-Symlinks beim Start, Sitter-Datenschutztext, Recalls Dark-Mode, Ausweis neuer Tab, SW by-v600
This commit is contained in:
parent
2677cff882
commit
b47a54db39
6 changed files with 47 additions and 24 deletions
|
|
@ -48,6 +48,7 @@ async def lifespan(app: FastAPI):
|
|||
init_db()
|
||||
from routes.movies import seed_movies
|
||||
seed_movies()
|
||||
_link_prod_media()
|
||||
logger.info(f"KI-Modus: {ki.KI_MODE}")
|
||||
sched.start()
|
||||
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.)
|
||||
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)
|
||||
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}")
|
||||
async def serve_media(path: str):
|
||||
p = _Path(MEDIA_DIR) / path
|
||||
if p.is_file():
|
||||
return _FileResponse(str(p))
|
||||
pp = _Path(PROD_MEDIA_DIR) / path
|
||||
if pp.is_file():
|
||||
return _FileResponse(str(pp))
|
||||
raise HTTPException(404, "Media not found")
|
||||
else:
|
||||
app.mount("/media", StaticFiles(directory=MEDIA_DIR), name="media")
|
||||
def _link_prod_media():
|
||||
"""Staging: symlinkt Production-Media-Verzeichnisse in das Staging-Media-Verzeichnis."""
|
||||
if not PROD_MEDIA_DIR or not os.path.isdir(PROD_MEDIA_DIR):
|
||||
return
|
||||
import pathlib
|
||||
staging = pathlib.Path(MEDIA_DIR)
|
||||
for item in pathlib.Path(PROD_MEDIA_DIR).iterdir():
|
||||
link = staging / item.name
|
||||
if not link.exists() and not link.is_symlink():
|
||||
try:
|
||||
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")
|
||||
async def robots():
|
||||
|
|
|
|||
|
|
@ -6924,3 +6924,26 @@ svg.empty-state-icon {
|
|||
margin-top: var(--space-1);
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
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 IS_STAGING = location.hostname === 'staging.banyaro.app';
|
||||
|
||||
|
|
|
|||
|
|
@ -213,7 +213,8 @@ window.Page_dog_profile = (() => {
|
|||
<div style="padding:var(--space-4);border-bottom:1px solid var(--c-border)">
|
||||
<div style="font-weight:600">Sitter-Zugang</div>
|
||||
<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 id="dp-sitting-access" style="padding:var(--space-4)">Lade…</div>
|
||||
|
|
|
|||
|
|
@ -38,13 +38,11 @@ window.Page_recalls = (() => {
|
|||
async function _render() {
|
||||
_container.innerHTML = `
|
||||
<!-- Warnbanner -->
|
||||
<div style="background:#fef2f2;border:1px solid #fca5a5;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)">
|
||||
<svg class="ph-icon" aria-hidden="true" style="color:#dc2626;flex-shrink:0;margin-top:2px">
|
||||
<div class="recalls-warning-banner">
|
||||
<svg class="ph-icon recalls-warning-icon" aria-hidden="true">
|
||||
<use href="/icons/phosphor.svg#warning"></use>
|
||||
</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
|
||||
bevor du ein gemeldetes Produkt entsorgst oder zurückgibst.
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
Offline-Cache + Push Notifications + Tile-Cache
|
||||
============================================================ */
|
||||
|
||||
const CACHE_VERSION = 'by-v599';
|
||||
const CACHE_VERSION = 'by-v600';
|
||||
const CACHE_STATIC = `${CACHE_VERSION}-static`;
|
||||
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
|
||||
const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue