Files
aza/AzA march 2026/project_todos.json
2026-04-16 13:32:32 +02:00

854 lines
50 KiB
JSON
Raw 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.
{
"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."
}
]
}