Product Updates

Release Notes — April 26, 2026

Release Notes — April 26, 2026

19 days ago we shipped a big release with the diagnostic module and prosody analysis. Since then the team pushed another 295 changes — and they’re not small. In this release you can record an ad-hoc session before the patient even arrives, your notes merge with AI work and transcription side-by-side in three columns, the public therapist profile is back in full force, and the mobile app now has a dark theme. Under the hood we went through a SOC 2 / HIPAA hardening pass, a DDD audit, and full pseudonymization of patient data on the AI side.

💚 Thanks to the team that drove this release — through reports, tests, code, and patience:

  • Bohdan — ad-hoc sessions, package limits and grace period, DDD audit, KSeF invoices, dozens of fixes (SCRUM-756, 815, 1267, 1268, 1276, 1280-1290, 1293, 1309-1316, 1353-1357, 1366, 1388, 1391, 1392)
  • Bartek — 3-way merge, 9 separate CBT analyses, cognitive distortions, package session counter (SCRUM-1266, 1320, 1338, 1368-1375, 1385, 1386)
  • Ewa Cylwik / Ewa — Beck PDF, second AITS session for the same patient, mobile dark theme and empty state, multilingual mailing, UI colors, patient email uniqueness (SCRUM-883, 898, 902, 1089, 1094, 1297, 1304, 1307, 1319)
  • Joanna — recurring calendar, hiding Zoom, on-time cancellation, self-reflection instead of session quality rating (SCRUM-789, 874, 918, 919, 1005)
  • Plus Bartlomiej for cognitive distortions and the session counter, which became the foundation of the new subscription model

1. ⚡ Ad-hoc sessions — record before the patient arrives

If you’ve ever had to flip on a recorder fast — because a patient walked in unannounced, because it’s a one-time consultation, because it’s a meeting with someone not yet in your records — the new ad-hoc session module solves that whole pain point.

  • Quick Record Button in the web dashboard, in PWA on phone, and in the MAUI app — one click starts recording before you even fill in the patient’s data
  • AdHoc Inbox — a dedicated tray for unassigned recordings until you decide where they go
  • AssignPatientModal — assign the recording to an existing patient or create a new one straight from the inbox
  • Resume / Re-enter room — finish recording a session you started earlier
  • Orphan retention + auto-complete — sessions unassigned for X days auto-close so the inbox stays tidy
  • Video “Start without patient” — in the LiveKit room you can begin a session without colliding with an existing patient; the AdHoc lands in the inbox afterward

The section is gated behind the PromptyAI code in Settings — off by default, for users who want to see the rest first. Designed and shipped by Bohdan.

2. 📊 Package limits and grace period — transparent subscription

Subscriptions got a full overhaul. The old Starter/Standard plans are deactivated, replaced by Start / Practice / Pro — sized for actual session volume per month.

  • Session counter on dashboard — see how many sessions you’ve used this month and how many remain in your package
  • Limit emails — automatic notifications at 80% and 100% utilization
  • Upgrade prompt — when you hit the limit, you get a gentle plan-change suggestion instead of a hard block
  • Pricing from Stripe + discounts — the price you see in the app comes directly from Stripe with active discounts applied (the betatester code does not expire)
  • Native subscription cancel — cancel directly in the app, no need to email support
  • 14-day grace period — if a payment fails, you get 14 days with access to your own account only (no patient previews), with T+0 and T+13 emails. Real data loss only kicks in after two weeks
  • Subscription banner — clean message at the top of the app with no empty bar between the menu and the alert
  • Session limit simulator — in the PromptyAI panel there’s a test mode where you can see how the app behaves on a full package

Joint work by Bartlomiej (counter and limits, SCRUM-1266) and Bohdan (subscription, grace, upgrade prompt — SCRUM-756, SCRUM-1366, SCRUM-1391, SCRUM-1392).

3. 📝 3-way merge for notes — therapist, AI and transcription in one view

This is one of the biggest architectural changes under the hood, but the effect on day-to-day work is highly visible: every notes field (Notes, SessionSummary, conceptualization sections) now separately remembers what the therapist wrote, what AI generated, and what came from the dictaphone / transcription.

  • Notes 3-way — the notes view shows three sources side-by-side: your text, AI suggestions, and automatic transcription, and you choose what to keep
  • SessionSummary 2-way + JSON merge — in the session summary you merge your work with the AI analysis into a single coherent document
  • Timestamp separator — when you edit an AI field manually, the system leaves a visible trace of when and whose fragment that is
  • [AI] marker from first generation — your fields don’t blend with generated ones
  • SourceBadge — colorful pill with an icon showing where a fragment comes from, instead of UPPERCASE text
  • AI section replacement instead of appending — when you ask for re-generation of the summary, AI replaces the section instead of stacking another copy underneath

Designed and shipped by Bartek (SCRUM-1320, SCRUM-1368-1375). Underneath: full i18n in 8 languages and new DDD contexts.

4. 🔍 CBT analyses — 9 separate on-demand reports

The old monolithic “generate CBT analysis” was split into 9 separate items that the therapist runs when they actually need them. Less waiting, more control.

  • 9 independent analyses — each generated separately, on demand
  • Prompt edit cog — click the cog next to each analysis to see/modify the prompt AI will use
  • CBT ANALYSES section behind PromptyAI code — section available after entering the code in Settings, for users testing new features

Cognitive distortions got their own view (reported by Bartlomiej, SCRUM-1385):

  • Data view instead of an AI report — you see concrete quotes from the transcription tagged by AI, not a narrative generated from them
  • All quotes after expand — no date range filter, expand reveals everything
  • Available in the main menu — under Conceptualization v2

The old COGNITIVE_DISTORTIONS_INVENTORY prompt has been removed (SCRUM-1386).

5. 🌐 Public therapist profile — full revamp with edit drawers

The public profile under the aitherapy.support brand has been fully rebuilt.

  • 3 new edit drawers — bio, specializations, contact details edited in elegant side panels
  • Owner edit mode — when you view your own profile while logged in, edit buttons are right at hand
  • Years of experience — new YearsOfExperience field visible on the public profile
  • Color rebrand — sage/lavender palette under the aitherapy.support brand
  • “Your privacy” section removed — it was redundant; GDPR is in the footer
  • Lucide icons — modern, clean icon typography

Underneath, a public endpoint GET /api/public/therapists was added — returning therapists with active public profiles. Foundation for a therapist directory.

6. 🎥 Video sessions — PiP, swap cameras, fixed background blur

Video got a set of fixes that any therapist running sessions through the app will notice.

  • PiP / minimize — minimize the video room to a floating mini-player and check notes in another tab without breaking the connection. Mic and camera keep working
  • Swap cameras — switch who’s in the main view and who’s in mini with one click
  • PiP resume — coming back from minimization, you skip the lobby (PreJoinLobby) and jump straight into the conversation
  • Per-participant audio for diarization — transcription splits speakers even in PiP
  • Background blur fixed — CSP was blocking MediaPipe WASM; blur now works with one click
  • Cleaner AITS session UI — the AI assistant disappeared from the toolbar, less visual noise
  • PiP overlay clickable — removing pointerEvents:none and overflow:hidden, PiP buttons respond to clicks
  • “Join session” button — was hidden by a CSS override, now visible
  • Stale closure in handleMaximize — fixed; PiP maximize no longer throws an error

7. 📐 Beck v2 conceptualization and ABC — PDF, version toggle, prompt editing

  • Beck and ABC v2 PDF — fixed formatting and automatic inclusion in session materials (reported by Ewa, SCRUM-1297)
  • Beck PDF — border-only sections, colorful specializations, clean initials, SVG arrow between sections
  • ABC v1/v2 toggle in Conceptualization v2 — pick which ABC version to display
  • Prompt edit cog in ABC v2 — modify the AI prompt in the ABC v2 tab
  • PDF export for AI analyses and ABC per session — individual analyses exported separately
  • ABC labels pluralization in 8 languages — conceptualization table has correct plural forms
  • ABC empty columns fix — backend returns proper plural property names

8. 🧾 Invoices and KSeF — payment selection + state machine

The invoicing system was refactored for compliance with KSeF (Polish national e-invoicing system).

  • Invoice from selected payments — pick payments and the system creates a single invoice from them (snapshot + Payment FK)
  • “Issue invoice” entry point in the therapist’s finance view — quick access from the dashboard
  • Item removal in the invoice issuance modal — fix mistakes on the fly
  • KSeF dev/prod separation — sandbox and production work on separate credentials
  • Invoice state machine (SCRUM-1357 Bohdan) — Draft → Issued → Sent → Cancelled, with a DB constraint on illegal transitions
  • AE KsefToken — KSeF token encrypted with Always Encrypted

Joint work by Bohdan (SCRUM-1357, SCRUM-1388).

9. 📅 Calendar, recurring sessions, and locations

The weekly and recurring calendar got dozens of small but visible improvements — most reported by Joanna and Ewa.

  • Sessions from 22:00 — were invisible on the weekly grid, now they show until end of day
  • All hours on the recurring slot grid (SCRUM-874, Joanna)
  • On-time cancelled session — does not show as “Unpaid” (SCRUM-918, Joanna)
  • Recurrence label next to the recurring slot (SCRUM-919, Joanna) — you see “weekly”, “biweekly” next to each repeating session
  • Hiding Zoom integration from UI (SCRUM-789, Joanna) — Zoom is no longer supported as a video channel
  • Session popover in calendar — no longer hides off-screen
  • TherapistAvailability — auto-save on every change (debounce 800 ms), no save button needed
  • AddSessionModal — option “create session outside availability hours” — exceptions can force a slot
  • Status “No-show” (NoShow=5) — new status, settable even from completed or cancelled
  • RecurringSessionsCalendar — summary tiles above the legend and grid

Therapist locations got online meeting channels per location:

  • Onsite mode — address and city fields for in-person locations
  • Onsite/online switch instead of a checkbox — clearer mode choice
  • Online channel per location — different locations can have different channels (AITS, Google Meet, external link), auto-propagated to sessions
  • Per-patient permanent meeting rooms — every patient has a permanent AITS room link and a separate external link visible in patient settings
  • Location deletion — fixed (was disappearing from DB but staying on the UI list)

And finally meeting type in recurring sessions — fixed propagation of MeetingType and MeetingLink from the recurring series configuration to each generated session and to reminder emails (SCRUM-902, Ewa).

10. 📱 Mobile app — dark theme, AdHoc Inbox, polish

Mobile moved to version 1.5.0 (build 18) with a load of user-visible changes and a few App Store / Play Store signing touches.

  • Dark theme — full dark mode with readable group headers (SCRUM-1089, Ewa + SCRUM-815)
  • Configurable reminders — pick when you want a session notification
  • Mobile reminder 15 min — 15-minute pre-session reminder + warning when system notifications are off (SCRUM-815, Bohdan)
  • Empty state for session list — instead of a blank screen, a richer onboarding (SCRUM-1094, Ewa)
  • Auto-refresh banner — when the app detects an update, it shows an inviting refresh banner
  • AdHoc Inbox + AssignPatient + quick-start in MAUI (SCRUM-1289, Bohdan)
  • PWA mobile quick-start for ad-hoc sessions (SCRUM-1286, Bohdan)
  • Responsive web view for phone — desktop unchanged, on phone the layout adapts to the narrow screen
  • Deep-link handler in iOS — uses BindingContext, URL scheme registration
  • iOS NSLocation purpose strings — fixing ITMS-90683 (App Store rejected build without these)
  • Android AAB — explicit jarsigner step
  • App Store Connect and Google Play materials — full pack plus WCAG 2.2 audit

11. 🔐 Security: SOC 2 / HIPAA, MFA, full AI pseudonymization

Underneath the product layer we did a full SOC 2 and HIPAA hardening pass plus a DDD audit with five concrete deliveries.

  • MFA re-verification for critical operations — for sensitive actions (password change, data export) you re-confirm with MFA
  • Backup codes for MFA — emergency codes if you lose your phone
  • IAnonymizedLlmGateway (SCRUM-1353, Bohdan) — all AI model calls now go through a pseudonymizing gateway. Names, dates, places are replaced with pseudonyms before they leave the app; AI gets only the anonymized version
  • Pseudonymization of email/SMS notifications (SCRUM-1354) — message templates also don’t leak patient data on send
  • OAuth tokens Google/Zoom encrypted with Always Encrypted (SCRUM-1355) — integration access tokens are column-encrypted
  • Patient.PendingConsent flag (SCRUM-1356) — patients without active consent get an enforcement flow + frontend badge
  • Invoice state machine (SCRUM-1357) — invoice statuses are immutable in invalid directions, enforced at the DB level
  • Audit immutability + user snapshot in 3 audit tables — action log cannot be modified post-fact
  • DeanonymizationAuditLog — every use of patient data after deanonymization is logged together with the email + displayName snapshot of the user who performed it
  • Hardcoded secrets removed — all keys and passwords from appsettings.json moved to Azure Key Vault
  • Always Encrypted for all user text data (ADR-0018) — architectural direction approved; further tables migrate next release
  • ISO/IEC compliance gap analysis — 95 gaps across 9 standards mapped, with a remediation plan

Backed by a full DDD audit (Sessions 1-8, Phases 1-6) — domain context restructure, architecture documentation, ADRs, mermaid + tests, playbooks, Confluence integration.

12. 👤 Patient portal — analyses in Goals, materials, better preview

  • Beck conceptualization in the patient’s “Goals” tab — when you publish the conceptualization, the patient sees it in their portal
  • Publishing analyses to the patient portal + notification preferences (SCRUM-1338, Bartlomiej) — control what and when the patient receives
  • Portal PDF previewiframe instead of embed, CSP allows blob: (PDFs load)
  • Patient portal preview from the therapist’s view — see what the patient sees (chrome in wrapper, dashboard 1:1)
  • Session materials in Azure Blob Storage — SessionMaterial as blob, no more local filesystem
  • Consent / documents section + registration source in patient settings
  • Global patient email uniqueness (SCRUM-898) — a second patient with the same email gets a 409 + closed modal (SCRUM-898, Ewa)
  • Notification template seeder for SK, CA, RU, UK, LT (SCRUM-883, Joanna) — full multilingual mailing
  • Resolver fallback to platform default — when a therapist hasn’t overridden the template, the default multilingual one is sent (SCRUM-883)

13. 🎙️ Transcription — reliable recording, append, real-time with diarization

  • Append to existing transcription — continue recording into the same session; segments append (intent survives a page reload)
  • Per-participant audio for diarization — video transcription separates speakers on independent tracks
  • Transcription survives PiP — minimizing the room doesn’t break recording
  • Transcription language from session settings — STT uses the language you set for the patient
  • Auto-refresh for transcription on focus / visibilitychange / return from video
  • Confirm on stop recording < 2s — guard against an empty WAV from a misclick
  • “Sending” badge in the session list — you see when a recording is in upload
  • Real-time with diarization in video session — wasn’t starting before; now works
  • OPFS backup + 48 kbps Opus — recording also saves locally to OPFS as fallback, audio parameters unified
  • SAS direct upload audio (SCRUM-1276, Bohdan) — audio goes directly to Azure via SAS URL, bypassing the backend
  • m4a native to Azure Speech — m4a handled natively, no conversion
  • Format detection by magic bytes (SCRUM-1311, Bohdan) — when Content-Type=application/octet-stream, format is detected from file content
  • Hub without DB text — SignalR realtime hub no longer persists text in DB; finishPending uses multipart POST like MAUI
  • SignalR 1006 fix — removed skipNegotiation so Azure SignalR works + keep-alive tuning
  • [AI] marker from first generation + reliable marker lookup

14. 💬 Notifications, patient settings, small UX

  • NotificationTemplatesAdmin — HTML/Text toggle in the email editor
  • NotificationSettings — email preview renders HTML with fallback
  • PromptEditModal — rebuilt: tabs, model selector, required version names
  • Hide_dev_ui flag reset on logout — developer flags don’t persist across sessions
  • Test patient Ann Fauler — English 1:1 of Polish Anna Pełnialska for EN-only demos
  • Dev UI presentation mode toggle — quick switch into presentation mode
  • Bug report — Jira attachments + reporter label + centered “Submit” button
  • Auth-refresh loop fixed — abort requests and return to login on 401
  • “Server is starting” banner — on cold start (scale-to-zero) we show a notice instead of a blank page
  • Session rating scale — self-reflection instead of quality rating + disclaimer (SCRUM-1005, Joanna)
  • “Minimize” button color changed to cobalt violet (SCRUM-1307, Ewa)
  • “Transcription” label color from red to green (SCRUM-1304, Ewa)
  • “Record now” → “Record AdHoc session” — more accurate button name
  • Sandbox with green ribbon in the top-left corner + [SANDBOX] prefix in title — to avoid environment confusion, plus a repeatable PROD → Sandbox clone (Azure IaC + scripts)

✅ QA Checklist — what to verify after deploy

FeatureVerify
Ad-hoc session — Quick RecordClick Quick Record on the dashboard or PWA — recording starts immediately, the session lands in the AdHoc Inbox
AssignPatient in AdHoc InboxOpen an ad-hoc recording — you can assign to an existing patient or create a new one
Package limitDashboard shows the session counter for the current month and how many remain in the package
Grace period after failed paymentSubscription simulator in PromptyAI — force a failed payment, you get account-only access for 14 days
3-way merge notesIn session details, the Notes field shows three sources side-by-side (therapist / AI / transcription); you can choose what to keep
9 CBT analysesThe CBT analyses tab shows 9 separate items; each generated on demand; each has a prompt-edit cog
Public profile — drawersOpen your own public profile while logged in — bio, specialization, contact edit drawers are visible
Video PiPDuring a video session click minimize — window collapses to mini-player, mic still works, you return without lobby
Background blurIn the video lobby enable background blur — works immediately, no CSP errors
Beck conceptualization PDFGenerate the conceptualization PDF — also appears in session materials
ABC v1/v2 toggleIn conceptualization v2 you can switch the ABC source between version 1 and 2
Invoice from selected paymentsSelect a few payments and click “Issue invoice” — a single invoice is produced from the snapshot
Recurring session with Google MeetThe second and third session in the series have Google Meet correctly set and the email contains the right link
Sessions from 22:00The weekly calendar shows sessions scheduled at 22:00 and later
”No-show” statusIn a completed / cancelled session you can change status to “No-show”
Mobile dark themeIn the mobile app switch to dark theme — group headers are readable
AdHoc Inbox in mobileMobile shows the ad-hoc inbox and lets you assign a patient
MFA re-verificationWhen changing password, the app asks for MFA again
AI pseudonymizationIn logs you see patient data going to AI as pseudonyms
Session materials as blobUpload a file to session materials — it lands in Azure Blob Storage, not on local disk
Global patient email uniquenessAdd a second patient with the same email — you get a 409 and the modal closes
”Server is starting” bannerAfter a longer idle period, app entry shows the banner instead of a blank page

🛠️ What we fixed — fine print

In addition to the big features, ~80 reports from testers and users were resolved. Highlights:

  • PiP overlay was not clickable — fixed
  • Stale closure in handleMaximize — PiP maximize no longer throws
  • PiP keeps the connection — previously room.disconnect() triggered on the fullscreen↔PiP transition
  • “Join session” button was hidden by a CSS override — uncovered
  • Second AITS session for the same patient (SCRUM-1319, Ewa) — drop UNIQUE INDEX on Session.VideoInviteToken
  • Session numbering in conceptualization skips cancelled (SCRUM-1267, Bohdan)
  • Null-safe Payment access in GetSessionDetailsAsync (SCRUM-1268, Bohdan)
  • Test session collision of Anna Pełnialska with Jan at 14:00 — fixed in the seeder
  • Dashboard slowdown — null-safe mapping in GetTodaySessionsAsync and GetSessionDetailsAsync
  • Auto-refresh after recording from microphone ends — works
  • Batch fallback doesn’t overwrite text from previous recordings or block the UI with Processing status
  • Transcription language from session settings — STT respects the patient’s preference
  • CSP — allowing *.clarity.ms, blob: in connect-src, analytics in script-src
  • Auth-refresh loop — aborting requests after 401 and returning to login
  • CSP MediaPipe WASM — background blur works
  • DEV/SANDBOX ribbon also on Azure FQDN, not just custom domain
  • False toast “Transcription failed” on session entry — removed
  • Toast instead of red banner on failed transcription + removed “Resample” button
  • Real-time with diarization in video session — starts properly
  • AI streaming — per-handler AbortController instead of shared (BodyStreamBuffer was aborted)
  • Nginx non-root + Azure Container Apps — multiple iterations to make it work
  • Distributed lock (sp_getapplock) — startup migrations no longer conflict on parallel deploys
  • DbUpdateConcurrencyException in batch transcription poller (SCRUM-1313, Bohdan)
  • BlobNotFound as expected state (SCRUM-1314, Bohdan)
  • Stripe webhook non-JSON payloads (scanners / bots) — silently handled (SCRUM-1315, Bohdan)
  • Audio format detection by magic bytes (SCRUM-1311, Bohdan)
  • Resilient audio upload + defensive Content-Type (SCRUM-1293, Bohdan)
  • FK migration ActiveEmbeddingModelId → ON DELETE NO ACTION
  • Dev client deploy — CACHE_BUST=github.sha forces frontend rebuild

This is the largest, densest release of this spring. If a feature feels familiar — it’s because it was your request or your ticket. Thank you for every report and every screenshot.

Article prepared by the Therapy Support team

Beta testavimas · Prisijunkite dabar

Susigrąžinkite laiką sau
ir savo pacientams

Esate KET terapeutas?
Pažiūrėkite, kaip platforma palaiko jūsų kasdienį darbą.
Sesijų santraukos, kurios tvarko klinikinę medžiagą. Administravimas, kuris netrukdo.