1. Admin → Geheimnisse sub-tab lets you edit ANTHROPIC_API_KEY +
BERLIN_WOHNEN_USERNAME/PASSWORD at runtime. Migration v7 adds a
secrets(key,value,updated_at) table; startup seeds missing keys from
env (idempotent). web reads secrets DB-first (env fallback) via
llm._api_key(); alert fetches them from web /internal/secrets on each
scan, passes them into Scraper(). Rotating creds no longer needs a
redeploy.
Masked display: 6 leading + 4 trailing chars, "…" in the middle.
Blank form fields leave the stored value untouched.
2. Drop the max_morning_commute filter from UI + server + FILTER_KEYS +
filter summary (the underlying Maps.calculate_score code stays for
potential future re-enable).
3. /static/didi.webp wired as favicon via <link rel="icon"> in base.html.
4. apply.open_page wraps page.goto in try/except so a failed load still
produces a "goto.failed" step + screenshot instead of returning an
empty forensics blob. networkidle + post-submission sleep are also
made best-effort. The error ZIP export already writes screenshot+HTML
per step and final_html — with this change every apply run leaves a
reconstructable trail even when the listing is already offline.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1. New /admin route with sub-tabs (Protokoll, Benutzer) for admins.
Top nav: "Protokoll" dropped, "Admin" added right of Einstellungen.
/logs and /einstellungen/benutzer issue 301 redirects to the new paths.
Benutzer is no longer part of Einstellungen sub-nav.
2. User_filters.max_age_hours (migration v6) — new dropdown (1–10 h /
beliebig) under Einstellungen → Filter; Wohnungen list drops flats
older than the cutoff by discovered_at.
3. Header shows "aktualisiert vor X s" instead of a countdown. Template
emits data-counter-up-utc with last_alert_heartbeat; app.js ticks up
each second. When a scrape runs, the heartbeat updates and the HTMX
swap resets the counter naturally.
4. Chevron state synced after HTMX swaps: panes preserved via hx-preserve
keep the user's open/closed state, and the sibling button's .open
class is re-applied by syncFlatExpandState() on afterSwap — previously
a scroll-triggered poll would flip the chevron back to closed while
the pane stayed open.
5. "Final absenden" footer removed from the profile page (functionality
is unchanged, the switch still sits atop Wohnungen).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>