lazyflat: combined alert + apply behind authenticated web UI

Three isolated services (alert scraper, apply HTTP worker, web UI+DB)
with argon2 auth, signed cookies, CSRF, rate-limited login, kill switch,
apply circuit breaker, audit log, and strict CSP.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Moritz 2026-04-21 09:51:35 +02:00
commit 69f2f1f635
46 changed files with 4183 additions and 0 deletions

72
.env.example Normal file
View file

@ -0,0 +1,72 @@
# =====================================================
# lazyflat environment configuration
# Copy to .env for local runs; paste into Coolify for deploy.
# =====================================================
# -- Auth (web UI) --------------------------------------
AUTH_USERNAME=moritz
# Generate with:
# python -c "from argon2 import PasswordHasher; print(PasswordHasher().hash('YOUR_PASSWORD'))"
AUTH_PASSWORD_HASH=
# Long random string — used to sign session & CSRF cookies.
# Generate with: python -c "import secrets; print(secrets.token_urlsafe(48))"
SESSION_SECRET=
# Must be "true" when running behind HTTPS (i.e. Coolify/Traefik). Set to "false" for plain-http local dev.
COOKIE_SECURE=true
SESSION_MAX_AGE_SECONDS=604800
LOGIN_RATE_LIMIT=5
LOGIN_RATE_WINDOW_SECONDS=900
# -- Internal service auth ------------------------------
# Shared between web <-> apply and alert -> web. Generate with:
# python -c "import secrets; print(secrets.token_urlsafe(48))"
INTERNAL_API_KEY=
# -- Alert / scraping -----------------------------------
SLEEP_INTERVALL=60
GMAPS_API_KEY=
BERLIN_WOHNEN_USERNAME=
BERLIN_WOHNEN_PASSWORD=
# -- Filter criteria (applied by web) -------------------
FILTER_ROOMS=2.0,2.5
FILTER_MAX_RENT=1500
FILTER_MAX_MORNING_COMMUTE=50
# -- Apply (experimental!) ------------------------------
# Keep SUBMIT_FORMS=False until you have verified the provider flow end-to-end.
SUBMIT_FORMS=False
APPLY_TIMEOUT=600
APPLY_FAILURE_THRESHOLD=3
LANGUAGE=de
BROWSER_WIDTH=600
BROWSER_HEIGHT=800
BROWSER_LOCALE=de-DE
POST_SUBMISSION_SLEEP_MS=0
# Personal info for applications
SALUTATION=Herr
LASTNAME=
FIRSTNAME=
EMAIL=
TELEPHONE=
STREET=
HOUSE_NUMBER=
POSTCODE=
CITY=
# WBS
IS_POSSESSING_WBS=False
WBS_TYPE=0
WBS_VALID_TILL=1970-01-01
WBS_ROOMS=0
WBS_ADULTS=0
WBS_CHILDREN=0
IS_PRIO_WBS=False
# Optional: immomio login
IMMOMIO_EMAIL=
IMMOMIO_PASSWORD=