Container names, FastAPI titles, email subjects, filenames, brand text,
session cookie, User-Agent, docstrings, README. Volume lazyflat_data and
/data/lazyflat.sqlite already used the new name, so on-disk data is
preserved; dropped the now-obsolete legacy-rename comments.
Side effect: SESSION_COOKIE_NAME change logs everyone out on deploy.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per review §2:
- web/db.py: new _tx() context manager wraps multi-statement writers in
BEGIN IMMEDIATE … COMMIT/ROLLBACK (our connections run in autocommit
mode, so plain `with _lock:` doesn't give atomicity). partnership_accept
(UPDATE + DELETE) and cleanup_retention (3 deletes/updates) now use it.
- Fire-and-forget tasks: add module-level _bg_tasks sets in web/app.py and
web/enrichment.py. A _spawn() helper holds a strong ref until the task
finishes so the GC can't drop it mid-flight (CPython's event loop only
weakly references pending tasks).
- apply/main.py: require_api_key uses hmac.compare_digest, matching web's
check. Also imports now use explicit names instead of `from settings *`.
- apply/language.py: replace `from settings import *` + `from paths import *`
with explicit imports — this is the pattern that caused the LANGUAGE
NameError earlier.
- alert/utils.py: pickle-based hash_any_object → deterministic JSON+sha256.
Cheaper, portable across Python versions, no pickle attack surface.
- web/notifications.py: /fehler links repointed to /bewerbungen (the
former page doesn't exist).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- App is now called "wohnungsdidi" everywhere user-facing (page title,
nav brand, login header, notification subjects, report filename,
FastAPI titles, log messages)
- Brand dot replaced with an image of Didi (web/static/didi.webp),
rendered as a round 2.25rem avatar in _layout + login
- "Programmiert für Annika ♥" footer now shows for every logged-in user,
not only Annika
- Count-up shows only seconds ("vor 73 s") regardless of age — no
rollover to minutes/hours
- Data continuity: DB file stays /data/lazyflat.sqlite and the Docker
volume stays lazyflat_data so the rename doesn't strand existing data
- Session cookie renamed to wohnungsdidi_session (one-time logout on
rollout)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Surface "X/Y passende Wohnungen mit Koordinaten" on the Karte view +
admin-only "Koordinaten nachladen" button (POST /actions/backfill-coords)
that geocodes missing flats via Google Maps directly from the web container
- Add googlemaps dep + GMAPS_API_KEY env to web service
- Light console.log in map.js ("rendering N/M markers", "building Leaflet…")
so the browser DevTools shows what's happening
- Drop e-mail channel from notifications UI, notify dispatcher, and _alert_status;
coerce legacy 'email' channel rows back to 'ui' on save
- Countdown said "Aktualisierung läuft…" next to "nächste Aktualisierung" →
shortened to "aktualisiere…"
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>