Release Notes — 27 maja 2026
Tydzień po wielkim release Outlooka i AvailabilityTypeId SSOT — kolejna duża paczka. Centralnym tematem są drobne, ale dotykające codziennej pracy ulepszenia kalendarza: wirtualne tła w pokojach video, konfigurowalna granularność slotów (od 5 do 60 min) z osobnym pickerem godzin i minut w modal’u “Dodaj sesję”, oraz porządek w workflow ustawień — krok rezerwacji i toggle płatności przeniesione z modal’u sesji do Dostępności, gdzie ich miejsce. Drugi nurt to hardening integracji Outlook (poprawki AADSTS error mapping, account type, retry, scope drift). Trzeci — PDF-y dostały logo TherapySupport i jednolitą stopkę (SCRUM-1625 — Bohdan). Czwarty — aits-agent migruje z Claude SDK na Azure OpenAI GPT-5.5 z round-robin pool, żeby ominąć rate limity i kosztować mniej.
💚 Podziękowania dla zespołu testowego: Martyny, Magdaleny, Małgorzaty, Joanny, Gosi, fantasticolikante oraz Bohdana — każdy z Was zgłosił coś, co wylądowało w tym release’ie.
1. 🎥 Wirtualne tła i mocny blur w pokojach video LiveKit
W sesjach video pojawiła się długo oczekiwana opcja: virtual backgrounds oraz mocny blur tła. Funkcjonalność oparta o LiveKit Track Processors (machine-learning model uruchamiany lokalnie w przeglądarce — żadne klatki video nie opuszczają urządzenia). Wybór tła zapamiętany w localStorage per urządzenie.
- Trzy presety: blur (mocny) — gaussian blur z radius 24, soft blur — radius 12, virtual background — wybór z 6 predefiniowanych obrazów (gabinet, biuro, neutralna ściana, abstrakcja, mountain view, ocean).
- Toggle “Tło” w pasku kontrolek pokoju video — overlay z miniaturkami i preview.
- Performance: lokalny model GPU-accelerated (gdy dostępne), fallback do CPU. Na słabszym sprzęcie automatyczne wyłączenie z toastem ostrzegającym (Web Worker timeout 3s).
Co to daje terapeutom: profesjonalny wygląd nawet przy pracy z domu, większa prywatność (dziecko w tle, bałagan, otwarte okno na ulicę) — wszystko bez zewnętrznego software’u typu OBS.
2. 🕐 Konfigurowalna granularność slotów + picker godzin/minut
Duży refaktor logiki rezerwacji. Wcześniej dostępność zawsze była dzielona na pełne godziny (toggle “Pełne godziny”), a modal “Dodaj sesję” miał jeden time picker który nie współpracował z 5/10-minutowymi blokami. Teraz pełna konfiguracja per terapeuta.
Zmiana w Ustawieniach → Dostępność
- Toggle “Pełne godziny” zastąpiony selektorem 5 / 10 / 15 / 30 / 60 min (
SlotGranularityMinutes— INT NOT NULL DEFAULT 60 naTherapistProfile). - Migracja
AddSlotGranularityMinuteswcześniej padała na DEV — backfill rozdzielony na osobnyUPDATE, terazALTER + UPDATEw jednymIF NOT EXISTSbloku (defensywnie). - Widoczność rodzaju sesji (Stacjonarna/Online) w widoku Dostępności —
AvailabilityType.IsOnlinejako badge.
Zmiana w modal’u “Dodaj sesję” (SessionForm)
- Picker godzin i minut osobno — dwa dropdowny zamiast jednego
<input type="time">. Lista minut filtrowana poSlotGranularityMinutes(5 min → [0, 5, 10, …, 55], 10 min → [0, 10, …, 50], etc.). - Diagnostyka selektora — log do konsoli przy mismatchu między granulacją a dostępnymi minutami.
- Granularność dziedziczona z profilu terapeuty (fetchowana raz przy load formularza).
Reorganizacja workflow ustawień
- “Krok rezerwacji” (pełne godziny / 30 min / 15 min) — przeniesione z modal’u “Dodaj sesję” do Ustawienia → Dostępność, gdzie ma logiczne miejsce.
- Toggle “Wymagaj płatności z góry” — analogicznie przeniesiony z modal’u sesji.
- Blokuj zapisy publiczne online (
PublicBookingEnabled) — toggle dostępny w Dostępności (powiela się z sekcją “Profil publiczny”, ale jest tu dla wygody — częsta operacja przy urlopie).
Co to daje: terapeuci pracujący w 15-minutowych blokach (krótkie konsultacje, follow-upy) mogą wreszcie ustawić to spójnie. Praca Bohdana + diagnostyka Martyny.
3. 🔧 Outlook / Microsoft Graph — hardening po pierwszym tygodniu produkcji
Tydzień po starcie integracji Outlook (release 20 maja) zebraliśmy raporty z terenu i wprowadziliśmy serię ulepszeń odporności. Praca Bohdana.
- Mapowanie błędów AADSTS — Microsoft zwraca błędy autoryzacji w formacie
AADSTS<code>: <message>(np.AADSTS50076— wymagane MFA,AADSTS70008— refresh token expired). Wcześniej te błędy lądowały w logach jakoOAuthExceptionbez kontekstu. TerazMicrosoftOAuthService.MapAadstsErrordekoduje kod i mapuje na konkretnyOutlookConnectionErrorenum, frontend pokazuje terapeucie czytelny komunikat (“Wymagana ponowna autoryzacja w Twojej organizacji” zamiast “Microsoft Auth Error”). - Account type detection —
OutlookCalendarServicewykrywa, czy konto to Personal (@outlook.com,@hotmail.com) czy Work/School (Azure AD tenant). Personal nie ma capability Microsoft Teams meeting auto-create — wcześniejIsOnlineMeeting=truerzucał 403; teraz graceful skip + log + event tworzy się bez Teams linku. - Retry z exponential backoff — wszystkie wywołania Graph API mają teraz retry policy (3 próby, 1s/3s/9s) na transient errors (429/500/502/503/504). Wcześniej pojedyncze 429 wywalały całą operację.
- Scope drift detection — gdy refresh token nie zawiera już oczekiwanych scope’ów (Microsoft potrafi je odebrać po zmianie polityki w tenant’cie), service oznacza
TherapistMicrosoftToken.RequiresReauth=truei frontend pokazuje banner “Połącz Outlook ponownie” zamiast cichego failowania. OutlookCalendarImportService— analogiczna logika dla importu wydarzeń: SCRUM-1640 (Bohdan) —EventAlreadyImportedExceptionzamiast generycznego “Konflikt” gdy event był już zaimportowany. Komunikat “To wydarzenie zostało już wcześniej zaimportowane jako sesja AITS” + odświeżanie listy per-provider (Google/Outlook/Apple osobno).docs/contexts/integrations-outlook.mdzaktualizowany o sekcję “Error handling matrix” — tabela AADSTS codes → user-facing message.
4. 📄 Logo TherapySupport + stopka we wszystkich PDFach (SCRUM-1625)
Wszystkie generowane PDF-y (transkrypty sesji, konceptualizacje, restrukturyzacje, formularze, faktury) dostały jednolitą stopkę z datą wydruku, wersją aplikacji, znakiem TherapySupport oraz logiem w prawym górnym rogu. Praca Bohdana.
- Stopka 3-kolumnowa: data wydruku (lewy), TherapySupport (centrum), wersja (prawy).
- Logo SVG embed w prawym górnym rogu pierwszej strony.
- Hotfix po pierwszej iteracji: usunięcie
build dateze stopki — wbudowywało się timestamp commit’a, co tworzyło osobny PDF per deploy mimo identycznej treści (paranoja audytorów). - Adres terapeuty w klauzuli pacjenta —
BusinessAddress + kod + miasto + krajjako jeden string (MultiLineAddress). Wcześniej poleBusinessAddresszawierało tylko ulicę → klauzula była niekompletna prawnie. - Klauzula RODO dla zalogowanego pacjenta —
/legal/klauzula-pacjentpodstawia dane terapeuty ({therapistName},{therapistAddress},{therapistEmail}) dynamicznie zamiast hardcoded placeholders.
5. 📝 Ogólne notatki do pacjenta — niezależne od sesji (SCRUM-1623)
Zgłoszenie Martyny. Wcześniej notatki w panelu pacjenta były zawsze przyczepione do konkretnej sesji — nie było miejsca na ogólne uwagi typu “skierowanie do psychiatry”, “preferuje wieczory”, “alergia na leki SSRI”. Teraz osobna sekcja “Ogólne notatki” na karcie pacjenta z autozapisem.
- Backend: nowe pole
Patient.GeneralNotes(Always Encrypted nvarchar(max) — dane medyczne, RODO art. 9), endpointPUT /api/patients/{id}/general-notes. - Frontend: nowa zakładka
GeneralNotesTabzTextAreaautozapisującym po 1s debounce. - Hotfix #1: cascada toastów “Zapisano” przy load (load triggerował dirty flag → autosave po 1s → toast). Stabilizacja
toastref przezuseRef. - Hotfix #2: limit 4000 znaków na froncie blokował długie notatki, choć backend trzyma
nvarchar(max). Limit zdjęty.
6. 🔔 Historia wysłanych powiadomień (SCRUM-1631)
Zgłoszenie Martyny. Sekcja w Ustawienia → Powiadomienia pokazująca historię ostatnich 100 powiadomień wysłanych z systemu do pacjentów terapeuty (email + SMS + in-app). Każdy wpis: data, kanał, odbiorca, szablon, status (delivered / failed), preview treści.
- Backend: nowy widok
vw_TherapistNotificationHistory(LEFT JOINNotificationLogzPatientpoRecipientId), endpointGET /api/therapist/notifications/history?limit=100. - Frontend: tabela z filtrem po kanale + statusie + datą, expandable row z pełną treścią szablonu (po decryptowaniu — content jest Always Encrypted).
- Use case: terapeuta widzi “wysłałem przypomnienie SMS — czy doszło”, bez konieczności pytania pacjenta.
7. 💳 Stripe trial-only checkout — dla warsztatu PTTPB 2026
Specjalny flow rejestracji dla uczestników warsztatu Polskiego Towarzystwa Terapii Poznawczo-Behawioralnej (PTTPB) w 2026 roku.
- Nowy SubscriptionType
trial-pttpb-2026— 30-dniowy darmowy trial bez wymaganej karty. - Bez UI Stripe Checkout — zamiast redirect na
checkout.stripe.com, backend bezpośrednio tworzySubscriptionztrial_end=+30di inline user provisioning (rejestracja + email aktywacyjny + auto-login w jednym callbacku). /pttpb-2026Payment Link w Stripe Dashboard zclient_reference_id= email uczestnika (preloaded z formularza warsztatu).- Po 30 dniach automatyczna konwersja na płatną subskrypcję wymaga dodania karty — webhook
customer.subscription.trial_will_end(3 dni przed) wysyła reminder mail.
Cross-RG moduł role assignment usunięty z Bicep — deploy z service principalem padał na “Authorization failed” (SP nie miał scope na resource group warsztatu).
8. 🤖 aits-agent — migracja na Azure OpenAI GPT-5.5 + round-robin pool
Tydzień produkcji aits-agent (pilot na Container Apps) ujawnił dwa problemy: Claude OAuth padał co kilka godzin (subskrypcja flapowała) i rate limit 429 na pojedynczym deploymencie GPT-5.5 blokował kolejne joby. Oba rozwiązane.
- Migracja wszystkich handlerów na Azure OpenAI GPT-5.5 —
jira-triage,jira-analyse,ddd-audit,weekly-report,pr-review,telegram-chat. Claude SDK wymontowane z workera. - Round-robin deployment pool — wzór z AITS
AiModelPoolService: 10× deploymentgpt-5-5-1..10na kontoaits-ai-prod, worker losuje jeden per request. Każdy deployment niezależny TPM quota → 10× headroom. AiModelPoolServicew workerze —acquireDeployment()retry-on-different-deployment przy 429 (max 3 attempts), graceful break przy całkowitym faulu (wszystkie 10 zwracają 429 → log error + skip job, retry za 5 min).- Content filter 400 — Azure OpenAI sporadycznie zwraca 400 z
code=content_filterdla nieszkodliwych wejść (false positive). Obsługa: try alternative deployment, jeśli też 400 — log + skip + telegram alert. openaiSDK config —maxRetries: 0 → 1,timeout: 60s(kompromis: 429 retry przez nasz pool, ale jeden retry SDK na transient TCP error daje sens).runAgentOpenAIcapture intermediate content — gdy maxTurns wyczerpane bezfinal_message, brałem ostatniąassistantwiadomość jako result (zamiast zwracać pusty string). Plus forced final przy maxTurns ztool_choice: "none".- Weekly email —
timeout 30s → 60s+ guard na pustyfinalText(zamiast wysyłać pusty mail). Wcześniejtool_choicebeztoolsw request body dawał 400 — naprawione. - diag commits (
865cb2bb,edfe8b2f) — log lifecycle wrunAgentOpenAI+ jawny AAD token fetch. Doprowadziły do zlokalizowania bugu, zostały w kodzie jako trwała obserwowalność.
Nowy feature: ddd-audit-apply — auto-PR z aktualizacją context docs
- Po audycie DDD (
/audit-ddd) agent wysyła telegram z propozycją zmian wdocs/contexts/**. - Terapeuta/admin zatwierdza w Telegramie (“apply” / “skip per file”) → agent tworzy branch
auto/ddd-audit-YYYY-MM-DD, commit per plik, draft PR. - Idempotent: ten sam audit przy 2× apply nie tworzy 2× PR.
9. 🔁 auto-fix-ticket — autonomiczna pętla napraw Jira
Nowy slash-command /auto-fix-ticket (i sam skill w ~/.claude/skills/). Pobiera wszystkie otwarte SCRUM bugi nieoznaczone etykietą auto-analysed, analizuje każdy, implementuje fix na dedykowanym branchu auto/SCRUM-XXX, otwiera draft PR przeciwko dev i wysyła Telegram notification. Zero pytań do użytkownika między krokami.
- Fail-safe: każdy ticket osobny branch, błąd w jednym nie blokuje kolejnych.
- Idempotent: label
auto-analyseddodawany po przejściu — drugi run pomija. - Workflow przewidziany do uruchomienia w lokalnym cronie (np. raz dziennie o 4:00 rano).
- Z tego flow powstał PR
auto/SCRUM-1427(fantasticolikante: LanguageSwitcher dla pacjentów) — pierwszy ticket naprawiony autonomicznie.
10. 🛠️ Admin transcription tool — stereo per-channel diarization
Nowe narzędzie w panelu administratora do transkrypcji dwukanałowego audio (stereo: terapeuta lewy kanał / pacjent prawy) z osobną diaryzacją per kanał — eliminuje błędy “kto-do-kogo-mówi” w głośnych nagraniach. Praca Bohdana.
- Mode selector:
auto(single-channel z Whisper diarization) /mono(zsumuj kanały) /per-channel(stereo split → 2× transkrypcja → merge timestamps). - Upload limit bump: 500 MB → 5 GB (długie sesje grupowe, warsztaty całodzienne).
nginx.client_max_body_size: 200m → 5g. - Async/polling: upload triggeruje background job, frontend pollu status — omijamy 240s ingress timeout Container Apps na długich plikach.
- Workflow: admin uploaduje (drag-drop), wybiera tryb, dostaje JSON output + SRT + plain text per speaker.
11. 🚀 Wstrzymanie zapisów online + opt-in respektowania zewn. kalendarzy (hotfix 21 maja)
Hotfix wgrany na PROD 21 maja. Modal “Dodaj sesję” w terapeuty od 20 maja domyślnie respektował zajętość z Google / Outlook / Apple Calendar (część SCRUM-1378 — public booking). Niestety dla terapeutów którzy mają eventy “all day” lub “block” w prywatnych kalendarzach, lista wolnych slotów była pusta.
Fix: zewn. kalendarze respektowane opt-in — toggle “Uwzględniaj zajętość z kalendarzy zewnętrznych” w Ustawienia → Integracje (default false dla therapist-side, true dla patient-side). Patient-side booking bez zmian (SCRUM-1378 nadal aktywne).
12. 🎯 ServiceType dropdown w widoku szczegółów sesji
Nowy dropdown w SessionDetailViewNew pozwalający terapeucie zmienić typ usługi (TherapistAvailabilityType — np. “Konsultacja”, “Sesja CBT”, “Sesja par”) po fakcie utworzenia sesji. Wcześniej trzeba było usunąć i utworzyć od nowa.
- Dropdown filtrowany po
AvailabilityType.IsOnlinematchingSession.MeetingType. - Update endpoint:
PUT /api/sessions/{id}/availability-type. - Spójne z Variant B (
AvailabilityTypeIdSSOT z release 20 maja).
Drobne poprawki (bug fixes)
- SCRUM-1277 (Joanna): usunięcie ID sesji z kontekstu AI konceptualizacji — prompt zawierał
SessionId=12345jako część kontekstu wysyłanego do LLM. Bez biznesowego znaczenia + niepotrzebny PII vector. Usunięte z buildera kontekstu (SessionContextBuilder.cs). - SCRUM-1427 (fantasticolikante): LanguageSwitcher widoczny dla pacjentów i terapeutów — komponent przełącznika języków był rendrowany tylko gdy user.role === Anonymous (na stronach publicznych). Dodany do
NavBarpo lewej stronie avatara dla wszystkich ról. - SCRUM-1602 (Bohdan): patient profile audio upload via SAS — upload notatki głosowej w profilu pacjenta szedł multipart przez API (240s timeout, OOM przy >100MB). Przepisane na SAS: backend generuje pre-signed URL, frontend wrzuca bezpośrednio do Azure Blob, backend dostaje webhook z BlobId.
- SCRUM-1606 (Bohdan): MAUI Recorder auto-resume po telefonie — przerwanie recordingu przez interrupt audio (połączenie telefoniczne, alarm) zostawiało nagranie zatrzymane. Teraz
AVAudioSession.InterruptionNotificationz opcją.shouldResume→ recorder.resume() automatycznie po zakończeniu rozmowy. - SCRUM-1607 (Martyna): nieprawidłowy link do pokoju online w mailu —
SessionMeetLinkbył liczony w 3 miejscach (mail template, frontend, push notification) z różnymi rezultatami przy edge case’ach (sesja AITS Video bez przypisanego pokoju). Refaktor: jedenISessionMeetLinkResolverjako single source of truth. Druga iteracja w PR #164: niespójność url-template (część maili miałahttps://, częśćhttp://). - SCRUM-1608 (Bohdan): sesje odwołane przez pacjenta po terminie w rejestrze zaległych płatności — sesja anulowana po jej rozpoczęciu była dalej widoczna w “zaległe płatności” mimo statusu Cancelled. Query w
FinanceService.GetOutstandingSessionsdodał warunekSession.StatusId != Cancelled. - SCRUM-1609 (Martyna): per-session payment link + relabel “RequirePaymentUpfront” —
RequirePaymentUpfront(globalny toggle) zmieniony na per-session (nadpisanie zSession.RequirePaymentUpfront). Plus relabel UI: “Wymagaj zapłaty przed sesją” zamiast technicznego “Płatność z góry”. - SCRUM-1614 (Martyna): “Najbliższa sesja” widoczna do końca sesji + 10 min grace — widget “Najbliższa sesja” znikał o
StartDateTimezamiast po jej zakończeniu (terapeuta tracił szybki dostęp do linku w czasie trwania). Fix: widoczny doEndDateTime + 10 min(grace dla overrun). - SCRUM-1621 (Martyna + Gosia): wywiad konsultacji znika po nawigacji — dwie różne przyczyny: (1) Martyna — wywiad rozwojowy “Brak danych” mimo zapisanych pól dzieciństwa, fix w
PatientInterviewQueryService(LEFT JOIN zamiast INNER); (2) Gosia — wywiad konsultacji znikał po przejściu na inną zakładkę i powrocie, fix: defer blob delete (DeleteAsyncz opóźnieniem 5s, blokowany jeśli komponent się remountuje). - SCRUM-1637 (Bohdan + Małgorzata): AITS Video room mismatch — terapeuta i pacjent lądowali w różnych pokojach gdy sesja była bulk-created (już naprawione w SCRUM-1597). Druga warstwa: anonimowy video join (bez tokenu) filtrował sesje po
MeetingType == AITS, więc zaproszenia “external link” (Zoom/Meet/Teams) padały na 404. Filtr usunięty — anonymous join akceptuje wszystkieMeetingType. - SCRUM-1641 (Bohdan): portal pacjenta — resend invite + reset hasła po edycji email — terapeuta edytował email pacjenta z lewizny (np. typo) i nie miał jak ponownie wysłać zaproszenia. Dodane dwa buttony w panelu pacjenta: “Wyślij ponownie zaproszenie” (gdy
EmailConfirmed=false) + “Wyślij link resetu hasła” (gdyEmailConfirmed=true). - SCRUM-1642 (Magdalena): fallback na segmenty w
GetOrRehydrateAsync— podsumowanie działa gdyTranscriptTextpuste — niektóre stare sesje (przed migracją na blob storage) miałyTranscriptText=NULL, aleTranscriptionSegmentsz timestampami. Generowanie podsumowania AI padało na “TranscriptText is empty”. Fix: jeśli text NULL → rekonstruuj z segmentów (string.Join(" ", segments.Select(s => s.Text))). - MAUI block upload retry na 401 + exempt
/api/auth/refreshz legal compliance — MAUI klient retry’ował 401 z legal compliance gate (modal “zaakceptuj regulamin”), wpadając w nieskończoną pętlę. Fix: 401 z legal compliance → break retry + sygnalizacja UI. Plus/api/auth/refreshwyłączone z legal compliance middleware (jajko-kura: refresh tokenu wymagał zalogowania, zalogowanie wymagało aktualnego tokenu). - AnalysisApprovalControls przeniesione na górę w Restrukturyzacji poznawczej — w ABC controls są na górze tabu, w Restrukturyzacji były na dole, terapeuci scrollowali. Spójność z ABC.
- TwentyCRM
__GatewayUrlpoints to actual gateway host — env var wskazywał nacrm.aitherapy.supportale gateway sluchał nacrm-twentyCRM-gateway.aitherapy.support. Fix env w Container App + dokumentacja w[[reference_crm_vm]]. - nodemailer SNI — nodemailer validate TLS cert przeciwko
localhostzamiastwebd.plprzy custom domain VHost (mail zaits-agent). Fix: explicittls.servername: 'webd.pl'. - Notifications fallback base URL —
therapysupport.pl(legacy domena) zastąpiony przezapp.aitherapy.supportw fallbackach gdyRequest.Hostjest pusty.
Infrastruktura i dokumentacja
docs/contexts/integrations-outlook.md— sekcja “Error handling matrix” (AADSTS codes → user-facing message) + diagram retry flow.docs/coding-playbook.md— sekcja “Bumping PR through dev to main” (jeden commit per ticket + jak rozdzielać scope).- SCRUM-1519, 1529 (Bohdan): docs polish (Phase 4) — clean
verify-ddd-docsprzejście dla wszystkich kontekstów L1-L4 (zero errors, zero warnings). - DDD audit apply — nowy ścieżka workflow w
aits-agent(sekcja 8). docs/contexts/transcription.mdzaktualizowany o admin transcription tool (sekcja 10).- CLAUDE.md: dopisana sekcja “push do
devbez pytania o zgodę” — po commicie pushuj od razu, deploy na DEV jest tani. - Container Apps auto-cleanup — workflow CI/CD usuwa stare rewizje (Multiple revision mode) starsze niż 24h żeby nie zalegały w panelu Azure.
QA Checklist
| Co testuje | Jak | Status |
|---|---|---|
| Wirtualne tła w pokoju video | Wejdź do sesji → toggle “Tło” → wybierz blur / VBG → tło zmienia się lokalnie | ✅ |
| Granularność slotów 5 min | Ustawienia → Dostępność → 5 min → modal “Dodaj sesję” pokazuje 5-min sloty | ✅ |
| Granularność slotów 30 min | Ustawienia → Dostępność → 30 min → modal pokazuje co 30 min | ✅ |
| Time picker godziny/minuty | SessionForm → osobny dropdown godzin i osobny minut | ✅ |
| “Krok rezerwacji” w Dostępności | Ustawienia → Dostępność → toggle “Krok rezerwacji” obecny (nie w modal’u sesji) | ✅ |
| Toggle “Wymagaj płatności” w Dostępności | Ustawienia → Dostępność → toggle obecny | ✅ |
| Outlook AADSTS error message | Symuluj 70008 → user widzi “Wymagana ponowna autoryzacja” zamiast generic error | ✅ |
| Outlook personal account graceful | Połącz konto @outlook.com → sesja Teams się tworzy bez linku, ale nie failuje | ✅ |
| Outlook retry on 429 | Symuluj 429 na Graph API → retry 3× z backoff → finalnie sukces | ✅ |
| SCRUM-1640 Calendar import dedup | Importuj event 2× → drugi raz pokazuje “już zaimportowany” zamiast “konflikt” | ✅ |
| Logo TherapySupport w PDF | Wygeneruj transkrypt sesji → logo w prawym górnym rogu pierwszej strony | ✅ |
| Stopka PDF — data wydruku | PDF stopka pokazuje aktualną datę (nie build date) | ✅ |
| Klauzula pacjenta — adres terapeuty | Otwórz /legal/klauzula-pacjent jako zalogowany pacjent → adres terapeuty pełny | ✅ |
| SCRUM-1623 Ogólne notatki autosave | Wpisz tekst w GeneralNotes → po 1s pojawia się toast “Zapisano” (raz!) | ✅ |
| SCRUM-1623 Limit znaków | Wklej >4000 znaków → input nie blokuje | ✅ |
| SCRUM-1631 Historia powiadomień | Ustawienia → Powiadomienia → Historia → ostatnie 100 zdarzeń widoczne | ✅ |
| Stripe trial-only PTTPB | /pttpb-2026 link → rejestracja bez karty → konto aktywne na 30 dni | ✅ |
| aits-agent telegram-chat | /help w Telegramie → bot odpowiada bez 429 | ✅ |
| Round-robin AI pool | Wymuś 5 jobów równolegle → wszystkie kończą sukcesem (różne deploymenty) | ✅ |
| ddd-audit-apply | /audit-ddd → akceptuj per plik w Telegram → PR auto/ddd-audit-* powstaje | ✅ |
| auto-fix-ticket | /auto-fix-ticket SCRUM-XXX → branch auto/SCRUM-XXX + draft PR | ✅ |
| Admin transcription stereo | Upload stereo MP3 → wybierz “per-channel” → JSON ma 2 speakers | ✅ |
| Upload 2GB plik | Upload 2GB MP4 → nie pada na 240s timeout (async/polling) | ✅ |
| Hotfix 21-maja — external busy opt-in | Ustawienia → Integracje → toggle OFF → modal “Dodaj sesję” pokazuje sloty | ✅ |
| ServiceType dropdown po fakcie | Otwórz istniejącą sesję → zmień typ usługi → zapisuje się | ✅ |
| SCRUM-1277 SessionId w prompt | Wygeneruj konceptualizację AI → prompt log nie zawiera SessionId | ✅ |
| SCRUM-1427 LanguageSwitcher | Zaloguj jako pacjent → widoczny w NavBar | ✅ |
| SCRUM-1602 SAS audio upload | Upload notatki głosowej 50MB → nie pada na timeout | ✅ |
| SCRUM-1606 MAUI auto-resume | Nagrywaj → odbierz telefon → po zakończeniu nagranie wznawia się | ✅ |
| SCRUM-1607 Link pokoju online w mailu | Wyślij przypomnienie sesji → link działa (nie 404) | ✅ |
| SCRUM-1608 Anulowane sesje | Anuluj sesję po jej terminie → znika z “zaległe płatności” | ✅ |
| SCRUM-1609 Per-session payment link | Sesja z RequirePaymentUpfront=true → link do płatności widoczny | ✅ |
| SCRUM-1614 “Najbliższa sesja” grace | Sesja się skończyła → widget widoczny przez 10 min | ✅ |
| SCRUM-1621 Wywiad rozwojowy | Wypełnij dzieciństwo → wróć po 5 min → dane są | ✅ |
| SCRUM-1637 Video room anonymous | Anonimowy gość z linkiem zewnętrznym Teams → wchodzi do pokoju | ✅ |
| SCRUM-1641 Resend invite | Edytuj email pacjenta → kliknij “Wyślij ponownie zaproszenie” → mail przychodzi | ✅ |
| SCRUM-1642 Podsumowanie ze segmentów | Sesja z TranscriptText=NULL ale z segmentami → podsumowanie się generuje | ✅ |
Artykuł przygotowany przez zespół Therapy Support