lazyflat/web/templates/_admin_secrets.html
EiSiMo 3bb04210c4 secrets tab, drop commute filter, favicon, robust error reports
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>
2026-04-21 17:56:57 +02:00

46 lines
2.3 KiB
HTML

<h2 class="font-semibold mb-2">Geheimnisse</h2>
<p class="text-sm text-slate-600 mb-4">
Hier hinterlegte Werte überschreiben die entsprechenden Umgebungsvariablen zur Laufzeit.
Leerlassen bedeutet: der gespeicherte Wert bleibt unverändert.
</p>
{% if secret_flash %}
<div class="chip chip-ok mb-4">Gespeichert.</div>
{% endif %}
<form method="post" action="/actions/secrets" class="space-y-5 max-w-xl"
autocomplete="off" data-lpignore="true" data-1p-ignore data-bwignore data-form-type="other">
<input type="hidden" name="csrf" value="{{ csrf }}">
<div>
<label class="block text-xs uppercase tracking-wide text-slate-500 mb-1">Anthropic API Key</label>
<input class="input" type="text" name="ANTHROPIC_API_KEY"
placeholder="{{ secrets_masked.ANTHROPIC_API_KEY or 'nicht gesetzt' }}"
autocomplete="off" data-lpignore="true" data-1p-ignore data-bwignore>
<p class="text-xs text-slate-500 mt-1">Wird für die Bild-URL-Auswahl durch Haiku verwendet.</p>
</div>
<div class="border-t border-soft pt-4">
<h3 class="font-semibold text-sm mb-3">inberlinwohnen.de Login</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
<div>
<label class="block text-xs uppercase tracking-wide text-slate-500 mb-1">Benutzer / E-Mail</label>
<input class="input" type="text" name="BERLIN_WOHNEN_USERNAME"
placeholder="{{ secrets_masked.BERLIN_WOHNEN_USERNAME or 'nicht gesetzt' }}"
autocomplete="off" data-lpignore="true" data-1p-ignore data-bwignore>
</div>
<div>
<label class="block text-xs uppercase tracking-wide text-slate-500 mb-1">Passwort</label>
<input class="input" type="password" name="BERLIN_WOHNEN_PASSWORD"
placeholder="{{ secrets_masked.BERLIN_WOHNEN_PASSWORD or 'nicht gesetzt' }}"
autocomplete="new-password" data-lpignore="true" data-1p-ignore data-bwignore>
</div>
</div>
<p class="text-xs text-slate-500 mt-2">
Wird vom Scraper beim Login auf inberlinwohnen.de verwendet. Änderungen greifen
automatisch beim nächsten Scrape-Zyklus.
</p>
</div>
<button class="btn btn-primary" type="submit">Speichern</button>
</form>