hsg_rag_eea / DEPLOYMENT_CHECKLIST.md
Pygmales's picture
Sync from GitHub 50cd1ca57c1ae023f7e08f8af52ee596195014df
b5bb08f verified
|
Raw
History Blame
7.59 kB

Deployment Checklist — EMBA HSG RAG Chatbot

Stand: 2026-07-04 (Abschnitte 0/3/5/7 an den Ist-Zustand angepasst; ursprünglich 2026-06-16 @ b0f8038) Ablöst: docs/deploy_readiness_checklist.md (vom 10.04., in Teilen veraltet — siehe Abschnitt 7)

Ziel: Single-Host-Deployment des Bots, eingebettet per <iframe> in die EMBA-Website (emba.unisg.ch / embax.ch), DSGVO-bewusst in EU/CH gehostet.


0. Architektur (Ist-Zustand im Code)

Browser auf emba.unisg.ch / embax.ch
   └─ <iframe src="https://bot.hsg.ch">
        └─ Caddy (TLS, reverse proxy, CSP)        deploy/Caddyfile
             └─ Container: python main.py --app de   →  0.0.0.0:7860  (Gradio/FastAPI, /health)
                  ├─ Weaviate Cloud (EU-Region)                 Retrieval
                  ├─ OpenRouter gpt-4.1                          Agent (alle LLM-Rollen, config.py)
                  └─ OpenRouter text-embedding-3-small           Embeddings (app-seitig)

GitHub Actions (kein Host-Cron nötig):
   update_programme_facts.yml   täglich 06:23 UTC   (verifizierte Fakten + Diff-Alerts)
   scrape.yml                   wöchentlich So 05:17 UTC
   NOTIFY_*-Secrets sind im Repo hinterlegt (Alerts laufen aus der Action)

1. Host & Infrastruktur (BLOCKER — mit HSG-IT klären)

  • Host-Eigentümer von bot.hsg.ch geklärt — wer betreibt die Domain/DNS?
  • Linux-Host in EU/CH bereitgestellt (DSGVO) — entweder HSG-IT-VM oder eigener EU-Cloud-VM (Hetzner/Exoscale/Swisscom …)
  • Docker + Caddy + Cron auf dem Host erlaubt (von HSG-IT bestätigt)
  • DNS: bot.hsg.ch zeigt auf den Ziel-Host
  • Port 7860 intern auf dem Host erreichbar (nur lokal; nach außen nur via Caddy/443)
  • Ausgehender Netzzugang zu: Weaviate Cloud, api.openai.com, openrouter.ai, SMTP/Slack

Entscheidungsfrage an HSG-IT: "Wer betreibt bot.hsg.ch, stellt ihr uns einen Linux-Host in EU/CH, und dürfen wir dort Docker + Caddy + Cron betreiben?" Davon hängt der Rest ab.


2. Datenschutz / EU (vor Go-Live entscheiden)

  • Weaviate Cloud in EU-Region (Frankfurt europe-west3 o.ä.) + AVV/DPA unterschrieben
  • Bewusste Entscheidung dokumentiert, dass OpenAI (US) und OpenRouter (US) Nutzer-Eingaben verarbeiten — bei echtem EU-Konformitätsanspruch auf EU-Hosting umstellen (z. B. Azure OpenAI EU-Region + No-Training-DPA, EU-gehostetes Embedding-Modell)
  • Nutzerprofile (logs/user_profiles/) liegen lokal auf dem Host — Aufbewahrung/Löschung (GDPR-Withdrawal-Pfad wipe_session_data existiert) und Backup-Policy geklärt
  • Consent-Flow im UI vor Go-Live verifiziert
  • Sign-off durch Datenschutzbeauftragte:n

3. Repo-Stand & Code (vor Build)

  • PR #41 (Caching-Entfernung) gemergtsrc/cache/ existiert nicht mehr in main.
  • requirements.txt entspricht dem tatsächlichen Runtime-Bedarf
  • Dockerfile-Base-Image aktuell (Dockerfile: python:3.11.14-slim-bookworm ✓)
  • Offline-Tests grün: pytest tests/test_verified_facts.py tests/test_stream_parser.py
  • Vor Release: RUN_LLM_EVAL=1 pytest tests/test_llm_fact_eval.py -v31/31

4. Weaviate (PR #40 abschließen)

  • EU-Cluster bereitgestellt, .env: WEAVIATE_CLUSTER_URL + WEAVIATE_API_KEY gesetzt
  • python main.py --weaviate checkhealth → Connection ✓ OK
  • python main.py --weaviate init → Collections hsg_rag_content_de/_en angelegt
  • Datenimport abgeschlossen: python main.py --scrape full (läuft; danach Objekt-Counts in beiden Collections plausibel prüfen — EN/embax nicht unterrepräsentiert)
  • python main.py --weaviate checkhealth → beide Collections ✓ OK
  • Stichprobe: Query "Was macht die HSG besonders?" liefert echte Chunks (keine QUERY_EXCEPTION_MESSAGE)

5. Umgebungsvariablen (Prod-.env)

  • OPEN_ROUTER_API_KEY (alle LLM-Rollen + Embeddings — seit PR #49 läuft nichts mehr direkt über OpenAI)
  • WEAVIATE_CLUSTER_URL, WEAVIATE_API_KEY (EU-Cluster)
  • Optional LANGSMITH_* (Tracing)
  • Werte gegen src/config/configs.py verifiziert (Vorlage: .env.example)

OPENAI_API_KEY wird zur Laufzeit nicht mehr gebraucht — nur die opt-in Test-Suiten (RUN_LLM_EVAL, RUN_UAT_LLM_JUDGE) nutzen ihn. NOTIFY_* (SMTP/Slack) liegt als GitHub-Secrets bei der Facts-Action — auf dem App-Host nur nötig, falls der Host selbst Alerts verschicken soll.


6. iframe-Integration ⚠️

  • CSP im deploy/Caddyfile korrigiert (2026-07-04): frame-ancestors https://*.unisg.ch https://embax.ch https://*.embax.ch (vorher https://*.hsg.ch — hätte die Einbettung auf den Zielseiten blockiert)
  • Einbettungs-Domains mit dem EMBA-Webteam final abstimmen
  • <iframe src="https://bot.hsg.ch"> auf einer EMBA-Testseite einbauen
  • Cross-Origin-Test: Bot lädt auf der Zielseite (nicht nur standalone)

7. Zeitgesteuerte Tasks (laufen als GitHub Actions — kein Host-Cron nötig)

  • Verifizierte Fakten: .github/workflows/update_programme_facts.yml, täglich 06:23 UTC — läuft und ist grün (geprüft 2026-07-04; NOTIFY_*-Secrets im Repo hinterlegt)
  • Scraping-Refresh: .github/workflows/scrape.yml, wöchentlich So 05:17 UTC — läuft
  • Alert-Chain einmal end-to-end testen: Preis in data/database/programme_facts.json ändern → Workflow manuell triggern (gh workflow run update_programme_facts.yml) → E-Mail/Slack muss ankommen → Änderung zurücknehmen
  • HUGGING_FACE_API_KEY erneuern — Docling-Remote-Parsing der Fee-Sheet-PDFs liefert aktuell 401 und fällt auf pypdf zurück (Qualität der Ratenplan-PDFs prüfen)
  • Veralteten Cron auf dem Dev-Mac entfernen (crontab -e) — crasht täglich an macOS-TCC (failed to make path absolute) und ist durch die GitHub Action ersetzt

8. Build & Rollout

  • Image bauen aus gemergetem main
  • Image-Vulnerability-Scan gegen neues Digest
  • Schreibbare Runtime-Pfade auf dem Host: logs/, data/, backups/
  • Container starten (0.0.0.0:7860), Caddy mit deploy/Caddyfile davor
  • python main.py --weaviate checkhealth auf dem Host

9. Funktions-Smoke-Tests (über die öffentliche Domain)

  • Bot über https://bot.hsg.ch und als iframe auf der EMBA-Seite erreichbar
  • Consent-Flow
  • DE- und EN-Antworten
  • Retrieval aus Weaviate (Programm-/USP-Fragen liefern echte Inhalte)
  • Admissions-Handover-Pfad
  • Booking-Widget erscheint korrekt

10. Betrieb / Monitoring

  • Facts-Action wöchentlich prüfen (gh run list --workflow=update_programme_facts.yml) — laufen die Runs durch, sind Diffs plausibel?
  • grep "\[timing\]" logs/logs.log — Latenz im Blick (Ziel ~6 s end-to-end)
  • Weaviate-Cluster-Status (läuft, nicht abgelaufen — Lehre aus dem 404-Ausfall)
  • Health-Check GET /health in Host-Monitoring eingebunden

Go / No-Go

Go, wenn: Host in EU/CH steht · Datenschutz-Sign-off · Weaviate gefüllt & checkhealth grün · iframe-CSP gefixt & auf Zielseite getestet · beide GitHub Actions grün & Alert getestet · Smoke-Tests grün.

No-Go, wenn: kein DSGVO-Sign-off · Weaviate leer/abgelaufen · CSP blockiert iframe auf *.unisg.ch · SMTP/Slack fehlt (Fakten-Alerts stumm) · LLM-Eval nicht 31/31.