773 lines
40 KiB
Markdown
773 lines
40 KiB
Markdown
# 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 400–600/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
|