Files
2026-03-30 07:59:11 +02:00

773 lines
40 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AZA Master Handover / Operational Runbook
## Arbeitsmodus / Regeln
User bastelt nicht; nur Composer-Patches (meist Opus) oder 1 exakter Command mit Pfad.
- Alle Aenderungen kommen als fertige, vollstaendige Dateien (ready-to-paste).
- User fuehrt nur vorgegebene Commands aus, keine manuellen Edits.
- Jede Aenderung in 1 Patch, kein schrittweises Anleiten.
- Keine risky Refactors immer minimal und sicher.
## AKTUELLE PROJEKTPHASE (Stand 2026-03-25)
**Phase:** B1 Backend-Sprint Serverseitige OpenAI-Architektur (Variante B verbindlich)
**ARCHITEKTURENTSCHEIDUNG VARIANTE B (verbindlich, 2026-03-25):**
- KEIN OpenAI-Key in der Desktop-App
- KEIN eigener OpenAI-Key pro Kunde als Pflicht
- KEIN gemeinsamer OpenAI-Key clientseitig
- Stattdessen: AZA Office spricht NUR mit eigenem AZA-Backend
- Nur das AZA-Backend spricht mit OpenAI
- Der OpenAI-Key liegt AUSSCHLIESSLICH serverseitig
- KEINE halben Uebergangsloesung, KEINE Shared-Key-Bastelei
**Ehrliche Einordnung:**
- Desktop-App ist weit fortgeschritten und grundsaetzlich benutzbar
- Architekturentscheidung Variante B ist getroffen
- Hetzner-Backend wird jetzt ernsthaft als Server-Pfad aufgebaut
- WordPress/Shop (Hostpoint) laeuft parallel weiter
## B1 BACKEND-SPRINT (4 Wochen)
| Woche | Zeitraum ca. | Fokus |
|-------|-------------|-------|
| **1** | 25.03 01.04 | Backend Chat Proxy Endpoint (POST /v1/chat) + Auth + Rate Limiting |
| **2** | 02.04 08.04 | Desktop-App: alle OpenAI-Calls ueber Backend statt direkt |
| **3** | 09.04 15.04 | Hetzner Deploy: Docker/Caddy/HTTPS + Production-Env + Smoke-Tests |
| **4** | 16.04 22.04 | E2E-Test Desktop→Backend→OpenAI + Kundenweg ohne OpenAI-Key + Go-Live |
## AKTUELLE PRIORITAETSREIHENFOLGE (B1 Backend-Sprint)
1. **Backend Chat Proxy POST /v1/chat** (Woche 1) Grundstein der Architektur
2. **Desktop-App auf Backend umstellen** (Woche 2) Alle OpenAI-Calls migrieren
3. **Hetzner Deploy** (Woche 3) Produktionsserver aufsetzen
4. **E2E-Test + Go-Live Backend-Pfad** (Woche 4) Kundenweg ohne OpenAI-Key
5. WooCommerce/Stripe/Kauf-Weg laeuft PARALLEL weiter (Hostpoint)
**EXPLIZIT NACHRANGIG / NICHT JETZT:**
- Update-Komfort / separater Auto-Updater
- Browser-AZA Web-App (nach Backend-Architektur)
- Grosse Refactors die nicht Variante B dienen
**HOSTPOINT vs. HETZNER:**
- Hostpoint bleibt fuer Website/Marketing/WooCommerce/Stripe
- Hetzner ist JETZT der Backend-Pfad fuer OpenAI-Proxy/API
- Beides laeuft parallel, nicht gegeneinander
## ERLEDIGT: B1-W1 Backend Chat Proxy Endpoint (2026-03-26)
**POST /v1/chat IMPLEMENTIERT UND VERIFIZIERT.**
| Aspekt | Detail |
|---|---|
| Auth | `require_api_token` (X-API-Token Header, bestehendes Muster) |
| Rate Limiting | `default_ip_limiter` + `default_token_limiter` |
| Request-Schema | `ChatRequest`: model, messages[], temperature?, max_tokens?, top_p? |
| Message-Schema | `ChatMessage`: role (system/user/assistant), content |
| Modell-Whitelist | gpt-5.2, gpt-5-mini, gpt-5-nano, gpt-4o, gpt-4o-mini, gpt-4o-mini-search-preview |
| Input-Limits | Max 64 Messages, max 100k Zeichen/Nachricht |
| OpenAI-Call | `_get_openai().chat.completions.create(**params)` serverseitig |
| Response-Schema | `{success, content, finish_reason, model, usage, request_id, duration_ms, error}` |
| Secret-Scrubbing | `sk-`, `sk-proj-`, `org-` in Fehlertexten werden ersetzt |
| Tests | 7/7 gruen (Auth, Modell, Validierung, OpenAI-Proxy, /license/status, Schema) |
**Datei:** `backend_main.py` (~100 Zeilen)
## ERLEDIGT: B1-W2 Desktop Chat Migration (2026-03-26)
**Desktop-App: Chat-Completions laufen jetzt ueber Backend POST /v1/chat.**
**Migriert:**
1. `call_chat_completion()` in basis14.py zentraler Wrapper -> `_backend_chat_completion()`
2. News-Suche direkter `self.client` Call -> `_backend_chat_completion()`
3. Kommentare eigener `OpenAI()` Client -> `_backend_chat_completion()`
4. Med-Detail Kurzinfo eigener `OpenAI()` Client -> `_backend_chat_completion()`
5. Briefstil-Analyse in `aza_text_windows_mixin.py` -> `_backend_chat_completion()`
**Neue Architektur in basis14.py:**
- `_BackendChatResponse` Wrapper-Klasse, OpenAI-Interface-kompatibel (.choices[0].message.content, .usage)
- `_backend_chat_completion(**kwargs)` POST /v1/chat mit bestehender Token-Mechanik (get_backend_url/get_backend_token)
- `call_chat_completion(**kwargs)` Consent/Capacity Check, dann `_backend_chat_completion()`
- Timeout: 5s connect, 120s read
- Fehler: RuntimeError mit lesbarer Meldung, keine Secrets
**Verbleibend fuer spaetere Bloecke:** translate.py, congress_window.py, aza_email.py (eigenstaendige Module)
**7/7 Tests gruen:** Health, Auth, Model-Validation, E2E Desktop->Backend->OpenAI, Response-Schema, /license/status OK.
## VORBEREITET: B1-W3 Hetzner Deploy (2026-03-26)
**Deploy-Dateien fuer Hetzner/Variante B fertig.**
| Datei | Aenderung |
|---|---|
| `requirements.txt` | NEU: fastapi, uvicorn, openai, stripe, pydantic, python-dotenv, python-multipart |
| `deploy/Dockerfile` | Gehaertet: requirements.txt first, HEALTHCHECK, curl fuer healthcheck |
| `deploy/.env.example` | OPENAI_API_KEY als Pflicht-Variable ergaenzt |
| `deploy/.env` | OPENAI_API_KEY als Pflicht-Variable ergaenzt |
| `deploy/DEPLOY_CHECKLIST.md` | Komplett fuer Hetzner/Variante B ueberarbeitet |
| `deploy/PRODUCTION_CONFIG.md` | OPENAI_API_KEY + Desktop-Abschnitt fuer Variante B |
| `.gitignore` | .env und backend_token.txt hinzugefuegt |
**Deploy-Pfad auf Hetzner:**
```
1. DNS: api.aza-medwork.ch -> Hetzner-IP (A-Record)
2. Repo auf Hetzner klonen
3. cd deploy && cp .env.example .env && vim .env (echte Keys eintragen)
4. docker compose --profile proxy up -d --build
5. curl https://api.aza-medwork.ch/health
```
**Desktop-App Backend-URL:** `https://api.aza-medwork.ch`
**Verbleibend:** DNS setzen, echte Secrets eintragen, docker compose starten, Smoke-Test.
## AKTUELLER HAUPTBLOCK: B1-W4 E2E-Test (2026-03-26)
### Teil A Manuelle Hetzner-Schritte (Pflicht, in dieser Reihenfolge)
**Schritt 1: DNS A-Record**
- Im DNS-Provider (vermutlich Hostpoint) einen A-Record anlegen:
`api.aza-medwork.ch``<Hetzner-VPS-IP>`
- TTL kurz setzen (300s) fuer schnelle Propagation
- Pruefen: `nslookup api.aza-medwork.ch` oder `dig api.aza-medwork.ch`
- ACHTUNG: Keine bestehenden DNS-Eintraege fuer aza-medwork.ch aendern!
**Schritt 2: Repo auf Hetzner**
```bash
ssh root@<HETZNER-IP>
apt update && apt install -y docker.io docker-compose-plugin git
git clone <REPO-URL> /opt/aza
cd /opt/aza/deploy
```
**Schritt 3: .env mit echten Werten**
```bash
cp .env.example .env
nano .env
```
Pflicht-Eintraege:
- `OPENAI_API_KEY=sk-proj-...` (echter OpenAI-Key)
- `MEDWORK_API_TOKENS=<starkes-zufallstoken>` (mindestens 32 Zeichen)
- `AZA_DOMAIN=api.aza-medwork.ch`
- `ACME_EMAIL=info@aza-medwork.ch`
**Schritt 4: Docker starten**
```bash
docker compose --profile proxy up -d --build
docker compose logs -f # Logs beobachten bis "Uvicorn running" + Caddy HTTPS OK
```
**Schritt 5: Server-Smoke-Test**
```bash
# Health
curl https://api.aza-medwork.ch/health
# Chat (mit Token)
curl -X POST https://api.aza-medwork.ch/v1/chat \
-H "Content-Type: application/json" \
-H "X-API-Token: <DEIN-MEDWORK-TOKEN>" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Sage OK"}],"max_tokens":5}'
# License Status (Regression-Check)
curl -H "X-API-Token: <DEIN-MEDWORK-TOKEN>" https://api.aza-medwork.ch/license/status
```
### Teil B E2E-Test: Desktop → Hetzner → OpenAI
**Desktop-Konfiguration:**
1. `backend_url.txt` im App-Verzeichnis: `https://api.aza-medwork.ch`
(oder Env: `MEDWORK_BACKEND_URL=https://api.aza-medwork.ch`)
2. `backend_token.txt`: das gleiche Token wie `MEDWORK_API_TOKENS` auf dem Server
3. Lokalen `OPENAI_API_KEY` ENTFERNEN (Security-Vault / .env)
**Testschritte (konkret):**
| # | Test | Erwartung | Variante-B-Nachweis |
|---|------|-----------|---------------------|
| 1 | App starten, Health-Icon pruefen | Gruener Status | Backend erreichbar via HTTPS |
| 2 | Kurze Aufnahme diktieren → KG generieren | KG-Text erscheint | `call_chat_completion` → Backend → OpenAI |
| 3 | Kommentare-Fenster oeffnen | Medizinische Kommentare erscheinen | `_backend_chat_completion` statt lokalem OpenAI |
| 4 | Medikament-Detail anklicken | Kurzinfo erscheint | `_backend_chat_completion` via Hetzner |
| 5 | News-Tab oeffnen | Medizin-News laden | `_backend_chat_completion` via Hetzner |
| 6 | App OHNE lokalen OpenAI-Key starten | Alles funktioniert trotzdem | **DER Variante-B-Beweis** |
| 7 | `/license/status` in Browser pruefen | JSON-Response, kein Fehler | Keine Regression |
**Woran erkennt man, dass Variante B aktiv ist:**
- App hat KEINEN lokalen `OPENAI_API_KEY` mehr
- Chat/KG/Kommentare funktionieren trotzdem
- In `client_debug.log` (falls vorhanden): Requests gehen an `https://api.aza-medwork.ch`
- Im Server-Log (docker logs): `CHAT request_id=... success=true`
### Teil C Wahrscheinlichste Fehlerpunkte
| # | Fehler | Symptom | Loesung |
|---|--------|---------|---------|
| 1 | DNS nicht propagiert | `curl: Could not resolve host` | Warten (5-60 Min), TTL pruefen, `nslookup` |
| 2 | Let's Encrypt scheitert | Caddy-Log: ACME challenge failed | Port 80+443 offen? DNS korrekt? Rate Limit? |
| 3 | OPENAI_API_KEY fehlt/falsch | HTTP 502 bei /v1/chat | `docker compose exec aza-api env | grep OPENAI` |
| 4 | Token-Mismatch | HTTP 401 bei /v1/chat | Token in Desktop `backend_token.txt` = Server `MEDWORK_API_TOKENS` |
| 5 | Backend-URL falsch | Connection refused / timeout | `backend_url.txt` pruefen, HTTPS nicht HTTP |
| 6 | Firewall blockiert 443 | Timeout | `ufw allow 443/tcp` oder Hetzner-Firewall |
| 7 | Docker-Image baut nicht | pip-Fehler | `docker compose logs aza-api`, requirements.txt pruefen |
| 8 | Caddy bekommt kein Zertifikat | HTTPS-Fehler im Browser | Domain muss auf VPS-IP zeigen BEVOR docker compose startet |
| 9 | CORS-Fehler (Browser) | Nicht relevant fuer Desktop | Desktop nutzt `requests`, kein CORS-Problem |
| 10 | Timeout bei Chat | Request dauert >120s | Server-Last pruefen, max_tokens reduzieren |
**Blocker-Regel:** Ein klarer Block nach dem anderen.
## KUNDENWEG-ANALYSE (2026-03-25)
| Strecke | Status | Detail |
|---|---|---|
| Kauf (WooCommerce) | IN ARBEIT (parallel) | Doku fertig, 7 Admin-Schritte in WordPress-Admin (Hostpoint) |
| Download | TEILWEISE | Mechanik da, WooCommerce-Upload fehlt |
| Installer | FUNKTIONAL FERTIG | Kein Code-Signing (SmartScreen-Warnung) |
| Aktivierung | BRIDGE IMPLEMENTIERT | AZA-Key setzt Vollmodus, Trial-Dialog zeigt Status |
| Erster Start | IN UMBAU (VARIANTE B) | OpenAI-Key wird durch Backend-Proxy ersetzt. B1 Sprint laeuft. |
## OFFENE FOKUSBLOECKE
| Prio | Block | Beschreibung |
|---|---|---|
| ERLEDIGT | B1-W1: Backend /v1/chat | Chat Proxy Endpoint Grundstein Variante B |
| ERLEDIGT | B1-W2: Desktop umstellen | Alle OpenAI-Calls in basis14.py + Mixin ueber Backend |
| VORBEREITET | B1-W3: Hetzner Deploy | Deploy-Dateien fertig, DNS + docker compose ausfuehren |
| IN ARBEIT | B1-W4: E2E + Go-Live | Testplan dokumentiert, manuelle Hetzner-Schritte definiert |
| HOCH (parallel) | FB-A: WooCommerce | Stripe-Kauf-Weg auf Hostpoint |
| MITTEL | FB-C: Signing | Signing-Readiness vorbereitet |
| NACHGELAGERT | FB-D: Update-Komfort | Erst nach stabilem Kundenweg |
## PRODUKTNAME AKTUELLE RICHTUNG
**Aktueller Favorit:** AZA Office
**Bevorzugte Langform:**
- **AZA Office Ihr medizinischer KI-Arbeitsplatz fuer die Praxis**
**Zweite gute Variante:**
- AZA Office Die KI-Assistenz fuer medizinische Dokumentation
**Status:** Aktuelle bevorzugte Naming-Richtung. Noch nicht zwingend final juristisch/brand-strategisch entschieden. Soll fuer WooCommerce/Website/Download/Go-Live/Produktdarstellung wiederverwendet werden.
**Fruehere Shortlist (AZA Desktop):** Dokumentiert in project_roadmap.json und project_plan.json. Durch AZA Office abgeloest.
## VARIANTE B BESTANDSANALYSE (2026-03-25)
### Was fuer serverseitigen OpenAI-Zugriff BEREITS existiert:
| Baustein | Status | Detail |
|---|---|---|
| POST /v1/transcribe | FUNKTIONIERT | Backend→OpenAI fuer Transkription. Muster fuer /v1/chat. |
| Auth-Contract | FUNKTIONIERT | X-API-Token + X-Device-Id. Etabliert. |
| License /license/status | FUNKTIONIERT | Lizenzpruefung ueber Backend. |
| Stripe Billing Portal | FUNKTIONIERT | Desktop holt URL vom Backend. |
| Docker/Caddy/Compose | VORBEREITET | deploy/ Ordner komplett. Lokal verifiziert. |
| OpenAI-Client in backend_main.py | VORHANDEN | `from openai import OpenAI` importiert. |
| Rate Limiting | VORHANDEN | aza_rate_limit.py (IP + Token Limiter). |
### Was die Desktop-App DIREKT zu OpenAI ruft (zu migrieren):
| Feature | Datei | Zeile ca. | API |
|---|---|---|---|
| Chat (zentral) | basis14.py | ~5458 | chat.completions.create |
| News-Suche | basis14.py | ~3417 | chat.completions.create |
| Kommentare | basis14.py | ~7058 | chat.completions.create |
| Med-Detail Kurzinfo | basis14.py | ~7453 | chat.completions.create |
| Usage/Budget | aza_persistence.py | ~500 | /v1/usage (REST) |
| Briefgenerierung | aza_text_windows_mixin.py | diverse | chat.completions.create |
| Uebersetzer | translate.py | diverse | chat.completions.create |
| Diktat-App | apps/diktat/diktat_app.py | diverse | transcriptions/chat |
### Was BEREITS ueber Backend laeuft:
- Transkription: transcribe_file_via_backend_with_fallback() → POST /v1/transcribe
- Lizenzpruefung: GET /license/status
- Billing Portal: GET /stripe/billing_portal_url
### Luecken fuer Variante B:
1. **KEIN /v1/chat Endpoint** Muss in backend_main.py erstellt werden
2. **Kein kundenbezogenes Usage-Tracking** auf dem Server
3. **Backend NICHT auf Hetzner deployed** Nur lokaler Docker-Test
4. **Desktop erfordert noch lokalen OpenAI-Key** fuer Chat-Features
5. **Kein Kunden-Quota/Budget-Management** serverseitig
## ARBEITSWEISE FUER NAECHSTE CHATS
- Root-cause-first statt blindem Nachpatchen
- Ein klarer Block nach dem anderen
- Keine 10 Baustellen gleichzeitig
- Reale installierte Builds staerker gewichten als Code-Behauptungen
- Nicht zu frueh "fertig" sagen
- Desktop unterscheiden in:
1. Dev-Code
2. Neu gebauter Installer
3. Reales Verhalten im installierten Build
## Lokaler Start
```
cd "C:\Users\surov\Documents\AZA\backup 24.2.26"
powershell -ExecutionPolicy Bypass -File .\deploy\local_reset_and_start.ps1
```
## Tests (Lokal)
```
powershell -ExecutionPolicy Bypass -File .\deploy\authorized_test.ps1
powershell -ExecutionPolicy Bypass -File .\deploy\smoke_suite.ps1
```
## Step 14 Docker/Compose Smoke-Test
**Ziel:** Container bauen, starten, smoke_suite PASS gegen Docker.
**1 Command:**
```
cd "C:\Users\surov\Documents\AZA\backup 24.2.26"
powershell -ExecutionPolicy Bypass -File .\deploy\docker_smoke.ps1
```
**Was das Script macht:**
- `docker compose up -d --build` (baut und startet Container)
- Wartet bis `/health` HTTP 200 liefert (max 60s)
- Fuehrt `smoke_suite.ps1` gegen den Container aus
- Gibt `[RESULT] PASS` oder `[RESULT] FAIL` aus
- Bei FAIL bleiben Container laufen (Logs inspizierbar)
**Erwartete Checks (smoke_suite):**
- GET /health -> 200
- GET /version -> 200 mit {name, build}
- GET /license/status ohne Token -> 401/403
- GET /license/status mit Token -> 200 mit {valid, valid_until}
- GET /stripe/health -> 200 oder 404 (WARN)
- GET /openapi.json -> 200
**Bei Fehler:**
```
docker compose -f .\deploy\docker-compose.yml logs --follow
docker compose -f .\deploy\docker-compose.yml down
```
## Step 15 Caddy/HTTPS Reverse Proxy
**Ziel:** HTTPS live mit ACME-Zertifikat, Reverse Proxy auf :8000.
- Caddyfile finalisieren (Domain, TLS)
- ACME-Challenge testen
- Reverse Proxy pruefen (`curl https://DOMAIN/health`)
## Step 16 Go-Live Runbook
**Ziel:** Production-Deployment auf VPS oder Buero-PC.
- Webhook erreichbar (Stripe)
- Stripe Signatur ok (STRIPE_WEBHOOK_SECRET)
- Billing Portal Return URL korrekt
- Log-Hygiene: keine Secrets in Logs
## Desktop UX / Persistence Block (2026-03-18)
**Benutzerdaten bei Deinstallation:**
- Inno Setup `CurUninstallStepChanged` fragt ob `%APPDATA%\AZA Desktop` geloescht werden soll
- Standard: Nein (Daten bleiben erhalten, Neuinstallation nutzt vorhandene Daten)
- Dateien: `installer/aza_installer.iss`
**Signatur-/Benutzername-Logik:**
- `load_signature_name()` faellt auf Profilname zurueck wenn kein expliziter Signaturname gesetzt
- Einstellungsdialog: Haekchen "Profilname verwenden" + Feld fuer abweichenden Signaturnamen
- Wenn Haekchen aktiv → Profilname. Wenn aus + Name eingetragen → diesen verwenden
- Dateien: `aza_persistence.py`, `aza_settings_mixin.py`
**Rechtsklick im Minifenster:**
- Gleiche Checkbox wie im Hauptfenster, teilt `_rclick_paste_var`, synchronisiert
- Datei: `basis14.py`
**Kommentare-Fenster (TEILWEISE):**
- Grundstruktur: Button "Kommentare" in Toolbar, separates Fenster, KI-Kurzkommentare via GPT
- OFFEN: Live-Aktualisierung bei KG-Aenderung, Detailfenster bei Klick auf Kommentar
- Datei: `basis14.py`
**Briefstil-Lernen aus frueheren Word-Briefen (TEILWEISE):**
- DOCX-Upload (Mehrfach), Stilprofil-Analyse via GPT, persistente Stilprofile
- Profilauswahl im Brief-Fenster, Integration in Briefgenerierung als System-Prompt
- OFFEN: Detailmodus-Erweiterung der Stilanalyse, erweiterte Formatunterstuetzung
- Dateien: `aza_persistence.py`, `aza_text_windows_mixin.py`, `basis14.py`
**Autotext Root-Cause-Fix:**
- Root Cause: `_is_admin` NameError verhinderte Autotext-Dialog im installierten Build
- Listener auf bewaehrten Stand (Kopie 13) zurueckgesetzt
- Datei: `basis14.py`
**Uebersetzer-Stabilitaetsfix (2026-03-19):**
- Root Cause: translate.main() erzeugte tk.Tk() in Hintergrund-Thread (frozen Build) Tkinter nicht threadsafe
- Fix: translate.py akzeptiert parent-Parameter, erstellt Toplevel statt Tk(), kein eigener mainloop()
- basis14.py ruft translate.main(parent=self) direkt auf dem Main-Thread auf
- Zusaetzlich: API-Key-Fallback ueber openai_runtime_config
- Dateien: `translate.py`, `basis14.py`
**Briefstil-Profile (2026-03-19, nachgeschaerft):**
- KISIM Bericht + Klinischer Bericht als feste Systemprofile (immer sichtbar, nicht loeschbar)
- KISIM = klassischer Gesamtbericht: Diagnose/Allergien/Therapie/Anamnese/Beurteilung/Diagnostik/Procedere
- Klinisch = diagnosezentriert: pro Diagnose KLINIK/DIAGNOSTIK/THERAPIE/Aktuell, dann Allergien/Beurteilung/Procedere
- Praezise medizinische Regeln: keine Ueberinterpretation, keine Halluzination, konservativ kodieren
- Vereinheitlichtes Stilprofil-System im Brief-Fenster:
- Haekchen "Stilprofil anwenden" + Dropdown (keins / Klinischer Bericht / KISIM Bericht / Benutzerprofile)
- Haekchen "Standard fuer Arztbriefe" (persistent)
- Reihenfolge Dropdown: (keins) -> Systemprofile -> gelernte Benutzerprofile
- Stilprofil-Dialog: System-Profile als feste nicht-loeschbare Eintraege, Benutzerprofile per Word-Upload
- Persistenz: stilprofil_enabled, stilprofil_name, stilprofil_default_brief in autotext_data
- Dateien: `aza_prompts.py`, `aza_text_windows_mixin.py`, `aza_persistence.py`
**Persistenz- und Consent-Patch:**
- KI-Einwilligung direkt beim Erststart (nach Fachgebiet-Dialog, vor normalem App-Betrieb)
- Benutzerprofil um Code (ZSR/GLN) erweitert (Registrierung + Profil-Bearbeiten)
- Deinstallations-Frage listet alle Benutzerdaten einzeln auf (Profil, Transkripte, Vorlagen, Consent, Signatur etc.)
- Kommentare-Fenster: Toggle "beim Start automatisch oeffnen" + persistent
- Einstellungen logisch gruppiert: LabelFrame "Startverhalten / Fenster"
- Alle Benutzerdaten liegen in %APPDATA%\AZA Desktop und ueberleben Reinstall (Standard: behalten)
- Dateien: `basis14.py`, `aza_settings_mixin.py`, `aza_persistence.py`, `installer/aza_installer.iss`
## AZA Clean Uninstall / Reset Tool (2026-03-19)
**Zweck:** Saubere Deinstallation und Reset von AZA Desktop ohne Neustart. Fuer Installer-Abnahme und Reinstall-Tests.
**Starten (Doppelklick):**
```
AZA_Deinstallieren.bat
```
**Oder direkt in PowerShell:**
```
cd "C:\Users\surov\Documents\AZA\backup 24.2.26"
powershell -ExecutionPolicy Bypass -File .\tools\aza_clean_uninstall.ps1
```
**Modi:**
- **Modus 1**: Nur App entfernen, Benutzerdaten behalten (Standard fuer Reinstall-Tests)
- **Modus 2**: Vollstaendig zuruecksetzen inkl. aller Benutzerdaten
**Was das Tool macht:**
1. AZA-Prozesse sauber beenden (erst freundlich, dann forciert)
2. Inno-Setup-Uninstaller silent ausfuehren
3. Installationsreste bereinigen (Verzeichnis, Shortcuts)
4. Firewall-Regel entfernen
5. Benutzerdaten je nach Modus behalten oder loeschen
6. Registry-Reste bereinigen (falls Inno-Uninstaller nicht verfuegbar)
7. Abschlussmeldung: Neustart noetig? Neuinstallation moeglich?
**Benutzerdaten-Pfade:**
- AppData: `%APPDATA%\AZA Desktop` (Profil, Einstellungen, Lizenz, Consent, Autotext, Stilprofile)
- Dokumente: `%USERPROFILE%\Documents\KG_Diktat_Ablage` (Transkripte, Briefe, Rezepte, Kostengutsprachen)
**Dateien:** `tools/aza_clean_uninstall.ps1`, `AZA_Deinstallieren.bat`
## Do-Not-Break Regeln
1. Keine bestehenden API-Response-Formate aendern (besonders /license/status)
2. Auth/Security nicht modifizieren (Token-Rotation, _check_token)
3. Keine Secrets loggen/printen (Tokens, Keys, Passwoerter)
4. backend_token.txt nie committen (steht in .gitignore)
5. deploy/.env nie committen (enthaelt Produktions-Secrets)
6. Immer try/except um History-Logging (darf Response nie blockieren)
7. Windows PowerShell 5.1 kompatibel bleiben
8. Signatur-/Profilname-Fallback: Wenn kein expliziter Signaturname gesetzt, wird Profilname verwendet
9. Benutzerdaten in %APPDATA%\AZA Desktop bei Deinstallation standardmaessig NICHT loeschen
10. Aus frueheren Briefen wird nur Stil/Struktur gelernt, KEINE Patientendaten/Altinhalte uebernehmen
## Korrektur-Patch (FIX-01) 2026-03-19
Sammel-Korrektur-Patch mit folgenden Aenderungen:
1. **Uebersetzer-Label**: "Fachuebersetzer" ueberall zu "Uebersetzer" umbenannt (aza_config.py, version.json, CHANGELOG.md, web/index.html, deploy-Docs)
2. **Kommentare-Fenster fertiggestellt**: Haekchen "beim Start automatisch oeffnen" (persistent), Live-Update bei KG-Aenderung (auto-refresh nach KG-Erstellung), klickbare Diagnose-Ueberschriften mit Detailfenster
3. **Korrektur-Fenster**: Scrollbar fuer Liste der gespeicherten Korrekturen (height=8 statt 4), Korrekturen bleiben bei Benutzerdaten-Behalten erhalten
4. **Stilprofil Live-Anwendung**: Bei Profilwechsel/Toggle im Brief-Fenster wird der aktuelle Brief sofort neu generiert (nicht erst beim naechsten Brief). Extrahierte Methode _build_brief_prompt_for_profile() und _regenerate_brief_live()
5. **Profil-anwenden-Button**: Im Stilprofil-Verwaltungsdialog neuer gruener Button "Profil anwenden" wendet das gewaehlte Profil sofort auf den aktuellen Brief an
6. **KG direkt im Hauptfenster**: make_kg_from_text() schreibt jetzt direkt ins txt_output (via _fill_kg_and_finish), kein separates Popup-Fenster mehr
7. **Persistenz**: dokumente_collapsed wird jetzt korrekt geladen/gespeichert in autotext_data
8. **Hauptfenster-Zentrierung**: Robuste verzoegerte Zentrierung nach vollstaendigem Widget-Aufbau via self.after(50, _ensure_centered), statt zu fruehem center_window() im __init__
## Nachschaerfungs-Patch (FIX-02) 2026-03-19
1. **Stilprofil-Dialog nur Verwaltung**: Im Dialog _open_brief_stilprofil_dialog() wurde die aktive Profilauswahl (Dropdown+Combobox+on_profile_change) entfernt. Dialog zeigt jetzt nur: aktuell aktives Profil als Status, verfuegbare System-/Benutzerprofile als Liste, Lernfunktion fuer neue Profile, Loeschen von Benutzerprofilen. Aktive Auswahl NUR im Arztbrief-Fenster (Haekchen+Dropdown).
2. **Kommentare-Fenster auto-open**: _auto_refresh_kommentare() oeffnet jetzt das Kommentare-Fenster automatisch nach KG-Erstellung, wenn kommentare_auto_open=True und das Fenster noch nicht offen ist. Checkbox-Text geaendert zu "Kommentare-Fenster standardmaessig oeffnen (nach KG-Erstellung)".
3. **Logo-Trennung**: Wassertropfen-Bild (assets/wassertropfen aza medwork.png) wird zu logo.ico konvertiert fuer EXE-Icon, Desktop-Shortcut, Installer-Icon und Titelleisten-Icon. Originales Logo (assets/logo.png) wird als logo.png im Root fuer internes Branding unten links verwendet. logo.ico in aza_desktop.spec datas aufgenommen fuer Runtime-Zugriff.
**Dateien:** basis14.py, aza_text_windows_mixin.py, aza_desktop.spec, logo.png, logo.ico
## Medikamenten-Detailfenster (FIX-03) 2026-03-20
1. **Klick auf Medikament/Diagnose im Kommentare-Fenster**: Oeffnet strukturiertes Detailfenster (zentriert) mit KI-generierter Kurzinfo (Indikation, Nebenwirkungen, Anwendung, Schwangerschaft/Stillzeit, Hinweise).
2. **Quellenauswahl**: Dropdown im Detailfenster: compendium.ch (Standard), BASG All-in-One Register, BfArM AMIce. Auswahl persistent in medikament_quelle (autotext_data).
3. **Originalquelle oeffnen**: Button "Originalquelle oeffnen" im Detailfenster oeffnet passende Suchseite zur aktiven Quelle im Browser.
4. **Persistenz**: medikament_quelle in aza_persistence.py (load/save/default).
**Dateien:** basis14.py, aza_persistence.py
## Diagnose-Detailfenster (FIX-04) 2026-03-20
1. **Getrennte Detail-Logik**: Medikamente ([MED]) und Diagnosen ([DX]) haben eigene Detailfenster mit eigenen Prompts, Quellen und Persistenz-Keys.
2. **Diagnose-Quellen**: DocCheck Flexikon (Standard bei Deutsch), MSD Manual Patienten (Standard bei anderer Sprache). Persistent in diagnose_quelle.
3. **Medikament-Quellen**: compendium.ch / BASG / BfArM (wie bisher). Persistent in medikament_quelle.
4. **KI-Kommentare**: Prompt erzeugt [DX]/[MED]-Tags pro Ueberschrift. _apply_kommentare erkennt Tags und leitet an _show_dx_detail bzw _show_med_detail weiter.
5. **Visuelle Trennung**: Medikamente gruen mit Pillen-Icon, Diagnosen blau mit Krankenhaus-Icon.
**Dateien:** basis14.py, aza_persistence.py
## Detailfenster-Nachschaerfung (FIX-05) 2026-03-20
1. **Medikamenten-Prompt**: Dosierung jetzt mit konkreter Standarddosierung fuer Erwachsene (z.B. "100 mg s.c. Woche 0 und 4, dann alle 8 Wochen"). Explizite Anweisung, nicht "gemaess aerztlicher Anweisung" zu schreiben. Zielgruppe: Fachpersonal.
2. **Diagnose-Prompt**: Ebenfalls fuer Fachpersonal optimiert, konsistente Abschnittsueberschriften.
3. **Klickbare Abschnitte**: Abschnittsueberschriften in Med- und Dx-Detailfenstern sind blau, fett, unterstrichen und klickbar. Klick oeffnet die aktuell gewaehlte Originalquelle (compendium.ch/BASG/BfArM bzw. DocCheck/MSD).
4. **Erkennungslogik**: Ueberschriften werden anhand bekannter Headings-Liste erkannt (_DETAIL_SECTION_HEADINGS_MED / _DX), mit Umlaut-Normalisierung.
5. **Hint-Label**: Kleiner Hinweistext unter dem Quellen-Dropdown informiert ueber Klickbarkeit.
**Dateien:** basis14.py
## Qualitaets- und Sicherheits-Fixblock (FIX-06) 2026-03-20
### 1. Keine Fantasie-Medikamente
- Kommentar-Generator-Prompt verschaerft: NUR real existierende Medikamente als [MED] taggen.
- Medikamenten-Detail-Prompt: Obligatorische Sicherheitspruefung VOR Fachinfo-Generierung.
Falls kein reales Medikament erkannt: "KEIN MEDIKAMENT ERKANNT" statt halluzinierter Fachinfos.
Bei Tippfehlern: "NICHT EINDEUTIG Meinten Sie evtl. [Name]?" ohne Fachinfos.
### 2. Korrektur-Fenster UX
- Hint-Label: "Doppelklick auf Wort im Text = Feld Falsch wird befuellt"
- Felder mit groesserer Schrift und fetter Beschriftung
- Gruener "Uebernehmen"-Button
### 3. Audionotiz-Stabilitaetsfix
- Root Cause: DiktatApp(tk.Tk) erzeugte zweite Tk-Instanz in Daemon-Thread → Crashes.
- Fix: Toplevel statt Tk im eingebetteten Modus (_as_toplevel_of parameter).
- Recorder-Referenz Race-Condition behoben. Fehlerbehandlung abgesichert.
### 4. Resize-Griff fuer alle Toplevel-Fenster
add_resize_grip() zu: Kommentare, News, Fachgebiet, Arztzeugnis, KI-Einwilligung, KG-Vorlage, Med/Dx-Detail, Registrierung.
**Dateien:** basis14.py, apps/diktat/diktat_app.py
**Status:** Code umgesetzt, Build erstellt. Verifikation im installierten Build steht noch aus.
## Nachschaerfungs-Fixblock (FIX-07) 2026-03-20
### 1. Resize-Grip Root Cause Fix
- **Root Cause:** `grip.place()` wurde von pack/grid-Inhalten ueberdeckt (Z-Order-Problem).
- **Fix:** `grip.lift()` + wiederholte `after()`-Aufrufe, um den Grip garantiert ueber allen Inhalten anzuzeigen.
Cursor auf `size_nw_se` geaendert.
- **Datei:** aza_ui_helpers.py → `add_resize_grip()`
### 2. Korrekturfenster Sichtbare Falsch/Richtig-Felder
- Neuer `korr_frame` (blauer Rahmen) direkt OBERHALB der gespeicherten Korrekturen-Liste.
- Enthalt: "Falsch:" (rot) + Eingabefeld, "Richtig:" (gruen) + Eingabefeld, "Uebernehmen"-Button.
- Hint-Text: "Doppelklick auf ein Wort oben befuellt 'Falsch' automatisch."
- Alter doppelter bottom_add-Block mit Feldern entfernt.
- **Datei:** basis14.py
### 3. DocCheck-Links mit konkretem Suchbegriff
- **Root Cause:** DocCheck Flexikon URL verwendete `?q=` (falscher Parameter).
DocCheck basiert auf MediaWiki → korrekter Parameter ist `?search=`.
- **Fix:** URL geaendert zu `Spezial:Suche?search={q}&go=Seite` (versucht zuerst Direktartikel, dann Suchergebnis).
- **Datei:** basis14.py → `_DX_QUELLEN`
### 4. Medikamenten-Kurzvorschau Zentrale Validierung VOR Anzeige (FIX-08)
- **Root Cause:** Die Kommentar-Generierung lief als EINZELNER AI-Call:
1. GPT-4o-mini erzeugte `[MED] Dermowartecreme` MIT halluziniertem Kurztext
2. `_apply_kommentare()` zeigte diesen Text 1:1 an
3. Validierung existierte NUR im ZWEITEN AI-Call des Detailfensters
4. Ergebnis: Kurzansicht halluzinierte, Detailfenster sagte "KEIN MEDIKAMENT ERKANNT"
- **Loesung (deterministisch, nicht prompt-basiert):**
- Neue Datei `aza_med_validator.py` mit ~300 realen Medikamenten/Wirkstoffen (DACH-Raum)
- `validate_medication_name(name)` prueft gegen diese Liste (exakt + `difflib.get_close_matches()`)
- Wird in `_apply_kommentare()` fuer JEDEN `[MED]`-Eintrag VORHER aufgerufen
- Ergebnis:
- Sicher erkannt → normale Anzeige + echte Fachinfo
- Nicht erkannt, aber Kandidat gefunden → ⚠ grau + "Meinten Sie evtl. X?" + klickbarer [Uebernehmen]-Link
- Nicht erkannt, kein Kandidat → ⚠ grau + "Kein sicher erkanntes Medikament."
- AI-generierte Kurzinfo wird bei nicht-erkannten Medikamenten komplett unterdrueckt (skip_until_next_heading)
- `_accept_med_candidate()` ersetzt den Namen im AI-Text und re-rendert
- **Dateien:** aza_med_validator.py (NEU), basis14.py, aza_desktop.spec
**Status:** Code nachgeschaerft, Build + Installer erstellt (2026-03-20 17:52). Manuelle Verifikation im installierten Build erforderlich.
SHA256: 27EB38F60965F23C4C2526D47BB4418306AB5ED4F2CB01910CA18D770D2EF2AB
### 5. Quellenstrenge Kommentarlogik Inhaltsquelle / Originallink Trennung (FIX-09/10/11)
- **Root Cause (FIX-09):** LLM generierte Medikamenten-Infos rein aus Modellwissen.
- **Root Cause (FIX-10):** System blieb auf Wirkstoff-Ebene haengen. PharmaWiki-Regex falsch, Compendium SPA nicht scrapbar.
- **Root Cause (FIX-11):** Inhaltsquelle und Originallink waren im Code vermischt. Ein Dropdown steuerte beides.
- **Loesung (FIX-11, 2026-03-22) Saubere Trennung:**
- **INHALTSQUELLE** (was im Detailfenster angezeigt wird):
- `_fetch_doccheck_info(med_name)`: DocCheck Flexikon (Standard)
- `_fetch_pharmawiki_info(med_name)`: PharmaWiki (Fallback)
- Benutzerwaehlbar ueber Dropdown "Inhaltsquelle:" im Detailfenster
- Persistent gespeichert als `med_content_quelle` in `_autotext_data`
- Neues Dict `_MED_CONTENT_QUELLEN` (DocCheck, PharmaWiki)
- **ORIGINALQUELLE** (externer Link / "Originalquelle oeffnen"):
- CH = Compendium, AT = BASG, DE = BfArM UNVERAENDERT
- Weiterhin ueber `_MED_QUELLEN` / `medikament_quelle`
- Kuratierte Fakten `_MEDICATION_FACTS` als Offline-Fallback
- **Therapien/Prozeduren** weiterhin getrennt mit DocCheck/PharmaWiki
- **Kandidatenlogik** (Dermowarte→Dermovate, Vilastin→Bilastin) unberuehrt
- **Dateien:** basis14.py
## Medikamenten-Quellenlogik Schweiz Zielarchitektur (ARCH-MED)
**Status:** Erste Stufe umgesetzt (2026-03-22). Compendium Produkt-Aufloesung + PharmaWiki Quelltext-Extraktion live.
**Aktueller Stand (teilweise umgesetzt):**
- Compendium.ch Produkt-Aufloesung: Wirkstoff → konkreter Praeparat-Name + Darreichungsform
- PharmaWiki Quelltext-Extraktion: Strukturierte Sektionen fuer Prompt-Injektion
- Kuratierte Faktenliste `_MEDICATION_FACTS` (~18 Medikamente) als Offline-Fallback
**Endziel fuer Schweizer Modus:**
AZA soll Medikamenteninformationen fuer die Schweiz grundsaetzlich ueber Compendium.ch
nachschlagen koennen nicht nur ueber eine kleine interne Faktenliste,
nicht nur Link-Weiterleitung, nicht nur LLM-Wissen.
**Zielarchitektur:**
1. Medikament im KG-Text erkennen (bestehendes Tagging + Validierung)
2. In Compendium.ch suchen (echte Suche, nicht nur Link) UMGESETZT
3. Konkreten Produkt-/Praeparattreffer bestimmen UMGESETZT (Name + Darreichungsform)
4. Relevante Fach-/Produktinfo strukturiert auswerten UMGESETZT via PharmaWiki, Compendium-Detailseite noch offen
5. Kommentarinfo NUR aus diesen quellenbasierten Daten bauen UMGESETZT
6. Was nicht aus der Quelle kommt → weglassen, nicht erfinden UMGESETZT
**Abdeckung:**
- PharmaWiki-Fetch deckt grundsaetzlich alle dort verfuegbaren Medikamente ab
- Compendium Produkt-Aufloesung liefert konkreten Praeparat-Namen (abhaengig von Compendium-HTML-Struktur)
- Lokale Faktenliste bleibt als Offline-Fallback
**Naechste Schritte (ARCH-MED-01/02):**
1. Compendium-Detailseiten-Extraktion evaluieren (zusaetzlich zu Produkt-Aufloesung)
2. Caching-Strategie festlegen (PharmaWiki-/Compendium-Antworten lokal cachen)
3. Robustheit gegen HTML-Strukturaenderungen absichern
4. Langfristig: HCI Solutions Datenlizenz / Compendium-API evaluieren
**Spaetere Marktprofile:**
- DE: BfArM / Gelbe Liste separat
- AT: BASG separat
- Jeweils eigenstaendig, nicht mit CH vermischen
## Zukunftsblock Internationalisierung / Laender- und Quellenprofile (GEPARKT)
**Status:** Zukunftsthema NICHT fuer jetzt. Erst nach DACH-Stabilitaet und Produkterfolg.
**Voraussetzung:** DACH-Markt (Schweiz / Deutschland / Oesterreich) sauber stabilisiert, Go-Live gesichert, Produkt erfolgreich.
**Zielbild:**
- UI je nach Markt/Sprache anpassbar
- Medikamentenquellen je nach Land/Sprache anpassbar
- Diagnose-/Therapiequellen je nach Land/Sprache anpassbar
- Beispiel: DACH zuerst, spaeter franzoesische UI + franzoesische medizinische Quellen/Links
**Profil-Architektur (spaeter umsetzen):**
- `app_language` UI-Sprache
- `market_region` Zielmarkt/Land
- `med_source_profile` Medikamentenquellen (Compendium, BASG, BfArM, …)
- `dx_source_profile` Diagnosequellen (DocCheck, MSD, …)
- `therapy_source_profile` Therapiequellen
- Manueller Override durch Benutzer/Praxis
**Wichtig:**
- Nicht hart nach Herkunftsland des Users schalten, sondern saubere Profil-Logik
- Handelsnamen, Zulassungen, Fachinfos und Verfuegbarkeit sind laenderspezifisch
- Deshalb spaeter Quellenprofile pro Markt statt Einheitslogik
- Kein aktueller Implementierungsblock reines Roadmap-Thema
**Status:** Build + Installer erstellt (2026-03-22 22:14). Manuelle Verifikation im installierten Build empfohlen.
SHA256: ABC12791E0DB8472C78E673EC57D416A796E4B5534FF39D2B7A76B8E94B10C0E
## Aktivierungsschluessel → Lizenzmodus Bridge (2026-03-24)
**Root Cause:** Zwei unabhaengige Gating-Systeme im Desktop-Build:
1. Aktivierungsschluessel (aza_activation.py): Kontrolliert ob App STARTET (Trial oder AZA-Key)
2. Subscription-Lizenz (check_license_status): Kontrolliert ob DEMO- oder VOLL-Modus
Diese waren NICHT verbunden. Ein zahlender Kunde mit gueltigem AZA-Key lief trotzdem im DEMO-Modus,
weil die Subscription-Lizenzpruefung mangels MEDWORK_BACKEND_URL immer fehlschlug.
**Fix:** In KGDesktopApp.__init__ (basis14.py): Nach check_license_status() wird geprueft, ob ein
gueltiger Aktivierungsschluessel vorhanden ist. Falls ja und license_mode noch "demo" → auf "active" setzen.
**Auswirkung:** ~10 Zeilen, kein Monsterpatch. /license/status unberuehrt. Keine Auth-Aenderung.
Erster Kundenweg damit praktikabel: Entwickler generiert Key, sendet per E-Mail, Kunde gibt ein → Vollmodus.
**Entschaerfender Faktor:** DEMO_MAX_DICTATIONS=9999 (Demo-Modus ist de facto unbeschraenkt).
Die Bridge ist trotzdem korrekt, weil DEMO_MAX_DICTATIONS spaeter gesenkt werden soll.
**Datei:** basis14.py (KGDesktopApp.__init__, nach self.check_license_status())
## Windows Code-Signing / Smart App Control Readiness (2026-03-23)
**Problem:** Windows Smart App Control (ab Windows 11 22H2) blockiert unsignierte und unbekannte
Anwendungen automatisch. Auch ohne Smart App Control zeigt SmartScreen Warnungen bei unsignierten Downloads.
Fuer Kundenauslieferung muessen alle ausfuehrbaren Artefakte signiert werden.
**Status:** Signing-Readiness vorbereitet, noch NICHT produktiv aktiviert (kein Zertifikat vorhanden).
**Vorbereitete Dateien:**
- `sign_release.ps1` Signing-Skript (signiert EXE, DLLs/PYDs, Installer; DryRun-Modus; Verifikation)
- `build_and_test_release.ps1` Release-Pipeline mit optionalem Signing-Schritt (graceful skip ohne Zertifikat)
- `build_release_artifacts.ps1` Artefakt-Report enthaelt jetzt signing_status und signing_subject
- `SIGNING_READINESS.md` Vollstaendige Dokumentation mit Artefakt-Liste, Signing-Reihenfolge, Zertifikats-Optionen, Checkliste
**Artefakte die signiert werden muessen:**
| Prioritaet | Artefakt | Pfad |
|---|---|---|
| Kritisch | Haupt-EXE | `dist\aza_desktop\aza_desktop.exe` |
| Kritisch | Installer | `dist\installer\aza_desktop_setup.exe` |
| Empfohlen | DLLs | `dist\aza_desktop\_internal\*.dll` |
| Empfohlen | PYDs | `dist\aza_desktop\_internal\*.pyd` |
**Signing-Reihenfolge in der Pipeline:**
```
Desktop Build → DLLs/PYDs signieren → EXE signieren → Installer Build → Installer signieren → Artefakt-Report → Publish
```
**Noch offen vor Kundenauslieferung:**
1. EV Code-Signing-Zertifikat beschaffen (empfohlen: DigiCert/Sectigo, ca. CHF 400600/Jahr; alternativ Azure Trusted Signing)
2. signtool.exe installieren (Windows SDK)
3. Publisher-Name im Zertifikat mit `AppPublisher` in `aza_installer.iss` abstimmen (aktuell: `AZA MedWork`)
4. `sign_release.ps1` produktiv ausfuehren
5. Signierte Artefakte auf sauberem Windows-PC mit aktivem Smart App Control testen
**Publisher-/Namenskonsistenz (Analyse 2026-03-23):**
Im Projekt existieren 3 verschiedene Namensformen. Dies ist KEINE Inkonsistenz jede Form hat eine klare Rolle:
| Namensform | Rolle | Signing-relevant | Stellen |
|---|---|---|---|
| **AZA MedWork** | Firma / Publisher | **JA signing-kritisch** | aza_installer.iss, legal/privacy_policy.md, legal/ai_consent.md, deploy/WOOCOMMERCE_PRODUCT.md, deploy/WORDPRESS_GOLIVE.md |
| **AZA Desktop** | Produktname | Nein | aza_config.py, CHANGELOG.md, web/download.html, tools/aza_clean_uninstall.ps1, translate.py, build_exe.ps1, deploy/PRODUCT_V1.md |
| **AZA Medical AI Assistant** | Interner Projektname | Nein | project_status.json, project_status_routes.py, web/index.html, billing/invoice_template.json, billing/BILLING_FLOW.md |
**Vor Zertifikatskauf zu klaeren:**
1. Offiziellen Firmennamen im Handelsregister pruefen
2. EV-Zertifikats-Subject muss exakt mit HR-Name uebereinstimmen
3. `AppPublisher` in `aza_installer.iss` auf Zertifikats-Subject abstimmen
4. Falls HR-Name von "AZA MedWork" abweicht: alle signing-relevanten Stellen gemeinsam anpassen
5. SmartScreen-Reputation baut auf Publisher-Namen auf nach Festlegung NICHT mehr aendern
**Stellen die bei Namensaenderung gemeinsam angepasst werden muessen:**
- `installer/aza_installer.iss``MyAppPublisher`
- `legal/privacy_policy.md` → Zeile 5 + Zeile 27
- `legal/ai_consent.md` → Zeile 10, 12, 132
- `deploy/WOOCOMMERCE_PRODUCT.md` → Absendername
- `deploy/WORDPRESS_GOLIVE.md` → Absendername
- `SIGNING_READINESS.md` → Beispielname
- `apps/diktat/diktat_app.py` → Docstring
- `aza_consent.py` → Docstring
**Stellen die NICHT angepasst werden muessen (nicht signing-relevant):**
- `project_status.json` ("AZA Medical AI Assistant" ist interner Projektname)
- `project_status_routes.py` (API-Response, intern)
- `billing/invoice_template.json` (Rechnungsposition, kann abweichen)
- `web/index.html`, `web/download.html` (Marketing-Langname)
**Do-Not-Break:**
- Keine echten Zertifikate oder Secrets ins Repository committen
- Signing-Schritt ist optional (Pipeline laeuft auch ohne Zertifikat durch)
- Keine Pseudo-Signierung oder Fake-Zertifikate
- Publisher-Name nach Festlegung NICHT mehr wechseln