505 lines
23 KiB
Markdown
505 lines
23 KiB
Markdown
|
|
# AZA - Master Handover / Operational Runbook
|
|||
|
|
|
|||
|
|
## Working Mode Rules
|
|||
|
|
|
|||
|
|
- User does not tinker or manually edit files.
|
|||
|
|
- Always provide 1:1 Composer patches (usually Opus).
|
|||
|
|
- One step at a time.
|
|||
|
|
|
|||
|
|
## CURRENT PROJECT PHASE (2026-03-27)
|
|||
|
|
|
|||
|
|
**Phase:** B1 Backend Sprint COMPLETE – Variant B proven in production
|
|||
|
|
|
|||
|
|
**STATUS: B1 Backend Sprint FULLY COMPLETE (2026-03-27)**
|
|||
|
|
- B1-W1 through B1-W5 all successfully completed
|
|||
|
|
- Desktop → Hetzner → OpenAI works in the real app
|
|||
|
|
- No local OpenAI key needed for main path
|
|||
|
|
- `basis14.py` locally tested against live backend successfully
|
|||
|
|
|
|||
|
|
**Hetzner Backend is LIVE (2026-03-26)**
|
|||
|
|
- Production API path: `https://api.aza-medwork.ch`
|
|||
|
|
- DNS: `api.aza-medwork.ch` → `178.104.51.177`
|
|||
|
|
- Repo on Hetzner: `/root/aza-app`
|
|||
|
|
- Deploy directory: `/root/aza-app/deploy`
|
|||
|
|
- Running services: `aza-api` + `aza-caddy`
|
|||
|
|
- Variant B technically proven end-to-end
|
|||
|
|
|
|||
|
|
**ARCHITECTURE DECISION VARIANT B (mandatory, 2026-03-25):**
|
|||
|
|
- NO OpenAI key in the desktop app
|
|||
|
|
- NO per-customer OpenAI key requirement
|
|||
|
|
- NO shared OpenAI key client-side
|
|||
|
|
- Instead: AZA Office talks ONLY to own AZA backend
|
|||
|
|
- Only the AZA backend talks to OpenAI
|
|||
|
|
- The OpenAI key resides EXCLUSIVELY server-side
|
|||
|
|
- NO half-measures, NO shared-key hacks
|
|||
|
|
|
|||
|
|
**Successful Proofs (2026-03-26):**
|
|||
|
|
- `curl https://api.aza-medwork.ch/health` → successful
|
|||
|
|
- `curl -X POST https://api.aza-medwork.ch/v1/chat` with valid `X-API-Token` → success:true, content:OK
|
|||
|
|
- Proven: Hetzner backend runs, Caddy/HTTPS runs, server-side OpenAI access works, Variant B works end-to-end
|
|||
|
|
|
|||
|
|
**Root Causes Solved During Deploy:**
|
|||
|
|
1. Wrong git remote (`naswinterthur`) was unsuitable
|
|||
|
|
2. Uploading only `deploy/` was wrong – `docker-compose.yml` expects repo root context (`context: ..`, `dockerfile: deploy/Dockerfile`)
|
|||
|
|
3. Host `nginx` blocked port 80
|
|||
|
|
4. Caddy DNS/ACME issues due to resolver `127.0.0.53` → Fix: explicit DNS `1.1.1.1` + `8.8.8.8` in caddy service
|
|||
|
|
|
|||
|
|
**Final Hetzner State:**
|
|||
|
|
- Services: `aza-api` + `aza-caddy`
|
|||
|
|
- Compose runs from `/root/aza-app/deploy`
|
|||
|
|
- `.env` is production-relevant there
|
|||
|
|
- `AZA_DOMAIN=api.aza-medwork.ch`
|
|||
|
|
- `ACME_EMAIL=info@aza-medwork.ch`
|
|||
|
|
- `MEDWORK_API_TOKENS` is set productively
|
|||
|
|
- `OPENAI_API_KEY` is set server-side
|
|||
|
|
|
|||
|
|
## B1 BACKEND SPRINT (4 Weeks)
|
|||
|
|
|
|||
|
|
| Week | Approx. Dates | Focus |
|
|||
|
|
|------|--------------|-------|
|
|||
|
|
| **1** | Mar 25 – Apr 01 | Backend Chat Proxy Endpoint (POST /v1/chat) + Auth + Rate Limiting |
|
|||
|
|
| **2** | Apr 02 – Apr 08 | Desktop app: all OpenAI calls via backend instead of direct |
|
|||
|
|
| **3** | Apr 09 – Apr 15 | Hetzner Deploy: Docker/Caddy/HTTPS + Production Env + Smoke Tests |
|
|||
|
|
| **4** | Apr 16 – Apr 22 | E2E Test Desktop→Backend→OpenAI + Customer journey without OpenAI key + Go-Live |
|
|||
|
|
|
|||
|
|
## CURRENT PRIORITY ORDER (B1 Backend Sprint)
|
|||
|
|
|
|||
|
|
1. **Backend Chat Proxy POST /v1/chat** (Week 1) – Foundation of architecture
|
|||
|
|
2. **Desktop app migration to backend** (Week 2) – Migrate all OpenAI calls
|
|||
|
|
3. **Hetzner Deploy** (Week 3) – Set up production server
|
|||
|
|
4. **E2E Test + Go-Live backend path** (Week 4) – Customer journey without OpenAI key
|
|||
|
|
5. WooCommerce/Stripe purchase path runs IN PARALLEL (Hostpoint)
|
|||
|
|
|
|||
|
|
**EXPLICITLY DEFERRED / NOT NOW:**
|
|||
|
|
- Update comfort / separate auto-updater
|
|||
|
|
- Browser-AZA web app (after backend architecture)
|
|||
|
|
- Large refactors not serving Variant B
|
|||
|
|
|
|||
|
|
**HOSTPOINT vs. HETZNER:**
|
|||
|
|
- Hostpoint remains for website/marketing/WooCommerce/Stripe
|
|||
|
|
- Hetzner is NOW the backend path for OpenAI proxy/API
|
|||
|
|
- Both run in parallel, not against each other
|
|||
|
|
|
|||
|
|
## DONE: B1-W1 Backend Chat Proxy Endpoint (2026-03-26)
|
|||
|
|
|
|||
|
|
**POST /v1/chat – IMPLEMENTED AND VERIFIED.**
|
|||
|
|
|
|||
|
|
| Aspect | Detail |
|
|||
|
|
|---|---|
|
|||
|
|
| Auth | `require_api_token` (X-API-Token header, existing pattern) |
|
|||
|
|
| Rate Limiting | `default_ip_limiter` + `default_token_limiter` |
|
|||
|
|
| Request Schema | `ChatRequest`: model, messages[], temperature?, max_tokens?, top_p? |
|
|||
|
|
| Message Schema | `ChatMessage`: role (system/user/assistant), content |
|
|||
|
|
| Model Whitelist | gpt-5.2, gpt-5-mini, gpt-5-nano, gpt-4o, gpt-4o-mini, gpt-4o-mini-search-preview |
|
|||
|
|
| Input Limits | Max 64 messages, max 100k chars/message |
|
|||
|
|
| OpenAI Call | `_get_openai().chat.completions.create(**params)` server-side |
|
|||
|
|
| Response Schema | `{success, content, finish_reason, model, usage, request_id, duration_ms, error}` |
|
|||
|
|
| Secret Scrubbing | `sk-`, `sk-proj-`, `org-` in error texts are replaced |
|
|||
|
|
| Tests | 7/7 green (auth, model, validation, OpenAI proxy, /license/status, schema) |
|
|||
|
|
|
|||
|
|
**File:** `backend_main.py` (~100 lines added)
|
|||
|
|
|
|||
|
|
## DONE: B1-W2 Desktop Chat Migration (2026-03-26)
|
|||
|
|
|
|||
|
|
**Desktop app: Chat completions now routed through backend POST /v1/chat.**
|
|||
|
|
|
|||
|
|
**Migrated:**
|
|||
|
|
1. `call_chat_completion()` in basis14.py – central wrapper -> `_backend_chat_completion()`
|
|||
|
|
2. News search – direct `self.client` call -> `_backend_chat_completion()`
|
|||
|
|
3. Comments – own `OpenAI()` client -> `_backend_chat_completion()`
|
|||
|
|
4. Med detail short info – own `OpenAI()` client -> `_backend_chat_completion()`
|
|||
|
|
5. Letter style analysis in `aza_text_windows_mixin.py` -> `_backend_chat_completion()`
|
|||
|
|
|
|||
|
|
**New architecture in basis14.py:**
|
|||
|
|
- `_BackendChatResponse` – wrapper class, OpenAI-interface compatible (.choices[0].message.content, .usage)
|
|||
|
|
- `_backend_chat_completion(**kwargs)` – POST /v1/chat using existing token mechanism (get_backend_url/get_backend_token)
|
|||
|
|
- `call_chat_completion(**kwargs)` – consent/capacity check, then `_backend_chat_completion()`
|
|||
|
|
- Timeout: 5s connect, 120s read
|
|||
|
|
- Errors: RuntimeError with readable message, no secrets
|
|||
|
|
|
|||
|
|
**Remaining for later blocks:** translate.py, congress_window.py, aza_email.py (standalone modules)
|
|||
|
|
|
|||
|
|
**7/7 tests green:** Health, Auth, Model validation, E2E Desktop->Backend->OpenAI, Response schema, /license/status OK.
|
|||
|
|
|
|||
|
|
## DONE: B1-W3 Hetzner Deploy (2026-03-26)
|
|||
|
|
|
|||
|
|
**Hetzner backend is LIVE.**
|
|||
|
|
|
|||
|
|
| Aspect | Detail |
|
|||
|
|
|---|---|
|
|||
|
|
| Domain | `https://api.aza-medwork.ch` |
|
|||
|
|
| DNS | `api.aza-medwork.ch` → `178.104.51.177` (A record) |
|
|||
|
|
| Repo on Hetzner | `/root/aza-app` |
|
|||
|
|
| Deploy directory | `/root/aza-app/deploy` |
|
|||
|
|
| Running services | `aza-api` + `aza-caddy` |
|
|||
|
|
| Compose | runs from `/root/aza-app/deploy` |
|
|||
|
|
| `.env` production | `AZA_DOMAIN=api.aza-medwork.ch`, `ACME_EMAIL=info@aza-medwork.ch`, `MEDWORK_API_TOKENS` set, `OPENAI_API_KEY` set server-side |
|
|||
|
|
|
|||
|
|
## DONE: B1-W4 Server E2E Test (2026-03-26)
|
|||
|
|
|
|||
|
|
**Server-side Variant B proven end-to-end:**
|
|||
|
|
- `curl https://api.aza-medwork.ch/health` → successful
|
|||
|
|
- `curl -X POST /v1/chat` with valid `X-API-Token` → success:true, content:OK
|
|||
|
|
|
|||
|
|
## DONE: B1 Desktop Finalization (Code Patches, 2026-03-27)
|
|||
|
|
|
|||
|
|
**All code patches for Variant B in the desktop app are verified and correct:**
|
|||
|
|
|
|||
|
|
| Patch | Status | Detail |
|
|||
|
|
|---|---|---|
|
|||
|
|
| `ensure_ready()` | CORRECT | Remote backend counts as ready (no local OpenAI key needed) |
|
|||
|
|
| OpenAI key setup dialog | CORRECT | Dialog suppressed when remote backend configured |
|
|||
|
|
| `backend_url.txt` | CORRECT | Points to `https://api.aza-medwork.ch` |
|
|||
|
|
| `backend_token.txt` | CORRECT | Primary local token source, prioritized by app |
|
|||
|
|
| `start_all.bat` guard | CORRECT | Variant B protection: does not overwrite URL for live backend |
|
|||
|
|
| `start_backend_autoport.bat` guard | CORRECT | Variant B protection: does not overwrite URL for live backend |
|
|||
|
|
| Chat/text path | CORRECT | Routes through `POST {backend_url}/v1/chat` |
|
|||
|
|
|
|||
|
|
**Token priority (confirmed):** `backend_token.txt` > Env `MEDWORK_API_TOKENS` > Env `MEDWORK_API_TOKEN`
|
|||
|
|
|
|||
|
|
**Backend URL priority (confirmed):** Env `MEDWORK_BACKEND_URL` > `backend_url.txt`
|
|||
|
|
|
|||
|
|
**Unchanged side paths (do NOT block main test):**
|
|||
|
|
- `translate.py`, `aza_email.py`, `apps/diktat/diktat_app.py` still have local OpenAI clients → side paths only
|
|||
|
|
- `kongress2_window.py` has hardcoded URL → congress feature is parked
|
|||
|
|
|
|||
|
|
## DONE: B1-W5 Local Desktop Live Test (2026-03-27)
|
|||
|
|
|
|||
|
|
**Desktop → Hetzner → OpenAI successfully tested in the real app.**
|
|||
|
|
|
|||
|
|
- `backend_url.txt` points to `https://api.aza-medwork.ch`
|
|||
|
|
- `backend_token.txt` locally present, accepted by live backend
|
|||
|
|
- `basis14.py` started locally and successfully tested against live backend
|
|||
|
|
- No local OpenAI key needed
|
|||
|
|
- No OpenAI key dialog appears
|
|||
|
|
- Chat/text path routes through Hetzner backend
|
|||
|
|
|
|||
|
|
**Desktop-specific notes (for future chats):**
|
|||
|
|
- `ensure_ready()` is correctly patched for remote backend
|
|||
|
|
- OpenAI key dialog suppressed when remote backend configured
|
|||
|
|
- Do NOT use local starters for live test (`start_all.bat`, `RUN_AZA_ONECLICK.bat`, `START_AZA.bat`, `start_backend_autoport.bat`) – they set env to localhost
|
|||
|
|
- Preferred start method: `python basis14.py` directly
|
|||
|
|
|
|||
|
|
## CURRENT MAIN BLOCK: License/Subscription Lifecycle (from 2026-03-27)
|
|||
|
|
|
|||
|
|
**Goal:** Reliably tie license status to subscription payment.
|
|||
|
|
|
|||
|
|
**Scope:**
|
|||
|
|
1. License active as long as subscription is paid
|
|||
|
|
2. Fall back to test mode / restricted mode when user cancels or stops paying
|
|||
|
|
3. Check app/license status reliably
|
|||
|
|
4. Do NOT break existing `/license/status` structure
|
|||
|
|
5. No premature auth/API contract changes
|
|||
|
|
|
|||
|
|
## PARALLEL BLOCK: WooCommerce / Stripe Live Setup (from 2026-03-27)
|
|||
|
|
|
|||
|
|
**Goal:** Make payment flow production-ready including payout to bank account.
|
|||
|
|
|
|||
|
|
**Scope:**
|
|||
|
|
1. Complete WooCommerce/Stripe configuration
|
|||
|
|
2. Prepare live payment flow
|
|||
|
|
3. Ensure payouts go to user's bank account
|
|||
|
|
4. Validate test purchase / payment flow
|
|||
|
|
|
|||
|
|
## CURRENT SUBSCRIPTION PRICES (2026-03-27)
|
|||
|
|
|
|||
|
|
| Plan | Monthly | Yearly |
|
|||
|
|
|---|---|---|
|
|||
|
|
| **1 User (Basic)** | CHF 59 | CHF 590 |
|
|||
|
|
| **2 Users (Team)** | CHF 89 | CHF 890 |
|
|||
|
|
|
|||
|
|
**Stripe Lookup Keys and Price IDs:**
|
|||
|
|
|
|||
|
|
| Lookup Key | Price ID | Amount |
|
|||
|
|
|---|---|---|
|
|||
|
|
| `aza_basic_monthly` | `price_1T53xHL5lREAW68VbuK43lmz` | CHF 59 |
|
|||
|
|
| `aza_basic_yearly` | `price_1T542BL5lREAW68VNLQGCKWZ` | CHF 590 |
|
|||
|
|
| `aza_team_monthly` | `price_1T544tL5lREAW68VkmnmZ21Q` | CHF 89 |
|
|||
|
|
| `aza_team_yearly` | `price_1T545RL5lREAW68VLbIh73AN` | CHF 890 |
|
|||
|
|
|
|||
|
|
**OPEN REQUIRED DOCUMENTATION – Stripe Account:**
|
|||
|
|
- Active Stripe account (login / email): NOT YET DOCUMENTED
|
|||
|
|
- Test mode or live mode currently active: NOT YET DOCUMENTED
|
|||
|
|
- Bank account for payouts configured: NOT YET DOCUMENTED
|
|||
|
|
- Webhook active and URL: NOT YET DOCUMENTED
|
|||
|
|
- Leading success/cancel URLs: NOT YET DOCUMENTED
|
|||
|
|
These items must be documented before the first real customer purchase.
|
|||
|
|
|
|||
|
|
## DONE: Stripe Live Webhook Stabilized (2026-03-27)
|
|||
|
|
|
|||
|
|
**Status:** Webhook returns 200 OK. License entry written to SQLite.
|
|||
|
|
|
|||
|
|
**Solved problems:**
|
|||
|
|
1. **StripeObject vs dict:** Code used `.get(...)` on raw Stripe objects → `AttributeError: get`. Fix: parse event as `json.loads(body)` after signature verification.
|
|||
|
|
2. **`.to_dict_recursive()` does not exist** in the installed stripe-python version. Never use it.
|
|||
|
|
3. **Double prefix 404:** `main.py` mounts router with `prefix="/stripe"`. Using `@router.post("/stripe/webhook")` creates `/stripe/stripe/webhook`. Correct: `@router.post("/webhook")`.
|
|||
|
|
4. **Email lookup:** `customer_email` is often null. Cascade: `session.customer_email` → `session.customer_details.email` → `stripe.Customer.retrieve(id)`.
|
|||
|
|
5. **Container env trap:** `.env` was correct but container had stale values. `docker compose restart` is not enough. Correct: `docker compose up -d --build --force-recreate aza-api`.
|
|||
|
|
|
|||
|
|
**NEVER AGAIN – Stripe Webhook Rules:**
|
|||
|
|
- Never use `.to_dict_recursive()` – does not exist in all stripe-python versions
|
|||
|
|
- Never use `.get(...)` on raw StripeObjects
|
|||
|
|
- After signature verification, always parse as plain JSON: `event = json.loads(body)`
|
|||
|
|
- For `Subscription.retrieve()` / `Customer.retrieve()`: use `json.loads(str(obj))`
|
|||
|
|
- Always consider prefix routing in FastAPI: with `prefix="/stripe"`, decorator must be `@router.post("/webhook")`
|
|||
|
|
- For Stripe `.env` changes: `docker compose up -d --build --force-recreate aza-api`, not just `restart`
|
|||
|
|
|
|||
|
|
**Operational reference Hetzner:**
|
|||
|
|
- Working backup: `/root/aza-app/stripe_routes.py.working_backup`
|
|||
|
|
- SQLite DB: `/root/aza-app/data/stripe_webhook.sqlite`
|
|||
|
|
- Logs: `docker logs -f --tail 20 aza-api`
|
|||
|
|
|
|||
|
|
## EXPLICITLY DEFERRED (Polish Phase)
|
|||
|
|
|
|||
|
|
- Autotext fix
|
|||
|
|
- Window sizes adjustment
|
|||
|
|
- Button sizes / layout for online presentation
|
|||
|
|
- General UI polish
|
|||
|
|
- Clean up direct OpenAI side paths in secondary modules (translate.py, aza_email.py, diktat_app.py)
|
|||
|
|
|
|||
|
|
**Blocker Rule:** One clear block at a time.
|
|||
|
|
|
|||
|
|
## CUSTOMER JOURNEY ANALYSIS (2026-03-25)
|
|||
|
|
|
|||
|
|
| Step | Status | Detail |
|
|||
|
|
|---|---|---|
|
|||
|
|
| Purchase (WooCommerce) | IN PROGRESS (parallel) | Docs ready, 7 admin steps on Hostpoint |
|
|||
|
|
| Download | PARTIAL | Mechanism exists, WooCommerce upload missing |
|
|||
|
|
| Installer | FUNCTIONALLY COMPLETE | No code signing (SmartScreen warning) |
|
|||
|
|
| Activation | BRIDGE IMPLEMENTED | AZA key sets full mode, trial dialog shows status |
|
|||
|
|
| First Start | VARIANT B LIVE (2026-03-27) | Desktop → Hetzner → OpenAI works. No local OpenAI key needed. |
|
|||
|
|
|
|||
|
|
## FOCUS BLOCKS
|
|||
|
|
|
|||
|
|
| Priority | Block | Description |
|
|||
|
|
|---|---|---|
|
|||
|
|
| DONE | B1-W1: Backend /v1/chat | Chat Proxy Endpoint – foundation of Variant B |
|
|||
|
|
| DONE | B1-W2: Desktop migration | All OpenAI calls in basis14.py + mixin via backend |
|
|||
|
|
| DONE | B1-W3: Hetzner Deploy | Backend LIVE on api.aza-medwork.ch |
|
|||
|
|
| DONE | B1-W4: Server E2E | /health + /v1/chat successful, Variant B server-side proven |
|
|||
|
|
| DONE | B1-W5: Desktop Live Test | basis14.py locally tested against live backend (2026-03-27) |
|
|||
|
|
| DONE | Stripe Live Webhook | Webhook 200 OK, license entry in DB, StripeObject/routing/env traps solved (2026-03-27) |
|
|||
|
|
| **CURRENT** | License/Subscription Lifecycle | Tie license to subscription, fallback on cancellation |
|
|||
|
|
| **PARALLEL** | WooCommerce / Stripe Live | Payment flow + payout to bank account |
|
|||
|
|
| DEFERRED | UI Polish | Autotext fix, window sizes, buttons, layout |
|
|||
|
|
| DEFERRED | FB-C: Signing | Signing readiness prepared |
|
|||
|
|
| DEFERRED | FB-D: Update Comfort | Only after stable customer journey |
|
|||
|
|
|
|||
|
|
## PRODUCT NAME – CURRENT DIRECTION
|
|||
|
|
|
|||
|
|
**Current favorite:** AZA Office
|
|||
|
|
|
|||
|
|
**Preferred long form:**
|
|||
|
|
- **AZA Office – Ihr medizinischer KI-Arbeitsplatz fuer die Praxis**
|
|||
|
|
|
|||
|
|
**Second good variant:**
|
|||
|
|
- AZA Office – Die KI-Assistenz fuer medizinische Dokumentation
|
|||
|
|
|
|||
|
|
**Status:** Current preferred naming direction. Not yet legally/brand-strategically finalized. Use for WooCommerce/website/download/Go-Live/product presentation.
|
|||
|
|
|
|||
|
|
**Earlier shortlist (AZA Desktop):** Documented in project_roadmap.json and project_plan.json. Superseded by AZA Office.
|
|||
|
|
|
|||
|
|
## WORKING PRINCIPLES FOR NEXT CHATS
|
|||
|
|
|
|||
|
|
- Root-cause-first instead of blind patching
|
|||
|
|
- One clear block at a time
|
|||
|
|
- No 10 construction sites simultaneously
|
|||
|
|
- Weight real installed builds higher than code assertions
|
|||
|
|
- Don't declare "done" too early
|
|||
|
|
- Distinguish Desktop into:
|
|||
|
|
1. Dev code
|
|||
|
|
2. Newly built installer
|
|||
|
|
3. Real behavior in installed build
|
|||
|
|
|
|||
|
|
**COMMUNICATION NOTE (2026-03-27):**
|
|||
|
|
- In next chat do NOT re-explain server deploy from scratch – Hetzner is live
|
|||
|
|
- Do NOT re-discuss Caddy/nginx/DNS/TLS – it is completed
|
|||
|
|
- Do NOT re-debate Variant A/B – Variant B is mandatory and productive
|
|||
|
|
- Do NOT re-prioritize shop/translate/naming
|
|||
|
|
- Do NOT keep repeating rm/cleanup commands
|
|||
|
|
- B1 desktop live test is DONE – do not reopen
|
|||
|
|
- Go directly to: License/Subscription logic + WooCommerce/Stripe live setup
|
|||
|
|
- Secure product/customer journey
|
|||
|
|
- Weight real behavior higher than old assumptions
|
|||
|
|
|
|||
|
|
## Current Local Workspace
|
|||
|
|
|
|||
|
|
**CURRENT PATH (from 2026-03-27):**
|
|||
|
|
```
|
|||
|
|
C:\Users\surov\Documents\AZA_GIT\aza\AzA march 2026
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**OLD PATH (HISTORICAL, do not use):**
|
|||
|
|
```
|
|||
|
|
C:\Users\surov\Documents\AZA\backup 24.2.26
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Key Commands
|
|||
|
|
|
|||
|
|
**Preferred start method for live test against Hetzner backend:**
|
|||
|
|
```
|
|||
|
|
cd "C:\Users\surov\Documents\AZA_GIT\aza\AzA march 2026"
|
|||
|
|
python basis14.py
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**DO NOT use for live test (set env to localhost):**
|
|||
|
|
- `start_all.bat`, `RUN_AZA_ONECLICK.bat`, `START_AZA.bat`, `start_backend_autoport.bat`
|
|||
|
|
|
|||
|
|
**Local dev start (only for local development with own backend):**
|
|||
|
|
```
|
|||
|
|
cd "C:\Users\surov\Documents\AZA_GIT\aza\AzA march 2026"
|
|||
|
|
powershell -ExecutionPolicy Bypass -File .\deploy\local_reset_and_start.ps1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Tests:**
|
|||
|
|
```
|
|||
|
|
cd "C:\Users\surov\Documents\AZA_GIT\aza\AzA march 2026"
|
|||
|
|
powershell -ExecutionPolicy Bypass -File .\deploy\authorized_status.ps1
|
|||
|
|
powershell -ExecutionPolicy Bypass -File .\deploy\smoke_suite.ps1
|
|||
|
|
powershell -ExecutionPolicy Bypass -File .\deploy\docker_smoke.ps1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Desktop UX Block (2026-03-18)
|
|||
|
|
|
|||
|
|
- Benutzerdaten bei Deinstallation erhalten (Inno Setup, Standard: Nein)
|
|||
|
|
- Signatur-UI: Haekchen "Profilname verwenden" + abweichender Signaturname in Einstellungen
|
|||
|
|
- Rechtsklick-Haekchen im Minifenster (synchronisiert)
|
|||
|
|
- Kommentare-Fenster (TEILWEISE: Grundstruktur, Detailmodus + Live-Update offen)
|
|||
|
|
- Briefstil-Lernen (DOCX-Upload, Stilprofil-Analyse, Profilauswahl, Integration)
|
|||
|
|
- Briefstil-Profile Fix: KISIM/Klinisch als feste Systemprofile, vereinheitlichtes Stilprofil-UI im Brief-Bereich
|
|||
|
|
- Autotext Root-Cause-Fix (_is_admin NameError, Listener-Revert)
|
|||
|
|
- Persistenz-Patch: Erststart-Consent, Profil+Code, Kommentare-Toggle, Einstellungs-Gruppierung
|
|||
|
|
- Uebersetzer-Stabilitaetsfix: Toplevel-Embedded statt Tkinter-in-Thread
|
|||
|
|
- Briefprofile: KISIM Bericht + Klinischer Bericht als vordefinierte Profile
|
|||
|
|
|
|||
|
|
## AZA Clean Uninstall / Reset Tool
|
|||
|
|
|
|||
|
|
**Per Doppelklick:** `AZA_Deinstallieren.bat`
|
|||
|
|
|
|||
|
|
**Per PowerShell:**
|
|||
|
|
```
|
|||
|
|
powershell -ExecutionPolicy Bypass -File .\tools\aza_clean_uninstall.ps1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- Modus 1: Nur App entfernen, Benutzerdaten behalten
|
|||
|
|
- Modus 2: Vollstaendig zuruecksetzen (App + Benutzerdaten)
|
|||
|
|
- Kein Neustart noetig (Standardfall)
|
|||
|
|
- Danach direkt Neuinstallation moeglich
|
|||
|
|
|
|||
|
|
## Do-Not-Break Rules
|
|||
|
|
|
|||
|
|
1. Do not change existing API response formats (especially /license/status).
|
|||
|
|
2. Do not modify auth/security mechanisms.
|
|||
|
|
3. Do not log or print secrets/tokens/keys.
|
|||
|
|
4. Signature fallback: profile name used when no explicit signature set.
|
|||
|
|
5. User data in %APPDATA%\AZA Desktop NOT deleted on uninstall by default.
|
|||
|
|
6. Style learning from old letters: only style/structure, NEVER copy patient data or old content.
|
|||
|
|
|
|||
|
|
## Correction Patch (FIX-01) – 2026-03-19
|
|||
|
|
|
|||
|
|
1. Translator label: "Fachuebersetzer" renamed to "Uebersetzer" everywhere
|
|||
|
|
2. Comments window: auto-open checkbox (persistent), live-update on KG change, clickable diagnosis headings with detail popups
|
|||
|
|
3. Correction window: scrollbar for saved corrections list
|
|||
|
|
4. Style profile live application: brief regenerated immediately on profile change/toggle
|
|||
|
|
5. "Profil anwenden" button in style profile management dialog
|
|||
|
|
6. KG creation writes directly to main window (no popup)
|
|||
|
|
7. Persistence: dokumente_collapsed now properly saved/loaded
|
|||
|
|
8. Main window centering: robust delayed centering after widget build via self.after()
|
|||
|
|
|
|||
|
|
## FIX-02 Nachschaerfungs-Patch (2026-03-19)
|
|||
|
|
|
|||
|
|
1. Style profile dialog: now management-only (status display, learn, delete). Active selection exclusively in brief window.
|
|||
|
|
2. Comments window: auto-opens after KG creation when checkbox is active (not just refreshes existing window).
|
|||
|
|
3. Logo separation: Wassertropfen (logo.ico) for EXE/desktop/installer/title bar icon. Original logo (logo.png) for internal branding (bottom-left).
|
|||
|
|
|
|||
|
|
Files: basis14.py, aza_text_windows_mixin.py, aza_desktop.spec, logo.png, logo.ico
|
|||
|
|
|
|||
|
|
## FIX-09/10/11 Quellenstrenge Kommentarlogik – Inhaltsquelle / Originallink Trennung (2026-03-22)
|
|||
|
|
|
|||
|
|
Root Cause (FIX-09): LLM generated medication info purely from model knowledge.
|
|||
|
|
Root Cause (FIX-10): PharmaWiki regex wrong (used h2/h3 instead of span#subtitle). Compendium.ch is SPA (not scrapable).
|
|||
|
|
Root Cause (FIX-11): Content source and external link were mixed in one dropdown/dict.
|
|||
|
|
|
|||
|
|
Fix (FIX-11): Clean separation of content source and external link:
|
|||
|
|
|
|||
|
|
**CONTENT SOURCE** (what is shown in detail window):
|
|||
|
|
- `_fetch_doccheck_info(med_name)`: DocCheck Flexikon (default) – server-rendered, h2/h3 headings
|
|||
|
|
- `_fetch_pharmawiki_info(med_name)`: PharmaWiki (fallback) – span#subtitle headings
|
|||
|
|
- User-selectable via "Inhaltsquelle:" dropdown, persistent in `med_content_quelle`
|
|||
|
|
- New dict `_MED_CONTENT_QUELLEN` (DocCheck, PharmaWiki)
|
|||
|
|
- Curated `_MEDICATION_FACTS` as offline fallback
|
|||
|
|
|
|||
|
|
**EXTERNAL LINK** ("Originalquelle oeffnen" button):
|
|||
|
|
- CH = Compendium, AT = BASG, DE = BfArM – UNCHANGED
|
|||
|
|
- Still via `_MED_QUELLEN` / `medikament_quelle` – NOT modified
|
|||
|
|
|
|||
|
|
Therapies/procedures: separate handling via DocCheck/PharmaWiki (unchanged).
|
|||
|
|
Candidate logic (Dermowarte→Dermovate etc.): untouched.
|
|||
|
|
|
|||
|
|
Files: basis14.py
|
|||
|
|
|
|||
|
|
## ARCH-MED: Medication Source Architecture (2026-03-22)
|
|||
|
|
|
|||
|
|
Architecture (implemented):
|
|||
|
|
1. Detect medication in KG text (existing tagging + validation)
|
|||
|
|
2. Fetch content from DocCheck Flexikon (default) or PharmaWiki (user choice/fallback)
|
|||
|
|
3. Inject source text into LLM prompt (strict: only use provided data)
|
|||
|
|
4. Curated facts list as offline fallback
|
|||
|
|
5. External link always country-based (CH/AT/DE)
|
|||
|
|
6. Omit anything not from the source
|
|||
|
|
|
|||
|
|
Coverage: All medications available on DocCheck Flexikon + PharmaWiki.
|
|||
|
|
|
|||
|
|
Next steps:
|
|||
|
|
1. Caching strategy (cache fetched content locally)
|
|||
|
|
2. Robustness against HTML structure changes
|
|||
|
|
3. Long-term: Compendium API / HCI Solutions data license evaluation
|
|||
|
|
|
|||
|
|
Later market profiles (DE: BfArM, AT: BASG) separately.
|
|||
|
|
|
|||
|
|
## Zukunftsblock – Internationalisierung / Laender- und Quellenprofile (GEPARKT)
|
|||
|
|
|
|||
|
|
**Status:** Zukunftsthema – NICHT fuer jetzt. Erst nach DACH-Stabilitaet und Produkterfolg.
|
|||
|
|
|
|||
|
|
**Voraussetzung:** DACH (CH/DE/AT) stabil, Go-Live gesichert, Produkt erfolgreich.
|
|||
|
|
|
|||
|
|
**Zielbild:**
|
|||
|
|
- UI/Sprache, Medikamenten-/Diagnose-/Therapiequellen pro Markt anpassbar
|
|||
|
|
- Profil-Felder: app_language, market_region, med_source_profile, dx_source_profile, therapy_source_profile
|
|||
|
|
- Manueller Override durch Benutzer/Praxis
|
|||
|
|
- Nicht hart nach Herkunftsland schalten – saubere Profil-Logik
|
|||
|
|
- Handelsnamen/Zulassungen/Fachinfos sind laenderspezifisch → Quellenprofile pro Markt
|
|||
|
|
|
|||
|
|
**Kein aktueller Implementierungsblock.** Erst nach Go-Live und DACH-Erfolg relevant.
|
|||
|
|
|
|||
|
|
## Windows Code-Signing / Smart App Control Readiness (2026-03-23)
|
|||
|
|
|
|||
|
|
**Problem:** Windows Smart App Control blockiert unsignierte Apps bei Kunden.
|
|||
|
|
|
|||
|
|
**Status:** Signing-Readiness vorbereitet, noch NICHT produktiv aktiviert.
|
|||
|
|
|
|||
|
|
**Vorbereitet:**
|
|||
|
|
- `sign_release.ps1` – signiert EXE + DLLs/PYDs + Installer (DryRun-Modus verfuegbar)
|
|||
|
|
- `build_and_test_release.ps1` – Signing-Schritt integriert (optional, graceful skip)
|
|||
|
|
- `build_release_artifacts.ps1` – Artefakt-Report mit Signatur-Status
|
|||
|
|
- `SIGNING_READINESS.md` – Vollstaendige Dokumentation
|
|||
|
|
|
|||
|
|
**Signing-Reihenfolge:** DLLs/PYDs → EXE → Installer-Build → Installer signieren → Artefakt-Report
|
|||
|
|
|
|||
|
|
**Vor Kundenauslieferung noch offen:**
|
|||
|
|
1. EV Code-Signing-Zertifikat beschaffen
|
|||
|
|
2. signtool.exe installieren (Windows SDK)
|
|||
|
|
3. Publisher-Name abstimmen (Zertifikat ↔ AppPublisher ↔ Handelsregister)
|
|||
|
|
4. Produktiver Signierlauf + Test auf Windows-PC mit Smart App Control
|
|||
|
|
|
|||
|
|
**Publisher-/Namenskonsistenz (Analyse 2026-03-23):**
|
|||
|
|
|
|||
|
|
3 Namensformen im Projekt – beabsichtigt, keine Inkonsistenz:
|
|||
|
|
- **AZA MedWork** = Firma/Publisher → SIGNING-KRITISCH (Installer, Legal, Consent, E-Mail-Absender)
|
|||
|
|
- **AZA Desktop** = Produktname → konsistent, kein Handlungsbedarf
|
|||
|
|
- **AZA Medical AI Assistant** = interner Projektname → nicht signing-relevant
|
|||
|
|
|
|||
|
|
Vor Zertifikatskauf: HR-Name pruefen, AppPublisher auf Zertifikats-Subject abstimmen.
|
|||
|
|
Falls HR-Name abweicht: alle signing-relevanten Stellen gemeinsam anpassen (Liste in handover.md).
|
|||
|
|
Nach Festlegung: Publisher-Name NICHT mehr wechseln (SmartScreen-Reputation).
|