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>
* Wohnungen header: single slim row with Alert status · Filter summary ·
Auto-Bewerben toggle · Trockenmodus toggle. Big filter panel removed —
filters live only in /einstellungen/filter.
* Alert status: 'nicht eingerichtet' until the user has actual filters (+
valid notification creds if telegram/email). 'aktiv' otherwise.
* Logs tab: admin-only (gated both in layout and server-side). Shows merged
audit + errors across all users, sorted newest-first, capped at 300.
* Apply, auto-apply, trockenmodus and circuit reset buttons post via HTMX and
swap the Wohnungen body. While any application is still running for the
user the poll interval drops from 30s to 3s so status flips to 'beworben'
or 'fehlgeschlagen' almost immediately.
* Browser tab title is now always 'lazyflat'.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* DB: users + user_profiles/filters/notifications/preferences; applications gets
user_id + forensics_json + profile_snapshot_json; new errors table
with 14d retention; schema versioning via MIGRATIONS list
* auth: password hashes in DB (argon2); env vars seed first admin; per-user
sessions; CSRF bound to user id
* apply: personal info/WBS moved out of env into the request body; providers
take an ApplyContext with Profile + submit_forms; full Playwright recorder
(step log, console, page errors, network, screenshots, final HTML)
* web: five top-level tabs (Wohnungen/Bewerbungen/Logs/Fehler/Einstellungen);
settings sub-tabs profil/filter/benachrichtigungen/account/benutzer;
per-user matching, auto-apply and notifications (UI/Telegram/SMTP); red
auto-apply switch on Wohnungen tab; forensics detail view for bewerbungen
and fehler; retention background thread
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>