Files
aza/AzA march 2026 - Kopie (16)/project_todos.json

854 lines
50 KiB
JSON
Raw Normal View History

2026-04-19 20:41:37 +02:00
{
"version": 12,
"updated_at": "2026-03-31",
"project_phase": "Device-/Seat-Logik V1 implementiert (2026-04-12). Backup-Konzept + Deinstallations-UX als naechste Hauptbloecke.",
"go_live_sprint": {
"start": "2026-03-25",
"target": "ca. 2026-04-22",
"woche_1": "WooCommerce / Stripe / Checkout / Download / Testkauf",
"woche_2": "Installer / Aktivierung / Erststart",
"woche_3": "Produktdarstellung / Bilder / Signing-Entscheidung",
"woche_4": "End-to-End-Test / Go-Live-Freigabe"
},
"priority_order": "Woche 1 (WooCommerce/Stripe) → Woche 2 (Installer/Aktivierung) → Woche 3 (Produktseite/Signing) → Woche 4 (E2E-Test/Go-Live). Desktop-Blocker nur gezielt. Update-Komfort/Hetzner/Refactors NACHRANGIG.",
"priority_note": "B1 Backend-Sprint: Variante B verbindlich. Hetzner ist JETZT Backend-Pfad (OpenAI-Proxy/API). Hostpoint bleibt fuer Website/WooCommerce. Beides parallel.",
"working_principles": [
"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"
],
"next_main_block": "NAECHSTE BLOECKE: (1) Vollstaendiges Backup-Konzept (lokal, Hetzner, Stripe, WordPress, Offsite Luino) HOHE PRIORITAET. (2) Deinstallations-UX: kein Zwangs-Neustart, Option jetzt/spaeter. (3) WooCommerce/Produktiver Verkaufspfad. (4) Browser-AZA. SICHERHEITSNOTIZ: AZA_ADMIN_TOKEN Rotation vor Produktivbetrieb.",
"items": [
{
"id": "B1-W1",
"priority": "ERLEDIGT",
"group": "B1 Backend-Sprint Variante B",
"area": "Backend / Architektur / OpenAI",
"title": "ERLEDIGT: Backend Chat Proxy Endpoint (POST /v1/chat)",
"status": "erledigt",
"description": "POST /v1/chat in backend_main.py implementiert und verifiziert (2026-03-26). Auth via X-API-Token (require_api_token). Pydantic-Modelle ChatRequest/ChatMessage. Modell-Whitelist (gpt-5.2/5-mini/5-nano/4o/4o-mini/4o-mini-search-preview). Rate Limiting IP+Token. Input-Validierung (max 64 Messages, max 100k Zeichen). Secret-Scrubbing bei Fehlern. 7/7 Tests gruen: Auth 401, Bad Model 400, Empty 422, Valid 200 success=true, /license/status 200 OK, Schema komplett."
},
{
"id": "B1-W2",
"priority": "ERLEDIGT",
"group": "B1 Backend-Sprint Variante B",
"area": "Desktop / Backend",
"title": "ERLEDIGT: Desktop-App OpenAI-Calls auf Backend umgestellt (2026-03-26)",
"status": "erledigt",
"description": "call_chat_completion() in basis14.py nutzt jetzt _backend_chat_completion() -> POST /v1/chat. 4 Call-Sites migriert: (1) call_chat_completion zentral, (2) News-Suche, (3) Kommentare, (4) Med-Detail Kurzinfo. aza_text_windows_mixin.py (Briefstil-Analyse) ebenfalls migriert. _BackendChatResponse Wrapper fuer OpenAI-Interface-Kompatibilitaet. Kein direkter OpenAI-Chat-Call mehr in basis14.py. 7/7 Tests gruen. Verbleibend fuer spaeter: translate.py, congress_window.py, aza_email.py (separate Module)."
},
{
"id": "B1-W3",
"priority": "ERLEDIGT",
"group": "B1 Backend-Sprint Variante B",
"area": "Ops / Deploy / Hetzner",
"title": "ERLEDIGT: Hetzner Deploy LIVE (2026-03-26)",
"status": "erledigt",
"description": "Hetzner-Backend ist live. DNS A-Record api.aza-medwork.ch → 178.104.51.177. Repo unter /root/aza-app, deploy unter /root/aza-app/deploy. Services aza-api + aza-caddy laufen. Caddy/HTTPS aktiv. Root Causes geloest: falsches Git-Remote (naswinterthur), fehlender Repo-Root-Kontext fuer Docker, nginx auf Port 80, Caddy DNS-Resolver 127.0.0.53. Fix: explizite DNS-Server 1.1.1.1 + 8.8.8.8 im caddy-Service. .env produktiv: AZA_DOMAIN=api.aza-medwork.ch, ACME_EMAIL=info@aza-medwork.ch, MEDWORK_API_TOKENS + OPENAI_API_KEY gesetzt."
},
{
"id": "B1-W4",
"priority": "ERLEDIGT",
"group": "B1 Backend-Sprint Variante B",
"area": "Product / E2E / Go-Live",
"title": "ERLEDIGT: Server-E2E-Test erfolgreich (2026-03-26)",
"status": "erledigt",
"description": "curl https://api.aza-medwork.ch/health erfolgreich. curl -X POST /v1/chat mit gueltigem X-API-Token erfolgreich (success:true, content:OK). Variante B serverseitig Ende-zu-Ende nachgewiesen: Hetzner-Backend laeuft, Caddy/HTTPS laeuft, serverseitiger OpenAI-Zugriff laeuft."
},
{
"id": "B1-W5",
"priority": "ERLEDIGT",
"group": "B1 Backend-Sprint Variante B",
"area": "Desktop / E2E / Go-Live",
"title": "ERLEDIGT: Realer lokaler Desktop-Live-Test (2026-03-27)",
"status": "erledigt",
"description": "Desktop → Hetzner → OpenAI erfolgreich in der echten App getestet. basis14.py lokal gegen Live-Backend gestartet. Kein lokaler OpenAI-Key noetig. Chat-/Textpfad funktioniert ueber Hetzner-Backend. Variante B produktiv nachgewiesen."
},
{
"id": "LIC-01",
"priority": "HOCH",
"group": "Lizenz-/Subscription-Lifecycle",
"area": "Backend / Lizenz / Product",
"title": "Lizenz-/Subscription-Lifecycle sauber machen (nach Desktop-Validierung)",
"status": "offen",
"description": "Lizenz aktiv solange Subscription bezahlt ist. Rueckfall auf Testmodus / eingeschraenkten Modus bei Kuendigung/Nichtzahlung. App-/Lizenzstatus sauber pruefen. /license/status-Struktur NICHT kaputtmachen. Keine vorschnellen Auth-/API-Contract-Aenderungen."
},
{
"id": "LIC-02",
"priority": "HOCH",
"group": "Lizenz-/Subscription-Lifecycle",
"area": "Billing / Product",
"title": "PARALLELER BLOCK: WooCommerce / Stripe Live-Setup inkl. Auszahlung",
"status": "offen",
"description": "WooCommerce-/Stripe-Konfiguration fertigstellen. Live-Zahlungsfluss vorbereiten. Sicherstellen dass Auszahlungen auf das Bankkonto des Nutzers gehen. Testkauf / Zahlungsfluss validieren. Fuehrende Preise: Basic (1 User) CHF 59/Monat CHF 590/Jahr. Team (2 User) CHF 89/Monat CHF 890/Jahr. Stripe Lookup Keys: aza_basic_monthly (price_1T53xHL5lREAW68VbuK43lmz), aza_basic_yearly (price_1T542BL5lREAW68VNLQGCKWZ), aza_team_monthly (price_1T544tL5lREAW68VkmnmZ21Q), aza_team_yearly (price_1T545RL5lREAW68VLbIh73AN)."
},
{
"id": "LIC-04",
"priority": "HOCH",
"group": "Lizenz-/Subscription-Lifecycle",
"area": "Billing / Ops",
"title": "Stripe-Konto fuehrend dokumentieren + Auszahlung pruefen",
"status": "offen",
"description": "Fuehrendes Stripe-Konto (Login/E-Mail) dokumentieren. Testmodus vs. Livemodus klaeren. Bankkonto fuer Auszahlungen pruefen/hinterlegen. Webhook-URL und Status dokumentieren. Success-/Cancel-URLs fuehrend festlegen."
},
{
"id": "STRIPE-W1",
"priority": "ERLEDIGT",
"group": "Lizenz-/Subscription-Lifecycle",
"area": "Billing / Ops",
"title": "ERLEDIGT: Stripe-Webhook Nacharbeiten (2026-03-28)",
"status": "erledigt",
"description": "Sandbox-Kauf erfolgreich: admin@aza-medwork.ch, sub_1TG4fSRGaRoJio7WyM2KwN53, status=active, lookup_key=aza_basic_monthly. Root Causes geloest: (1) Sandbox+Live API-Key-Mix (2) missing_lookup_key (3) Idempotenz-Bug (4) Decimal-Serialisierung (5) Stille Exits. SQLite bereinigt. license_debug funktional."
},
{
"id": "STRIPE-W2-LIVE",
"priority": "ERLEDIGT",
"group": "Lizenz-/Subscription-Lifecycle",
"area": "Billing / Ops",
"title": "ERLEDIGT: Stripe Live-Testkauf + Storno + Refund (2026-03-30)",
"status": "erledigt",
"description": "Echter Live-Testkauf durchgefuehrt und sauber neutralisiert. Subscription initial active, danach storniert + Zahlung refundiert. license_debug zeigt korrekt canceled. Drei Bugs in stripe_routes.py gepatcht: (A) _upsert_license COALESCE-Fix gegen customer_email-Verlust, (B) cancel_at_period_end-Erkennung in Webhook, (C) sync_subscription robuster (optional subscription_id, nicht nur active). DB-Backup: stripe_webhook.sqlite.before_email_fix. Stripe-/Webhook-/Live-Pfad technisch bewiesen."
},
{
"id": "STRIPE-W3",
"priority": "ERLEDIGT",
"group": "Lizenz-/Subscription-Lifecycle",
"area": "Desktop / Lizenz",
"title": "ERLEDIGT: Desktop-Lizenzpfad gegen Live-Backend validiert (2026-03-30)",
"status": "erledigt",
"description": "Desktop respektiert canceled-Status korrekt und faellt auf Testmodus zurueck. Kompletter Lizenz-Lifecycle nachgewiesen: Kauf → active → Storno/Refund → canceled → Desktop-Testmodus. check_license_status() in basis14.py, compute_license_decision() in aza_license_logic.py funktionieren korrekt."
},
{
"id": "LIVE-KAUF-01",
"priority": "ERLEDIGT",
"group": "Lizenz-/Subscription-Lifecycle",
"area": "Billing / Desktop / Lizenz",
"title": "ERLEDIGT: Echter Live-Kauf CHF 59 + Desktop Vollmodus (2026-03-30)",
"status": "erledigt",
"description": "Echter Live-Kauf Basic Monthly (CHF 59) erfolgreich. Backend-Lizenz active fuer admin@aza-medwork.ch. Desktop startet ohne Testfenster und im Vollmodus. current_period_end korrekt gesetzt (1777652509)."
},
{
"id": "LIVE-KAUF-02",
"priority": "ERLEDIGT",
"group": "Lizenz-/Subscription-Lifecycle",
"area": "Desktop / Bugfix",
"title": "ERLEDIGT: Desktop Aktivierungs-Gate Fix (2026-03-30)",
"status": "erledigt",
"description": "Root Cause: Lokales Aktivierungs-Gate (_show_activation_gate) pruefte Aktivierungsschluessel/Trial vor Backend-Lizenzcheck. Fix: _has_remote_backend() erkennt nicht-localhost Backend. Bei Remote-Backend wird lokales Gate komplett uebersprungen. Backend-Lizenzstatus allein fuehrend. Datei: basis14.py."
},
{
"id": "LIVE-KAUF-03",
"priority": "ERLEDIGT",
"group": "Lizenz-/Subscription-Lifecycle",
"area": "Backend / Webhook",
"title": "ERLEDIGT: current_period_end-Fallback in Webhook (2026-03-30)",
"status": "erledigt",
"description": "Root Cause: checkout.session.completed und subscription.updated/deleted Webhook-Handler hatten keinen Fallback auf items.data[0].current_period_end. Fix: Fallback-Extraktion ergaenzt. Bestehende null-Daten via sync_subscription repariert. current_period_end jetzt 1777652509. Datei: stripe_routes.py."
},
{
"id": "BETREIBER-01",
"priority": "ERLEDIGT",
"group": "Ops / Admin-Monitor",
"area": "Backend / Ops",
"title": "ERLEDIGT: Betreiber-Kontrolle mit Einzelposten (2026-03-31)",
"status": "erledigt",
"description": "Root Cause 16: revenue_overview zeigte nur Summen, keine Einzelposten. Fix: recent_charges und recent_refunds Listen in revenue_overview ergaenzt. Bewiesen: recent_charges zeigt 59.0 CHF fuer admin@aza-medwork.ch, recent_refunds zeigt 59.0 CHF. Datei: admin_routes.py."
},
{
"id": "SEC-TOKEN-01",
"priority": "HOCH",
"group": "Sicherheit",
"area": "Ops / Security",
"title": "Admin-Token-Rotation (Token im Chat offengelegt)",
"status": "offen",
"description": "AZA_ADMIN_TOKEN wurde in einem Chat-Verlauf sichtbar. Chat loeschen rotiert den Token NICHT. Vor produktivem Kundenbetrieb rotieren: (1) Neuen Token generieren, (2) In /root/aza-app/deploy/.env setzen, (3) docker compose up -d --build --force-recreate aza-api. Mini-Block, kein Code noetig."
},
{
"id": "ADMIN-V1",
"priority": "ERLEDIGT",
"group": "Ops / Admin-Monitor",
"area": "Backend / Ops",
"title": "ERLEDIGT: Admin Monitor v1 live (2026-03-30)",
"status": "erledigt",
"description": "Interne Admin-Endpunkte live und durch X-Admin-Token / AZA_ADMIN_TOKEN geschuetzt. Endpunkte: GET /admin/system_status, GET /admin/licenses_overview, GET /admin/backup_status, GET /admin/billing_overview. Datei: admin_routes.py, eingebunden in backend_main.py mit prefix=/admin."
},
{
"id": "ADMIN-V2",
"priority": "ERLEDIGT",
"group": "Ops / Admin-Monitor",
"area": "Backend / Ops",
"title": "ERLEDIGT: Control Panel v2 live (2026-03-30)",
"status": "erledigt",
"description": "Erweiterte Admin-Endpunkte: GET /admin/license_customer_map (Lizenznehmer-Uebersicht), GET /admin/revenue_overview (Umsatz/Refunds), GET /admin/alerts (Warn-/Ampelliste), GET /admin/dashboard_summary (Sammel-Endpunkt). Nachweislich funktionierend: revenue_overview zeigt 59 CHF gross / 59 CHF refund / 0 CHF net fuer 2026-03. alerts und dashboard_summary funktional."
},
{
"id": "BACKUP-MON",
"priority": "ERLEDIGT",
"group": "Ops / Backup",
"area": "Ops / Hetzner",
"title": "ERLEDIGT: Backup/Storage-Monitor aktiv (2026-03-30)",
"status": "erledigt",
"description": "Taegliches Backup-Skript eingerichtet (/root/aza-backups/backup_aza.sh, Cronjob). /host_backups read-only in Container gemountet. backup_status erkennt Backups korrekt. Ca. 137 GB frei, ca. 4-5% belegt. Kein akuter Speicherdruck."
},
{
"id": "FB-A",
"priority": "HOCH",
"group": "Fokusblock A Kundenweg End-to-End (PARALLEL)",
"area": "Product / Billing / Release",
"title": "WooCommerce-Grundkonfiguration + Testkauf",
"status": "offen",
"description": "7 Admin-Schritte in WordPress/WooCommerce. Zusammengefuehrt mit LIC-02 (WooCommerce/Stripe Live-Setup)."
},
{
"id": "FB-A-BRIDGE",
"priority": "ERLEDIGT",
"group": "Fokusblock A Kundenweg End-to-End",
"area": "Desktop / Lizenz",
"title": "Aktivierungsschluessel → Lizenzmodus Bridge",
"status": "erledigt",
"description": "Kritischer Bruch behoben: Gueltiger AZA-Aktivierungsschluessel setzt jetzt license_mode=active (Vollmodus), nicht nur Start-Erlaubnis. Damit ist der manuelle erste Kundenweg praktikabel: Entwickler generiert Key, sendet per E-Mail, Kunde gibt ein, App laeuft voll. Datei: basis14.py."
},
{
"id": "FB-B",
"priority": "HOCH",
"group": "Fokusblock B Kritische Restfehler",
"area": "Desktop / Bugfix",
"title": "Kritische Desktop-Restfehler nur gezielt und einzeln behandeln",
"status": "offen",
"description": "Keine neuen Monsterpatches. Root-cause-first. Installierten Build hoeher gewichten als Code-Behauptungen. Nur Blocker fuer den Kundenweg."
},
{
"id": "FB-C",
"priority": "MITTEL",
"group": "Fokusblock C Windows-Signing",
"area": "Release / Security",
"title": "Windows-Kundenauslieferung absichern (Signing)",
"status": "offen",
"description": "Signing-Readiness vorbereitet. Produktives Signing vor Kundenauslieferung noch offen. Smart App Control / Reputation / Publisher-Konsistenz beachten."
},
{
"id": "FB-D",
"priority": "NACHGELAGERT",
"group": "Fokusblock D Update-Komfort",
"area": "Desktop / Release",
"title": "Update-Verbesserungen BEWUSST NACHGELAGERT",
"status": "nachgelagert",
"description": "Update-Komfort / separater Updater ist NICHT aktuelle Prioritaet. Kein aktueller Hauptblock. Erst nach stabilem Kauf-/Download-/Installationspfad."
},
{
"id": "A-01",
"priority": "SOFORT",
"group": "A Go-Live extern",
"area": "Ops",
"title": "Hostpoint-Website stabil lassen",
"status": "in_progress",
"description": "Keine riskanten Domain-/DNS-Experimente. Bestehende WordPress/Kadence-Seite bleibt Haupt-Website auf Hostpoint."
},
{
"id": "A-02",
"priority": "SOFORT",
"group": "A Go-Live extern",
"area": "Billing",
"title": "Stripe Live-Setup sauber fertigstellen",
"status": "teilweise",
"description": "Stripe Live-Konto eingerichtet. Produkt AzA Office mit 4 Preisen. Payment Links erstellt. Webhook operational (200 OK). OFFEN: Stripe-Konto-Ownership dokumentieren, Bankkonto fuer Auszahlung pruefen, Testkauf validieren, WooCommerce-Integration finalisieren."
},
{
"id": "A-03",
"priority": "SOFORT",
"group": "A Go-Live extern",
"area": "Security",
"title": "Live-Secrets pruefen",
"status": "teilweise",
"description": "STRIPE_SECRET_KEY und STRIPE_WEBHOOK_SECRET korrekt in Hetzner .env. MEDWORK_API_TOKEN gesetzt. OFFEN: Nach stabilem Abschluss kompromittierte/sichtbare Secrets rotieren."
},
{
"id": "A-04",
"priority": "ERLEDIGT",
"group": "A Go-Live extern",
"area": "Ops",
"title": "ERLEDIGT: Deploy-Stack auf Hetzner live (2026-03-26)",
"status": "erledigt",
"description": "Docker Compose + Caddy + Backend auf Hetzner live. Services aza-api + aza-caddy. api.aza-medwork.ch erreichbar. Haupt-Website bleibt auf Hostpoint."
},
{
"id": "A-05",
"priority": "SOFORT",
"group": "A Go-Live extern",
"area": "Product",
"title": "Testkauf Ende-zu-Ende durchfuehren",
"status": "offen",
"description": "Stripe-Testmodus: Subscription monatlich + jaehrlich kaufen, Download-Link pruefen, E-Mail pruefen, Mein-Konto pruefen."
},
{
"id": "A-06",
"priority": "SOFORT",
"group": "A Go-Live extern",
"area": "Product",
"title": "Download-/Lizenzfluss live validieren",
"status": "offen",
"description": "Installer herunterladen, installieren, Aktivierung, Lizenzpruefung, Backend-Anbindung alles End-to-End."
},
{
"id": "BRAND-01",
"priority": "HOCH",
"group": "Branding / Produktname",
"area": "Product / Marketing",
"title": "Produktname AZA Office final entscheiden (vor Go-Live)",
"status": "in_arbeit",
"description": "AKTUELLE RICHTUNG: AZA Office. Favorit-Langform: 'AZA Office Ihr medizinischer KI-Arbeitsplatz fuer die Praxis'. Zweite gute Variante: 'AZA Office Die KI-Assistenz fuer medizinische Dokumentation'. Noch nicht zwingend final juristisch/brand-strategisch entschieden, aber bevorzugte Naming-Richtung fuer WooCommerce/Website/Download/Go-Live. Fruehere Shortlist (AZA Desktop) bleibt dokumentiert in project_roadmap.json und project_plan.json."
},
{
"id": "B-01",
"priority": "HOCH",
"group": "B Verkauf / Subscription",
"area": "Product",
"title": "Subscription in Website/Checkout konsistent abbilden",
"status": "offen",
"description": "Basic (1 User): CHF 59/Monat, CHF 590/Jahr. Team (2 User): CHF 89/Monat, CHF 890/Jahr. Stripe Billing direkt. Pricing auf Produktseite, Checkout, E-Mails konsistent."
},
{
"id": "B-02",
"priority": "HOCH",
"group": "B Verkauf / Subscription",
"area": "Product",
"title": "Pricing-Texte und Lizenztexte festziehen",
"status": "erledigt",
"description": "deploy/PRODUCT_V1.md und deploy/WOOCOMMERCE_PRODUCT.md auf Subscription-Modell aktualisiert."
},
{
"id": "B-03",
"priority": "HOCH",
"group": "B Verkauf / Subscription",
"area": "Billing",
"title": "Billing / Invoices / VAT / Stripe-Rechnungslogik",
"status": "offen",
"description": "Rechnungen mit CHF, MwSt-Hinweis, korrekte Absenderadresse. Stripe Invoice-Einstellungen. AGB mit Subscription-Hinweisen."
},
{
"id": "C-01",
"priority": "HOCH",
"group": "C Download-Produkt",
"area": "Release",
"title": "Stabile Basisversion als erste verkaufbare Version definieren",
"status": "erledigt",
"description": "v1.0.0 definiert, Installer gebaut und getestet. 6 Module, Systemstatus, Launcher, Firewall-Fix."
},
{
"id": "C-02",
"priority": "HOCH",
"group": "C Download-Produkt",
"area": "Release",
"title": "Release-/Update-Strategie sauber machen",
"status": "erledigt",
"description": "Versionierung (v1.0.x / v1.x / v2.0), Update-Lieferung ueber WooCommerce-Account, Changelog."
},
{
"id": "C-03",
"priority": "MITTEL",
"group": "C Download-Produkt",
"area": "Release",
"title": "Signierte Downloads / Versionierung / Changelog vervollstaendigen",
"status": "teilweise",
"description": "Signing-Readiness vorbereitet: sign_release.ps1 erstellt, Release-Pipeline mit optionalem Signing-Schritt (build_and_test_release.ps1), Artefakt-Report mit Signatur-Status (build_release_artifacts.ps1), SIGNING_READINESS.md mit Checkliste. OFFEN: Echtes EV Code-Signing-Zertifikat beschaffen, signtool.exe auf Build-Rechner installieren, produktiver Signierlauf durchfuehren, Publisher-Name im Zertifikat mit AppPublisher in aza_installer.iss abstimmen."
},
{
"id": "C-04",
"priority": "HOCH",
"group": "C Download-Produkt",
"area": "Release / Security",
"title": "Code-Signing vor Kundenauslieferung aktivieren",
"status": "offen",
"description": "VOR erster Kundenauslieferung verpflichtend: (1) Offiziellen Firmennamen im Handelsregister pruefen (EV-Validierung prueft HR-Eintrag). (2) EV Code-Signing-Zertifikat beschaffen (DigiCert/Sectigo empfohlen, alternativ Azure Trusted Signing). (3) signtool.exe installieren (Windows SDK). (4) AppPublisher in aza_installer.iss auf exakten Zertifikats-Subject abstimmen (aktuell 'AZA MedWork'). (5) Falls HR-Name abweicht: auch legal/privacy_policy.md, legal/ai_consent.md, deploy/WOOCOMMERCE_PRODUCT.md (Absendername), deploy/WORDPRESS_GOLIVE.md gemeinsam anpassen. (6) sign_release.ps1 produktiv ausfuehren. (7) Signierte Artefakte auf Windows-PC mit Smart App Control testen. (8) Publisher-Name nach Festlegung NICHT mehr aendern (Reputation). Grund: Windows Smart App Control blockiert unsignierte/unbekannte Apps bei Kunden."
},
{
"id": "C-05",
"priority": "HOCH",
"group": "C Download-Produkt",
"area": "Release / Legal",
"title": "Publisher-/Firmenname final festlegen (vor Zertifikatskauf)",
"status": "offen",
"description": "Vor Zertifikatskauf: (1) Offiziellen Firmennamen im Handelsregister pruefen. (2) Entscheiden ob Signing-Publisher 'AZA MedWork', 'AZA MedWork GmbH' oder anders lauten soll. (3) AppPublisher in aza_installer.iss anpassen falls noetig. (4) Alle signing-relevanten Stellen gemeinsam aktualisieren: aza_installer.iss, legal/privacy_policy.md, legal/ai_consent.md, deploy/WOOCOMMERCE_PRODUCT.md, deploy/WORDPRESS_GOLIVE.md. (5) Nicht-signing-relevante Stellen (project_status.json 'AZA Medical AI Assistant', billing/invoice_template.json) koennen unabhaengig bleiben. Analyse: Aktuell 3 Namensformen im Projekt 'AZA MedWork' (Firma/Publisher), 'AZA Desktop' (Produkt), 'AZA Medical AI Assistant' (interner Projektname). Nur 'AZA MedWork' ist signing-kritisch."
},
{
"id": "D-01",
"priority": "HOCH",
"group": "D Browser-AZA",
"area": "Web",
"title": "Nach Go-Live Step 22 verbindlich starten",
"status": "offen",
"description": "Browser-AZA ist Kern des Projekts. Wird nach Go-Live sofort gestartet, nicht optional."
},
{
"id": "D-02",
"priority": "HOCH",
"group": "D Browser-AZA",
"area": "Web",
"title": "Browser-AZA MVP nach Spec umsetzen",
"status": "offen",
"description": "browser_aza_mvp_spec.md: Upload-Bereich, Fachrichtungsauswahl, /v1/transcribe, Ergebnisansicht, Copy-Button."
},
{
"id": "D-03",
"priority": "HOCH",
"group": "D Browser-AZA",
"area": "Security",
"title": "Minimaler Zugangsschutz ohne Breaking Change",
"status": "offen",
"description": "Auth fuer Browser-AZA, ohne /license/status oder X-API-Token Contract zu brechen."
},
{
"id": "D-04",
"priority": "HOCH",
"group": "D Browser-AZA",
"area": "Web",
"title": "Upload-Flow / Result-Flow / Specialty-Auswahl bauen",
"status": "offen",
"description": "Audio-Upload, Fachrichtungsauswahl, Transkript-Anzeige, Copy-Button. Keine PHI in Logs."
},
{
"id": "E-01",
"priority": "SPAETER",
"group": "E Ops / Spaeter",
"area": "Ops",
"title": "Observability",
"status": "offen",
"description": "Logging, Metriken, Alerting. Kein PHI in Logs. Uptime-Monitoring."
},
{
"id": "E-02",
"priority": "ERLEDIGT",
"group": "E Ops / Spaeter",
"area": "Ops",
"title": "ERLEDIGT: Admin Control Panel v2 live (2026-03-30)",
"status": "erledigt",
"description": "Admin Monitor v1 + Control Panel v2 in admin_routes.py. 8 Endpunkte. Geschuetzt via X-Admin-Token / AZA_ADMIN_TOKEN. Weitere Support-Workflows und Nutzer-Management spaeter bei Bedarf."
},
{
"id": "E-03",
"priority": "SPAETER",
"group": "E Ops / Spaeter",
"area": "Ops",
"title": "Runbook final",
"status": "offen",
"description": "Backups, Log-Rotation, Incident-Playbook, Token-Rotation."
},
{
"id": "E-04",
"priority": "SPAETER",
"group": "E Ops / Spaeter",
"area": "Ops",
"title": "Go-Live Cutover final",
"status": "offen",
"description": "Finale Checkliste, Rollback-Plan, DNS-Cutover fuer Browser-AZA (app.aza-medwork.ch)."
},
{
"id": "ARCH-01",
"priority": "ERLEDIGT",
"group": "Architektur OpenAI-Key (VARIANTE B VERBINDLICH)",
"area": "Backend / Architektur",
"title": "ERLEDIGT: Serverseitige OpenAI-Architektur Variante B produktiv (2026-03-26)",
"status": "erledigt",
"description": "VERBINDLICHE ENTSCHEIDUNG (2026-03-25) UMGESETZT: OpenAI-Key AUSSCHLIESSLICH serverseitig auf Hetzner. Hetzner-Backend live unter api.aza-medwork.ch. POST /v1/chat, Caddy/HTTPS, serverseitiger OpenAI-Zugriff nachgewiesen. Verbleibend: Desktop-Client auf Live-Backend umstellen."
},
{
"id": "ARCH-02",
"priority": "ERLEDIGT",
"group": "Architektur OpenAI-Key (VARIANTE B VERBINDLICH)",
"area": "Backend / Architektur",
"title": "ERLEDIGT: Codepfade mit lokaler Key-Eingabe identifiziert und Hauptpfad migriert",
"status": "erledigt",
"description": "MIGRATION ERLEDIGT (B1-W2, 2026-03-26): Hauptpfad-Calls in basis14.py + aza_text_windows_mixin.py auf Backend /v1/chat umgestellt. Verbleibende Nebenpfade (translate.py, aza_email.py, apps/diktat/diktat_app.py) blockieren Haupttest nicht spaeteres Cleanup."
},
{
"id": "ARCH-03",
"priority": "ERLEDIGT",
"group": "Architektur OpenAI-Key (VARIANTE B VERBINDLICH)",
"area": "Backend / Architektur",
"title": "ERLEDIGT: Migrationspfad umgesetzt Key-Dialog bei Remote-Backend unterdrueckt",
"status": "erledigt",
"description": "UMGESETZT (2026-03-27): Key-Setup-Dialog wird bei konfiguriertem Remote-Backend unterdrueckt. ensure_ready() akzeptiert Remote-Backend als ready. Lokaler Key bleibt als Dev-Fallback. Produktivauslieferung hat keinen Key-Setup-Dialog wenn backend_url.txt auf Live-Backend zeigt."
},
{
"id": "ARCH-04",
"priority": "HOECHSTE",
"group": "Architektur OpenAI-Key (VARIANTE B VERBINDLICH)",
"area": "Security",
"title": "GESPERRT: Keine Keys hardcoden, keinen Shared-Key, keine halben Loesungen",
"status": "gesperrt",
"description": "VERBINDLICHE SPERRUNG: NIEMALS OpenAI-Key hardcoded in die App. NIEMALS Shared-Key ausliefern. KEINE halben Uebergangsloesung fuer Kunden. KEINE Shared-Key-Bastelei in der App. Secrets NIEMALS loggen. /license/status nicht leichtfertig kaputtpatchen."
},
{
"id": "LOCK-01",
"priority": "GESPERRT",
"group": "Gesperrte Entscheidungen",
"area": "Audio / Aufnahme",
"title": "Audioaufnahme IMMER als M4A NICHT AENDERN",
"status": "gesperrt",
"description": "ENDGUELTIGE ENTSCHEIDUNG: Audioaufnahme erfolgt direkt als M4A (AAC 64kbps via ffmpeg stdin-Pipe). KEIN WAV-Zwischenschritt. WAV nur als Fallback wenn ffmpeg fehlt. Diese Regel wurde bereits einmal faelschlich gebrochen und darf NIEMALS wieder geaendert werden. Jede Aenderung an aza_audio.py muss diese Regel respektieren."
},
{
"id": "SEC-01",
"priority": "HOCH",
"group": "Sicherheits-Zielbild HIN-nahe Schutzprinzipien",
"area": "Security / Architektur",
"title": "Sicherheitszielbild fuer Browser-AZA entlang HIN-naher Schutzprinzipien konkretisieren",
"status": "offen",
"description": "Geschlossener Vertrauensraum, verifizierte digitale Identitaet (eID), 2FA, asymmetrische Verschluesselung, S/MIME, TLS, digitale Signatur, TOM, ISMS nach ISO/IEC 27001 als Zielbild, EPD-/IdP-nahe Logik. KEIN Marketing-Claim nur internes Zielbild."
},
{
"id": "SEC-02",
"priority": "HOCH",
"group": "Sicherheits-Zielbild HIN-nahe Schutzprinzipien",
"area": "Security",
"title": "Pruefen: 2FA (Zwei-Faktor-Authentisierung)",
"status": "offen",
"description": "Evaluieren und planen, wie 2FA fuer Browser-AZA und spaetere geschuetzte App umgesetzt wird. Benchmark: HIN-aehnlicher Vertrauensraum."
},
{
"id": "SEC-03",
"priority": "HOCH",
"group": "Sicherheits-Zielbild HIN-nahe Schutzprinzipien",
"area": "Security",
"title": "Pruefen: Rollenbasierte Zugriffskontrolle (RBAC)",
"status": "offen",
"description": "Rollenmodell fuer Arzt, Praxis-Admin, Support, Super-Admin definieren. Prinzip der minimalen Rechte."
},
{
"id": "SEC-04",
"priority": "HOCH",
"group": "Sicherheits-Zielbild HIN-nahe Schutzprinzipien",
"area": "Security",
"title": "Pruefen: Audit-Logs / Nachvollziehbarkeit",
"status": "offen",
"description": "Nachvollziehbare Protokollierung sicherheitsrelevanter Aktionen. Keine PHI in Logs. Aufbewahrungsfrist definieren."
},
{
"id": "SEC-05",
"priority": "HOCH",
"group": "Sicherheits-Zielbild HIN-nahe Schutzprinzipien",
"area": "Security",
"title": "Pruefen: Verschluesselung in Transit und at Rest",
"status": "offen",
"description": "TLS fuer alle Verbindungen (Transit). Verschluesselung gespeicherter Daten (at Rest) evaluieren. Benchmark: asymmetrische Verschluesselung, S/MIME wo relevant."
},
{
"id": "SEC-06",
"priority": "HOCH",
"group": "Sicherheits-Zielbild HIN-nahe Schutzprinzipien",
"area": "Security / Ops",
"title": "Pruefen: Schweizer Hosting / Datenstandort",
"status": "offen",
"description": "Sicherstellen, dass Gesundheitsdaten in der Schweiz oder einem aequivalent geschuetzten Rechtsraum gehostet werden. Hetzner-Standort pruefen."
},
{
"id": "SEC-07",
"priority": "HOCH",
"group": "Sicherheits-Zielbild HIN-nahe Schutzprinzipien",
"area": "Security / Architektur",
"title": "Pruefen: Identitaets-/Vertrauenslogik fuer spaetere geschuetzte App",
"status": "offen",
"description": "EPD-/IdP-nahe Vertrauenslogik als Orientierung. Verifizierte digitale Identitaet. Kein eigener IdP bauen, sondern etablierte Standards (OIDC, SAML) evaluieren."
},
{
"id": "SEC-08",
"priority": "HOCH",
"group": "Sicherheits-Zielbild HIN-nahe Schutzprinzipien",
"area": "Security / Compliance",
"title": "Keine ueberzogenen Aussenbehauptungen ohne Zertifizierung",
"status": "offen",
"description": "REGEL: Keine Marketing- oder Produktbehauptungen zu HIN-Zertifizierung, ISO-Zertifizierung oder EPD-Integration, solange diese nicht tatsaechlich vorliegen. Intern als Zielbild fuehren, extern nur als Orientierung kommunizieren."
},
{
"id": "DX-01",
"priority": "ERLEDIGT",
"group": "Desktop UX / Persistence",
"area": "Desktop / Installer",
"title": "Benutzerdaten bei Deinstallation erhalten",
"status": "erledigt",
"description": "Inno Setup fragt bei Deinstallation ob Benutzerdaten (%APPDATA%\\AZA Desktop) geloescht werden sollen. Standard: Nein. Daten bleiben bei Neuinstallation erhalten."
},
{
"id": "DX-02",
"priority": "ERLEDIGT",
"group": "Desktop UX / Persistence",
"area": "Desktop / UX",
"title": "Signaturlogik: Profilname als Fallback",
"status": "erledigt",
"description": "load_signature_name() faellt automatisch auf den Profilnamen zurueck wenn kein expliziter Signaturname gesetzt ist. Wirkt in Briefen, Rezepten, KoGu, OP-Berichten."
},
{
"id": "DX-03",
"priority": "ERLEDIGT",
"group": "Desktop UX / Persistence",
"area": "Desktop / UX",
"title": "Rechtsklick-Haekchen im Minifenster",
"status": "erledigt",
"description": "Im minimierten Hauptfenster dieselbe Option 'Rechtsklick = Einfuegen' wie im Vollbild. Gleiche Variable, synchronisiert, sofort wirksam."
},
{
"id": "DX-04",
"priority": "ERLEDIGT",
"group": "Desktop UX / Persistence",
"area": "Desktop / UX / KI",
"title": "Kommentare-Fenster (fertiggestellt)",
"status": "erledigt",
"description": "Vollstaendig umgesetzt: Button 'Kommentare' in Toolbar, separates Fenster, KI-Kurzkommentare via GPT, manuelles Aktualisieren, Live-Aktualisierung bei KG-Aenderung, automatisches Oeffnen nach KG-Erstellung wenn Haekchen aktiv, klickbare Diagnose-Kommentare mit Detailfenster, Tag-basiertes Highlighting."
},
{
"id": "DX-05",
"priority": "ERLEDIGT",
"group": "Desktop UX / Persistence",
"area": "Desktop / Bugfix",
"title": "Autotext Root-Cause-Fix",
"status": "erledigt",
"description": "Root Cause: _is_admin NameError verhinderte Oeffnen des Autotext-Dialogs im installierten Build. Listener-Architektur auf bewaehrten Stand (Kopie 13) zurueckgesetzt. Prozess-basierter Fokus-Check entfernt zugunsten des einfacheren FocusIn/FocusOut-Mechanismus."
},
{
"id": "DX-06",
"priority": "ERLEDIGT",
"group": "Desktop UX / Persistence",
"area": "Desktop / UX",
"title": "Signatur-UI: Haekchen + abweichender Signaturname in Einstellungen",
"status": "erledigt",
"description": "Einstellungsdialog: Haekchen 'Profilname verwenden' + Feld fuer abweichenden Signaturnamen. Wenn Haekchen aktiv: Profilname. Wenn Haekchen aus + Name: diesen verwenden. Persistenz via kg_diktat_signature.txt."
},
{
"id": "BSL-01",
"priority": "ERLEDIGT",
"group": "Briefstil-Lernen",
"area": "Desktop / KI / Brief",
"title": "Briefstil-Lernen: Architektur + DOCX-Parsing + Stilprofil-Datenmodell",
"status": "erledigt",
"description": "python-docx fuer DOCX-Parsing. Persistence: kg_diktat_brief_style_profiles.json. Datenmodell: style_prompt, source_files, source_count, created. Funktionen: load/save/get_active/set_active/extract_texts."
},
{
"id": "BSL-02",
"priority": "ERLEDIGT",
"group": "Briefstil-Lernen",
"area": "Desktop / UX",
"title": "Briefstil-Lernen: UI / Upload / Profilverwaltung",
"status": "erledigt",
"description": "Button 'Stilprofil' im Brief-Fenster. Dialog: Profilauswahl (Combobox), Mehrfach-DOCX-Upload, GPT-Stilanalyse, Profilname, Loeschen. Aktives Profil sofort sichtbar."
},
{
"id": "BSL-03",
"priority": "ERLEDIGT",
"group": "Briefstil-Lernen",
"area": "Desktop / KI",
"title": "Briefstil-Lernen: Integration in Briefgenerierung",
"status": "erledigt",
"description": "Aktives Stilprofil wird VOR der Briefgenerierung als Stil-Anweisung in den System-Prompt injiziert. Klare Abgrenzung: nur Stil/Struktur, KEINE Patientendaten/Altinhalte. Reihenfolge: Stilprofil → Briefvorlage → Generierung."
},
{
"id": "BSL-04",
"priority": "HOCH",
"group": "Briefstil-Lernen",
"area": "Desktop / KI",
"title": "Briefstil-Lernen: Erweiterungen (OFFEN)",
"status": "offen",
"description": "OFFEN: (a) Erweiterte Stilanalyse mit strukturiertem JSON statt Freitext, (b) Mehrere Profile gleichzeitig vergleichen, (c) Stilprofil-Vorschau/Zusammenfassung im Dialog, (d) Weitere Dateiformate (PDF, RTF), (e) Anonymisierungs-Pipeline fuer Trainingsinput."
},
{
"id": "PCP-01",
"priority": "ERLEDIGT",
"group": "Persistenz / Consent / Profil",
"area": "Desktop / UX / Consent",
"title": "KI-Einwilligung beim Erststart (nicht erst bei Start-Klick)",
"status": "erledigt",
"description": "Consent-Dialog wird direkt nach Fachgebiet-Auswahl im Init-Flow angezeigt, bevor die App normal weiterlaueft. Wenn bereits erteilt, wird nicht erneut gefragt."
},
{
"id": "PCP-02",
"priority": "ERLEDIGT",
"group": "Persistenz / Consent / Profil",
"area": "Desktop / Profil",
"title": "Benutzerprofil um Code (ZSR/GLN) erweitert",
"status": "erledigt",
"description": "Registrierungs- und Profil-Bearbeiten-Dialog enthalten Feld 'Code (ZSR/GLN, optional)'. Persistent in kg_diktat_user_profile.json in %APPDATA%."
},
{
"id": "PCP-03",
"priority": "ERLEDIGT",
"group": "Persistenz / Consent / Profil",
"area": "Desktop / Installer",
"title": "Deinstallations-Frage listet alle Benutzerdaten einzeln auf",
"status": "erledigt",
"description": "Inno Setup Uninstaller zeigt detaillierte Liste: Profil, Transkripte, Briefe, Vorlagen, Sichtbarkeit, Consent, Signatur, Autotext, Stilprofile. Standard: behalten."
},
{
"id": "PCP-04",
"priority": "ERLEDIGT",
"group": "Persistenz / Consent / Profil",
"area": "Desktop / UX",
"title": "Kommentare-Fenster: Toggle 'beim Start automatisch oeffnen'",
"status": "erledigt",
"description": "Einstellung 'kommentare_auto_open' in autotext_data. Haekchen in Einstellungen (LabelFrame 'Startverhalten/Fenster'). Auto-open nach 1000ms wenn aktiv. Persistent."
},
{
"id": "PCP-05",
"priority": "ERLEDIGT",
"group": "Persistenz / Consent / Profil",
"area": "Desktop / UX",
"title": "Einstellungsdialog logisch gruppiert",
"status": "erledigt",
"description": "Startverhalten/Fenster als eigener LabelFrame (Diktat, Audionotiz, Kommentare). Sichtbarkeit, Add-ons, Statusanzeige, Autotext, Signatur, Datenschutz als klare Abschnitte."
},
{
"id": "UEB-01",
"priority": "ERLEDIGT",
"group": "Uebersetzer / Stabilitaet",
"area": "Desktop / Bugfix",
"title": "Uebersetzer-Stabilitaetsfix: Tkinter-in-Thread behoben",
"status": "erledigt",
"description": "Root Cause: translate.main() wurde im frozen Build in einem Hintergrund-Thread gestartet und erzeugte tk.Tk() Tkinter ist nicht threadsafe. Fix: translate.py akzeptiert parent-Parameter und erstellt Toplevel statt Tk(). basis14.py ruft translate.main(parent=self) direkt auf dem Main-Thread auf. Kein eigener mainloop() im Embedded-Modus."
},
{
"id": "BRP-01",
"priority": "ERLEDIGT",
"group": "Briefprofile",
"area": "Desktop / KI / Brief",
"title": "KISIM Bericht als vordefiniertes Briefprofil",
"status": "erledigt",
"description": "Festes Briefstrukturprofil: Einleitung mit vidit-Zeile, Abschnitte Diagnose/Allergien/Therapie/Anamnese/Beurteilung/Diagnostik/Procedere, nummerierte Diagnosen mit ICD-10, Schlussformel mit Signatur."
},
{
"id": "BRP-02",
"priority": "ERLEDIGT",
"group": "Briefprofile",
"area": "Desktop / KI / Brief",
"title": "Klinischer Bericht als vordefiniertes Briefprofil",
"status": "erledigt",
"description": "Festes Briefstrukturprofil: Einleitung mit vidit-Zeile, pro Diagnose Untergliederung KLINIK/DIAGNOSTIK/THERAPIE/Aktuell, danach Allergien/Beurteilung/Procedere, Schlussformel mit Signatur."
},
{
"id": "BRP-03",
"priority": "ERLEDIGT",
"group": "Briefprofile",
"area": "Desktop / UX",
"title": "Berichtsprofil-Auswahl im Brief-Fenster",
"status": "erledigt",
"description": "Combobox 'Berichtsprofil' im Brief-Fenster: Standard / KISIM Bericht / Klinischer Bericht. Persistent via active_brief_profile in autotext_data. Bei Auswahl wird das Profil direkt als System-Prompt verwendet, nicht nachtraeglich umgeformt."
},
{
"id": "DX-07",
"priority": "ERLEDIGT",
"group": "Desktop UX / DevTools",
"area": "Desktop / Installer / DevOps",
"title": "AZA Clean Uninstall/Reset Tool",
"status": "erledigt",
"description": "PowerShell-Tool fuer saubere AZA-Deinstallation und Reset ohne Neustart. 2 Modi: (1) Nur App entfernen, Benutzerdaten behalten, (2) Vollstaendig zuruecksetzen inkl. Benutzerdaten. Prozesse beenden, Inno-Setup-Uninstaller silent, Restdateien/Firewall/Registry bereinigen, Installer-Ready-Meldung. Dateien: tools/aza_clean_uninstall.ps1, AZA_Deinstallieren.bat."
},
{
"id": "BRP-04",
"priority": "ERLEDIGT",
"group": "Briefprofile",
"area": "Desktop / KI / Brief",
"title": "Briefstil-Profile Fix und Nachschaerfung",
"status": "erledigt",
"description": "KISIM Bericht und Klinischer Bericht als feste Systemprofile immer im Dropdown sichtbar (nicht durch Neuinstallation/leere Datei/Loeschen entfernbar). Praezise medizinische Prompt-Definitionen mit klaren Strukturunterschieden: KISIM=Gesamtbericht mit uebergreifenden Abschnitten, Klinisch=pro Diagnose KLINIK/DIAGNOSTIK/THERAPIE/Aktuell. Vereinheitlichtes Stilprofil-System direkt im Brief-UI: Haekchen 'Stilprofil anwenden' + Dropdown (keins/Klinisch/KISIM/Benutzerprofile) + Haekchen 'Standard fuer Arztbriefe'. Medizinische Sicherheitsregeln (keine Ueberinterpretation, keine Halluzination fehlender Diagnostik). Dateien: aza_prompts.py, aza_persistence.py, aza_text_windows_mixin.py."
},
{
"id": "FIX-01",
"priority": "ERLEDIGT",
"group": "Korrektur-Patch",
"area": "Desktop / UX / Build",
"title": "Korrektur-Patch: UI-Fixes, Kommentare, Stilprofil-Live, KG-Inline, Zentrierung",
"status": "erledigt",
"description": "Sammel-Korrektur-Patch: (1) Fachuebersetzer final zu Uebersetzer umbenannt ueberall, (2) Kommentare-Fenster fertiggestellt: Haekchen auto-oeffnen, Live-Update bei KG-Aenderung, klickbare Diagnose-Kommentare mit Detailfenster, (3) Korrektur-Fenster: Scrollbar fuer Liste, (4) Stilprofil Live-Anwendung: Brief wird bei Profilwechsel sofort neu generiert, (5) Profil-anwenden-Button im Stilprofil-Dialog, (6) KG erstellen schreibt direkt ins Hauptfenster (kein Popup), (7) Persistenz: dokumente_collapsed hinzugefuegt, (8) Hauptfenster zentriert starten - robuste verzoegerte Zentrierung nach Widget-Aufbau. Dateien: basis14.py, aza_text_windows_mixin.py, aza_persistence.py, aza_config.py, version.json, CHANGELOG.md, web/index.html, deploy/*.md."
},
{
"id": "FIX-02",
"priority": "ERLEDIGT",
"group": "Nachschaerfungs-Patch",
"area": "Desktop / UX / Build",
"title": "Nachschaerfungs-Patch: Stilprofil-Dialog, Kommentare auto-open, Logo-Trennung",
"status": "erledigt",
"description": "Nachschaerfungs-Patch: (1) Stilprofil-Dialog nur noch Verwaltung (Statusanzeige, Profile anlegen/loeschen), aktive Auswahl ausschliesslich im Arztbrief-Fenster, (2) Kommentare-Fenster oeffnet sich automatisch nach KG-Erstellung wenn Haekchen gesetzt, (3) Logo-Trennung: Wassertropfen (logo.ico) fuer EXE/Desktop/Installer/Titelleiste, originales Logo (logo.png) fuer internes Branding unten links. Dateien: basis14.py, aza_text_windows_mixin.py, aza_desktop.spec."
},
{
"id": "FIX-07",
"priority": "ERLEDIGT",
"group": "Nachschaerfungs-Fixblock",
"area": "Desktop / UX / Sicherheit",
"title": "Resize-Grip Root-Cause, Korrekturfenster-UX, DocCheck-Links, Med-Kurzvorschau",
"status": "in Verifikation",
"description": "Nachschaerfungs-Fixblock: (1) Resize-Grip Root-Cause behoben: lift()+after() statt reines place(), (2) Korrekturfenster: sichtbare Falsch/Richtig-Felder OBERHALB der Korrekturliste in blauem Rahmen, (3) DocCheck-Links: search statt q Parameter fuer Flexikon-Suche, (4) Medikamenten-Kurzvorschau: _is_suspicious_med_name() Heuristik + verdaechtige Eintraege grau markiert ohne halluzinierte Infos. Dateien: aza_ui_helpers.py, basis14.py."
},
{
"id": "FIX-09/10/11",
"priority": "ERLEDIGT",
"group": "Quellenstrenge Kommentarlogik",
"area": "Desktop / KI / Medikamente",
"title": "Inhaltsquelle/Originallink Trennung + DocCheck + PharmaWiki",
"status": "in Verifikation",
"description": "FIX-11: Inhaltsquelle (Detailinhalt) und Originallink (externer Button) sauber getrennt. Inhaltsquelle: DocCheck Flexikon (Standard) + PharmaWiki (Fallback), benutzerwaehlbar + persistent (med_content_quelle). Originallink: CH=Compendium, AT=BASG, DE=BfArM unveraendert. 9/9 Medikamente verifiziert fuer beide Quellen. Kandidatenlogik unberuehrt. Dateien: basis14.py."
},
{
"id": "ARCH-MED-01",
"priority": "HOCH",
"group": "Architektur Medikamenten-Quellenlogik Schweiz",
"area": "Backend / Architektur / Medikamente",
"title": "Compendium-basierte Medikamenten-Nachschlagelogik naechste Stufe",
"status": "teilweise umgesetzt",
"description": "Erste Stufe umgesetzt (FIX-10): (1) Compendium.ch Produkt-Aufloesung (Wirkstoff → Praeparat + Darreichungsform). (2) PharmaWiki Quelltext-Extraktion (strukturierte Sektionen). (3) Kuratierte Fakten als Offline-Fallback. Naechste Stufe: (a) Compendium-Detailseiten-Extraktion (zusaetzlich zu Produkt-Aufloesung). (b) Caching-Strategie. (c) Robustheit gegen HTML-Aenderungen. (d) HCI Solutions API / Datenlizenz evaluieren."
},
{
"id": "ARCH-MED-02",
"priority": "HOCH",
"group": "Architektur Medikamenten-Quellenlogik Schweiz",
"area": "Backend / Architektur / Medikamente",
"title": "Compendium-Zugang und Datenextraktion evaluieren",
"status": "offen",
"description": "Technische Evaluation: (1) Welche Compendium.ch-Zugaenge gibt es? (API, Scraping, Datenlizenz, HCI Solutions). (2) Strukturierte Daten oder HTML-Extraktion? (3) Lizenzrechtliche Rahmenbedingungen fuer kommerzielle Nutzung. (4) Machbarkeitspruefung: Welche Felder sind extrahierbar (Indikation, Einnahme, Dosierung, Warnhinweise)? (5) Caching-Strategie (lokal vs. serverseitig). Ergebnis: Klare Empfehlung welcher Compendium-Zugangsweg fuer AZA tragfaehig ist."
},
{
"id": "DEV-V1",
"priority": "ERLEDIGT",
"group": "Lizenz-/Device-Logik V1",
"area": "Backend / Desktop / Lizenz",
"title": "ERLEDIGT: Device-/Seat-Logik V1 implementiert (2026-04-12)",
"status": "erledigt",
"description": "V1-Lizenzmodell umgesetzt: 1 aktive Lizenz = 2 gleichzeitig aktive Computer. Mehrere Lizenzen derselben Kaeufer-Email addieren sich (2 Lizenzen = 4 Geraete, 3 = 6 usw.). Backend fuehrend: _count_active_licenses() aggregiert ueber alle aktiven Lizenzen pro Email. /license/status und /license/activate liefern license_active, allowed_devices, used_devices, device_allowed, reason. Desktop sendet X-Device-Id + X-Device-Name + X-App-Version. Bei device_limit_reached: klare Benutzermeldung. Admin-Endpoint GET /admin/devices?email=... fuer Geraete-Uebersicht. Dateien: aza_device_enforcement.py (komplett), backend_main.py, admin_routes.py, basis14.py."
},
{
"id": "DEV-V1-MODEL",
"priority": "VERBINDLICH",
"group": "Projektkontinuitaet Verbindliche Regeln",
"area": "Product / Lizenz",
"title": "VERBINDLICH: V1-Lizenzmodell (1 Lizenz = 2 Geraete, Stacking)",
"status": "gesperrt",
"description": "VERBINDLICHE PRODUKTREGEL: 1 aktive Lizenz = 2 gleichzeitig aktive Computer. Dieselbe Kaeufer-Email darf mehrere Lizenzen kaufen. Die erlaubten Geraete addieren sich: 1 Lizenz = 2, 2 Lizenzen = 4, 3 Lizenzen = 6. Backend entscheidet fuehrend. Desktop sendet email + device_id an Backend. Backend liefert mindestens: license_active, allowed_devices, used_devices, device_allowed, reason. Diese Regel in allen kuenftigen Handovern wiederverwenden."
},
{
"id": "UX-DEINSTALL",
"priority": "HOCH",
"group": "Desktop UX / Installer",
"area": "Desktop / Installer / UX",
"title": "Deinstallation: Kein Zwangs-Neustart, Option jetzt/spaeter",
"status": "offen",
"description": "Nach Deinstallation darf AZA keinen sofortigen Zwangs-Neustart ausloesen. Es muss die Option geben: jetzt neu starten / spaeter neu starten. Benutzer entscheidet selbst. Datei: installer/aza_installer.iss oder Inno-Setup-Konfiguration."
},
{
"id": "BACKUP-FULL",
"priority": "HOCH",
"group": "Ops / Backup",
"area": "Ops / Security / Infrastruktur",
"title": "Vollstaendiges Backup-Konzept (lokal + Hetzner + Stripe + WordPress + Offsite Luino)",
"status": "offen",
"description": "HOHE PRIORITAET. Vollstaendiges Backup-Konzept fuer: (1) Lokale AZA-App / Code / Builds. (2) Installer-Artefakte (EXE, Setup, signierte Releases). (3) Hetzner-Backend / Server-Konfiguration / relevante Daten (stripe_webhook.sqlite, .env, Docker-Config, Caddy-Config). (4) Stripe-relevante Konfiguration und Referenzen (Webhook-URLs, Produkt-/Preis-IDs, Subscription-Daten). (5) WordPress / WooCommerce / oeffentliche Website (Hostpoint). (6) Release-/Download-Dateien (version.json, Installer, Changelog). Zusaetzlich: Offsite-Sicherheitskopie in Luino. Ziel: kein Single Point of Failure fuer Code, Daten, Konfiguration oder Kundeninformationen."
},
{
"id": "F-01",
"priority": "ZUKUNFT",
"group": "F Zukunft / Internationalisierung",
"area": "Architektur / Produkt / Quellen",
"title": "Internationalisierung / Laender- und Quellenprofile",
"status": "geparkt",
"description": "NICHT FUER JETZT. Erst nach DACH-Stabilitaet (CH/DE/AT) und Produkterfolg. Zielbild: (1) UI-Sprache je nach Markt anpassbar (app_language). (2) Medikamentenquellen je nach Land (med_source_profile). (3) Diagnose-/Therapiequellen je nach Land (dx_source_profile, therapy_source_profile). (4) market_region als uebergreifendes Profil. (5) Manueller Override durch Benutzer/Praxis. Nicht hart nach Herkunftsland schalten, sondern saubere Profil-Logik. Handelsnamen, Zulassungen, Fachinfos und Verfuegbarkeit sind laenderspezifisch deshalb spaeter Quellenprofile pro Markt. Beispiel: DACH zuerst, spaeter franzoesische UI + franzoesische med. Quellen/Links. Relevant erst nach Go-Live und DACH-Erfolg."
}
]
}